Index: !MkExamples,fd7
===================================================================
--- !MkExamples,fd7	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ !MkExamples,fd7	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -1,5 +0,0 @@
-Dir <Obey$Dir>
-CDir o
-CDir aif
-amu examples RELEASE=Release THROWBACK=-throwback
-echo [Complete]
Index: !MkClean,fd7
===================================================================
--- !MkClean,fd7	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ !MkClean,fd7	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -1,3 +0,0 @@
-Dir <Obey$Dir>
-amu clean RELEASE=Release
-echo [Cleaned]
Index: Makefile,fe1
===================================================================
--- Makefile,fe1	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ Makefile,fe1	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -1,190 +0,0 @@
-# Project:   CMunge Makefile
-
-# MakeDir:
-#  o
-#  o32
-#  aif
-#  aif32
-
-# Toolflags:
-
-INCLUDE = C:,
-
-CCflags = -c -fa -depend !Depend -I$(INCLUDE) -throwback
-CCflags32 = -apcs 3/32 -c -fa -depend !Depend -I$(INCLUDE) -throwback
-CCflagsM = -c -g -fa -depend !Depend -I$(INCLUDE) -throwback
-
-WIPE = wipe
-WIPEFLAGS = F~C~R~V
-
-CDIR = c
-ODIR = o
-HDIR = h
-C++flags = -c -g -depend !Depend -I$(INCLUDE) -throwback
-LinkflagsD = -aif -d -c++ -o $@
-Linkflags = -aif -c++ -o $@
-PartLinkflags = -aof -c++ -o $@
-
-#ObjAsmflags = -g -throwback -NoCache -depend !Depend
-ObjAsmflags = -throwback -NoCache -depend !Depend
-
-CMHGflags =
-LibFileflags = -c -o $@
-Squeezeflags = -o $@
-
-.SUFFIXES:      .o .om .o32 .c
-
-.c.o:;   cc $(CCflags) -o $@ $<
-.c.o32:; cc $(ccflags32) -o $@ $<
-
-.c.om:; MemCheck.CC cc $(ccflagsM) -o $@ $<
-
-OS_FILES =
-
-OC_FILES = \
-        o.apcscli       \
-        o.assemble      \
-        o.datestamp     \
-        o.error         \
-        o.main          \
-        o.mem           \
-        o.options       \
-        o.readfile      \
-        o.str           \
-        o.gfile         \
-        o.throwback     \
-        o.writeheader   \
-        o.writeexport   \
-        o.writefile     \
-        o.blank         \
-        o.format        \
-        o.system        \
-        o.filename      \
-        o.comments
-
-OC32_FILES = \
-        o32.apcscli       \
-        o32.assemble      \
-        o32.datestamp     \
-        o32.error         \
-        o32.main          \
-        o32.mem           \
-        o32.options       \
-        o32.readfile      \
-        o32.str           \
-        o32.gfile         \
-        o32.throwback     \
-        o32.writeheader   \
-        o32.writeexport   \
-        o32.writefile     \
-        o32.blank         \
-        o32.format        \
-        o32.system        \
-        o32.filename      \
-        o32.comments
-
-OMC_FILES = \
-        om.apcscli      \
-        om.assemble     \
-        om.datestamp    \
-        om.error        \
-        om.main         \
-        om.mem          \
-        om.options      \
-        om.readfile     \
-        om.str          \
-        om.gfile        \
-        om.throwback    \
-        om.writeheader  \
-        om.writeexport  \
-        om.writefile    \
-        om.blank        \
-        om.format       \
-        om.system       \
-        om.filename     \
-        om.comments
-
-LIBS = C:o.stubs
-# NOTE: (JRF) Do not use StubsGS until it's been released.
-LIBS32 = C:o.stubsG
-
-# Final targets:
-# We still generate the 26 bit version so that we can compare the output
-Most: aif.cmunge aif32.cmunge
-
-All: aif.cmunge aif32.cmunge aif.cmungeM
-
-Examples: aif.cmunge aif32.cmunge
-        -examples.!Make
-        dir ^
-
-aif.cmunge: aif.cmungeU
-        Squeeze aif.cmungeU aif.cmunge
-aif32.cmunge: aif32.cmungeU
-        Squeeze aif32.cmungeU aif32.cmunge
-
-aif.cmungeU: $(OC_FILES) $(OS_FILES) $(LIBS)
-        link $(linkflags) $(OC_FILES) $(OS_FILES) $(LIBS)
-
-aif32.cmungeU: $(OC32_FILES) $(OS32_FILES) $(LIBS32)
-        link $(linkflags) $(OC32_FILES) $(OS32_FILES) $(LIBS32)
-
-aif.cmungeM: $(OMC_FILES) $(OS_FILES)
-        link $(linkflagsD) $(OMC_FILES) $(OS_FILES) $(LIBS) \
-        MemCheck:o.MC
-
-clean:
-        -wipe aif ~C ~V R F
-        -wipe aif32 ~C ~V R F
-        -wipe o ~C ~V R F
-        -wipe o32 ~C ~V R F
-        -wipe om ~C ~V R F
-        -if "$(RELEASE)" <> "" Then wipe $(RELEASE) ~C ~V R F
-        -wipe Release ~C ~V R F
-        dir Examples
-        /!Clean
-        dir ^
-
-release: aif32.cmunge
-        @echo -- Source $(RELEASE)
-        cdir $(RELEASE)
-        cdir $(RELEASE).Source
-        wipe $(RELEASE).Source ~C~VR
-        cdir $(RELEASE).Source
-        cdir $(RELEASE).Source.Examples
-        cdir $(RELEASE).Source.Examples.cmhg
-        cdir $(RELEASE).Source.Examples.h
-        cdir $(RELEASE).Source.Examples.hdr
-        cdir $(RELEASE).Source.Examples.inc
-        cdir $(RELEASE).Source.Examples.o
-        cdir $(RELEASE).Source.Examples.s
-        cdir $(RELEASE).Source.linux
-        copy Docs          $(RELEASE).Source.Docs ~C~VR
-        IfThere VersionLog Then copy VersionLog $(RELEASE).Source.Docs.History ~C~VR
-        copy Examples.!*   $(RELEASE).Source.Examples.* ~C~VR
-        copy Examples.inc  $(RELEASE).Source.Examples.inc ~C~VR
-        copy Examples.cmhg $(RELEASE).Source.Examples.cmhg ~C~VR
-        copy c             $(RELEASE).Source.c ~C~VR
-        copy linux.mklinks $(RELEASE).Source.linux.mklinks ~C~VR
-        copy h             $(RELEASE).Source.h ~C~VR
-        copy Makefile      $(RELEASE).Source.Makefile ~C~VR
-        IfThere Resources Then Copy Resources.!Mk* $(RELEASE).Source.* ~C~VR Else Copy !Mk* $(RELEASE).Source.* ~C~VR
-        copy VersionNum    $(RELEASE).Source.VersionNum ~C~VR
-        @echo -- Binary $(RELEASE)
-        cdir $(RELEASE).Binary
-        wipe $(RELEASE).Binary ~C~VR
-        cdir $(RELEASE).Binary
-        copy Docs          $(RELEASE).Binary.Docs ~C~VR
-        IfThere VersionLog Then copy VersionLog $(RELEASE).Binary.Docs.History ~C~VR
-        copy aif32.cmunge  $(RELEASE).Binary.cmunge ~C~VR
-        @echo -- Archive
-        IfThere Run:losecvs Then losecvs $(RELEASE)
-
-export:
-        @echo [No export of CMunge]
-
-# User-editable dependencies:
-
-# Static dependencies:
-
-# Dynamic dependencies:
Index: !Mk,fd7
===================================================================
--- !Mk,fd7	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ !Mk,fd7	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -1,5 +0,0 @@
-Dir <Obey$Dir>
-CDir o
-CDir aif
-amu THROWBACK=-throwback RELEASE=Release Most
-echo [Complete]
Index: !MkRelease,fd7
===================================================================
--- !MkRelease,fd7	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ !MkRelease,fd7	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -1,5 +0,0 @@
-Dir <Obey$Dir>
-CDir o
-CDir aif
-amu release RELEASE=Release THROWBACK=-throwback
-echo [Complete]
Index: options.h
===================================================================
--- options.h	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ options.h	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -31,8 +31,8 @@
   int          international;
   char        *invalid_syntax;
   char        *help_text;
-  char        *name;
-  char        *handler;
+  const char  *name;
+  const char  *handler;
   int          no_handler; /* There isn't a code entry point */
   help_list    next;
 } help_list_s;
@@ -51,18 +51,26 @@
 typedef struct swi_list_s *swi_list;
 
 typedef struct swi_list_s {
-  char     *name;
-  char     *handler;
-  swi_list  next;
+  const char *name;
+  const char *handler;
+  swi_list    next;
 } swi_list_s;
 
+/* PDriver list */
+
+typedef struct pdriver_list_s pdriver_list;
+struct pdriver_list_s {
+  const char   *handler;
+  pdriver_list *next;
+};
+
 /* Handler list */
 
 typedef struct handler_list_s *handler_list;
 
 typedef struct handler_list_s {
-  char         *name;
-  char         *handler;
+  const char  *name;
+  const char  *handler;
   int          private_word;
   int          carry_capable; /* Set for generics if it is capable of setting
                                  carry on return */
@@ -81,8 +89,8 @@
 typedef struct error_list_s *error_list;
 
 typedef struct error_list_s {
-  char         *name;
-  char         *message;
+  const char   *name;
+  const char   *message;
   unsigned int number; /* 0 to auto-allocate, number for an explicit number */
   error_list  next;
 } error_list_s;
@@ -119,13 +127,14 @@
     tc_gcc,
     tc_lcc
   } toolchain;
+  int           no_scl;         /* module does not need SCL */
   int           reentrant;	/* module-is-not-reentrant */
   int           cplusplus;      /* module-is-c-plus-plus */
-  char         *service;	/* service-call-handler */
+  const char   *service;	/* service-call-handler */
   int_list      services;	/* service-call-handler */
   char         *title;		/* title-string */
-  char         *help;		/* help-string */
-  char         *helpfn;		/* help-handler */
+  const char   *help;		/* help-string */
+  const char   *helpfn;		/* help-handler */
   help_list     commands;	/* command-keyword-table */
   int           command_codesupplied; /* commands include handler routines */
   int           swi_base;	/* swi-shunk-base-number */
@@ -133,6 +142,8 @@
   swi_list      swi_names;	/* swi-decoding-table */
   int           swi_codesupplied; /* swis include handler routines */
   handler_list  swi_decoder;	/* swi-decoding-code */
+  const char   *pdriver_entry;  /* pdriver-handler: entry point name */
+  pdriver_list *pdriver_names;  /* pdriver-handler: C function names per reason code */
   int           error_base;     /* error base */
   handler_list  irqs;		/* irq-handlers */
   handler_list  events;		/* event-handler */
@@ -150,8 +161,8 @@
 
   /* The files we're going to use */
   int          blank;           /* Are we producing a blank template file ? */
-  char         *ofile;		/* the AOF file */
-  char         *sfile;		/* the assembler file */
+  char         *ofile;		/* the AOF or ELF file */
+  const char   *sfile;		/* the assembler file */
   int           stemp;          /* is the assembler in a temporary file? */
   char         *hfile;		/* the C header */
   char         *x_hdr;		/* the assembler SWI header */
@@ -171,7 +182,7 @@
 
   /* For pre-processing */
   char         *rootinfile;     /* the base input file to emulate cmhg's ignoring of anything in include files */
-  char         *pfile;          /* preprocessed file */
+  const char   *pfile;          /* preprocessed file */
   int           pextended;      /* are we using extended pre-processor operations */
   defines_list  defines;        /* any defines added */
   include_list  includes;       /* Include Path List */
Index: copyright.h
===================================================================
--- copyright.h	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ copyright.h	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -8,6 +8,8 @@
 #ifndef COPYRIGHT_CMUNGE_H
 #define COPYRIGHT_CMUNGE_H
 
-#define Copyright_CMunge "Copyright (c) 1999-2006 Robin Watts/Justin Fletcher"
+#define Copyright_CMunge \
+  "Copyright (c) 1999-2006 Robin Watts/Justin Fletcher\n" \
+  "Copyright (c) 2007-2012 GCCSDK Developers and contributors"
 
 #endif
Index: apcscli.c
===================================================================
--- apcscli.c	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ apcscli.c	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -52,7 +52,7 @@
  Returns:      new flags
  ******************************************************************/
 unsigned long apcscli_parse(unsigned long flags, const char *arg,
-                            void (*errfunc)(char *format, ...))
+                            void (*errfunc)(const char *format, ...))
 {
   if (*arg == '3') arg++;
   while (*arg)
Index: configure.ac
===================================================================
--- configure.ac	(.../branches/CMungeImportBranch/cmunge)	(revision 0)
+++ configure.ac	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -0,0 +1,9 @@
+AC_PREREQ(2.64)
+AC_INIT([cmunge],[0.76],[http://gccsdk.riscos.info/])
+
+AC_PROG_CC
+
+AM_INIT_AUTOMAKE([-Wall -Werror foreign])
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
Index: GCCSDK-CHANGES
===================================================================
--- GCCSDK-CHANGES	(.../branches/CMungeImportBranch/cmunge)	(revision 0)
+++ GCCSDK-CHANGES	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -0,0 +1,34 @@
+The official CMunge v0.76 contains nearly all the changes needed for usage
+in the GCCSDK 3.4 project.  For GCCSDK 4 we had to made additional changes
+for ELF, instead of AOF, object format support only affecting the operation
+of the -tgcc option.  Two new features have been added : printer driver
+handler and no-SCL support.
+
+More detailed overview of the changes made so far:
+
+  - GCCSDK specific build structure changes.
+  - Hiding RISC OS specific build files (Makefile,fe1, !Mk*,fd7 files)
+  - Added to Module_FullVersionAndDate of VersionNum the substring
+    "[with GCCSDK 4 changes including r" followed by the Subversion revision
+    number of the code base used to make the cmunge binary.
+    This will be visible in the startup message and generated files will be
+    similary marked as well.
+  - -tgcc option supports ELF object format and no longer AOF object format.
+  - Added 'pdriver-handler' keyword for those wanting to create printer driver
+    module code. Added an example for this new feature.
+    Added explanation on 'pdriver-handler' in manual.
+  - Added the posibility to create modules without using the Shared C Library
+    runtime (option -znoscl) + manual update.
+  - Several manual typo fixes.
+  - Source improvements:
+    - strduptok/strfindpair/strstring : use memcpy() instead of strncpy() for
+      more clearness.
+    - constify a lot of pointers where it made sense.
+
+The GCCSDK-DIFF file contains those changes in diff format and are submitted
+back to the CMunge authors for possible inclusion in future versions.  It is
+generated using:
+
+  $ svn diff svn://svn.riscos.info/gccsdk/branches/CMungeImportBranch/cmunge svn://svn.riscos.info/gccsdk/trunk/gcc4/riscos/cmunge
+
+-EOF-
Index: apcscli.h
===================================================================
--- apcscli.h	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ apcscli.h	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -42,7 +42,7 @@
  Returns:      new flags
  ******************************************************************/
 unsigned long apcscli_parse(unsigned long flags, const char *arg,
-                            void (*errfunc)(char *format, ...));
+                            void (*errfunc)(const char *format, ...));
 
 /*************************************************** Gerph *********
  Function:     apcscli_help
Index: VersionNum
===================================================================
--- VersionNum	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ VersionNum	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -20,5 +20,5 @@
 #define Module_ComponentPath            "Sources/BuildTools/CMunge"
 
 #define Module_FullVersion              "0.76"
-#define Module_FullVersionAndDate       "0.76 (10 May 2006)"
+#define Module_FullVersionAndDate       "0.76 (10 May 2006) [with GCCSDK 4 changes " GCCSDK_REVISION "]"
 #define Module_HelpVersion              "0.76 (10 May 2006)"
Index: system.c
===================================================================
--- system.c	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ system.c	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -2,6 +2,12 @@
  * Copyright (C) 2003 Justin Fletcher
  */
 
+#if !defined(__riscos) || !defined(__TARGET_SCL__)
+/* To make WEXITSTATUS() available which converts the return code of
+   system() into a real exit status value.  */
+#  define _XOPEN_SOURCE
+#endif
+
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -42,7 +48,7 @@
 int our_system(const char *cmdtxt)
 {
   int rc;
-#ifdef __riscos
+#if defined(__riscos) && defined(__TARGET_SCL__)
 
 #ifndef DDEUtils_SetCLSize
 #define DDEUtils_SetCLSize (0x42581)
@@ -75,7 +81,7 @@
     ErrorFatal("Cannot set Extended CLI (%s); aborting\n",err->errmess);
   }
 
-  dprintf("Starting command '%s'\n", cmd);
+  dprintf("Starting command '%s' with DDEUtils CL '%s'\n", cmd, cmdtxt);
   /* The Pace SharedCLibrary is broken with regard to command line invocation.
      Apparently, it explicitly clears the DDEUtils command line before
      invocation of the command with system(). This means that we cannot set
@@ -86,6 +92,13 @@
    */
   rc = _kernel_system(cmd, 0);
   dprintf("  got return code %i\n", rc);
+  /* Clear DDEUtils' command line buffer as this seems not to happen when the
+     command can not be found.  */
+  if (rc != EXIT_SUCCESS
+      && (err = _swix(DDEUtils_SetCLSize, _IN(0), 0)) != NULL)
+  {
+    ErrorFatal("Cannot reset Extended CLI size (%s); aborting\n",err->errmess);
+  }
   free(cmd);
 #else
   int need_quotes =0;
@@ -134,6 +147,8 @@
   /* Fake the RISC OS form of 'could not start process' */
   if (rc==-1)
     rc = -2;
+  else
+    rc = WEXITSTATUS(rc);
 #endif
   return rc;
 }
Index: throwback.c
===================================================================
--- throwback.c	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ throwback.c	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -21,7 +21,7 @@
   _kernel_swi(DDEUtils_ThrowbackEnd,&ARM,&ARM);
 }
 
-void vThrowbackf(seriousness_t seriousness,char *file,int line,char *format,va_list args)
+void vThrowbackf(seriousness_t seriousness,const char *file,int line,const char *format,va_list args)
 {
   char buf[1024];
 
@@ -29,7 +29,7 @@
   Throwback(seriousness,file,line,buf);
 }
 
-void Throwback(seriousness_t seriousness,char *file,int line,char *message)
+void Throwback(seriousness_t seriousness,const char *file,int line,const char *message)
 {
   static int registered=0;
   _kernel_swi_regs ARM;
@@ -75,14 +75,14 @@
   /* Nothing to do */
 }
 
-void vThrowbackf(seriousness_t seriousness,char *file,int line,char *format,va_list args)
+void vThrowbackf(seriousness_t seriousness,const char *file,int line,const char *format,va_list args)
 {
   char buf[1024];
   vsprintf(buf,format,args);
   Throwback(seriousness,file,line,buf);
 }
 
-void Throwback(seriousness_t seriousness,char *file,int line,char *message)
+void Throwback(seriousness_t seriousness,const char *file,int line,const char *message)
 {
   fprintf(stderr, "%s:%d: %s: %s\n", file, line, (seriousness==s_information) ? "info" : "warning", message);
 }
Index: comments.c
===================================================================
--- comments.c	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ comments.c	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -11,6 +11,7 @@
 #include <stdio.h>
 #include "format.h"
 #include "comments.h"
+#include "options.h"
 
 /*************************************************** Gerph *********
  Function:     c_comment
@@ -35,8 +36,12 @@
  ******************************************************************/
 void asm_comment(FILE *file,char *text)
 {
-  format_wrap(file,"; ",
-                   "; ", text,
-                   "");
+  if (opt.toolchain == tc_gcc)
+    format_wrap(file,"@ ",
+                     "@ ", text,
+                     "");
+  else
+    format_wrap(file,"; ",
+                     "; ", text,
+                     "");
 }
-
Index: gfile.c
===================================================================
--- gfile.c	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ gfile.c	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -16,18 +16,19 @@
 /* Define this to debug this file */
 /* #define DEBUG */
 
-typedef struct {
-  void *next;
+typedef struct filelist_s filelist;
+struct filelist_s {
+  filelist *next;
   FILE *handle;
-  char *filename;
+  const char *filename;
   removetype remove;
-} filelist;
+};
 
 static filelist *list=NULL;
 static int failed=1;
 
 #ifdef DEBUG
-char *removenames[] =
+const char * const removenames[] =
 {
   "never",
   "onfail",
@@ -240,7 +241,7 @@
  Parameters:   none
  Returns:      pointer to filename, or NULL if failed
  ******************************************************************/
-char *file_temp(void)
+const char *file_temp(void)
 {
   filelist *ptr;
 
@@ -285,12 +286,12 @@
         *lastp=ptr->next; /* Unlink from chain */
         if (ptr->remove==remove_onclose)
           remove(ptr->filename);
-        free(ptr->filename);
+        free((void *)ptr->filename);
         free(ptr);
       }
       return 0;
     }
-    lastp=(filelist **)&ptr->next;
+    lastp=&ptr->next;
     ptr=ptr->next;
   }
 #ifdef DEBUG
Index: throwback.h
===================================================================
--- throwback.h	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ throwback.h	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -18,7 +18,7 @@
   s_warning=0, s_error, s_seriouserror, s_information
 } seriousness_t;
 
-void vThrowbackf(seriousness_t seriousness,char *file,int line,char *format,va_list args);
-void Throwback(seriousness_t seriousness,char *file,int line,char *message);
+void vThrowbackf(seriousness_t seriousness,const char *file,int line,const char *format,va_list args);
+void Throwback(seriousness_t seriousness,const char *file,int line,const char *message);
 
 #endif
Index: error.c
===================================================================
--- error.c	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ error.c	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -8,7 +8,7 @@
 #include "options.h"
 #include "throwback.h"
 
-void ErrorFatal(char *err, ...) {
+void ErrorFatal(const char *err, ...) {
 
   va_list args;
 
@@ -33,7 +33,7 @@
   exit(EXIT_FAILURE);
 }
 
-void Warning(char *err, ...) {
+void Warning(const char *err, ...) {
 
   va_list args;
 
@@ -53,7 +53,7 @@
 
 /* This will eventually do either warning or fatal error depending
    on a switch */
-void CMHGWarning(char *err, ...) {
+void CMHGWarning(const char *err, ...) {
 
   va_list args;
 
Index: writefile.c
===================================================================
--- writefile.c	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ writefile.c	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -1,7 +1,9 @@
 /*
  * Copyright (C) 1999-2003 Robin Watts/Justin Fletcher
+ * Copyright (c) 2007-2010 GCCSDK Developers
  */
 
+#include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -31,29 +33,256 @@
 #define IF_OPTIMISED_HEADER(cond) if (1)
 #endif
 
-/* Special ways we relocate ourselves to point at our special data */
-#define ADD_Lib_Reloc \
-"\t; This is equivalent of 'ADD r10, r10, #0' + |_Lib$Reloc$Off$DP|\n\
-\tDCD\t|_Lib$Reloc$Off$DP| + &E28AA000\n"
-#define ADD_Lib_Reloc_VC \
-"\t; This is equivalent of 'ADDVC r10, r10, #0' + |_Lib$Reloc$Off$DP|\n\
-\tDCD\t|_Lib$Reloc$Off$DP| + &728AA000\n"
-#define SUB_Lib_Reloc \
-"\t; This is equivalent of 'SUB r10, r10, #0' + |_Lib$Reloc$Off$DP|\n\
-\tDCD\t|_Lib$Reloc$Off$DP| + &E24AA000\n"
-#define SUB_Lib_Reloc_VC \
-"\t; This is equivalent of 'SUBVC r10, r10, #0' + |_Lib$Reloc$Off$DP|\n\
-\tDCD\t|_Lib$Reloc$Off$DP| + &724AA000\n"
-#define SUB_Lib_Reloc_S \
-"\t; This is equivalent of 'SUBS r10, r10, #0' + |_Lib$Reloc$Off$DP|\n\
-\tDCD\t|_Lib$Reloc$Off$DP| + &E25AA000\n"
-
 static FILE *file;
 
 static int finalise_imported = 0;
 
-static void outstring(const char *s,int terminate, char newline, int translate_underscore) {
+/* Special ways we relocate ourselves to point at our special data */
 
+static void
+output_ADD_Lib_Reloc(void)
+{
+  if (opt.no_scl)
+    fputs("\tADD\tr10, r10, #540\n", file); /* Hard coded as we don't link with a SCL stub.  */
+  else if (opt.toolchain == tc_gcc)
+    fputs("\t@ This is equivalent of 'ADD r10, r10, #0' + _Lib$Reloc$Off$DP\n"
+	  "\t.word\t_Lib$Reloc$Off$DP + 0xE28AA000\n", file);
+  else
+    fputs("\t; This is equivalent of 'ADD r10, r10, #0' + |_Lib$Reloc$Off$DP|\n"
+	  "\tDCD\t|_Lib$Reloc$Off$DP| + &E28AA000\n", file);
+}
+
+static void
+output_SUB_Lib_Reloc(void)
+{
+  if (opt.no_scl)
+    fputs("\tSUB\tr10, r10, #540\n", file); /* Hard coded as we don't link with a SCL stub.  */
+  else if (opt.toolchain == tc_gcc)
+    fputs("\t@ This is equivalent of 'SUB r10, r10, #0' + _Lib$Reloc$Off$DP\n"
+	  "\t.word\t_Lib$Reloc$Off$DP + 0xE24AA000\n", file);
+  else
+    fputs("\t; This is equivalent of 'SUB r10, r10, #0' + |_Lib$Reloc$Off$DP|\n"
+	  "\tDCD\t|_Lib$Reloc$Off$DP| + &E24AA000\n", file);
+}
+
+static void
+output_SUB_Lib_Reloc_S(void)
+{
+  if (opt.no_scl)
+    fputs("\tSUBS\tr10, r10, #540\n", file);
+  else if (opt.toolchain == tc_gcc)
+    fputs("\t@ This is equivalent of 'SUBS r10, r10, #0' + _Lib$Reloc$Off$DP\n"
+	  "\t.word\t_Lib$Reloc$Off$DP + 0xE25AA000\n", file);
+  else
+    fputs("\t; This is equivalent of 'SUBS r10, r10, #0' + |_Lib$Reloc$Off$DP|\n"
+	  "\tDCD\t|_Lib$Reloc$Off$DP| + &E25AA000\n", file);
+}
+
+/* Write comment in assembler file.  Support multiline comments but terminating
+   EOL characters are not part of the comment and outputed directly.  */
+static void
+output_comment(const char *comment)
+{
+  while (1)
+    {
+      fputc((opt.toolchain == tc_gcc) ? '@' : ';', file);
+      fputc(' ', file);
+      for (/* */; *comment != '\0' && *comment != '\n'; ++comment)
+	fputc(*comment, file);
+      if (*comment == '\0')
+	break;
+      /* Check if we have terminating EOL characters.  */
+      const char *s;
+      for (s = comment; *s == '\n'; ++s)
+	/* */;
+      if (*s != '\0')
+	{
+	  /* We have one or more EOL characters in the comment itself.  So
+	     start a new comment line in the output.  */
+	  fputc('\n', file);
+	  ++comment; /* Skip one EOL character.  */
+	}
+      else
+	{
+	  /* Output the rest of the comment which is nothing else than one or
+	     more EOL characters and bail out.  */
+	  fputs(comment, file);
+	  break;
+	}
+    }
+}
+
+/* Write comment in assembler file.  */
+static void output_comment_vargs(const char *comment, ...)
+{
+  va_list varg;
+  fputc((opt.toolchain == tc_gcc) ? '@' : ';', file);
+  fputc(' ', file);
+  va_start(varg, comment);
+  vfprintf(file, comment, varg);
+  va_end(varg);
+}
+
+/* Write import symbol statement in assembler file.  For GAS, this is
+   not necessary.  */
+static void output_import(const char *symbol)
+{
+  if (opt.toolchain != tc_gcc)
+    fprintf(file, "\tIMPORT\t|%s|\n", symbol);
+}
+
+/* Write import symbol statement in assembler file.  For GAS, this is
+   not necessary.  */
+static void output_import_vargs(const char *symbol, ...)
+{
+  if (opt.toolchain != tc_gcc)
+  {
+    va_list varg;
+    fputs("\tIMPORT\t|", file);
+    va_start(varg, symbol);
+    vfprintf(file, symbol, varg);
+    va_end(varg);
+    fputs("|\n", file);
+  }
+}
+
+/* Write export symbol statement in assembler file.  */
+static void output_export(const char *symbol)
+{
+  if (opt.toolchain == tc_gcc)
+    fprintf(file, "\t.global\t%s\n", symbol);
+  else
+    fprintf(file, "\tEXPORT\t|%s|\n", symbol);
+}
+
+/* Write export symbol statement in assembler file.  */
+static void output_export_vargs(const char *symbol, ...)
+{
+  if (opt.toolchain == tc_gcc)
+  {
+    va_list varg;
+    fputs("\t.global\t", file);
+    va_start(varg, symbol);
+    vfprintf(file, symbol, varg);
+    va_end(varg);
+    fputc('\n', file);
+  }
+  else
+  {
+    va_list varg;
+    fputs("\tEXPORT\t|", file);
+    va_start(varg, symbol);
+    vfprintf(file, symbol, varg);
+    va_end(varg);
+    fprintf(file, "|\n");
+  }
+}
+
+/* Write import symbol statement with weak attribute in assembler file.  For
+   GAS this just means a declaration of the symbol being weak.  */
+static void output_weak_import(const char *symbol)
+{
+  if (opt.toolchain == tc_gcc)
+    fprintf(file, "\t.weak\t%s\n", symbol);
+  else
+    fprintf(file, "\tIMPORT\t|%s|, WEAK\n", symbol);
+}
+
+/* Write a label.  */
+static void output_label(const char *label)
+{
+  if (opt.toolchain == tc_gcc)
+    fprintf(file, "%s:\n", label);
+  else
+    fprintf(file, "%s\n", label);
+}
+
+/* Write a label.  */
+static void output_label_vargs(const char *label, ...)
+{
+  va_list varg;
+  va_start(varg, label);
+  vfprintf(file, label, varg);
+  va_end(varg);
+  if (opt.toolchain == tc_gcc)
+    fputc(':', file);
+  fputc('\n', file);
+}
+
+/* Write word value.  */
+static void output_word(unsigned int wval, const char *comment)
+{
+  if (opt.toolchain == tc_gcc)
+    fprintf(file, "\t.word\t0x%x\t@ %s\n", wval, comment);
+  else
+    fprintf(file, "\tDCD\t&%x\t; %s\n", wval, comment);
+}
+
+/* Write word value using string.  */
+static void output_word_as_str(const char *wval, const char *comment)
+{
+  if (opt.toolchain == tc_gcc)
+    fprintf(file, "\t.word\t%s\t@ %s\n", wval, comment);
+  else
+    fprintf(file, "\tDCD\t%s\t; %s\n", wval, comment);
+}
+
+static void output_word_vargs(const char *wval, ...)
+{
+  va_list varg;
+  if (opt.toolchain == tc_gcc)
+    fputs("\t.word\t", file);
+  else
+    fputs("\tDCD\t", file);
+  va_start(varg, wval);
+  vfprintf(file, wval, varg);
+  va_end(varg);
+  fputc('\n', file);
+}
+
+/* Write align statement for 4 byte alignment.  */
+static void output_align(void)
+{
+  if (opt.toolchain == tc_gcc)
+    fputs("\t.align\n", file);
+  else
+    fputs("\tALIGN\n", file);
+}
+
+/* Write a string which does not contain any special characters like quotes,
+   top-bit chars, backslashes, newlines, etc.  */
+static void output_simple_string(const char *str)
+{
+  if (opt.toolchain == tc_gcc)
+    fprintf(file, "\t.asciz\t\"%s\"\n", str);
+  else
+    fprintf(file, "\t= \"%s\", 0\n", str);
+}
+
+/* Write a string which does not contain any special characters like quotes,
+   top-bit chars, backslashes, newlines, etc.  */
+static void output_simple_string_vargs(const char *str, ...)
+{
+  va_list varg;
+  fputs((opt.toolchain == tc_gcc) ? "\t.asciz\t\"" : "\t= \"", file);
+  va_start(varg, str);
+  vfprintf(file, str, varg);
+  va_end(varg);
+  if (opt.toolchain == tc_gcc)
+    fputs("\"\n", file);
+  else
+    fputs("\", 0\n", file);
+}
+
+/* Write the indication we're at the end of the assembler file.  */
+static void output_endfile(void)
+{
+  if (opt.toolchain != tc_gcc)
+    fprintf(file, "\tEND\n");
+}
+
+static void outstring(const char *s, int terminate, char newline, int translate_underscore)
+{
   int inquote=0;
   int chars=0;
 
@@ -61,201 +290,304 @@
   {
       char c=*s;
       if (!chars)
-        fprintf(file, "\t= ");
+      {
+	if (opt.toolchain == tc_gcc)
+	  fputs("\t.ascii\t", file);
+	else
+	  fprintf(file, "\t= ");
+      }
       if (translate_underscore && c=='_')
-        c = ' ';
-      if ((c>31) && (c<127) && (c!='"') && (c!='\\' || s[1]!='\"')) {
-        if (!inquote) {
-          chars+=fprintf(file,chars?",\"":"\"");
-          inquote=1;
-        }
-        fputc(c,file);
-        chars++;
-      } else {
-        if (c=='\\')
-          s++;
-        if (inquote) {
-          chars+=fprintf(file,"\"");
-          inquote=0;
-        }
-        chars+=fprintf(file,"%s%u",chars?",":"",(int)(*s=='\n'?newline:(*s & 0xFF)));
+	c = ' ';
+      if ((c>31) && (c<127) && (c!='"') && (c!='\\' || s[1]!='\"'))
+      {
+	if (!inquote)
+	{
+	  if (opt.toolchain == tc_gcc)
+	  {
+	    if (chars)
+	      fputs("\n\t.ascii\t\"", file);
+	    else
+	      fputc('\"', file);
+	    chars = 1;
+	  }
+	  else
+	    chars+=fprintf(file,chars ? ",\"" : "\"");
+	  inquote=1;
+	}
+	fputc(c,file);
+	chars++;
       }
-      if (*s)
-        s++;
       else
-        terminate=0;
-      if ((chars>60)||!(*s||terminate))
       {
-        if (inquote)
-          fputc('"',file);
-        fputc('\n',file);
-        inquote=0;
-        chars=0;
+	/* ctrl char, topbit char, '"' or any quoted char except quoted dbl quote */
+	if (c=='\\')
+	  c = *++s;
+	/* Terminate string if it is still open. */
+	if (inquote)
+	{
+	  chars+=fprintf(file, "\"");
+	  inquote=0;
+	}
+	/* Write value 'c' as one byte value. */
+	if (opt.toolchain == tc_gcc)
+	{
+	  if (chars)
+	  {
+	    fputc('\n', file);
+	    chars = 0;
+	  }
+	  else
+	    fputs("\"\"\n", file);
+	  fprintf(file, "\t.byte\t%u\n", (int)(c=='\n' ? newline : (c & 0xFF)));
+	}
+	else
+	  chars+=fprintf(file, "%s%u", chars ? "," : "", (int)(c=='\n'?newline:(c & 0xFF)));
       }
+      if (c)
+	s++;
+      else
+	terminate=0;
+      if ((chars>60) || !(*s || terminate))
+      {
+	/* Line too long, start new line in the assembler file.  */
+	if (inquote)
+	  fputc('"', file);
+	fputc('\n', file);
+	inquote=0;
+	chars=0;
+      }
   }
 }
 
-static void asm_header(void) {
+static void asm_header(void)
+{
+  output_comment("Generated by CMunge " Module_FullVersionAndDate "\n");
+  output_comment("CMunge " Copyright_CMunge "\n\n");
 
-  fprintf(file, "; Generated by CMunge " Module_FullVersionAndDate "\n");
-  fprintf(file, "; CMunge " Copyright_CMunge "\n\n");
-  if (opt.base) {
-    fprintf(file, "\tIMPORT\t|Image$$RO$$Base|\n");
-    fprintf(file, "\tEXPORT\tImage__RO_Base\n");
-    fprintf(file, "\tAREA\tCode_Description, DATA, REL\n");
-    fprintf(file, "Image__RO_Base\n");
-    fprintf(file, "\tDCD\t|Image$$RO$$Base|\n\n");
+  if (opt.toolchain == tc_gcc)
+    fputs("\t.ident\t\"CMunge " Module_FullVersionAndDate "\"\n\n", file);
+
+  if (opt.base)
+  {
+    output_import("Image$$RO$$Base");
+    output_export("Image__RO_Base");
+    if (opt.toolchain == tc_gcc)
+    {
+      fputs("\t.section\t.rodata\n"
+	    "\t.align 2\n"
+	    "\t.type Image__RO_Base, %object\n"
+	    "\t.size Image__RO_Base, 4\n", file);
+    }
+    else
+      fputs("\tAREA\tCode_Description, DATA, REL\n", file);
+    output_label("Image__RO_Base");
+    output_word_as_str("Image$$RO$$Base", "");
+    fputc('\n', file);
   }
-  if (opt.toolchain == tc_gcc ||
-      opt.toolchain == tc_lcc)
+
+  if (opt.toolchain == tc_gcc)
   {
+    /* FIXME: adr vs adrl support needs to be written when I start understanding the
+       GAS macro assembler syntax better. */
+    fputs(".macro\taddr reg:req object:req cc\n"
+	  "\tadrl\\cc\t\\reg, \\object\n"
+	  ".endm\n\n", file);
+  }
+  else
+  {
+    if (opt.toolchain == tc_lcc)
+    {
+      fprintf(file, "\
+	GBLL	UsingAS\n\
+UsingAS SETL	{TRUE}\n");
+    }
     fprintf(file, "\
-        GBLL    UsingAS\n\
-UsingAS SETL    {TRUE}\n");
-  }
-  fprintf(file, "\
 ; Some handy macros\n\
-        GBLL    immediate\n\
-        MACRO\n\
-        Immediate $var\n\
+	GBLL	immediate\n\
+	MACRO\n\
+	Immediate $var\n\
 immediate SETL  {FALSE}\n\
-        LCLA    count\n\
-        LCLA    varcopy\n\
-varcopy SETA    $var\n\
-        WHILE   count <= 30\n\
+	LCLA	count\n\
+	LCLA	varcopy\n\
+varcopy SETA	$var\n\
+	WHILE	count <= 30\n\
  [ ((varcopy:SHL:count) + (varcopy:SHR:(32-count))) :AND: (:NOT: &FF) = 0\n\
 immediate SETL  {TRUE}\n\
-        MEXIT\n\
+	MEXIT\n\
  ]\n\
-count   SETA    count + 2\n\
-        WEND\n\
-        MEND\n\
+count	SETA	count + 2\n\
+	WEND\n\
+	MEND\n\
 \n\
-        MACRO\n\
-$label  addr    $reg, $object, $cc\n\
+	MACRO\n\
+$label  addr	$reg, $object, $cc\n\
     [ :DEF: UsingAS\n\
 $label  ADR$cc.L $reg, $object\n\
     |\n\
-        LCLA    value\n\
-value   SETA    .-$object+8\n\
-        Immediate &$value\n\
+	LCLA	value\n\
+value	SETA	.-$object+8\n\
+	Immediate &$value\n\
  [ immediate\n\
 $label  ADR$cc  $reg, $object\n\
  |\n\
 $label  ADR$cc.L $reg, $object\n\
  ]\n\
     ]\n\
-        MEND\n\
+	MEND\n\
 \n\
 ");
+  }
 
-  fprintf(file, "; Now the REAL module header\n");
-  fprintf(file, "\tAREA\t|!Header$$code|, CODE, READONLY%s%s\n\n",
-                 (opt.apcs & APCS_REENTRANT) ? ", PIC, REENTRANT" : "",
-                 (opt.apcs & APCS_FPE3) ? ", FP3" : "");
+  /* Output useful definitions.  */
+  if (opt.toolchain == tc_gcc)
+    {
+      fprintf(file, ".set XSWIBit, 1<<17\n"
+		    ".set OS_Exit, 17\n"
+		    ".set OS_Module, 30\n"
+		    ".set OS_GenerateError, 43\n"
+		    ".set XOS_Exit, OS_Exit + XSWIBit\n"
+		    ".set XOS_Module, OS_Module + XSWIBit\n"
+		    ".set XOS_GenerateError, OS_GenerateError + XSWIBit\n"
+		    "\n");
+    }
+  else
+    {
+      fprintf(file, "XSWIBit * (1<<17)\n"
+		    "OS_Exit * 17\n"
+		    "OS_Module * 30\n"
+		    "OS_GenerateError * 43\n"
+		    "XOS_Exit * OS_Exit + XSWIBit\n"
+		    "XOS_Module * OS_Module + XSWIBit\n"
+		    "XOS_GenerateError * OS_GenerateError + XSWIBit\n"
+		    "\n");
+    }
 
   /* Things that everyone needs */
-  fprintf(file, "\tIMPORT\t|_Lib$Reloc$Off$DP|\n");
+  if (!opt.no_scl)
+    output_import("_Lib$Reloc$Off$DP");
 }
 
-static void mod_header(void) {
-
+static void mod_header(void)
+{
   if (opt.mode_errors)
     return;
 
-  fprintf(file, "\tEXPORT\t__module_header\n");
-  fprintf(file, "__module_header\n\n");
+  output_comment("Now the REAL module header\n");
 
-  fprintf(file, "_CMUNGE_origin\n");
-  if (opt.runnable) {
-    fprintf(file, "\tDCD\t_CMUNGE_start\t\t-_CMUNGE_origin\t; Start offset\n");
-  } else {
-    fprintf(file, "\tDCD\t0\t\t\t\t\t; Start offset\n");
+  if (opt.toolchain == tc_gcc)
+  {
+    /* Put module header in .init section and defining _start
+       symbol here.  This means that the linker will start with this (and
+       place it at front) and work further on it to get all the implied
+       unresolved symbols resolved.  */
+    fputs("\t.section\t\".riscos.module.header\",\"ax\"\n"
+	  "\t.global\t_start\n"
+	  "\t.type\t_start, %function\n"
+	  "_start:\n", file);
   }
-  fprintf(file, "\tDCD\t_CMUNGE_init\t\t-_CMUNGE_origin\t; Initialisation offset\n");
-  fprintf(file, "\tDCD\t_CMUNGE_fin\t\t-_CMUNGE_origin\t; Finalisation offset\n");
-  if (opt.service) {
-    fprintf(file, "\tDCD\t_CMUNGE_service\t\t-_CMUNGE_origin\t; Service handler offset\n");
-  } else {
-    fprintf(file, "\tDCD\t0\t\t\t\t\t; Service handler offset\n");
-  }
-  fprintf(file, "\tDCD\t_CMUNGE_title\t\t-_CMUNGE_origin\t; Title string offset\n");
-  fprintf(file, "\tDCD\t_CMUNGE_help\t\t-_CMUNGE_origin\t; Help string offset\n");
+  else
+    fprintf(file, "\tAREA\t|!Header$$code|, CODE, READONLY%s%s\n\n",
+		  (opt.apcs & APCS_REENTRANT) ? ", PIC, REENTRANT" : "",
+		  (opt.apcs & APCS_FPE3) ? ", FP3" : "");
 
+  output_export("__module_header");
+  output_label("__module_header"); fputc('\n', file);
+
+  output_label("_CMUNGE_origin");
+  if (opt.runnable)
+    output_word_as_str("_CMUNGE_start\t\t-_CMUNGE_origin", "Start offset");
+  else
+    output_word(0, "Start offset");
+  output_word_as_str("_CMUNGE_init\t\t-_CMUNGE_origin", "Initialisation offset");
+  /* Do not have a module finalisation routine when we're not using SCL
+     and no user supplied C routine.  */
+  if (!opt.no_scl || opt.final)
+    output_word_as_str("_CMUNGE_fin\t\t-_CMUNGE_origin", "Finalisation offset");
+  else
+    output_word(0, "Finalisation offset");
+  if (opt.service)
+    output_word_as_str("_CMUNGE_service\t\t-_CMUNGE_origin", "Service handler offset");
+  else
+    output_word(0, "Service handler offset");
+  output_word_as_str("_CMUNGE_title\t\t-_CMUNGE_origin", "Title string offset");
+  output_word_as_str("_CMUNGE_help\t\t-_CMUNGE_origin", "Help string offset");
+
   if (opt.commands)
-    fprintf(file, "\tDCD\t_CMUNGE_command\t\t-_CMUNGE_origin\t; Command table offset\n");
+    output_word_as_str("_CMUNGE_command\t\t-_CMUNGE_origin", "Command table offset");
   else
     IF_OPTIMISED_HEADER(opt.swi_base || opt.swi_names || opt.swi_decoder || opt.mfile)
-      fprintf(file, "\tDCD\t0\t\t\t; No commands specified\n");
+      output_word(0, "No commands specified");
 
-  if (opt.swi_base) {
-    fprintf(file, "\tDCD\t0x%08x\t\t\t\t; SWI chunk base number\n", opt.swi_base);
-    fprintf(file, "\tDCD\t_CMUNGE_swi_handler\t-_CMUNGE_origin\t; SWI handler offset\n");
-  } else {
+  if (opt.swi_base)
+  {
+    output_word(opt.swi_base, "SWI chunk base number");
+    output_word_as_str("_CMUNGE_swi_handler\t-_CMUNGE_origin", "SWI handler offset");
+  }
+  else
+  {
     IF_OPTIMISED_HEADER(opt.swi_names || opt.swi_decoder || opt.mfile)
     {
-      fprintf(file, "\tDCD\t0\t\t; SWI chunk base number\n");
-      fprintf(file, "\tDCD\t0\t\t; SWI handler offset\n");
+      output_word(0, "SWI chunk base number");
+      output_word(0, "SWI handler offset");
     }
   }
   if (opt.swi_names)
-    fprintf(file, "\tDCD\t_CMUNGE_swi_table\t-_CMUNGE_origin\t; SWI table offset\n");
+    output_word_as_str("_CMUNGE_swi_table\t-_CMUNGE_origin", "SWI table offset");
   else
     IF_OPTIMISED_HEADER(opt.swi_decoder || opt.mfile)
-      fprintf(file, "\tDCD\t0\t\t\t; SWI table offset\n");
+      output_word(0, "SWI table offset");
   if (opt.swi_decoder)
-    fprintf(file, "\tDCD\t_CMUNGE_swi_decoder\t-_CMUNGE_origin\t; SWI decoding code offset\n");
+    output_word_as_str("_CMUNGE_swi_decoder\t-_CMUNGE_origin", "SWI decoding code offset");
   else
     IF_OPTIMISED_HEADER(opt.mfile)
-      fprintf(file, "\tDCD\t0\t\t\t; SWI decoding code offset\n");
+      output_word(0, "SWI decoding code offset");
   if (opt.mfile)
-    fprintf(file, "\tDCD\t_CMUNGE_message_file\t-_CMUNGE_origin\t; Message file filename offset\n");
+    output_word_as_str("_CMUNGE_message_file\t-_CMUNGE_origin", "Message file filename offset");
   else
   {
     IF_OPTIMISED_HEADER(opt.mfile)
-      fprintf(file, "\tDCD\t0\t\t\t; Message file filename offset\n");
+      output_word(0, "Message file filename offset");
   }
   if (CODE26)
   {}
   else
-    fprintf(file, "\tDCD\t_CMUNGE_module_flags\t-_CMUNGE_origin\t; Module flags offset\n");
+    output_word_as_str("_CMUNGE_module_flags\t-_CMUNGE_origin", "Module flags offset");
 }
 
-static void strings(void) {
-
+static void strings(void)
+{
   if (opt.mode_errors)
     return;
 
-  fprintf(file, "_CMUNGE_title\n");
+  output_label("_CMUNGE_title");
   outstring(opt.title,1,'\n',0);
-  fprintf(file, "_CMUNGE_help\n");
+  output_label("_CMUNGE_help");
   outstring(opt.help,1,'\n',1);
 #ifndef CMHG_RESOURCE_FILE_ORDERING
-  if (opt.mfile) {
-    fprintf(file, "\tALIGN\n");
-    fprintf(file, "_CMUNGE_message_file\n");
+  if (opt.mfile)
+  {
+    output_align();
+    output_label("_CMUNGE_message_file");
     outstring(opt.mfile,1,'\n',0);
   }
 #endif
 }
 
-static void swi_table(void) {
-
+static void swi_table(void)
+{
   swi_list l;
 
   if (!opt.swi_names)
     return;
-  l = opt.swi_names;
-  fprintf(file, "_CMUNGE_swi_table\n");
-  while (l) {
-    fprintf(file, "\t= \"%s\",0\n", l->name);
-    l = l->next;
-  }
-  fprintf(file, "\t= 0\n");
+
+  output_label("_CMUNGE_swi_table");
+  for (l = opt.swi_names; l != NULL; l = l->next)
+    output_simple_string(l->name);
+  output_simple_string("");
 }
 
-static void commands(void) {
-
+static void commands(void)
+{
 /* JRF: 32bit'd */
   help_list l;
   int n,nentry;
@@ -264,169 +596,164 @@
   /* FIXME: Help entries can be commands - should work; or at least mirror CHMG */
   if (!opt.commands)
     return;
-  l = opt.commands;
-  n = 0;
-  while (l) {
-    if (l->help_text) {
-      fprintf(file, "_CMUNGE_ht%d\n", n);
+
+  for (l = opt.commands, n = 0; l != NULL; l = l->next, ++n)
+  {
+    if (l->help_text)
+    {
+      output_label_vargs("_CMUNGE_ht%d", n);
       if ((l->invalid_syntax) && (l->add_syntax))
-        outstring(l->help_text,0,'\r',0);
+	outstring(l->help_text,0,'\r',0);
       else
-        outstring(l->help_text,1,'\r',0);
+	outstring(l->help_text,1,'\r',0);
     }
-    if (l->invalid_syntax) {
-      fprintf(file, "_CMUNGE_is%d\n", n);
+    if (l->invalid_syntax)
+    {
+      output_label_vargs("_CMUNGE_is%d", n);
       outstring(l->invalid_syntax,1,'\r',0);
     }
-    l = l->next;
-    n++;
   }
-  l = opt.commands;
-  n = 0; nentry = 0;
-  fprintf(file, "\tALIGN\n");
-  fprintf(file, "_CMUNGE_command\n");
-  while (l) {
-    fprintf(file, "\t= \"%s\",0\n", l->name);
-    fprintf(file, "\tALIGN\n");
+
+  output_align();
+
+  nentry = 0;
+  output_label("_CMUNGE_command");
+  for (l = opt.commands, n = 0; l != NULL; l = l->next, ++n)
+  {
+    output_simple_string(l->name);
+    output_align();
     if (l->no_handler)
-      fprintf(file, "\tDCD\t0\n");
+      output_word(0, "No handler");
     else
     {
-      fprintf(file, "\tDCD\t_CMUNGE_ce%d\t- _CMUNGE_origin\n", n);
+      output_word_vargs("_CMUNGE_ce%d\t- _CMUNGE_origin", n);
       nentry++;
     }
     info = l->min_args | (l->max_args<<16) | (l->gstrans<<8) |
-           (l->fs_command ? (1U<<31) : 0) | (l->status ? (1<<30) : 0) |
-           (l->configure ? (1<<30) : 0) | (l->help ? (1<<29) : 0) |
-           (l->international ? (1<<28) : 0);
-    fprintf(file, "\tDCD\t0x%08x\n", info);
+	   (l->fs_command ? (1U<<31) : 0) | (l->status ? (1<<30) : 0) |
+	   (l->configure ? (1<<30) : 0) | (l->help ? (1<<29) : 0) |
+	   (l->international ? (1<<28) : 0);
+    output_word(info, "");
     if (l->invalid_syntax)
-      fprintf(file, "\tDCD\t_CMUNGE_is%d\t- _CMUNGE_origin\n", n);
+      output_word_vargs("_CMUNGE_is%d\t- _CMUNGE_origin", n);
     else
-      fprintf(file, "\tDCD\t0\n");
+      output_word(0, "No invalid syntax line");
     if (l->help_text)
-      fprintf(file, "\tDCD\t_CMUNGE_ht%d\t- _CMUNGE_origin\n", n);
+      output_word_vargs("_CMUNGE_ht%d\t- _CMUNGE_origin", n);
     else
-      fprintf(file, "\tDCD\t0\n");
-    l = l->next;
-    n++;
+      output_word(0, "No help line");
   }
   /* CMHG *doesn't* output the following, because the low byte of the next
      instruction is 0. Hacky or what? For compatibility I'll do the same,
      except when there are no entry points to follow, in which case we
      need the 0 as the following code doesn't have any.
    */
-  if (nentry==0)
+  if (nentry == 0)
   {
-    fprintf(file, "\tDCD\t0\n");
+    output_word(0, "");
     /* Of course, if there are no entry points there is no point in writing
        out any veneers. */
     return;
   }
-  l = opt.commands;
-  n = 0; nentry=0;
-  while (l) {
+
+  nentry=0;
+  for (l = opt.commands, n = 0; l != NULL; l = l->next, ++n)
+  {
     if (!l->no_handler)
     {
       if (nentry != 0)
-        fprintf(file, "\tB\t_CMUNGE_ce\n");
-      fprintf(file, "_CMUNGE_ce%d\n", n);
+	fprintf(file, "\tB\t_CMUNGE_ce\n");
+      output_label_vargs("_CMUNGE_ce%d", n);
       fprintf(file, "\tMOV\tr2,#%d\n", nentry++);
     }
-    l = l->next;
-    n++;
   }
-  fprintf(file, "_CMUNGE_ce\n");
-  fprintf(file, "\tSTMDB\tr13!,{r0,r10,r11,r14}\n");
-  fprintf(file, "\tMOV\tr10,r13,LSR #20\n");
-  fprintf(file, "\tMOV\tr10,r10,LSL #20\n");
-  fprintf(file, "\tLDMIA\tr10,{r4,r5}\n");
-  fprintf(file, "\tMOV\tr3,r12\n");
-  fprintf(file, "\tLDR\tr12,[r12]\n");
-  fprintf(file, "\tLDMIB\tr12,{r11,r12}\n");
-  fprintf(file, "\tSTMIA\tr10,{r11,r12}\n");
-  fprintf(file, ADD_Lib_Reloc);
+  output_label("_CMUNGE_ce");
+  fprintf(file, "\tSTMDB\tr13!,{r0,r10,r11,r14}\n"
+		"\tMOV\tr10,r13,LSR #20\n"
+		"\tMOV\tr10,r10,LSL #20\n"
+		"\tLDMIA\tr10,{r4,r5}\n"
+		"\tMOV\tr3,r12\n"
+		"\tLDR\tr12,[r12]\n"
+		"\tLDMIB\tr12,{r11,r12}\n"
+		"\tSTMIA\tr10,{r11,r12}\n");
+  output_ADD_Lib_Reloc();
   fprintf(file, "\tMOV\tr11,#0\n");
   if (opt.command_codesupplied)
   {
     help_list l;
     int numentries=0;
 
-    l = opt.commands;
-    while (l)
+    for (l = opt.commands; l; l = l->next)
     {
       if (!l->no_handler)
-        numentries++;
-      l=l->next;
+	numentries++;
     }
-    fprintf(file, "\tMOV\tr14,pc\n");
-    fprintf(file, "\tADD\tr14,r14,# _CMUNGE_com_ret - _CMUNGE_com_pc\n");
-    fprintf(file, "_CMUNGE_com_pc\n");
+    fprintf(file, "\tMOV\tr14,pc\n"
+		  "\tADD\tr14,r14,# _CMUNGE_com_ret - _CMUNGE_com_pc\n");
+    output_label("_CMUNGE_com_pc");
     fprintf(file, "\tCMP\tr2,#%i\n",numentries);
     fprintf(file, "\tADDLO\tpc,pc,r2,LSL #2\n");
     if (opt.helpfn)
     {
-      fprintf(file, "\tIMPORT\t%s\n", opt.helpfn);
+      output_import(opt.helpfn);
       fprintf(file, "\tB\t%s\n", opt.helpfn);
     }
     else
       fprintf(file, "\tB\t_CMUNGE_nocom_handler\n");
 
-    l = opt.commands;
-    while (l)
+    for (l = opt.commands; l; l = l->next)
     {
       if (!l->no_handler)
       {
-        if (l->handler)
-        {
-          fprintf(file, "\tIMPORT\t%s\n", l->handler);
-          fprintf(file, "\tB\t%s\n", l->handler);
-        }
-        else
-        {
-          if (opt.commands)
-            fprintf(file, "\tB\t%s\n", opt.helpfn);
-          else
-            fprintf(file, "\tB\t_CMUNGE_nocom_handler\n");
-        }
+	if (l->handler)
+	{
+	  output_import(l->handler);
+	  fprintf(file, "\tB\t%s\n", l->handler);
+	}
+	else
+	{
+	  if (opt.commands)
+	    fprintf(file, "\tB\t%s\n", opt.helpfn);
+	  else
+	    fprintf(file, "\tB\t_CMUNGE_nocom_handler\n");
+	}
       }
-      l=l->next;
     }
     if (!opt.helpfn)
     {
-      fprintf(file, "_CMUNGE_nocom_handler\n");
+      output_label("_CMUNGE_nocom_handler");
       fprintf(file, "\tMOV\tr0,#0\n"); /* no error (wrong!) */
     }
-    fprintf(file, "_CMUNGE_com_ret\n");
+    output_label("_CMUNGE_com_ret");
   }
   else
   {
-    fprintf(file, "\tIMPORT\t%s\n", opt.helpfn);
+    output_import(opt.helpfn);
     fprintf(file, "\tBL\t%s\n", opt.helpfn);
   }
-  fprintf(file, SUB_Lib_Reloc);
-  fprintf(file, "\tSTMIA\tr10,{r4,r5}\n");
-  fprintf(file, "\tLDMIA\tr13!,{r1,r10,r11,r14}\n");
-  fprintf(file, "\tCMP\tr1,r0\n");
-  fprintf(file, "\tCMPNE\tr0,#0\n");
+  output_SUB_Lib_Reloc();
+  fprintf(file, "\tSTMIA\tr10,{r4,r5}\n"
+		"\tLDMIA\tr13!,{r1,r10,r11,r14}\n"
+		"\tCMP\tr1,r0\n"
+		"\tCMPNE\tr0,#0\n");
   if (CODE26)
     fprintf(file, "\tBICEQS\tpc,r14,#0x10000000\n");
   else
     fprintf(file, "\tMOVEQ\tpc,r14\n");
-  fprintf(file, "\tCMN\tr0,#1\n");
-  fprintf(file, "\tMOVEQ\tr0,#0\n");
+  fprintf(file, "\tCMN\tr0,#1\n"
+		"\tMOVEQ\tr0,#0\n");
   if (CODE26)
     fprintf(file, "\tORRS\tpc,r14,#0x10000000\n");
   else
   {
-    fprintf(file, "\tMOV\tr1,#0\n");
-    fprintf(file, "\tCMP\tr1,#1<<31\n");
-    fprintf(file, "\tMOV\tpc,r14\n");
+    fprintf(file, "\tMOV\tr1,#0\n"
+		  "\tCMP\tr1,#1<<31\n"
+		  "\tMOV\tpc,r14\n");
   }
 }
 
-static unsigned int representable(unsigned int i) {
-
+static unsigned int representable(unsigned int i)
+{
   unsigned int mask;
 
   mask = 255;
@@ -435,9 +762,10 @@
   return i & mask;
 }
 
-static void service(void) {
-
-/* JRF: 32bit */
+static void
+service(void)
+{
+  /* JRF: 32bit */
   unsigned int n, m;
   int_list l;
   int big;
@@ -445,1260 +773,1470 @@
 
   if (!opt.service)
     return;
-  if (opt.services) {
-    unsigned int min = 0;
-    unsigned int found;
+  if (opt.services)
+    {
+      unsigned int min = 0;
+      unsigned int found;
 
-    fprintf(file, "_CMUNGE_service_fast\n");
-    fprintf(file, "\tDCD\t0\n");
-    fprintf(file, "\tDCD\t_CMUNGE_service_fast_entry\t- _CMUNGE_origin\n");
-    /* List services in ascending order */
-    do {
-      found = 0;
-      for (l = opt.services; l; l = l->next)
-      {
-        if (l->val > min && ((l->val < found) || (found == 0)))
-          found = l->val;
-      }
-      fprintf(file, "\tDCD\t0x%08x\n", found);
-      min = found;
-    } while (found);
-    fprintf(file, "\tDCD\t_CMUNGE_service_fast\t\t- _CMUNGE_origin\n");
-    fprintf(file, "_CMUNGE_service\n");
-    fprintf(file, "\tMOV\tr0,r0\n");
-  }
+      output_label("_CMUNGE_service_fast");
+      output_word(0, "");
+      output_word_as_str("_CMUNGE_service_fast_entry\t- _CMUNGE_origin", "");
+      /* List services in ascending order */
+      do
+	{
+	  found = 0;
+	  for (l = opt.services; l; l = l->next)
+	    {
+	      if (l->val > min && ((l->val < found) || (found == 0)))
+		found = l->val;
+	    }
+	  output_word(found, "Service call number");
+	  min = found;
+	} while (found);
+      output_word_as_str("_CMUNGE_service_fast\t\t- _CMUNGE_origin", "");
+      output_label("_CMUNGE_service");
+      fputs("\tMOV\tr0,r0\n", file);
+    }
   else
-  {
+    {
 #ifdef CMHG_REDUNDANT_FAST_SERVICE
-    fprintf(file, "\tDCD\t0\n");
-    fprintf(file, "_CMUNGE_service\n");
-    fprintf(file, "\tMOV\tr0,r0\n");
+      output_word(0, "");
+      output_label("_CMUNGE_service");
+      fputs("\tMOV\tr0,r0\n", file);
 #else
-    fprintf(file, "_CMUNGE_service\n");
+      output_label("_CMUNGE_service");
 #endif
-  }
+    }
 
-  if (opt.services) {
-    /* Do we have any 'big' numbers? */
-    big = 0;
-    for (l = opt.services; l; l = l->next) {
-      if (representable(l->val) != l->val) {
-        big = 1;
-        break;
-      }
-    }
-    /* Now the rejection code */
-    if (big) {
-      fprintf(file, "\tSTR\tr14,[r13,#-4]!\n");
-    }
-    l = opt.services;
-    first = 1;
-    while (l) {
-      n = l->val;
-      m = representable(n);
-      if (n == m) {
-        if (first)
-          fprintf(file, "\tTEQ\tr1,#0x%02x\n", n);
-        else
-          fprintf(file, "\tTEQNE\tr1,#0x%02x\n", n);
-      } else {
-        fprintf(file, "\tMOV\tr14,#0x%02x\n", m);
-        n &= ~m;
-        do {
-          m = representable(n);
-          fprintf(file, "\tORR\tr14,r14,#0x%02x\n", m);
-          n &= ~m;
-        } while (n);
-        if (first)
-          fprintf(file, "\tTEQ\tr1,r14\n");
-        else
-          fprintf(file, "\tTEQNE\tr1,r14\n");
-      }
-      l = l->next;
-      first = 0;
-    }
-    if (big) {
-      if (CODE26)
-        fprintf(file, "\tLDMNEIA\tr13!,{pc}^\n");
+  if (opt.services)
+    {
+      /* Do we have any 'big' numbers? */
+      big = 0;
+      for (l = opt.services; l; l = l->next)
+	{
+	  if (representable(l->val) != l->val)
+	    {
+	      big = 1;
+	      break;
+	    }
+	}
+      /* Now the rejection code */
+      if (big)
+	fputs("\tSTR\tr14,[r13,#-4]!\n", file);
+
+      first = 1;
+      for (l = opt.services; l != NULL; l = l->next)
+	{
+	  n = l->val;
+	  m = representable(n);
+	  if (n == m)
+	    {
+	      if (first)
+		fprintf(file, "\tTEQ\tr1,#0x%02x\n", n);
+	      else
+		fprintf(file, "\tTEQNE\tr1,#0x%02x\n", n);
+	    }
+	  else
+	    {
+	      fprintf(file, "\tMOV\tr14,#0x%02x\n", m);
+	      n &= ~m;
+	      do
+		{
+		  m = representable(n);
+		  fprintf(file, "\tORR\tr14,r14,#0x%02x\n", m);
+		  n &= ~m;
+		} while (n);
+	      if (first)
+		fputs("\tTEQ\tr1,r14\n", file);
+	      else
+		fputs("\tTEQNE\tr1,r14\n", file);
+	    }
+	  first = 0;
+	}
+      if (big)
+	{
+	  if (CODE26)
+	    fputs("\tLDMNEIA\tr13!,{pc}^\n", file);
+	  else
+	    fputs("\tLDMNEIA\tr13!,{pc}\n", file);
+	  /* CMHG is inefficient here, but I'll match it */
+	  fputs("\tLDR\tr14,[r13],#4\n", file);
+	}
       else
-        fprintf(file, "\tLDMNEIA\tr13!,{pc}\n");
-      /* CMHG is inefficient here, but I'll match it */
-      fprintf(file, "\tLDR\tr14,[r13],#4\n");
-    } else {
-      if (CODE26)
-        fprintf(file, "\tMOVNES\tpc,r14\n");
-      else
-        fprintf(file, "\tMOVNE\tpc,r14\n");
+	{
+	  if (CODE26)
+	    fputs("\tMOVNES\tpc,r14\n", file);
+	  else
+	    fputs("\tMOVNE\tpc,r14\n", file);
+	}
     }
-  }
-  fprintf(file, "_CMUNGE_service_fast_entry\n");
-  fprintf(file, "\tSTMDB\tr13!,{r0-r11,r14}\n");
-  fprintf(file, "\tMOV\tr0,r1\n");
-  fprintf(file, "\tMOV\tr1,r13\n");
+  output_label("_CMUNGE_service_fast_entry");
+  fputs("\tSTMDB\tr13!,{r0-r11,r14}\n"
+        "\tMOV\tr0,r1\n"
+        "\tMOV\tr1,r13\n", file);
   if (CODE26)
-  {
-    fprintf(file, "\tMOV\tr6,pc\n");
-    fprintf(file, "\tBIC\tr3,r6,#3\n");
-    fprintf(file, "\tTEQP\tr3,#3\n");
-  }
+    fputs("\tMOV\tr6,pc\n"
+          "\tBIC\tr3,r6,#3\n"
+          "\tTEQP\tr3,#3\n", file);
   else
-  {
-    fprintf(file, "\tTEQ      pc,pc\n");
-    fprintf(file, "\tMOVNE    r8,pc\n");
-    fprintf(file, "\tBICNE    r3,r8,#3\n");
-    fprintf(file, "\tTEQNEP   r3,#3\n");
-    fprintf(file, "\tMRSEQ    r6,cpsr\n");
-    fprintf(file, "\tORREQ    r3,r6,#3\n");
-    fprintf(file, "\tMSREQ    cpsr_ctl,r3\n");
-  }
-  fprintf(file, "\tMOV\tr11,#0\n");
-  fprintf(file, "\tMOV\tr7,r14\n");
-  fprintf(file, "\tMOV\tr10,r13,LSR #20\n");
-  fprintf(file, "\tMOV\tr10,r10,LSL #20\n");
-  fprintf(file, "\tLDMIA\tr10,{r4,r5}\n");
-  fprintf(file, "\tMOV\tr2,r12\n");
-  fprintf(file, "\tLDR\tr12,[r12,#0]\n");
+    fputs("\tTEQ\tpc,pc\n"
+          "\tMOVNE\tr8,pc\n"
+          "\tBICNE\tr3,r8,#3\n"
+          "\tTEQNEP\tr3,#3\n"
+          "\tMRSEQ\tr6,cpsr\n"
+          "\tORREQ\tr3,r6,#3\n"
+          "\tMSREQ\tcpsr_c,r3\n", file);
+  fputs("\tMOV\tr11,#0\n"
+        "\tMOV\tr7,r14\n"
+        "\tMOV\tr10,r13,LSR #20\n"
+        "\tMOV\tr10,r10,LSL #20\n"
+        "\tLDMIA\tr10,{r4,r5}\n"
+        "\tMOV\tr2,r12\n"
+        "\tLDR\tr12,[r12,#0]\n", file);
   if (CODE26)
-  {
-    fprintf(file, "\tLDMIB\tr12,{r8,r9}\n");
-    fprintf(file, "\tSTMIA\tr10,{r8,r9}\n");
-  }
+    fputs("\tLDMIB\tr12,{r8,r9}\n"
+          "\tSTMIA\tr10,{r8,r9}\n", file);
   else
-  {
-    fprintf(file, "\tLDMIB\tr12,{r12,r14}\n");
-    fprintf(file, "\tSTMIA\tr10,{r12,r14}\n");
-  }
-  fprintf(file, ADD_Lib_Reloc);
-  fprintf(file, "\tIMPORT\t%s\n", opt.service);
+    fputs("\tLDMIB\tr12,{r12,r14}\n"
+          "\tSTMIA\tr10,{r12,r14}\n", file);
+  output_ADD_Lib_Reloc();
+  output_import(opt.service);
   fprintf(file, "\tBL\t%s\n", opt.service);
-  fprintf(file, "\tMOV\tr14,r7\n");
+  fputs("\tMOV\tr14,r7\n", file);
   if (CODE26)
-  {
-    fprintf(file, "\tTEQP\tr6,#0\n");
-  }
+    fputs("\tTEQP\tr6,#0\n", file);
   else
-  {
-    fprintf(file, "\tTEQ      pc,pc\n");
-    fprintf(file, "\tMSREQ    cpsr_ctl,r6\n");
-    fprintf(file, "\tTEQNEP   r8,#0\n");
-  }
-  fprintf(file, SUB_Lib_Reloc);
-  fprintf(file, "\tSTMIA\tr10,{r4,r5}\n");
+    fputs("\tTEQ\tpc,pc\n"
+          "\tMSREQ\tcpsr_c,r6\n"
+          "\tTEQNEP\tr8,#0\n", file);
+  output_SUB_Lib_Reloc();
+  fputs("\tSTMIA\tr10,{r4,r5}\n", file);
   if (CODE26)
-    fprintf(file, "\tLDMIA\tr13!,{r0-r11,pc}^\n");
+    fputs("\tLDMIA\tr13!,{r0-r11,pc}^\n", file);
   else
-    fprintf(file, "\tLDMIA\tr13!,{r0-r11,pc}\n");
+    fputs("\tLDMIA\tr13!,{r0-r11,pc}\n", file);
 }
 
-static void start(void) {
-
-  if (opt.runnable) {
-    fprintf(file, "_CMUNGE_start\n");
-    switch (opt.runnable)
+static void
+start(void)
+{
+  if (opt.runnable == run_none)
     {
-      case run_blib:
-      case run_clib:
-        {
-          char *routine;
-          if (opt.runnable == run_blib)
-            routine="_blib_entermodule";
-          else
-            routine="_clib_entermodule";
+    }
+  else if (opt.no_scl)
+    ErrorFatal("Unsupported: service & noscl"); /* FIXME */
+  else
+    {
+      output_label("_CMUNGE_start");
+      switch (opt.runnable)
+	{
+	  case run_blib:
+	  case run_clib:
+	    {
+	      const char *routine;
+	      if (opt.runnable == run_blib)
+		routine="_blib_entermodule";
+	      else
+		routine="_clib_entermodule";
 
-          fprintf(file, "\tIMPORT\t%s\n",routine);
-          fprintf(file, "\tB\t%s\n",routine);
-        }
-        break;
+	      output_import(routine);
+	      fprintf(file, "\tB\t%s\n",routine);
+	      break;
+	    }
 
-      case run_rmaapp_simple: /* an incredibly simple task using RMA space */
-        fprintf(file,"OS_Module * 30\n");
-        fprintf(file,"OS_Exit * 17\n");
-        fprintf(file,"OS_GenerateError * 43\n");
-        fprintf(file,"\n");
-        fprintf(file,"\tIMPORT\t|__root_stack_size|, WEAK\n");
-        fprintf(file,"\tIMPORT\tmain\n");
-        fprintf(file,"\tEXPORT\t_CMUNGE_stack\n");
-        fprintf(file,"\tMOV\tv1,r0 \t; Save command tail\n");
-        fprintf(file,"\tLDR\tr12,[r12]\t; Workspace ptr from private word\n");
-        fprintf(file,"\tLDMIB\tr12,{v2,v3}\t; Module relocations\n");
-        fprintf(file,"\tLDR\tv4,_CMUNGE_stackptr\t; A Ptr to stack variable\n");
-        fprintf(file,"\tADD\tv4,v4,v3\t; gets relocated for user variable\n");
-        fprintf(file,"\tLDR\tr0,[v4]\t; stack chunk\n");
-        fprintf(file,"\tTEQ\tr0,#0\t; is it 0 ?\n");
-        fprintf(file,"\tBNE\t_CMUNGE_apprunning\t; if not, there's a stack already\n");
-        fprintf(file,"\tMOV\tr0,#6\n");
-        fprintf(file,"\tLDR\tr3, =|__root_stack_size|\n");
-        fprintf(file,"\tTEQ\tr3, #0\n");
-        fprintf(file,"\tMOVEQ\tr3,#8192\t; default stack size\n");
-        fprintf(file,"\tSWI\tOS_Module\n");
-        fprintf(file,"\tMOV\tsl,r2\n");
-        fprintf(file,"\tSTR\tsl,[v4]\n");
-        fprintf(file,"\tADD\tsp,sl,r3\n");
-        fprintf(file,"\tSTMIA\tsl,{v2,v3}\n");
-        fprintf(file,"\n");
-        fprintf(file,"" ADD_Lib_Reloc "");
-        fprintf(file,"\n");
-        fprintf(file,"\tMOV\tfp,#0\n");
-        fprintf(file,"\tMOV\ta1,v1\n");
-        fprintf(file,"\tBL\tmain\n");
-        fprintf(file,"\n");
-        fprintf(file,"" SUB_Lib_Reloc "");
-        fprintf(file,"\n");
-        fprintf(file,"\tMOV\tv1,r0\n");
-        fprintf(file,"\n");
-        fprintf(file,"\tMOV\tr2,sl\n");
-        fprintf(file,"\tMOV\tr0,#7\n");
-        fprintf(file,"\tSWI\tOS_Module\n");
-        fprintf(file,"\tMOV\tr0,#0\n");
-        fprintf(file,"\tSTR\tr0,[v4]\n");
-        fprintf(file,"\n");
-        fprintf(file,"\tMOV\tr0,v1\t; FIXME: this is wrong - it's ShareFS code\n");
-        fprintf(file,"\tSWI\tOS_Exit\n");
-        fprintf(file,"\n");
-        fprintf(file,"_CMUNGE_freeappstack\n");
-        fprintf(file,"\tSTMFD\tsp!,{r0-r4,r14}\n");
-        fprintf(file,"\tLDR\tr4,_CMUNGE_stackptr\t; A Ptr to stack variable\n");
-        fprintf(file,"\tLDR\tr3,[sl,#-536]\n");
-        fprintf(file,"\tADD\tr4,r4,r3\t; gets relocated for user variable\n");
-        fprintf(file,"\tLDR\tr2,[r4]\t; stack chunk pointer\n");
-        fprintf(file,"\tTEQ\tr2,#0\t; is it allocated ?\n");
-        fprintf(file,"\tMOVNE\tr0,#7\t; if so, free it\n");
-        fprintf(file,"\tSWINE\tOS_Module\n");
-        fprintf(file,"\tMOV\tr0,#0\n");
-        fprintf(file,"\tSTR\tr0,[r4]\n");
-        if (CODE26)
-          fprintf(file,"\tLDMFD\tsp!,{r0-r4,pc}^\n");
-        else
-        {
-          fprintf(file,"\tCMP\tpc,#0\t; clear V\n");
-          fprintf(file,"\tLDMFD\tsp!,{r0-r4,pc}^\n");
-        }
-        fprintf(file,"\n");
-        fprintf(file,"_CMUNGE_stackptr\n");
-        fprintf(file,"\tDCD\t_CMUNGE_stack\n");
-        fprintf(file,"\n");
-        fprintf(file,"_CMUNGE_apprunning\n");
-        fprintf(file,"\tADR\tr0,_CMUNGE_apprunning_error\n");
-        fprintf(file,"\tSWI\tOS_GenerateError\n");
-        fprintf(file,"_CMUNGE_apprunning_error\n");
-        fprintf(file,"\tDCD 0\t; FIXME: This is a bad error number to use\n");
-        fprintf(file,"\t= \"%s already running\",0\n", opt.title);
-        fprintf(file,"\tALIGN\n");
-        break;
+	  case run_rmaapp_simple: /* an incredibly simple task using RMA space */
+	    {
+	      output_weak_import("__root_stack_size");
+	      output_import("main");
+	      output_export("_CMUNGE_stack");
+	      fputs("\tMOV\tv1,r0\t", file); output_comment("Save command tail\n");
+	      fputs("\tLDR\tr12,[r12]\t", file); output_comment("Workspace ptr from private word\n");
+	      fputs("\tLDMIB\tr12,{v2,v3}\t", file); output_comment("Module relocations\n");
+	      fputs("\tLDR\tv4,_CMUNGE_stackptr\t", file); output_comment("A Ptr to stack variable\n");
+	      fputs("\tADD\tv4,v4,v3\t", file); output_comment("gets relocated for user variable\n");
+	      fputs("\tLDR\tr0,[v4]\t", file); output_comment("stack chunk\n");
+	      fputs("\tTEQ\tr0,#0\t", file); output_comment("is it 0 ?\n");
+	      fputs("\tBNE\t_CMUNGE_apprunning\t", file); output_comment("if not, there's a stack already\n");
+	      fputs("\tMOV\tr0,#6\n"
+	            "\tLDR\tr3, =__root_stack_size\n"
+	            "\tTEQ\tr3, #0\n"
+	            "\tMOVEQ\tr3,#8192\t; default stack size\n"
+	            "\tSWI\tOS_Module\n"
+	            "\tMOV\tsl,r2\n"
+	            "\tSTR\tsl,[v4]\n"
+	            "\tADD\tsp,sl,r3\n"
+	            "\tSTMIA\tsl,{v2,v3}\n"
+	            "\n", file);
+	      output_ADD_Lib_Reloc();
+	      fputs("\n"
+	            "\tMOV\tfp,#0\n"
+	            "\tMOV\ta1,v1\n"
+	            "\tBL\tmain\n"
+	            "\n", file);
+	      output_SUB_Lib_Reloc();
+	      fputs("\n"
+	            "\tMOV\tv1,r0\n"
+	            "\n"
+	            "\tMOV\tr2,sl\n"
+	            "\tMOV\tr0,#7\n"
+	            "\tSWI\tOS_Module\n"
+	            "\tMOV\tr0,#0\n"
+	            "\tSTR\tr0,[v4]\n"
+	            "\n"
+	            "\tMOV\tr0,v1\t", file); output_comment("FIXME: this is wrong - it's ShareFS code\n");
+	      fputs("\tSWI\tOS_Exit\n"
+	            "\n", file);
+	      output_label("_CMUNGE_freeappstack");
+	      fputs("\tSTMFD\tsp!,{r0-r4,r14}\n"
+	            "\tLDR\tr4,_CMUNGE_stackptr\t", file); output_comment("A Ptr to stack variable\n");
+	      fputs("\tLDR\tr3,[sl,#-536]\n"
+	            "\tADD\tr4,r4,r3\t", file); output_comment("gets relocated for user variable\n");
+	      fputs("\tLDR\tr2,[r4]\t", file); output_comment("stack chunk pointer\n");
+	      fputs("\tTEQ\tr2,#0\t", file); output_comment("is it allocated ?\n");
+	      fputs("\tMOVNE\tr0,#7\t", file); output_comment("if so, free it\n");
+	      fputs("\tSWINE\tOS_Module\n"
+	            "\tMOV\tr0,#0\n"
+	            "\tSTR\tr0,[r4]\n", file);
+	      if (CODE26)
+		fputs("\tLDMFD\tsp!,{r0-r4,pc}^\n", file);
+	      else
+		fputs("\tCMP\tpc,#0\t; clear V\n"
+		      "\tLDMFD\tsp!,{r0-r4,pc}^\n", file);
+	      fputs("\n", file);
+	      output_label("_CMUNGE_stackptr");
+	      output_word_as_str("_CMUNGE_stack", "");
+	      fputs("\n", file);
+	      output_label("_CMUNGE_apprunning");
+	      fputs("\tADR\tr0,_CMUNGE_apprunning_error\n"
+	            "\tSWI\tOS_GenerateError\n", file);
+	      output_label("_CMUNGE_apprunning_error");
+	      output_word(0, "FIXME: This is a bad error number to use");
+	      output_simple_string_vargs("%s already running", opt.title);
+	      output_align();
+	      break;
+	    }
 
-      default:
-        ErrorFatal("Start code type confusion");
+	  default:
+	    ErrorFatal("Start code type confusion");
+	}
     }
-  }
 }
 
-static void init(void) {
-
-/* JRF: 32bit ok */
+/**
+ * Provides the _CMUNGE_init routine.
+ */
+static void
+init(void)
+{
+  /* JRF: 32bit ok */
   if (opt.mode_errors)
     return;
 
-  fprintf(file, "\n_CMUNGE_init\n");
-  fprintf(file, "\tSTMFD\tr13!,{r7-r11,r14}\n");
-  fprintf(file, "\tMOV\tr0,#%i\n",opt.reentrant ? 1 : 0);
-  if (opt.lib_init) {
-    fprintf(file, "\tIMPORT\t%s\n", opt.lib_init);
-    fprintf(file, "\tBL\t%s\n", opt.lib_init);
-  } else {
-    fprintf(file, "\tIMPORT\t_clib_initialisemodule\n");
-    fprintf(file, "\tBL\t_clib_initialisemodule\n");
-  }
-  if (!opt.init && !opt.cplusplus) {
-    fprintf(file, "\tLDMIA\tr13!,{r7-r11,pc}\n");
-  } else {
-    if (CODE26)
+  fputc('\n', file);
+  output_label("_CMUNGE_init");
+  /* A module initialisation routine needs its r7-r11 preserved.  */
+  if (opt.no_scl)
     {
-      fprintf(file, "\tLDMVSIA\tr13!,{r7-r11,pc}\n");
-      fprintf(file, "\tMOV\tr6,r0\n");
-      fprintf(file, SUB_Lib_Reloc);
-      fprintf(file, "\tLDMIA\tr10,{r0,r1}\n");
-      fprintf(file, "\tSUB\tr10,r10,#0x14\n");
-      fprintf(file, "\tLDMIA\tr10,{r4,r5}\n");
-      fprintf(file, "\tSTMIA\tr10,{r0,r1}\n");
-      fprintf(file, ADD_Lib_Reloc);
-      fprintf(file, "\tMOV\tr11,#0\n");
-      if (opt.cplusplus)
-      {
-        if (opt.toolchain == tc_gcc)
-        {
-          fprintf(file, "\tIMPORT\t__gccmain\n");
-          fprintf(file, "\tBL\t__gccmain\n");
-        }
-        else
-        {
-          fprintf(file, "\tIMPORT\t______main\n");
-          fprintf(file, "\tBL\t______main\n");
-        }
-      }
+      /* No Shared C Library support.  */
+      if (opt.lib_init || opt.cplusplus)
+	ErrorFatal("Unsupported: noscl and lib_init/cplusplus");
+      fputs("\tSTMFD\tr13!, {r10-r11, r14}\n"
+            "\tBL\t__RelocCode\n" /* Relocate module code.  */
+            "\tMOV\tr0, #6\n" /* Create RMA based workspace.  */
+            "\tLDR\tr4, _CMUNGE_ImageRWBase\n" /* r4 => Image$$RW$$Base */
+            "\tLDR\tr5, _CMUNGE_ImageRWLimit\n" /* r5 => Image$$RW$$Limit */
+            "\tSUB\tr3, r5, r4\n"
+            "\tADD\tr3, r3, #12\n" /* 4*3 bytes own private workspace.  */
+            "\tSWI\tXOS_Module\n"
+            "\tLDMVSIA\tr13!, {r7-r11, pc}\n"
+            "\tMOV\tr6, r2\n" /* r6 => our workspace (fixed)  */
+            "\tSTR\tr2, [r12, #0]\n"
+            "\tSTR\tr3, [r2], #12\n" /* Also done for SCL stubs but we don't use it. r2 => rw data in workspace  */
+            /* Copy contents from Image$$RW$$Base to Image$$Image$$ZI$$Base to our workspace at offset 12.  */
+            "\tMOV\tr1, r4\n" /* r1 => source (Image$$RW$$Base)  */
+            "\tLDR\tr0, _CMUNGE_ImageZIBase\n" /* r0 => Image$$ZI$$Base */
+            "\tSUBS\tr3, r0, r4\n" /* r3 = number of bytes to copy (we assume this is always word rounded). */, file);
+      output_label("_CMUNGE_init_rwloop1");
+      fputs("\tLDRNE\tr14, [r1], #4\n"
+            "\tSTRNE\tr14, [r2], #4\n"
+            "\tSUBNES\tr3, r3, #4\n"
+            "\tBNE\t_CMUNGE_init_rwloop1\n"
+            /* Write Image$$RW$$Limit - Image$$ZI$$Base zero bytes to
+             our workspace at offset 12 + Image$$Image$$ZI$$Base
+             - Image$$RW$$Base.  */
+            "\tSUBS\tr14, r5, r0\n", file);
+      output_label("_CMUNGE_init_rwloop2");
+      fputs("\tSTRNE\tr3, [r2], #4\n"
+            "\tSUBNES\tr14, r14, #4\n"
+            "\tBNE\t_CMUNGE_init_rwloop2\n"
+            "\tMOV\tr10, r13, LSR #20\n"
+            "\tMOV\tr10, r10, LSL #20\n"
+            "\tSUB\tr1, r6, r4\n"
+            "\tADD\tr1, r1, #12\n" /* r1 = client data offset, i.e. difference between RW data in our workspace and RW data in module body.  */
+            "\tMOV\tr0, #0\n" /* r0 = library data offset (not used).  */
+            "\tSTMIB\tr6, {r0, r1}\n", file);
+      
       if (opt.init)
-      {
-        fprintf(file, "\tADD\tr0,r13,#0xc\n");
-        fprintf(file, "\tLDMIA\tr0,{r0,r1}\n");
-        fprintf(file, "\tMOV\tr2,r6\n");
-        fprintf(file, "\tIMPORT\t%s\n", opt.init);
-        fprintf(file, "\tBL\t%s\n", opt.init);
-        fprintf(file, "\tTEQ\tr0,#0\n");
-        fprintf(file, "\tBEQ\t_CMUNGE_init_10\n");
-        fprintf(file, "\tSTR\tr0,[r13,#-4]!\n");
-        fprintf(file, "\tMOV\tr0,r6\n");
-        if (!finalise_imported)
-          fprintf(file, "\tIMPORT\t_clib_finalisemodule\n"), finalise_imported = 1;
-        fprintf(file, "\tBL\t_clib_finalisemodule\n");
-        fprintf(file, "\tLDR\tr0,[r13],#4\n");
-        fprintf(file, "_CMUNGE_init_10\n");
-        fprintf(file, SUB_Lib_Reloc);
-        fprintf(file, "\tSTMIA\tr10,{r4,r5}\n");
-        fprintf(file, "\tTEQ\tr0,#0\n");
-        fprintf(file, "\tLDMEQIA\tr13!,{r7-r11,pc}^\n");
-        fprintf(file, "\tLDMIA\tr13!,{r7-r11,r14}\n");
-        fprintf(file, "\tORRS\tpc,r14,#0x10000000\n");
-      }
+	{
+	  /* We need to call user supplied C init routine.  */
+	  fputs("\tLDMIA\tr10, {r4, r5}\n"
+	        "\tSTMIA\tr10, {r0, r1}\n", file);
+	  if (opt.toolchain == tc_gcc)
+	    {
+	      /* Only available in the GCC toolchain.  */
+	      fputs("\tMOV\tr0, r1\n"
+	            "\tLDR\tr2, _CMUNGE_ImageRWBase\n" /* R2 => Image$$RW$$Base  */
+	            "\tBL\t__RelocData\n", file);
+	    }
+	  output_ADD_Lib_Reloc();
+	  fputs("\tMOV\tr11, #0\t", file); output_comment("Stop backtrace\n");
+	  /* Fetch input parameters.  */
+	  fputs("\tLDMIA\tr13, {r0, r1}\n" /* r0 => registers r10, r11 on stack.  */
+	        "\tMOV\tr2, r12\n", file);
+	  output_import(opt.init);
+	  /* _kernel_oserror *init(const char *tail, int podule_base, void *pw); */
+	  fprintf(file, "\tBL\t%s\n", opt.init);
+	  fputs("\tTEQ\tr0, #0\n"
+	        "\tBEQ\t_CMUNGE_init_10\n"
+	        "\tMOV\tr1, r0\n", file);
+	  fputs("\tMOV\tr0, #7\n"
+	        "\tMOV\tr2, r6\n"
+	        "\tSWI\tXOS_Module\n"
+	        "\tMOVVC\tr0, r1\n", file);
+	  output_label("_CMUNGE_init_10");
+	  output_SUB_Lib_Reloc();
+	  fputs("\tSTMIA\tr10, {r4, r5}\n", file);
+	  if (CODE26)
+	    fputs("\tTEQ\tr0, #0\n"
+	          "\tLDMEQIA\tr13!, {r10-r11, pc}^\n"
+	          "\tLDMIA\tr13!, {r10-r11, r14}\n"
+	          "\tORRS\tpc, r14, #0x10000000\n", file);
+	  else
+	    fputs("\tCMP\tr0, #0\n"
+	          "\tMOVNE\tr1, #0\n"
+	          "\tCMPNE\tr1, #1<<31\n"
+	          "\tLDMIA\tr13!, {r10-r11, pc}\n", file);
+	}
       else
-      {
-        fprintf(file, "\tSTMIA\tr10,{r4,r5}\n");
-        fprintf(file, "\tLDMIA\tr13!,{r7-r11,pc}^\n");
-      }
+	{
+	  if (opt.toolchain == tc_gcc)
+	    {
+	      /* Only available in the GCC toolchain.  */
+	      fputs("\tMOV\tr0, r1\n"
+	            "\tLDR\tr2, _CMUNGE_ImageRWBase\n" /* R2 => Image$$RW$$Base  */
+	            "\tBL\t__RelocData\n", file);
+	    }
+	  if (CODE26)
+	    fputs("\tLDMIA\tr13!, {r10-r11, pc}^\n", file);
+	  else
+	    fputs("\tCMP\tr0, r0\n" /* Clear V */
+	          "\tLDMIA\tr13!, {r10-r11, pc}\n", file);
+	}
+
+      /* We need Image$$RW$$Base, Image$$RW$$Limit and Image$$ZI$$Base which
+       are relocated so that they correctly point into our RMA module.  */
+      output_label("_CMUNGE_ImageRWBase");
+      output_import("Image$$RW$$Base");
+      output_word_as_str("Image$$RW$$Base(GOTOFF)", "");
+      output_label("_CMUNGE_ImageRWLimit");
+      output_import("Image$$RW$$Limit");
+      output_word_as_str("Image$$RW$$Limit(GOTOFF)", "");
+      output_label("_CMUNGE_ImageZIBase");
+      output_import("Image$$ZI$$Base");
+      output_word_as_str("Image$$ZI$$Base(GOTOFF)", "");
     }
-    else
+  else
     {
-      fprintf(file, "\tLDMVSIA\tr13!,{r7-r11,pc}\n");
-      fprintf(file, "\tMOV\tr6,r0\n");
-      fprintf(file, SUB_Lib_Reloc);
-      fprintf(file, "\tLDMIA\tr10,{r0,r1}\n");
-      fprintf(file, "\tSUB\tr10,r10,#0x14\n");
-      fprintf(file, "\tLDMIA\tr10,{r4,r5}\n");
-      fprintf(file, "\tSTMIA\tr10,{r0,r1}\n");
-      fprintf(file, ADD_Lib_Reloc);
-      fprintf(file, "\tMOV\tr11,#0\n");
-      if (opt.cplusplus)
-      {
-        if (opt.toolchain == tc_gcc)
-        {
-          fprintf(file, "\tIMPORT\t__gccmain\n");
-          fprintf(file, "\tBL\t__gccmain\n");
-        }
-        else
-        {
-          fprintf(file, "\tIMPORT\t______main\n");
-          fprintf(file, "\tBL\t______main\n");
-        }
-      }
-      if (opt.init)
-      {
-        fprintf(file, "\tADD\tr0,r13,#0xc\n");
-        fprintf(file, "\tLDMIA\tr0,{r0,r1}\n");
-        fprintf(file, "\tMOV\tr2,r6\n");
-        fprintf(file, "\tIMPORT\t%s\n", opt.init);
-        fprintf(file, "\tBL\t%s\n", opt.init);
-        fprintf(file, "\tTEQ\tr0,#0\n");
-        fprintf(file, "\tBEQ\t_CMUNGE_init_10\n");
-        fprintf(file, "\tSTR\tr0,[r13,#-4]!\n");
-        fprintf(file, "\tMOV\tr0,r6\n");
-        if (!finalise_imported)
-          fprintf(file, "\tIMPORT\t_clib_finalisemodule\n"), finalise_imported = 1;
-        fprintf(file, "\tBL\t_clib_finalisemodule\n");
-        fprintf(file, "\tLDR\tr0,[r13],#4\n");
-        fprintf(file, "_CMUNGE_init_10\n");
-        fprintf(file, SUB_Lib_Reloc);
-        fprintf(file, "\tSTMIA\tr10,{r4,r5}\n");
-        fprintf(file, "\tCMP\tr0,#0\n");
-        fprintf(file, "\tMOVNE\tr1,#0\n");
-        fprintf(file, "\tCMPNE\tr1,#1<<31\n");
-        fprintf(file, "\tLDMIA\tr13!,{r7-r11,pc}\n");
-      }
+      fprintf(file,
+              "\tSTMFD\tr13!,{r7-r11,r14}\n"
+	      "\tMOV\tr0,#%i\n",opt.reentrant ? 1 : 0);
+      if (opt.lib_init)
+	{
+	  output_import(opt.lib_init);
+	  fprintf(file, "\tBL\t%s\n", opt.lib_init);
+	}
       else
-      {
-        fprintf(file, "\tCMP\tr0,r0\n"); /* Clear V */
-        fprintf(file, "\tSTMIA\tr10,{r4,r5}\n");
-        fprintf(file, "\tLDMIA\tr13!,{r7-r11,pc}\n");
-      }
+	{
+	  output_import("_clib_initialisemodule");
+	  fputs("\tBL\t_clib_initialisemodule\n", file);
+	}
+      if (!opt.init && !opt.cplusplus)
+	fputs("\tLDMIA\tr13!,{r7-r11,pc}\n", file);
+      else
+	{
+	  fputs("\tLDMVSIA\tr13!,{r7-r11,pc}\n"
+	        "\tMOV\tr6,r0\n", file);
+	  output_SUB_Lib_Reloc();
+	  fputs("\tLDMIA\tr10,{r0,r1}\n"
+	        "\tSUB\tr10,r10,#0x14\n"
+	        "\tLDMIA\tr10,{r4,r5}\n"
+	        "\tSTMIA\tr10,{r0,r1}\n", file);
+	  output_ADD_Lib_Reloc();
+	  fputs("\tMOV\tr11,#0\n", file);
+	  if (opt.cplusplus)
+	    {
+	      if (opt.toolchain == tc_gcc)
+		{
+		  output_import("__gccmain");
+		  fputs("\tBL\t__gccmain\n", file);
+		}
+	      else
+		{
+		  output_import("______main");
+		  fputs("\tBL\t______main\n", file);
+		}
+	    }
+	  if (opt.init)
+	    {
+	      fputs("\tADD\tr0,r13,#(10-7)*4\n" /* r0 => registers r10, r11 on stack.  */
+	            "\tLDMIA\tr0,{r0,r1}\n"
+	            "\tMOV\tr2,r6\n", file);
+	      output_import(opt.init);
+	      /* _kernel_oserror *init(const char *tail, int podule_base, void *pw); */
+	      fprintf(file, "\tBL\t%s\n", opt.init);
+	      fputs("\tTEQ\tr0,#0\n"
+	            "\tBEQ\t_CMUNGE_init_10\n"
+	            "\tSTR\tr0,[r13,#-4]!\n"
+	            "\tMOV\tr0,r6\n", file);
+	      if (!finalise_imported)
+		{
+		  output_import("_clib_finalisemodule");
+		  finalise_imported = 1;
+		}
+	      fputs("\tBL\t_clib_finalisemodule\n"
+	            "\tLDR\tr0,[r13],#4\n", file);
+	      output_label("_CMUNGE_init_10");
+	      output_SUB_Lib_Reloc();
+	      fputs("\tSTMIA\tr10,{r4,r5}\n", file);
+	      if (CODE26)
+		fputs("\tTEQ\tr0,#0\n"
+		      "\tLDMEQIA\tr13!,{r7-r11,pc}^\n"
+		      "\tLDMIA\tr13!,{r7-r11,r14}\n"
+		      "\tORRS\tpc,r14,#0x10000000\n", file);
+	      else
+		fputs("\tCMP\tr0,#0\n"
+		      "\tMOVNE\tr1,#0\n"
+		      "\tCMPNE\tr1,#1<<31\n"
+		      "\tLDMIA\tr13!,{r7-r11,pc}\n", file);
+	    }
+	  else
+	    {
+	      if (CODE26)
+		fputs("\tSTMIA\tr10,{r4,r5}\n"
+		      "\tLDMIA\tr13!,{r7-r11,pc}^\n", file);
+	      else
+		fputs("\tCMP\tr0,r0\n" /* Clear V */
+		      "\tSTMIA\tr10,{r4,r5}\n"
+		      "\tLDMIA\tr13!,{r7-r11,pc}\n", file);
+	    }
+	}
     }
-  }
 }
 
-static void final(void) {
-
+static void
+final(void)
+{
   if (opt.mode_errors)
     return;
 
-  fprintf(file, "_CMUNGE_fin\n");
-  if (opt.final) {
-    /* JRF: 32bit ok */
-    fprintf(file, "\tSTMDB\tr13!,{r7-r12,r14}\n");
-    fprintf(file, "\tMOV\tr10,r13,LSR #20\n");
-    fprintf(file, "\tMOV\tr10,r10,LSL #20\n");
-    fprintf(file, "\tLDMIA\tr10,{r4,r5}\n");
-    fprintf(file, "\tLDR\tr12,[r12,#0]\n");
-    fprintf(file, "\tLDMIB\tr12,{r11,r12}\n");
-    fprintf(file, "\tSTMIA\tr10,{r11,r12}\n");
-    fprintf(file, ADD_Lib_Reloc);
-    fprintf(file, "\tMOV\tr11,#0\n");
-    fprintf(file, "\tADD\tr0,r13,#0xc\n");
-    fprintf(file, "\tLDMIA\tr0,{r0-r2}\n");
-    fprintf(file, "\tIMPORT\t%s\n", opt.final);
-    fprintf(file, "\tBL\t%s\n", opt.final);
-    fprintf(file, "\tCMP\tr0,#0\n");
-    if (CODE26)
+  if (opt.no_scl)
     {
-      fprintf(file, "\tLDREQ\tr0,[r13,#0x14]\n");
-      if (!finalise_imported)
-        fprintf(file, "\tIMPORT\t_clib_finalisemodule\n"), finalise_imported = 1;
-      fprintf(file, "\tBLEQ\t_clib_finalisemodule\n");
-      if (opt.runnable == run_rmaapp_simple)
-        fprintf(file,"\tBLEQ\t_CMUNGE_freeappstack\n");
+      if (opt.runnable)
+	ErrorFatal("Unsupported: rmaapp_simple and noscl");
+      if (opt.final)
+	{
+	  output_label("_CMUNGE_fin");
+	  fputs("\tSTMDB\tr13!, {r10-r12, r14}\n"
+	        "\tMOV\tr10, r13, LSR #20\n"
+	        "\tMOV\tr10, r10, LSL #20\n"
+	        "\tLDMIA\tr10, {r4-r5}\n"
+	        "\tLDR\tr12, [r12, #0]\n"
+	        "\tLDMIB\tr12, {r11-r12}\n"
+	        "\tSTMIA\tr10, {r11-r12}\n", file);
+	  output_ADD_Lib_Reloc();
+	  fputs("\tMOV\tr11, #0\n"
+	        "\tLDMIA\tr13, {r0-r2}\n", file);
+	  output_import(opt.final);
+	  fprintf(file, "\tBL\t%s\n", opt.final);
+	   /* When the user supplied finalisation call returns an error, we
+	      cancel the termination and pass the error on.  */
+	  fputs("\tMOVS\tr1, r0\n"
+	        "\tBNE\t_CMUNGE_final_10\n"
+	        "\tMOV\tr0, #7\n"
+	        "\tLDR\tr2, [r13, #(12-10)*4]\n"
+	        "\tLDR\tr2, [r2, #0]\n"
+	        "\tSWI\tXOS_Module\n"
+	        "\tMOVVC\tr0, r1\n", file);
+	  output_label("_CMUNGE_final_10");
+	  output_SUB_Lib_Reloc();
+	  fputs("\tSTMIA\tr10, {r4-r5}\n"
+	        "\tCMP\tr0, #0\n", file);
+	  if (CODE26)
+	    fputs("\tLDMEQIA\tr13!, {r10-r12, pc}^\n"
+	          "\tLDMIA\tr13!, {r10-r12, r14}\n"
+	          "\tORRS\tpc, r14, #0x10000000\n", file);
+	  else
+	    fputs("\tMOVNE\tr1, #0\n"
+	          "\tCMPNE\tr1, #1<<31\n"
+	          "\tLDMIA\tr13!, {r10-r12, pc}\n", file);
+	}
+      else
+	{
+	  /* When we don't have to call an user supplied C based finalisation
+	   routine, we choose to not have a module finalisation call at all
+	   because we count on the fact that RISC OS frees our workspace
+	   automatically.  */
+	}
     }
-    else
+  else if (opt.final)
     {
-      fprintf(file, "\tBNE\t_CMUNGE_final_10\n");
-      fprintf(file, "\tLDR\tr0,[r13,#0x14]\n");
+      /* JRF: 32bit ok */
+      output_label("_CMUNGE_fin");
+      fputs("\tSTMDB\tr13!,{r7-r12,r14}\n"
+            "\tMOV\tr10,r13,LSR #20\n"
+            "\tMOV\tr10,r10,LSL #20\n"
+            "\tLDMIA\tr10,{r4,r5}\n"
+            "\tLDR\tr12,[r12,#0]\n"
+            "\tLDMIB\tr12,{r11,r12}\n"
+            "\tSTMIA\tr10,{r11,r12}\n", file);
+      output_ADD_Lib_Reloc();
+      fputs("\tMOV\tr11,#0\n"
+            "\tADD\tr0,r13,#(10-7)*4\n"
+            "\tLDMIA\tr0,{r0-r2}\n", file);
+      output_import(opt.final);
+      fprintf(file, "\tBL\t%s\n", opt.final);
+      fputs("\tCMP\tr0,#0\n", file);
+      if (CODE26)
+	{
+	  fputs("\tLDREQ\tr0,[r13,#(12-7)*4]\n", file);
+	  if (!finalise_imported)
+	    {
+	      output_import("_clib_finalisemodule");
+	      finalise_imported = 1;
+	    }
+	  fputs("\tBLEQ\t_clib_finalisemodule\n", file);
+	  if (opt.runnable == run_rmaapp_simple)
+	    fputs("\tBLEQ\t_CMUNGE_freeappstack\n", file);
+	}
+      else
+	{
+	  fputs("\tBNE\t_CMUNGE_final_10\n"
+	        "\tLDR\tr0,[r13,#(12-7)*4]\n", file);
+	  if (!finalise_imported)
+	    {
+	      output_import("_clib_finalisemodule");
+	      finalise_imported = 1;
+	    }
+	  fputs("\tBL\t_clib_finalisemodule\n", file);
+	  if (opt.runnable == run_rmaapp_simple)
+	    fputs("\tBL\t_CMUNGE_freeappstack\n", file);
+	  fputs("\tMOVS\tr0,#0\n", file);
+	  output_label("_CMUNGE_final_10");
+	}
+      output_SUB_Lib_Reloc();
+      fputs("\tSTMIA\tr10,{r4,r5}\n", file);
+      if (CODE26)
+	fputs("\tLDMEQIA\tr13!,{r7-r12,pc}^\n"
+	      "\tLDMIA\tr13!,{r7-r12,r14}\n"
+	      "\tORRS\tpc,r14,#0x10000000\n", file);
+      else
+	fputs("\tMOVNE\tr1,#0\n"
+	      "\tCMPNE\tr1,#1<<31\n"
+	      "\tLDMIA\tr13!,{r7-r12,pc}\n", file);
+    }
+  else
+    {
+      output_label("_CMUNGE_fin");
+      fputs("\tSTMDB\tr13!,{r7-r11,r14}\n"
+            "\tMOV\tr10,r13,LSR #20\n"
+            "\tMOV\tr10,r10,LSL #20\n"
+            "\tLDMIA\tr10,{r4,r5}\n"
+            "\tMOV\tr0,r12\n"
+            "\tLDR\tr12,[r12]\n"
+            "\tLDMIB\tr12,{r11,r12}\n"
+            "\tSTMIA\tr10,{r11,r12}\n", file);
+      output_ADD_Lib_Reloc();
+      fputs("\tMOV\tr11,#0\n", file);
       if (!finalise_imported)
-        fprintf(file, "\tIMPORT\t_clib_finalisemodule\n"), finalise_imported = 1;
-      fprintf(file, "\tBL\t_clib_finalisemodule\n");
+	{
+	  output_import("_clib_finalisemodule");
+	  finalise_imported = 1;
+	}
+      fputs("\tBL\t_clib_finalisemodule\n", file);
       if (opt.runnable == run_rmaapp_simple)
-        fprintf(file,"\tBL\t_CMUNGE_freeappstack\n");
-      fprintf(file, "\tMOVS\tr0,#0\n");
-      fprintf(file,"_CMUNGE_final_10\n");
+	fputs("\tBLVC\t_CMUNGE_freeappstack\n", file);
+      if (CODE26)
+	output_SUB_Lib_Reloc();
+      else
+	output_SUB_Lib_Reloc_S();
+      fputs("\tSTMIA\tr10,{r4,r5}\n", file);
+      if (CODE26)
+	fputs("\tLDMIA\tr13!,{r7-r11,pc}^\n", file);
+      else
+	fputs("\tLDMIA\tr13!,{r7-r11,pc}\n", file);
     }
-    fprintf(file, SUB_Lib_Reloc);
-    fprintf(file, "\tSTMIA\tr10,{r4,r5}\n");
-    if (CODE26)
-    {
-      fprintf(file, "\tLDMEQIA\tr13!,{r7-r12,pc}^\n");
-      fprintf(file, "\tLDMIA\tr13!,{r7-r12,r14}\n");
-      fprintf(file, "\tORRS\tpc,r14,#0x10000000\n");
-    }
-    else
-    {
-      fprintf(file, "\tMOVNE\tr1,#0\n");
-      fprintf(file, "\tCMPNE\tr1,#1<<31\n");
-      fprintf(file, "\tLDMIA\tr13!,{r7-r12,pc}\n");
-    }
-  } else {
-    fprintf(file, "\tSTMDB\tr13!,{r7-r11,r14}\n");
-    fprintf(file, "\tMOV\tr10,r13,LSR #20\n");
-    fprintf(file, "\tMOV\tr10,r10,LSL #20\n");
-    fprintf(file, "\tLDMIA\tr10,{r4,r5}\n");
-    fprintf(file, "\tMOV\tr0,r12\n");
-    fprintf(file, "\tLDR\tr12,[r12]\n");
-    fprintf(file, "\tLDMIB\tr12,{r11,r12}\n");
-    fprintf(file, "\tSTMIA\tr10,{r11,r12}\n");
-    fprintf(file, ADD_Lib_Reloc);
-    fprintf(file, "\tMOV\tr11,#0\n");
-    if (!finalise_imported)
-      fprintf(file, "\tIMPORT\t_clib_finalisemodule\n"), finalise_imported = 1;
-    fprintf(file, "\tBL\t_clib_finalisemodule\n");
-    if (opt.runnable == run_rmaapp_simple)
-      fprintf(file,"\tBLVC\t_CMUNGE_freeappstack\n");
-    if (CODE26)
-      fprintf(file, SUB_Lib_Reloc);
-    else
-      fprintf(file, SUB_Lib_Reloc_S);
-    fprintf(file, "\tSTMIA\tr10,{r4,r5}\n");
-    if (CODE26)
-      fprintf(file, "\tLDMIA\tr13!,{r7-r11,pc}^\n");
-    else
-      fprintf(file, "\tLDMIA\tr13!,{r7-r11,pc}\n");
-  }
 }
 
-static void swi_handler(void) {
-
+static void
+swi_handler(void)
+{
   /* JRF: 32bit ok */
   if (!opt.swi_base)
     return;
-  fprintf(file, "_CMUNGE_swi_handler\n");
-  fprintf(file, "\tSTMDB\tr13!,{r0-r9,r14}\n");
+  output_label("_CMUNGE_swi_handler");
+  fputs("\tSTMDB\tr13!,{r0-r9,r14}\n", file);
   if (CODE26)
-  {}
+    {}
   else
-    fprintf(file, "\tMRS\tr8,cpsr\n");
-  fprintf(file, "\tMOV\tr10,r13,LSR #20\n");
-  fprintf(file, "\tMOV\tr10,r10,LSL #20\n");
-  fprintf(file, "\tMOV\tr0,r11\n");
-  fprintf(file, "\tMOV\tr1,r13\n");
-  fprintf(file, "\tLDMIA\tr10,{r4,r5}\n");
-  fprintf(file, "\tMOV\tr2,r12\n");
-  fprintf(file, "\tLDR\tr12,[r12]\n");
-  fprintf(file, "\tLDMIB\tr12,{r11,r12}\n");
-  fprintf(file, "\tSTMIA\tr10,{r11,r12}\n");
-  fprintf(file, ADD_Lib_Reloc);
-  fprintf(file, "\tMOV\tr11,#0\n");
+    fputs("\tMRS\tr8,cpsr\n", file);
+  fputs("\tMOV\tr10,r13,LSR #20\n"
+        "\tMOV\tr10,r10,LSL #20\n"
+        "\tMOV\tr0,r11\n"
+        "\tMOV\tr1,r13\n"
+        "\tLDMIA\tr10,{r4,r5}\n"
+        "\tMOV\tr2,r12\n"
+        "\tLDR\tr12,[r12]\n"
+        "\tLDMIB\tr12,{r11,r12}\n"
+        "\tSTMIA\tr10,{r11,r12}\n", file);
+  output_ADD_Lib_Reloc();
+  fputs("\tMOV\tr11,#0\n", file);
   if (opt.swi_codesupplied)
-  {
-    swi_list l;
-    int numswis=0;
+    {
+      swi_list l;
+      int numswis;
 
-    l = opt.swi_names->next; /* First one must be valid */
-    while (l)
-    {
-      numswis++;
-      l=l->next;
+      /* First one must be valid */
+      for (l = opt.swi_names->next, numswis = 0; l; l = l->next, ++numswis)
+	/* */;
+      fputs("\tMOV\tr14,pc\n"
+            "\tADD\tr14,r14,# _CMUNGE_swi_ret - _CMUNGE_swi_pc\n", file);
+      output_label("_CMUNGE_swi_pc");
+      fprintf(file, "\tCMP\tr0,#%i\n",numswis);
+      fputs("\tADDLT\tpc,pc,r0,LSL #2\n", file);
+      if (opt.swi_handler)
+	{
+	  output_import(opt.swi_handler);
+	  fprintf(file, "\tB\t%s\n", opt.swi_handler);
+	}
+      else
+	fputs("\tB\t_CMUNGE_noswi_handler\n", file);
+
+      /* First one must be valid */
+      for (l = opt.swi_names->next; l; l = l->next)
+	{
+	  if (l->handler)
+	    {
+	      output_import(l->handler);
+	      fprintf(file, "\tB\t%s\n", l->handler);
+	    }
+	  else
+	    {
+	      if (opt.swi_handler)
+		fprintf(file, "\tB\t%s\n", opt.swi_handler);
+	      else
+		fputs("\tB\t_CMUNGE_noswi_handler\n", file);
+	    }
+	}
+      if (!opt.swi_handler)
+	{
+	  output_label("_CMUNGE_noswi_handler");
+	  fputs("\tMOV\tr0,#-1\n", file); /* 'SWI not known' */
+	}
+      output_label("_CMUNGE_swi_ret");
     }
-    fprintf(file, "\tMOV\tr14,pc\n");
-    fprintf(file, "\tADD\tr14,r14,# _CMUNGE_swi_ret - _CMUNGE_swi_pc\n");
-    fprintf(file, "_CMUNGE_swi_pc\n");
-    fprintf(file, "\tCMP\tr0,#%i\n",numswis);
-    fprintf(file, "\tADDLT\tpc,pc,r0,LSL #2\n");
-    if (opt.swi_handler)
+  else
     {
-      fprintf(file, "\tIMPORT\t%s\n", opt.swi_handler);
-      fprintf(file, "\tB\t%s\n", opt.swi_handler);
+      output_import(opt.swi_handler);
+      fprintf(file, "\tBL\t%s\n", opt.swi_handler);
     }
-    else
-      fprintf(file, "\tB\t_CMUNGE_noswi_handler\n");
-
-    l = opt.swi_names->next; /* First one must be valid */
-    while (l)
+  output_SUB_Lib_Reloc();
+  fputs("\tSTMIA\tr10,{r4,r5}\n"
+        "\tTEQ\tr0,#0\n", file);
+  if (CODE26)
+    fputs("\tLDMEQIA\tr13!,{r0-r9,pc}^\n", file);
+  else
     {
-      if (l->handler)
-      {
-        fprintf(file, "\tIMPORT\t%s\n", l->handler);
-        fprintf(file, "\tB\t%s\n", l->handler);
-      }
-      else
-      {
-        if (opt.swi_handler)
-          fprintf(file, "\tB\t%s\n", opt.swi_handler);
-        else
-          fprintf(file, "\tB\t_CMUNGE_noswi_handler\n");
-      }
-      l=l->next;
+      fputs("\tBNE\t_CMUNGE_swi_10\n"
+            "\tTEQ\tpc,pc\n"
+            "\tLDMNEIA\tr13!,{r0-r9,pc}^\n"
+            "\tMSR\tcpsr_cxsf,r8\n", file);
+      fputs("\tLDMIA\tr13!,{r0-r9,pc}\n", file);
+      output_label("_CMUNGE_swi_10");
     }
-    if (!opt.swi_handler)
+  fputs("\tADD\tr13,r13,#4\n"
+        "\tCMN\tr0,#1\n", file);
+  if (CODE26)
+    fputs("\tLDMNEIA\tr13!,{r1-r9,r14}\n"
+          "\tORRNES\tpc,r14,#0x10000000\n", file);
+  else
     {
-      fprintf(file, "_CMUNGE_noswi_handler\n");
-      fprintf(file, "\tMOV\tr0,#-1\n"); /* 'SWI not known' */
+      fputs("\tBEQ\t_CMUNGE_swi_30\n", file);
+      output_label("_CMUNGE_swi_20");
+      fputs("\tTEQ\tpc,pc\n"
+            "\tLDMNEIA\tr13!,{r1-r9,r14}\n"
+            "\tORRNES\tpc,r14,#0x10000000\n"
+            "\tORR\tr8,r8,#0x10000000\n"
+            "\tMSR\tcpsr_cxsf,r8\n"
+            "\tLDMIA\tr13!,{r1-r9,pc}\n", file);
+      output_label("_CMUNGE_swi_30");
     }
-    fprintf(file, "_CMUNGE_swi_ret\n");
-  }
+  fputs("\tADR\tr0,_CMUNGE_sht\n"
+        "\tMOV\tr1,#0\n"
+        "\tMOV\tr2,#0\n"
+        "\taddr\tr4,_CMUNGE_title\n"
+        "\tSWI\t0x61506\t", file); output_comment("XMessageTrans_ErrorLookup\n");
+  if (CODE26)
+    fputs("\tLDMIA\tr13!,{r1-r9,pc}\n", file);
   else
-  {
-    fprintf(file, "\tIMPORT\t%s\n", opt.swi_handler);
-    fprintf(file, "\tBL\t%s\n", opt.swi_handler);
-  }
-  fprintf(file, SUB_Lib_Reloc);
-  fprintf(file, "\tSTMIA\tr10,{r4,r5}\n");
-  fprintf(file, "\tTEQ\tr0,#0\n");
+    fputs("\tB\t_CMUNGE_swi_20\n", file);
+  output_label("_CMUNGE_sht");
+  output_word(0x1e6 , "");
+  output_simple_string("BadSWI");
+  output_align();
+}
+
+// FIXME: some generated ARM code can be shared with pieces emited in swi_handler()
+static void
+pdriver_handler(void)
+{
+  pdriver_list *l;
+  int numpdreasons;
+
+  if (!opt.pdriver_entry)
+    return;
+
+  output_export(opt.pdriver_entry);
+  output_label(opt.pdriver_entry);
+  fputs("\tSTMDB\tr13!,{r0-r9,r14}\n", file);
   if (CODE26)
-    fprintf(file, "\tLDMEQIA\tr13!,{r0-r9,pc}^\n");
+    {}
   else
-  {
-    fprintf(file, "\tBNE      _CMUNGE_swi_10\n");
-    fprintf(file, "\tTEQ      pc,pc\n");
-    fprintf(file, "\tLDMNEIA  r13!,{r0-r9,pc}^\n");
-    fprintf(file, "\tDCD &e12ff008 ; MSR cpsr_cxsf,r8\n");
-    fprintf(file, "\tLDMIA    r13!,{r0-r9,pc}\n");
-    fprintf(file, "_CMUNGE_swi_10\n");
-  }
-  fprintf(file, "\tADD\tr13,r13,#4\n");
-  fprintf(file, "\tCMN\tr0,#1\n");
+    fputs("\tMRS\tr8,cpsr\n", file);
+  fputs("\tMOV\tr10,r13,LSR #20\n"
+        "\tMOV\tr10,r10,LSL #20\n"
+        "\tMOV\tr0,r11\n"
+        "\tMOV\tr1,r13\n" /* R1 => _kernel_swi_regs */
+        "\tLDMIA\tr10,{r4,r5}\n"
+        "\tMOV\tr2,r12\n" /* R2 => module's private word */
+        "\tLDR\tr12,[r12]\n"
+        "\tLDMIB\tr12,{r11,r12}\n"
+        "\tSTMIA\tr10,{r11,r12}\n", file);
+  output_ADD_Lib_Reloc();
+  fputs("\tMOV\tr11,#0\n", file);
+  for (l = opt.pdriver_names, numpdreasons = 0; l; l = l->next, ++numpdreasons)
+    /* */;
+  fputs("\tMOV\tr14,pc\n"
+        "\tADD\tr14,r14,# _CMUNGE_pdriver_ret - _CMUNGE_pdriver_pc\n", file);
+  output_label("_CMUNGE_pdriver_pc");
+  fprintf(file, "\tCMP\tr0,#%i\n", numpdreasons);
+  fputs("\tADDLT\tpc,pc,r0,LSL #2\n"
+        "\tB\t_CMUNGE_nopdriver_handler\n", file);
+
+  /* First one must be valid */
+  for (l = opt.pdriver_names; l; l = l->next)
+    {
+      output_import(l->handler);
+      fprintf(file, "\tB\t%s\n", l->handler);
+    }
+  output_label("_CMUNGE_nopdriver_handler");
+  fputs("\tMOV\tr0,#-1\n", file); /* 'SWI not known' */
+  output_label("_CMUNGE_pdriver_ret");
+  output_SUB_Lib_Reloc();
+  fputs("\tSTMIA\tr10,{r4,r5}\n"
+        "\tTEQ\tr0,#0\n", file);
   if (CODE26)
-  {
-    fprintf(file, "\tLDMNEIA\tr13!,{r1-r9,r14}\n");
-    fprintf(file, "\tORRNES\tpc,r14,#0x10000000\n");
-  }
+    fputs("\tLDMEQIA\tr13!,{r0-r9,pc}^\n", file);
   else
-  {
-    fprintf(file, "\tBEQ      _CMUNGE_swi_30\n");
-    fprintf(file, "_CMUNGE_swi_20\n");
-    fprintf(file, "\tTEQ      pc,pc\n");
-    fprintf(file, "\tLDMNEIA  r13!,{r1-r9,r14}\n");
-    fprintf(file, "\tORRNES   pc,r14,#0x10000000\n");
-    fprintf(file, "\tORR      r8,r8,#0x10000000\n");
-    fprintf(file, "\tDCD &e12ff008 ; MSR cpsr_cxsf,r8\n");
-    fprintf(file, "\tLDMIA    r13!,{r1-r9,pc}\n");
-    fprintf(file, "_CMUNGE_swi_30\n");
-  }
-  fprintf(file, "\tADR\tr0,_CMUNGE_sht\n");
-  fprintf(file, "\tMOV\tr1,#0\n");
-  fprintf(file, "\tMOV\tr2,#0\n");
-  fprintf(file, "\taddr\tr4,_CMUNGE_title\n");
-  fprintf(file, "\tSWI\t0x61506 ; XMessageTrans_ErrorLookup\n");
+    {
+      fputs("\tBNE\t_CMUNGE_pdriver_10\n"
+            "\tTEQ\tpc,pc\n"
+            "\tLDMNEIA\tr13!,{r0-r9,pc}^\n"
+            "\tMSR\tcpsr_cxsf,r8\n"
+            "\tLDMIA\tr13!,{r0-r9,pc}\n", file);
+      output_label("_CMUNGE_pdriver_10");
+    }
+  fputs("\tADD\tr13,r13,#4\n"
+        "\tCMN\tr0,#1\n", file);
   if (CODE26)
-    fprintf(file, "\tLDMIA\tr13!,{r1-r9,pc}\n");
+    fputs("\tLDMNEIA\tr13!,{r1-r9,r14}\n"
+          "\tORRNES\tpc,r14,#0x10000000\n", file);
   else
-    fprintf(file, "\tB\t_CMUNGE_swi_20\n");
-  fprintf(file, "_CMUNGE_sht\n");
-  fprintf(file, "\tDCD\t&1e6\n");
-  fprintf(file, "\t= \"BadSWI\",0\n");
-  fprintf(file, "\tALIGN\n");
+    {
+      fputs("\tBEQ\t_CMUNGE_pdriver_30\n", file);
+      output_label("_CMUNGE_pdriver_20");
+      fputs("\tTEQ\tpc,pc\n"
+            "\tLDMNEIA\tr13!,{r1-r9,r14}\n"
+            "\tORRNES\tpc,r14,#0x10000000\n"
+            "\tORR\tr8,r8,#0x10000000\n"
+            "\tMSR\tcpsr_cxsf,r8\n"
+            "\tLDMIA\tr13!,{r1-r9,pc}\n", file);
+      output_label("_CMUNGE_pdriver_30");
+    }
+  fputs("\tADR\tr0,_CMUNGE_sht_pd\n"
+        "\tMOV\tr1,#0\n"
+        "\tMOV\tr2,#0\n"
+        "\taddr\tr4,_CMUNGE_title\n"
+        "\tSWI\t0x61506\t", file); output_comment("XMessageTrans_ErrorLookup\n");
+  if (CODE26)
+    fputs("\tLDMIA\tr13!,{r1-r9,pc}\n", file);
+  else
+    fputs("\tB\t_CMUNGE_pdriver_20\n", file);
+  output_label("_CMUNGE_sht_pd");
+  output_word(0x1e6 , "");
+  output_simple_string("BadSWI");
+  output_align();
 }
 
-static void swi_decoder(void) {
-
+static void
+swi_decoder(void)
+{
   if (!opt.swi_decoder)
     return;
-  fprintf(file, "_CMUNGE_swi_decoder\n");
-  if (opt.swi_decoder->handler) {
-    fprintf(file, "\tSTMDB\tr13!,{r0-r3,r10,r11,r14}\n");
-    fprintf(file, "\tMOV\tr10,r13,LSR #20\n");
-    fprintf(file, "\tMOV\tr10,r10,LSL #20\n");
-    fprintf(file, "\tLDMIA\tr10,{r4,r5}\n");
-    fprintf(file, "\tLDR\tr14,[r12]\n");
-    fprintf(file, "\tLDMIB\tr14,{r11,r14}\n");
-    fprintf(file, "\tSTMIA\tr10,{r11,r14}\n");
-    fprintf(file, ADD_Lib_Reloc);
-    fprintf(file, "\tMOV\tr11,#0\n");
-    fprintf(file, "\tCMP\tr0,#0\n");
-    fprintf(file, "\tBGE\t_CMUNGE_sd1\n");
-    fprintf(file, "\tMOV\tr0,r1\n");
-    fprintf(file, "\tMOV\tr1,r12\n");
-    fprintf(file, "\tIMPORT\t%s\n", opt.swi_decoder->name);
-    fprintf(file, "\tBL\t%s\n", opt.swi_decoder->name);
-    fprintf(file, "\tSTR\tr0,[r13,#0]\n");
-    fprintf(file, "\tB\t_CMUNGE_sd2\n");
-    fprintf(file, "_CMUNGE_sd1\n");
-    fprintf(file, "\tSTMDB\tr13!,{r12}\n");
-    fprintf(file, "\tIMPORT\t%s\n", opt.swi_decoder->handler);
-    fprintf(file, "\tBL\t%s\n", opt.swi_decoder->handler);
-    fprintf(file, "\tADD\tr13,r13,#4\n");
-    fprintf(file, "\tSTR\tr0,[r13,#8]\n");
-    fprintf(file, "_CMUNGE_sd2\n");
-    if (CODE26)
-      fprintf(file, SUB_Lib_Reloc);
-    else
-      fprintf(file, SUB_Lib_Reloc_S);
-    fprintf(file, "\tSTMIA\tr10,{r4,r5}\n");
-    if (CODE26)
-      fprintf(file, "\tLDMIA\tr13!,{r0-r3,r10,r11,pc}^\n");
-    else
-      fprintf(file, "\tLDMIA\tr13!,{r0-r3,r10,r11,pc}\n");
-  } else {
-    fprintf(file, "\tSTMDB\tr13!,{r0-r3,r10,r11,r14}\n");
-    fprintf(file, "\tMOV\tr10,r13,LSR #20\n");
-    fprintf(file, "\tMOV\tr10,r10,LSL #20\n");
-    fprintf(file, "\tMOV\tr0,r13\n");
-    fprintf(file, "\tLDMIA\tr10,{r4,r5}\n");
-    fprintf(file, "\tMOV\tr1,r12\n");
-    fprintf(file, "\tLDR\tr12,[r12]\n");
-    fprintf(file, "\tLDMIB\tr12,{r11,r12}\n");
-    fprintf(file, "\tSTMIA\tr10,{r11,r12}\n");
-    fprintf(file, ADD_Lib_Reloc);
-    fprintf(file, "\tMOV\tr11,#0\n");
-    fprintf(file, "\tIMPORT\t%s\n", opt.swi_decoder->name);
-    fprintf(file, "\tBL\t%s\n", opt.swi_decoder->name);
-    if (CODE26)
-      fprintf(file, SUB_Lib_Reloc);
-    else
-      fprintf(file, SUB_Lib_Reloc_S);
-    fprintf(file, "\tSTMIA\tr10,{r4,r5}\n");
-    if (CODE26)
-      fprintf(file, "\tLDMIA\tr13!,{r0-r3,r10,r11,pc}^\n");
-    else
-      fprintf(file, "\tLDMIA\tr13!,{r0-r3,r10,r11,pc}\n");
-  }
+  output_label("_CMUNGE_swi_decoder");
+  if (opt.swi_decoder->handler)
+    {
+      fputs("\tSTMDB\tr13!,{r0-r3,r10,r11,r14}\n"
+            "\tMOV\tr10,r13,LSR #20\n"
+            "\tMOV\tr10,r10,LSL #20\n"
+            "\tLDMIA\tr10,{r4,r5}\n"
+            "\tLDR\tr14,[r12]\n"
+            "\tLDMIB\tr14,{r11,r14}\n"
+            "\tSTMIA\tr10,{r11,r14}\n", file);
+      output_ADD_Lib_Reloc();
+      fputs("\tMOV\tr11,#0\n"
+            "\tCMP\tr0,#0\n"
+            "\tBGE\t_CMUNGE_sd1\n"
+            "\tMOV\tr0,r1\n"
+            "\tMOV\tr1,r12\n" /* R2 => module's private word */, file);
+      output_import(opt.swi_decoder->name);
+      fprintf(file, "\tBL\t%s\n", opt.swi_decoder->name);
+      fputs("\tSTR\tr0,[r13,#0]\n"
+            "\tB\t_CMUNGE_sd2\n", file);
+      output_label("_CMUNGE_sd1");
+      fputs("\tSTMDB\tr13!,{r12}\n", file);
+      output_import(opt.swi_decoder->handler);
+      fprintf(file, "\tBL\t%s\n", opt.swi_decoder->handler);
+      fputs("\tADD\tr13,r13,#4\n"
+            "\tSTR\tr0,[r13,#8]\n", file);
+      output_label("_CMUNGE_sd2");
+      if (CODE26)
+	output_SUB_Lib_Reloc();
+      else
+	output_SUB_Lib_Reloc_S();
+      fputs("\tSTMIA\tr10,{r4,r5}\n", file);
+      if (CODE26)
+	fputs("\tLDMIA\tr13!,{r0-r3,r10,r11,pc}^\n", file);
+      else
+	fputs("\tLDMIA\tr13!,{r0-r3,r10,r11,pc}\n", file);
+    }
+  else
+    {
+      fputs("\tSTMDB\tr13!,{r0-r3,r10,r11,r14}\n"
+            "\tMOV\tr10,r13,LSR #20\n"
+            "\tMOV\tr10,r10,LSL #20\n"
+            "\tMOV\tr0,r13\n" /* R1 => _kernel_swi_regs */
+            "\tLDMIA\tr10,{r4,r5}\n"
+            "\tMOV\tr1,r12\n" /* R2 => module's private word */
+            "\tLDR\tr12,[r12]\n"
+            "\tLDMIB\tr12,{r11,r12}\n"
+            "\tSTMIA\tr10,{r11,r12}\n", file);
+      output_ADD_Lib_Reloc();
+      fputs("\tMOV\tr11,#0\n", file);
+      output_import(opt.swi_decoder->name);
+      fprintf(file, "\tBL\t%s\n", opt.swi_decoder->name);
+      if (CODE26)
+	output_SUB_Lib_Reloc();
+      else
+	output_SUB_Lib_Reloc_S();
+      fputs("\tSTMIA\tr10,{r4,r5}\n", file);
+      if (CODE26)
+	fputs("\tLDMIA\tr13!,{r0-r3,r10,r11,pc}^\n", file);
+      else
+	fputs("\tLDMIA\tr13!,{r0-r3,r10,r11,pc}\n", file);
+    }
 }
 
-static void veneers(void) {
-
+static void
+veneers(void)
+{
   int any_error = 0;
   int n;
   int first;
   handler_list l;
-  int_list il;
 
   first = 1;
-  n = 0;
   /* JRF: Note: we use the number in r9 to indicate the routine that is
-                being entered, as number increasing by 1 (previously we
-                increased it by 4), so that we can use the top bit to
-                mean that the entry point can return an error. */
+   being entered, as number increasing by 1 (previously we increased it
+   by 4), so that we can use the top bit to mean that the entry point
+   can return an error. */
   /* Events */
-  l = opt.events;
-  while (l)
-  {
-    if (!first)
-      fprintf(file, "\tB\t_CMUNGE_ve\n");
-    fprintf(file, "\tEXPORT\t%s\n", l->name);
-    fprintf(file, "%s\n", l->name);
-    /* Output the event list */
-    if (l->extradata) {
-      int firstteq;
-      il = (int_list)l->extradata;
-      firstteq = 1;
-      while (il) {
-        if (firstteq) {
-          fprintf(file, "\tTEQ\tr0,#%d\n", il->val);
-        } else {
-          fprintf(file, "\tTEQNE\tr0,#%d\n", il->val);
-        }
-        il = il->next;
-        firstteq = 0;
-      }
-      if (CODE26)
-      {
-        fprintf(file, "\tMOVNES\tpc,r14\n");
-      }
-      else
-      {
-        fprintf(file, "\tMOVNE\tpc,r14\n");
-      }
-      l=l->next;
+  for (l = opt.events, n = 0; l != NULL; l = l->next, ++n)
+    {
+      if (!first)
+	fputs("\tB\t_CMUNGE_ve\n", file);
+      output_export(l->name);
+      output_label(l->name);
+      /* Output the event list */
+      if (l->extradata)
+	{
+	  int_list il;
+	  int firstteq = 1;
+
+	  for (il = (int_list)l->extradata; il != NULL; il = il->next)
+	    {
+	      if (firstteq)
+		fprintf(file, "\tTEQ\tr0,#%d\n", il->val);
+	      else
+		fprintf(file, "\tTEQNE\tr0,#%d\n", il->val);
+	      firstteq = 0;
+	    }
+	  if (CODE26)
+	    fputs("\tMOVNES\tpc,r14\n", file);
+	  else
+	    fputs("\tMOVNE\tpc,r14\n", file);
+	}
+      fprintf(file, "\tSTMDB\tr13!,{r0-r11,r14}\n"
+              "\tMOV\tr9,#%d\n", n);
+      first = 0;
     }
-    fprintf(file, "\tSTMDB\tr13!,{r0-r11,r14}\n");
-    fprintf(file, "\tMOV\tr9,#%d\n", n);
-    n += 1;
-    first = 0;
-  }
 
   /* Vectors */
-  l = opt.vectors;
-  while (l) {
-    if (!first)
-      fprintf(file, "\tB\t_CMUNGE_ve\n");
-    fprintf(file, "\tEXPORT\t%s\n", l->name);
-    fprintf(file, "%s\n", l->name);
-    fprintf(file, "\tSTMDB\tr13!,{r0-r11,r14}\n");
-    if (l->error_capable)
+  for (l = opt.vectors; l != NULL; l = l->next, ++n)
     {
-      fprintf(file, "\tMOV\tr9,#%d :OR: (1<<31)\n", n);
-      any_error = 1;
+      if (!first)
+	fputs("\tB\t_CMUNGE_ve\n", file);
+      output_export(l->name);
+      output_label(l->name);
+      fputs("\tSTMDB\tr13!,{r0-r11,r14}\n", file);
+      if (l->error_capable)
+	{
+	  fprintf(file, "\tMOV\tr9,#%d :OR: (1<<31)\n", n);
+	  any_error = 1;
+	}
+      else
+	fprintf(file, "\tMOV\tr9,#%d\n", n);
+      first = 0;
     }
-    else
-      fprintf(file, "\tMOV\tr9,#%d\n", n);
-    l = l->next;
-    n += 1;
-    first = 0;
-  }
+
   /* Irqs */
-  l = opt.irqs;
-  while (l) {
-    if (!first)
-      fprintf(file, "\tB\t_CMUNGE_ve\n");
-    fprintf(file, "\tEXPORT\t%s\n", l->name);
-    fprintf(file, "%s\n", l->name);
-    fprintf(file, "\tSTMDB\tr13!,{r0-r11,r14}\n");
-    fprintf(file, "\tMOV\tr9,#%d\n", n);
-    l = l->next;
-    n += 1;
-    first = 0;
-  }
+  for (l = opt.irqs; l != NULL; l = l->next, ++n)
+    {
+      if (!first)
+	fputs("\tB\t_CMUNGE_ve\n", file);
+      output_export(l->name);
+      output_label(l->name);
+      fprintf(file, "\tSTMDB\tr13!,{r0-r11,r14}\n"
+              "\tMOV\tr9,#%d\n", n);
+      first = 0;
+    }
+
   if (n == 0)
     return;
-  fprintf(file, "_CMUNGE_ve\n");
-  fprintf(file, "\tMOV\tr0,r13\n");
+
+  output_label("_CMUNGE_ve");
+  fputs("\tMOV\tr0,r13\n", file);
   if (CODE26)
-  {
-    fprintf(file, "\tMOV\tr6,pc\n");
-    fprintf(file, "\tBIC\tr3,r6,#3\n");
-    fprintf(file, "\tTEQP\tr3,#3\n");
-  }
+    fputs("\tMOV\tr6,pc\n"
+          "\tBIC\tr3,r6,#3\n"
+          "\tTEQP\tr3,#3\n", file);
   else
-  {
-    fprintf(file, "\tTEQ      pc,pc\n");
-    fprintf(file, "\tMOVNE    r8,pc\n");
-    fprintf(file, "\tORRNE    r3,r8,#3\n");
-    fprintf(file, "\tTEQNEP   r3,#0\n");
-    fprintf(file, "\tMRSEQ    r6,cpsr\n");
-    fprintf(file, "\tORREQ    r3,r6,#3\n");
-    fprintf(file, "\tMSREQ    cpsr_ctl,r3\n");
-  }
-  fprintf(file, "\tMOV\tr1,r12\n");
-  fprintf(file, "\tMOV\tr7,r14\n");
-  fprintf(file, "\tMOV\tr10,r13,LSR #20\n");
-  fprintf(file, "\tMOV\tr10,r10,LSL #20\n");
-  fprintf(file, "\tLDMIA\tr10,{r4,r5}\n");
-  fprintf(file, "\tLDR\tr12,[r12]\n");
-  fprintf(file, "\tLDMIB\tr12,{r11,r12}\n");
-  fprintf(file, "\tSTMIA\tr10,{r11,r12}\n");
-  fprintf(file, ADD_Lib_Reloc);
-  fprintf(file, "\tMOV\tr11,#0\n");
+    fputs("\tTEQ\tpc,pc\n"
+          "\tMOVNE\tr8,pc\n"
+          "\tORRNE\tr3,r8,#3\n"
+          "\tTEQNEP\tr3,#0\n"
+          "\tMRSEQ\tr6,cpsr\n"
+          "\tORREQ\tr3,r6,#3\n"
+          "\tMSREQ\tcpsr_c,r3\n", file);
+  fputs("\tMOV\tr1,r12\n"
+        "\tMOV\tr7,r14\n"
+        "\tMOV\tr10,r13,LSR #20\n"
+        "\tMOV\tr10,r10,LSL #20\n"
+        "\tLDMIA\tr10,{r4,r5}\n"
+        "\tLDR\tr12,[r12]\n"
+        "\tLDMIB\tr12,{r11,r12}\n"
+        "\tSTMIA\tr10,{r11,r12}\n", file);
+  output_ADD_Lib_Reloc();
+  fputs("\tMOV\tr11,#0\n", file);
   if (CODE26)
-  {
-    fprintf(file, "\tMOV\tr14,pc\n");
-    fprintf(file, "\tADD\tr14,r14,# _CMUNGE_vret - _CMUNGE_vpc\n");
-  }
+    fputs("\tMOV\tr14,pc\n"
+          "\tADD\tr14,r14,# _CMUNGE_vret - _CMUNGE_vpc\n", file);
   else
-  {
-    fprintf(file, "\tADD\tr14,pc,# _CMUNGE_vret - _CMUNGE_vpc - 4\n");
-  }
-  fprintf(file, "_CMUNGE_vpc\n");
-  fprintf(file, "\tADD\tpc,pc,r9,LSL #2 ; notice that we lose the top bits\n");
-  fprintf(file, "\tMOV\tr0,r0\n");
+    fputs("\tADD\tr14,pc,# _CMUNGE_vret - _CMUNGE_vpc - 4\n", file);
+  output_label("_CMUNGE_vpc");
+  fputs("\tADD\tpc,pc,r9,LSL #2\t", file); output_comment("Notice that we lose the top bits\n");
+  fputs("\tMOV\tr0,r0\n", file);
 
   /* Events */
-  l = opt.events;
-  while (l) {
-    if (l->handler) {
-      fprintf(file, "\tIMPORT\t%s\n", l->handler);
-      fprintf(file, "\tB\t%s\n", l->handler);
-    } else {
-      fprintf(file, "\tIMPORT\t%s_handler\n", l->name);
-      fprintf(file, "\tB\t%s_handler\n", l->name);
+  for (l = opt.events; l != NULL; l = l->next)
+    {
+      if (l->handler)
+	{
+	  output_import(l->handler);
+	  fprintf(file, "\tB\t%s\n", l->handler);
+	}
+      else
+	{
+	  output_import_vargs("%s_handler", l->name);
+	  fprintf(file, "\tB\t%s_handler\n", l->name);
+	}
     }
-    l = l->next;
-  }
   /* Vectors */
-  l = opt.vectors;
-  while (l) {
-    if (l->handler) {
-      fprintf(file, "\tIMPORT\t%s\n", l->handler);
-      fprintf(file, "\tB\t%s\n", l->handler);
-    } else {
-      fprintf(file, "\tIMPORT\t%s_handler\n", l->name);
-      fprintf(file, "\tB\t%s_handler\n", l->name);
+  for (l = opt.vectors; l != NULL; l = l->next)
+    {
+      if (l->handler)
+	{
+	  output_import(l->handler);
+	  fprintf(file, "\tB\t%s\n", l->handler);
+	}
+      else
+	{
+	  output_import_vargs("%s_handler", l->name);
+	  fprintf(file, "\tB\t%s_handler\n", l->name);
+	}
     }
-    l = l->next;
-  }
   /* Irqs */
-  l = opt.irqs;
-  while (l) {
-    if (l->handler) {
-      fprintf(file, "\tIMPORT\t%s\n", l->handler);
-      fprintf(file, "\tB\t%s\n", l->handler);
-    } else {
-      fprintf(file, "\tIMPORT\t%s_handler\n", l->name);
-      fprintf(file, "\tB\t%s_handler\n", l->name);
+  for (l = opt.irqs; l != NULL; l = l->next)
+    {
+      if (l->handler)
+	{
+	  output_import(l->handler);
+	  fprintf(file, "\tB\t%s\n", l->handler);
+	}
+      else
+	{
+	  output_import_vargs("%s_handler", l->name);
+	  fprintf(file, "\tB\t%s_handler\n", l->name);
+	}
     }
-    l = l->next;
-  }
-  fprintf(file, "_CMUNGE_vret\n");
-  fprintf(file, SUB_Lib_Reloc);
-  fprintf(file, "\tSTMIA\tr10,{r4,r5}\n");
-  fprintf(file, "\tMOV\tr14,r7\n");
+
+  output_label("_CMUNGE_vret");
+  output_SUB_Lib_Reloc();
+  fputs("\tSTMIA\tr10,{r4,r5}\n"
+        "\tMOV\tr14,r7\n", file);
   if (CODE26)
-  {
-    fprintf(file, "\tTEQP\tr6,#0\n");
-  }
+    fputs("\tTEQP\tr6,#0\n", file);
   else
-  {
-    fprintf(file, "\tTEQ      pc,pc\n");
-    fprintf(file, "\tBEQ      _CMUNGE_vret_10\n");
-    fprintf(file, "\tTEQP     r8,#0\n");
-  }
+    fputs("\tTEQ\tpc,pc\n"
+          "\tBEQ\t_CMUNGE_vret_10\n"
+          "\tTEQP\tr8,#0\n", file);
   if (any_error)
-  {
-    /* r9 = has bit 31 set if :
-            r0 = 0 (claim)
-                 1 (pass on)
-                 pointer to error (claim + set v)
-            otherwise:
-            r0 = 0 (claim)
-                 other (pass on)
-     */
-    fprintf(file, "\tTST\tr9,#1<<31\n");
-    fprintf(file, "\tBEQ\t_CMUNGE_vret_26noerror\n");
+    {
+      /* r9 = has bit 31 set if :
+       r0 = 0 (claim)
+       1 (pass on)
+       pointer to error (claim + set v)
+       otherwise:
+       r0 = 0 (claim)
+       other (pass on)
+       */
+      fputs("\tTST\tr9,#1<<31\n"
+            "\tBEQ\t_CMUNGE_vret_26noerror\n"
+            "\tCMP\tr0,#1\n"
+            "\tLDMEQIA\tr13!,{r0-r11,pc}^\n"
+            "\tLDMLOIA\tr13!,{r0-r11,r14,pc}^\n"
+            "\tSTR\tr0,[sp]\n"
+            "\tLDMIA\tr13!,{r0-r11,r14}\n"
+            "\tLDR\tr14,[sp], #4\n"
+            "\tORRS\tpc, r14, #1<<28\t", file); output_comment("Return with V set\n");
+      output_label("_CMUNGE_vret_26noerror");
+    }
+  fputs("\tTEQ\tr0,#0\n"
+        "\tLDMEQIA\tr13!,{r0-r11,r14,pc}^\n"
+        "\tLDMNEIA\tr13!,{r0-r11,pc}^\n", file);
 
-    fprintf(file, "\tCMP\tr0,#1\n");
-    fprintf(file, "\tLDMEQIA\tr13!,{r0-r11,pc}^\n");
-    fprintf(file, "\tLDMLOIA\tr13!,{r0-r11,r14,pc}^\n");
-    fprintf(file, "\tSTR\tr0,[sp]\n");
-    fprintf(file, "\tLDMIA\tr13!,{r0-r11,r14}\n");
-    fprintf(file, "\tLDR\tr14,[sp], #4\n");
-    fprintf(file, "\tORRS\tpc, r14, #1<<28 ; return with V set\n");
-    fprintf(file, "_CMUNGE_vret_26noerror\n");
-  }
-  fprintf(file, "\tTEQ\tr0,#0\n");
-  fprintf(file, "\tLDMEQIA\tr13!,{r0-r11,r14,pc}^\n");
-  fprintf(file, "\tLDMNEIA\tr13!,{r0-r11,pc}^\n");
-
   if (CODE26)
-  {}
+    {}
   else
-  {
-    fprintf(file, "_CMUNGE_vret_10\n");
-    if (any_error)
     {
-      /* r9 = has bit 31 set if :
-              r0 = 0 (claim)
-                   1 (pass on)
-                   pointer to error (claim + set v)
-              otherwise:
-              r0 = 0 (claim)
-                   other (pass on)
-       */
-      fprintf(file, "\tTST\tr9,#1<<31\n");
-      fprintf(file, "\tBICNES\tr14,r0,#1\n");
-      fprintf(file, "\tORRNE\tr6,r6,#1<<28 ; V set on returned flags\n");
-      fprintf(file, "\tSTRNE\tr0,[sp, #0]  ; R0 updated for return\n");
-      fprintf(file, "\tMOVNE\tr0,#0        ; mark as claiming\n");
+      output_label("_CMUNGE_vret_10");
+      if (any_error)
+	{
+	  /* r9 = has bit 31 set if :
+	   r0 = 0 (claim)
+	   1 (pass on)
+	   pointer to error (claim + set v)
+	   otherwise:
+	   r0 = 0 (claim)
+	   other (pass on)
+	   */
+	  fputs("\tTST\tr9,#1<<31\n"
+	        "\tBICNES\tr14,r0,#1\n", file);
+	  fputs("\tORRNE\tr6,r6,#1<<28\t", file); output_comment("V set on returned flags\n");
+	  fputs("\tSTRNE\tr0,[sp, #0]\t", file); output_comment("R0 updated for return\n");
+	  fputs("\tMOVNE\tr0,#0\t", file); output_comment("Mark as claiming\n");
+	}
+      fputs("\tMOV\tr12,r6\n"
+            "\tMSR\tcpsr_c,r6\n"
+            "\tTEQ\tr0,#0\n"
+            "\tLDMIA\tr13!,{r0-r11,r14}\n"
+            "\tLDREQ\tr14,[r13],#4\n"
+            "\tMSR\tcpsr_f,r12\n"
+            "\tMOV\tpc,r14\n", file);
     }
-    fprintf(file, "\tMOV      r12,r6\n");
-    fprintf(file, "\tMSR      cpsr_ctl,r6\n");
-    fprintf(file, "\tTEQ      r0,#0\n");
-    fprintf(file, "\tLDMIA    r13!,{r0-r11,r14}\n");
-    fprintf(file, "\tLDREQ    r14,[r13],#4\n");
-    fprintf(file, "\tMSR      cpsr_flg,r12\n");
-    fprintf(file, "\tMOV      pc,r14\n");
-  }
 }
 
 /* Vector traps are a special case of veneers */
-static void vector_traps(void) {
-
+static void
+vector_traps(void)
+{
   int n;
   int first;
   handler_list l;
 
   first = 1;
-  n = 0;
   /* Vector traps */
-  l = opt.vector_traps;
-  while (l) {
-    if (!first)
-      fprintf(file, "\tB\t_CMUNGE_vte\n");
-    fprintf(file, "\tEXPORT\t%s\n", l->name);
-    fprintf(file, "%s\n", l->name);
-    fprintf(file, "\tSTMDB\tr13!,{r0-r11,r14}\n");
-    fprintf(file, "\tMOV\tr2,#%d\n", n);
-    l = l->next;
-    n += 4;
-    first = 0;
-  }
+  for (l = opt.vector_traps, n = 0; l != NULL; l = l->next, n += 4)
+    {
+      if (!first)
+	fputs("\tB\t_CMUNGE_vte\n", file);
+      output_export(l->name);
+      output_label(l->name);
+      fprintf(file,
+              "\tSTMDB\tr13!,{r0-r11,r14}\n"
+              "\tMOV\tr2,#%d\n", n);
+      first = 0;
+    }
+
   if (n == 0)
     return;
-  fprintf(file, "_CMUNGE_vte\n");
-  fprintf(file, "\tMOV\tr0,r13\n");
+
+  output_label("_CMUNGE_vte");
+  fputs("\tMOV\tr0,r13\n", file);
   if (CODE26)
-  {
-    fprintf(file, "\tMOV\tr6,pc\n");
-    fprintf(file, "\tBIC\tr3,r6,#3\n");
-    fprintf(file, "\tTEQP\tr3,#3\n");
-  }
+    fputs("\tMOV\tr6,pc\n"
+          "\tBIC\tr3,r6,#3\n"
+          "\tTEQP\tr3,#3\n", file);
   else
-  {
-    fprintf(file, "\tTEQ      pc,pc\n");
-    fprintf(file, "\tMOVNE    r8,pc\n");
-    fprintf(file, "\tBICNE    r3,r8,#3\n");
-    fprintf(file, "\tTEQNEP   r3,#3\n");
-    fprintf(file, "\tMRSEQ    r6,cpsr\n");
-    fprintf(file, "\tORREQ    r3,r6,#3\n");
-    fprintf(file, "\tMSREQ    cpsr_ctl,r3\n");
-  }
-  fprintf(file, "\tMOV\tr1,r12\n");
-  fprintf(file, "\tMOV\tr7,r14\n");
-  fprintf(file, "\tMOV\tr10,r13,LSR #20\n");
-  fprintf(file, "\tMOV\tr10,r10,LSL #20\n");
-  fprintf(file, "\tLDMIA\tr10,{r4,r5}\n");
-  fprintf(file, "\tLDR\tr12,[r12]\n");
-  fprintf(file, "\tLDMIB\tr12,{r11,r12}\n");
-  fprintf(file, "\tSTMIA\tr10,{r11,r12}\n");
-  fprintf(file, ADD_Lib_Reloc );
-  fprintf(file, "\tMOV\tr11,#0\n");
-  fprintf(file, "\tMOV\tr12,r2\n");
-  fprintf(file, "\tADR\tr2,_CMUNGE_vtcall\n");
-  fprintf(file, "\tMOV\tr3,r0\n");
-  fprintf(file, "\tMOV\tr14,pc\n");
-  fprintf(file, "\tADD\tr14,r14,# _CMUNGE_vtret - _CMUNGE_vtpc\n");
-  fprintf(file, "_CMUNGE_vtpc\n");
-  fprintf(file, "\tADD\tpc,pc,r12\n");
-  fprintf(file, "\tMOV\tr0,r0\n");
+    fputs("\tTEQ\tpc,pc\n"
+          "\tMOVNE\tr8,pc\n"
+          "\tBICNE\tr3,r8,#3\n"
+          "\tTEQNEP\tr3,#3\n"
+          "\tMRSEQ\tr6,cpsr\n"
+          "\tORREQ\tr3,r6,#3\n"
+          "\tMSREQ\tcpsr_c,r3\n", file);
+  fputs("\tMOV\tr1,r12\n"
+        "\tMOV\tr7,r14\n"
+        "\tMOV\tr10,r13,LSR #20\n"
+        "\tMOV\tr10,r10,LSL #20\n"
+        "\tLDMIA\tr10,{r4,r5}\n"
+        "\tLDR\tr12,[r12]\n"
+        "\tLDMIB\tr12,{r11,r12}\n"
+        "\tSTMIA\tr10,{r11,r12}\n", file);
+  output_ADD_Lib_Reloc();
+  fputs("\tMOV\tr11,#0\n"
+        "\tMOV\tr12,r2\n"
+        "\tADR\tr2,_CMUNGE_vtcall\n"
+        "\tMOV\tr3,r0\n"
+        "\tMOV\tr14,pc\n"
+        "\tADD\tr14,r14,# _CMUNGE_vtret - _CMUNGE_vtpc\n", file);
+  output_label("_CMUNGE_vtpc");
+  fputs("\tADD\tpc,pc,r12\n"
+        "\tMOV\tr0,r0\n", file);
 
   /* Vector traps */
-  l = opt.vector_traps;
-  while (l) {
-    if (l->handler) {
-      fprintf(file, "\tIMPORT\t%s\n", l->handler);
-      fprintf(file, "\tB\t%s\n", l->handler);
-    } else {
-      fprintf(file, "\tIMPORT\t%s_handler\n", l->name);
-      fprintf(file, "\tB\t%s_handler\n", l->name);
+  for (l = opt.vector_traps; l != NULL; l = l->next)
+    {
+      if (l->handler)
+	{
+	  output_import(l->handler);
+	  fprintf(file, "\tB\t%s\n", l->handler);
+	}
+      else
+	{
+	  output_import_vargs("%s_handler", l->name);
+	  fprintf(file, "\tB\t%s_handler\n", l->name);
+	}
     }
-    l = l->next;
-  }
-  fprintf(file, "_CMUNGE_vtret\n");
-  fprintf(file, SUB_Lib_Reloc );
-  fprintf(file, "\tSTMIA\tr10,{r4,r5}\n");
-  fprintf(file, "\tMOV\tr14,r7\n");
+  output_label("_CMUNGE_vtret");
+  output_SUB_Lib_Reloc();
+  fputs("\tSTMIA\tr10,{r4,r5}\n"
+        "\tMOV\tr14,r7\n", file);
   /* Return to the caller's mode */
   if (CODE26)
-  {
-    fprintf(file, "\tTEQP\tr6,#0\n");
-  }
+    fputs("\tTEQP\tr6,#0\n", file);
   else
-  {
-    fprintf(file, "\tTEQ      pc,pc\n");
-    fprintf(file, "\tMSREQ    cpsr_ctl,r6\n");
-    fprintf(file, "\tTEQNEP   r8,#0\n");
-  }
+    fputs("\tTEQ\tpc,pc\n"
+          "\tMSREQ\tcpsr_c,r6\n"
+          "\tTEQNEP\tr8,#0\n", file);
   /* We need to return if 1,
-                claim if 0,
-                claim with VS, r0 passed on if other values
+   claim if 0,
+   claim with VS, r0 passed on if other values
    */
   if (CODE26)
-  {
-    fprintf(file, "\tTEQ\tr0,#1\n");
-    fprintf(file, "\tLDMEQIA\tr13!,{r0-r11,pc}^\n");
-    fprintf(file, "\tTEQ\tr0,#0\n");
-    fprintf(file, "\tLDMEQIA\tr13!,{r0-r11,r14,pc}^\n");
-    fprintf(file, "\tADD\tr13,r13,#4\n");
-    fprintf(file, "\tLDMIA\tr13!,{r1-r11,r14}\n");
-    fprintf(file, "\tLDR\tr14,[r13],#4\n");
-    fprintf(file, "\tORRS\tpc,r14,#0x10000000\n");
-  }
+    fputs("\tTEQ\tr0,#1\n"
+          "\tLDMEQIA\tr13!,{r0-r11,pc}^\n"
+          "\tTEQ\tr0,#0\n"
+          "\tLDMEQIA\tr13!,{r0-r11,r14,pc}^\n"
+          "\tADD\tr13,r13,#4\n"
+          "\tLDMIA\tr13!,{r1-r11,r14}\n"
+          "\tLDR\tr14,[r13],#4\n"
+          "\tORRS\tpc,r14,#0x10000000\n", file);
   else
-  {
-    /* JRF: Checked 20 Feb 2006, and should now be correct */
-    fprintf(file,"\tCMP     r0, #1\n");
-    fprintf(file,"\tBHI     _CMUNGE_vtretv\n");
-    fprintf(file,"\tMOV     r12, r6\n");
-    fprintf(file,"\tLDMEQIA r13!,{r0-r11}      ; r0=1 case (pass on)\n");
-    fprintf(file,"\tLDMLOIA r13!,{r0-r11,r14}  ; r0=0 case (claim)\n");
-    fprintf(file,"\tTEQ     pc,pc\n");
-    fprintf(file,"\tLDR     r14, [sp], #4\n");
-    fprintf(file,"\tMOVNES  pc,r14\n");
-    fprintf(file,"\tMSR     cpsr_flg,r12\n");
-    fprintf(file,"\tMOV     pc, r14\n");
+    {
+      /* JRF: Checked 20 Feb 2006, and should now be correct */
+      fputs("\tCMP\tr0, #1\n"
+            "\tBHI\t_CMUNGE_vtretv\n"
+            "\tMOV\tr12, r6\n", file);
+      fputs("\tLDMEQIA\tr13!,{r0-r11}\t", file); output_comment("r0=1 case (pass on)\n");
+      fputs("\tLDMLOIA\tr13!,{r0-r11,r14}\t", file); output_comment("r0=0 case (claim)\n");
+      fputs("\tTEQ\tpc,pc\n"
+            "\tLDR\tr14, [sp], #4\n"
+            "\tMOVNES\tpc,r14\n"
+            "\tMSR\tcpsr_f,r12\n"
+            "\tMOV\tpc, r14\n", file);
 
-    fprintf(file,"_CMUNGE_vtretv               ; r0 = anything else (claim+VS+R0 returned)\n");
-    fprintf(file,"\tADD     r13, r13, #4\n");
-    fprintf(file,"\tLDMIA   r13!,{r1-r11,r14}\n");
-    fprintf(file,"\tTEQ     pc,pc\n");
-    fprintf(file,"\tLDR     r14, [sp], #4\n");
-    fprintf(file,"\tORREQ   r12, r6, #0x10000000\n");
-    fprintf(file,"\tORRNE   r14, r14, #0x10000000\n");
-    fprintf(file,"\tMOVNES  pc,r14\n");
-    fprintf(file,"\tMSR     cpsr_flg,r12\n");
-    fprintf(file,"\tMOV     pc, r14\n");
-  }
+      output_comment("r0 = anything else (claim+VS+R0 returned)\n");
+      output_label("_CMUNGE_vtretv");
+      fputs("\tADD\tr13, r13, #4\n"
+            "\tLDMIA\tr13!,{r1-r11,r14}\n"
+            "\tTEQ\tpc,pc\n"
+            "\tLDR\tr14, [sp], #4\n"
+            "\tORREQ\tr12, r6, #0x10000000\n"
+            "\tORRNE\tr14, r14, #0x10000000\n"
+            "\tMOVNES\tpc,r14\n"
+            "\tMSR\tcpsr_f,r12\n"
+            "\tMOV\tpc, r14\n", file);
+    }
 
   /* Now the call routine...
-     This routine is called with :
-       r0-> register block to pass to routine
-       r1-> *original* register block
-     What we must do is...
-  */
+   This routine is called with :
+   r0-> register block to pass to routine
+   r1-> *original* register block
+   What we must do is...
+   */
 
-  fprintf(file, "_CMUNGE_vtcall\n");
+  output_label("_CMUNGE_vtcall");
 
-  fprintf(file, "\tSTMFD\tr13!,{r0,r4-r11,r14}\n");
-  fprintf(file, "\tADD\tr12,r1,#10*4\n");
-  fprintf(file, "\tLDMIA\tr0,{r0-r9}\n");
-  fprintf(file, "\tSTMFD\tr13!,{pc}\n");
-  fprintf(file, "\tLDMFD\tr12,{r10,r11,pc}\n");
-  fprintf(file, "\tNOP\n");
-  fprintf(file, "\tLDR\tr12,[r13],#4\n");
-  fprintf(file, "\tSTMIA\tr12,{r0-r9}\n");
-  fprintf(file, "\tMOVVC\tr0,#0\n");
+  fputs("\tSTMFD\tr13!,{r0,r4-r11,r14}\n"
+        "\tADD\tr12,r1,#10*4\n"
+        "\tLDMIA\tr0,{r0-r9}\n"
+        "\tSTMFD\tr13!,{pc}\n"
+        "\tLDMFD\tr12,{r10,r11,pc}\n"
+        "\tNOP\n"
+        "\tLDR\tr12,[r13],#4\n"
+        "\tSTMIA\tr12,{r0-r9}\n"
+        "\tMOVVC\tr0,#0\n", file);
   if (CODE26)
-  {
-    fprintf(file, "\tLDMFD\tr13!,{r4-r11,pc}^\n");
-  }
+    fputs("\tLDMFD\tr13!,{r4-r11,pc}^\n", file);
   else
-  {
-    /* We're returning to APCS-32 so no need to preserve flags -
-       note that we're inside our client, so there is no
-       need to check for 26bitness. To do so would violate APCS-32.
-     */
-    fprintf(file, "\tLDMFD\tr13!,{r4-r11,pc}\n");
-  }
+    {
+      /* We're returning to APCS-32 so no need to preserve flags -
+         note that we're inside our client, so there is no
+         need to check for 26bitness. To do so would violate APCS-32.  */
+      fputs("\tLDMFD\tr13!,{r4-r11,pc}\n", file);
+    }
 }
 
-static void errors(void) {
+static void
+errors(void)
+{
+  int error = opt.error_base;
+  error_list l;
 
-  int error=opt.error_base;
-  error_list l=opt.errors;
-
   if (opt.errors==NULL)
     return;
 
-  fprintf(file,"\n; Error messages, based at &%08x\n",error);
-  while (l)
+  fputc('\n', file);
+
+  if (opt.toolchain == tc_gcc)
   {
-    fprintf(file,"\tEXPORT\t__err_%s\n",l->name);
-    fprintf(file,"__err_%s\n",l->name);
-    if (l->number)
-      fprintf(file,"\tDCD\t&%08x\n",l->number);
-    else
-      fprintf(file,"\tDCD\t&%08x\n",error++);
-    fprintf(file,"\t= \"%s\",0\n",l->message);
-    fprintf(file,"\tALIGN\n");
-    l = l->next;
+    /* Put the generated error messages in read-only data section.  */
+    fputs("\t.section\t.rodata\n"
+	  "\t.align 2\n", file);
   }
+  output_comment_vargs("Error messages, based at &%08x\n", error);
+  for (l = opt.errors; l != NULL; l = l->next)
+    {
+      output_export_vargs("__err_%s", l->name);
+      output_label_vargs("__err_%s", l->name);
+      output_word((l->number) ? l->number : error++, "An error number");
+      output_simple_string(l->message);
+      output_align();
+    }
 }
 
-static void generics(void) {
-
+static void
+generics(void)
+{
   int n;
   int first;
   handler_list l;
 
   /* So that we can preserve r12 when we use the generic veneers, we remember
-     whether we have had any registers specified */
+   whether we have had any registers specified */
   int preserve_endreg=11;
 
   /* 0 if we're not doing the carry_capable handlers,
-     1 if we're doing the carry_capable handlers */
+   1 if we're doing the carry_capable handlers */
   int carry_now;
 
   /* Check if we use any specific registers */
-  l = opt.generics;
-  while (l) {
-    if (l->private_word != -1)
-      preserve_endreg=12;
-    l = l->next;
-  }
+  for (l = opt.generics; l != NULL; l = l->next)
+    {
+      if (l->private_word != -1)
+	preserve_endreg=12;
+    }
 
-  for (carry_now=0; carry_now<2; carry_now++)
-  {
-    first = 1;
-    n = 0;
-
-    /* Generic */
-    l = opt.generics;
-    for (l=opt.generics; l; l=l->next)
+  for (carry_now = 0; carry_now < 2; carry_now++)
     {
-      if (carry_now != l->carry_capable)
-        continue;
+      first = 1;
 
-      if (!first)
-        fprintf(file, "\tB\t_CMUNGE_ge%s\n",carry_now ? "_carry" : "");
-      fprintf(file, "\tEXPORT\t%s\n", l->name);
-      fprintf(file, "%s\n", l->name);
-      fprintf(file, "\tSTMDB\tr13!,{r0-r%i,r14}\n",preserve_endreg);
+      /* Generic */
+      n = 0;
+      for (l = opt.generics; l != NULL; l = l->next)
+	{
+	  if (carry_now != l->carry_capable)
+	    continue;
 
-      /* If the private word appears elsewhere, use that */
-      if (l->private_word != -1 &&
-          l->private_word != 12)
-        fprintf(file, "\tMOV\tr12,r%i\n", l->private_word);
+	  if (!first)
+	    fprintf(file, "\tB\t_CMUNGE_ge%s\n",carry_now ? "_carry" : "");
+	  output_export(l->name);
+	  output_label(l->name);
+	  fprintf(file, "\tSTMDB\tr13!,{r0-r%i,r14}\n", preserve_endreg);
 
-      fprintf(file, "\tMOV\tr2,#%d\n", n);
-      n += 4;
-      first = 0;
-    }
+	  /* If the private word appears elsewhere, use that */
+	  if (l->private_word != -1 && l->private_word != 12)
+	    fprintf(file, "\tMOV\tr12,r%i\n", l->private_word);
 
-    if (n == 0)
-      continue;
+	  fprintf(file, "\tMOV\tr2,#%d\n", n);
+	  n += 4;
+	  first = 0;
+	}
 
-    fprintf(file, "_CMUNGE_ge%s\n",carry_now ? "_carry" : "");
-    fprintf(file, "\tMOV\tr0,r13\n");
-    if (CODE26)
-    {
-      fprintf(file, "\tMOV\tr6,pc\n");
-      fprintf(file, "\tBIC\tr3,r6,#3\n");
-      fprintf(file, "\tTEQP\tr3,#3\n");
-    }
-    else
-    {
-      fprintf(file, "\tTEQ      pc,pc\n");
-      fprintf(file, "\tMOVNE    r8,pc\n");
-      fprintf(file, "\tORRNE    r3,r8,#3\n");
-      fprintf(file, "\tTEQNEP   r3,#0\n");
-      fprintf(file, "\tMRSEQ    r6,cpsr\n");
-      fprintf(file, "\tORREQ    r3,r6,#3\n");
-      fprintf(file, "\tMSREQ    cpsr_ctl,r3\n");
-    }
-    fprintf(file, "\tMOV\tr1,r12\n");
-    fprintf(file, "\tMOV\tr7,r14\n");
-    fprintf(file, "\tMOV\tr10,r13,LSR #20\n");
-    fprintf(file, "\tMOV\tr10,r10,LSL #20\n");
-    fprintf(file, "\tLDMIA\tr10,{r4,r5}\n");
-    fprintf(file, "\tLDR\tr12,[r12]\n");
-    fprintf(file, "\tLDMIB\tr12,{r11,r12}\n");
-    fprintf(file, "\tSTMIA\tr10,{r11,r12}\n");
-    fprintf(file, ADD_Lib_Reloc);
-    fprintf(file, "\tMOV\tr11,#0\n");
-    if (CODE26)
-    {
-      fprintf(file, "\tMOV\tr14,pc\n");
-      fprintf(file, "\tADD\tr14,r14,#_CMUNGE_gret%s - _CMUNGE_gpc%s\n",
-                    carry_now ? "_carry" : "",
-                    carry_now ? "_carry" : "");
-    }
-    else
-    {
-      fprintf(file, "\tADD\tr14,pc,#_CMUNGE_gret%s - _CMUNGE_gpc%s - 4\n",
-                    carry_now ? "_carry" : "",
-                    carry_now ? "_carry" : "");
-    }
-    fprintf(file, "_CMUNGE_gpc%s\n", carry_now ? "_carry" : "");
-    fprintf(file, "\tADD\tpc,pc,r2\n");
-    fprintf(file, "\tMOV\tr0,r0\n");
-    for (l = opt.generics; l; l=l->next) {
-      if (carry_now != l->carry_capable)
-        continue;
+      if (n == 0)
+	continue;
 
-      if (l->handler) {
-        fprintf(file, "\tIMPORT\t%s\n", l->handler);
-        fprintf(file, "\tB\t%s\n", l->handler);
-      } else {
-        fprintf(file, "\tIMPORT\t%s_handler\n", l->name);
-        fprintf(file, "\tB\t%s_handler\n", l->name);
-      }
-    }
-    fprintf(file, "_CMUNGE_gret%s\n", carry_now ? "_carry" : "");
-    fprintf(file, SUB_Lib_Reloc);
-    fprintf(file, "\tSTMIA\tr10,{r4,r5}\n");
-    fprintf(file, "\tMOV\tr14,r7\n");
-    if (CODE26)
-    {
-      fprintf(file, "\tTEQP\tr6,#0\n");
-      fprintf(file, "\tTEQ\tr0,#0\n");
-      fprintf(file, "\tLDMEQIA\tr13!,{r0-r%i,pc}^\n",preserve_endreg);
-      if (carry_now)
-      {
-        fprintf(file, "\tTEQ\tr0,#2\n");
-        fprintf(file, "\tLDMEQIA\tr13!,{r0-r%i,r14}\n",preserve_endreg);
-        fprintf(file, "\tORREQS\tpc,r14,#0x20000000\n");
-        fprintf(file, "\tADD\tr13,r13,#4\n");
-        fprintf(file, "\tLDMIA\tr13!,{r1-r%i,r14}\n",preserve_endreg);
-        fprintf(file, "\tORRS\tpc,r14,#0x10000000\n");
-      }
+      output_label_vargs("_CMUNGE_ge%s", carry_now ? "_carry" : "");
+      fputs("\tMOV\tr0,r13\n", file);
+      if (CODE26)
+	fputs("\tMOV\tr6,pc\n"
+	      "\tBIC\tr3,r6,#3\n"
+	      "\tTEQP\tr3,#3\n", file);
       else
-      {
-        fprintf(file, "\tADD\tr13,r13,#4\n");
-        fprintf(file, "\tLDMIA\tr13!,{r1-r%i,r14}\n",preserve_endreg);
-        fprintf(file, "\tORRS\tpc,r14,#0x10000000\n");
-      }
-    }
-    else
-    {
-      fprintf(file, "\tTEQ      pc,pc\n");
-      fprintf(file, "\tBEQ      _CMUNGE_genv%s ; 32bit PC\n", carry_now ? "_carry" : "");
-      fprintf(file, "\tTEQP     r8,#0\n");
-      fprintf(file, "\tTEQ      r0,#0\n");
-      fprintf(file, "\tLDMEQIA  r13!,{r0-r11,pc}^\n");
-      if (carry_now)
-      {
-        /* If r0 = 2, return CS
-              r0 = 0, has already been dealt with
-              r0 = anything else, return VS + R0 value
-              r8 = 26bit PSR on entry
-         */
-        fprintf(file, "\tTEQ\tr0,#2\n");
-        fprintf(file, "\tLDMEQIA\tr13!,{r0-r%i,r14}\n",preserve_endreg);
-        fprintf(file, "\tORREQS\tpc,r14,#0x20000000\n");
-        fprintf(file, "\tADD\tr13,r13,#4\n");
-        fprintf(file, "\tLDMIA\tr13!,{r1-r%i,r14}\n",preserve_endreg);
-        fprintf(file, "\tORRS\tpc,r14,#0x10000000\n");
-        fprintf(file, "_CMUNGE_genv_carry\n");
-        /* 32bit return for the same case as the above 26bit case, except:
-              r0 = 0 has not been dealt with
-              r6 = 32bit PSR on entry
-         */
-        fprintf(file, "\tTEQ      r0,#2\n");
-        fprintf(file, "\tORREQ    r6,r6,#0x20000000\n");
-        fprintf(file, "\tBICS     r14,r0,#2 ; NE if r0 <> 0 and r0 <> 2\n");
-        fprintf(file, "\tSTRNE    r0,[r13,#0]\n");
-        fprintf(file, "\tORRNE    r6,r6,#0x10000000\n");
-        fprintf(file, "\tMSR      cpsr_flg,r6\n");
-        fprintf(file, "\tLDMIA    r13!,{r0-r11,pc}\n");
-      }
+	fputs("\tTEQ\tpc,pc\n"
+	      "\tMOVNE\tr8,pc\n"
+	      "\tORRNE\tr3,r8,#3\n"
+	      "\tTEQNEP\tr3,#0\n"
+	      "\tMRSEQ\tr6,cpsr\n"
+	      "\tORREQ\tr3,r6,#3\n"
+	      "\tMSREQ\tcpsr_c,r3\n", file);
+      fputs("\tMOV\tr1,r12\n"
+            "\tMOV\tr7,r14\n"
+            "\tMOV\tr10,r13,LSR #20\n"
+            "\tMOV\tr10,r10,LSL #20\n"
+            "\tLDMIA\tr10,{r4,r5}\n"
+            "\tLDR\tr12,[r12]\n"
+            "\tLDMIB\tr12,{r11,r12}\n"
+            "\tSTMIA\tr10,{r11,r12}\n", file);
+      output_ADD_Lib_Reloc();
+      fputs("\tMOV\tr11,#0\n", file);
+      if (CODE26)
+	fprintf(file, "\tMOV\tr14,pc\n"
+	        "\tADD\tr14,r14,#_CMUNGE_gret%s - _CMUNGE_gpc%s\n",
+	        carry_now ? "_carry" : "",
+	        carry_now ? "_carry" : "");
       else
-      {
-        fprintf(file, "\tADD\tr13,r13,#4\n");
-        fprintf(file, "\tLDMIA\tr13!,{r1-r%i,r14}\n",preserve_endreg);
-        fprintf(file, "\tORRS\tpc,r14,#0x10000000\n");
-        fprintf(file, "_CMUNGE_genv\n");
-        /* 32bit return for the same case as the above 26bit case, except:
-              r6 = 32bit PSR on entry
-         */
-        fprintf(file, "\tTEQ      r0,#0\n");
-        fprintf(file, "\tSTRNE    r0,[r13,#0]\n");
-        fprintf(file, "\tORRNE    r6,r6,#0x10000000\n");
-        fprintf(file, "\tMSR      cpsr_flg,r6\n");
-        fprintf(file, "\tLDMIA    r13!,{r0-r11,pc}\n");
-      }
+	fprintf(file, "\tADD\tr14,pc,#_CMUNGE_gret%s - _CMUNGE_gpc%s - 4\n",
+	        carry_now ? "_carry" : "",
+	        carry_now ? "_carry" : "");
+      output_label_vargs("_CMUNGE_gpc%s", carry_now ? "_carry" : "");
+      fputs("\tADD\tpc,pc,r2\n"
+            "\tMOV\tr0,r0\n", file);
+      for (l = opt.generics; l != NULL; l = l->next)
+	{
+	  if (carry_now != l->carry_capable)
+	    continue;
+
+	  if (l->handler)
+	    {
+	      output_import(l->handler);
+	      fprintf(file, "\tB\t%s\n", l->handler);
+	    }
+	  else
+	    {
+	      output_import_vargs("%s_handler", l->name);
+	      fprintf(file, "\tB\t%s_handler\n", l->name);
+	    }
+	}
+      output_label_vargs("_CMUNGE_gret%s", carry_now ? "_carry" : "");
+      output_SUB_Lib_Reloc();
+      fputs("\tSTMIA\tr10,{r4,r5}\n"
+            "\tMOV\tr14,r7\n", file);
+      if (CODE26)
+	{
+	  fprintf(file,
+	          "\tTEQP\tr6,#0\n"
+	          "\tTEQ\tr0,#0\n"
+	          "\tLDMEQIA\tr13!,{r0-r%i,pc}^\n",preserve_endreg);
+	  if (carry_now)
+	    {
+	      fprintf(file,
+	              "\tTEQ\tr0,#2\n"
+	              "\tLDMEQIA\tr13!,{r0-r%i,r14}\n",preserve_endreg);
+	      fputs("\tORREQS\tpc,r14,#0x20000000\n", file);
+	    }
+	  fprintf(file,
+	          "\tADD\tr13,r13,#4\n"
+	          "\tLDMIA\tr13!,{r1-r%i,r14}\n",preserve_endreg);
+	  fputs("\tORRS\tpc,r14,#0x10000000\n", file);
+	}
+      else
+	{
+	  fprintf(file,
+	          "\tTEQ\tpc,pc\n"
+	          "\tBEQ\t_CMUNGE_genv%s\t", carry_now ? "_carry" : ""); output_comment("32bit PC\n");
+	  fputs("\tTEQP\tr8,#0\n"
+	        "\tTEQ\tr0,#0\n"
+	        "\tLDMEQIA\tr13!,{r0-r11,pc}^\n", file);
+	  if (carry_now)
+	    {
+	      /* If r0 = 2, return CS
+	       r0 = 0, has already been dealt with
+	       r0 = anything else, return VS + R0 value
+	       r8 = 26bit PSR on entry
+	       */
+	      fprintf(file,
+	              "\tTEQ\tr0,#2\n"
+	              "\tLDMEQIA\tr13!,{r0-r%i,r14}\n",preserve_endreg);
+	      fprintf(file, "\tORREQS\tpc,r14,#0x20000000\n"
+	              "\tADD\tr13,r13,#4\n"
+	              "\tLDMIA\tr13!,{r1-r%i,r14}\n",preserve_endreg);
+	      fputs("\tORRS\tpc,r14,#0x10000000\n", file);
+	      output_label("_CMUNGE_genv_carry");
+	      /* 32bit return for the same case as the above 26bit case, except:
+	       r0 = 0 has not been dealt with
+	       r6 = 32bit PSR on entry
+	       */
+	      fputs("\tTEQ\tr0,#2\n"
+	            "\tORREQ\tr6,r6,#0x20000000\n"
+	            "\tBICS\tr14,r0,#2\t", file); output_comment("NE if r0 <> 0 and r0 <> 2\n");
+	      fputs("\tSTRNE\tr0,[r13,#0]\n"
+	            "\tORRNE\tr6,r6,#0x10000000\n"
+	            "\tMSR\tcpsr_f,r6\n"
+	            "\tLDMIA\tr13!,{r0-r11,pc}\n", file);
+	    }
+	  else
+	    {
+	      fprintf(file,
+	              "\tADD\tr13,r13,#4\n"
+	              "\tLDMIA\tr13!,{r1-r%i,r14}\n",preserve_endreg);
+	      fputs("\tORRS\tpc,r14,#0x10000000\n", file);
+	      output_label("_CMUNGE_genv");
+	      /* 32bit return for the same case as the above 26bit case, except:
+	       r6 = 32bit PSR on entry
+	       */
+	      fputs("\tTEQ\tr0,#0\n"
+	            "\tSTRNE\tr0,[r13,#0]\n"
+	            "\tORRNE\tr6,r6,#0x10000000\n"
+	            "\tMSR\tcpsr_f,r6\n"
+	            "\tLDMIA\tr13!,{r0-r11,pc}\n", file);
+	    }
+	}
     }
-  }
 }
 
-static void trailer(void) {
+static void trailer(void)
+{
   /* We need to have some space allocated for the stack for an entered RMA
      application. This code needs re-working such that other parts of the
      system can place blocks in this section without code re-writes. This
@@ -1710,26 +2248,32 @@
      I do. Really. Oh yes. */
   if (opt.runnable == run_rmaapp_simple)
   { /* Icky */
-    fprintf(file,"\n\n\tAREA\t|!Header$$Data|, DATA\n");
-    fprintf(file, "_CMUNGE_stack\n");
-    fprintf(file, "\tDCD\t0 ; no stack at present\n");
+    fputs("\n\n", file);
+    if (opt.toolchain == tc_gcc)
+      fputs("\t.data\n", file); /* FIXME: perhaps too simple */
+    else
+      fprintf(file, "\tAREA\t|!Header$$Data|, DATA\n");
+    output_label("_CMUNGE_stack");
+    output_word(0, "No stack at present");
   }
-  fprintf(file, "\n\n\tEND\n");
+  fprintf(file, "\n\n");
+  output_endfile();
 }
 
 /* This function generates the module flags for 32bit modules */
-static void flags(void) {
+static void flags(void)
+{
   if (CODE26)
   {}
   else
   {
-    fprintf(file, "_CMUNGE_module_flags\n");
-    fprintf(file, "\tDCD\t1 ; 32bit supported\n");
+    output_label("_CMUNGE_module_flags");
+    output_word(1, "32bit supported");
   }
 }
 
-void WriteFile(void) {
-
+void WriteFile(void)
+{
   file = file_write(opt.sfile, remove_onfail);
   if (file == NULL)
     ErrorFatal("Couldn't open output file: %s", opt.sfile);
@@ -1738,14 +2282,15 @@
   mod_header();
   strings(); /* Afterwards, PC can end on a non word boundary */
   swi_table(); /* Afterwards, PC could end on a non word boundary */
-  fprintf(file, "\tALIGN\n");
+  output_align();
   /* From here onwards, PC is always word aligned */
   commands();
 #ifdef CMHG_RESOURCE_FILE_ORDERING
-  if (opt.mfile) {
-    fprintf(file, "_CMUNGE_message_file\n");
+  if (opt.mfile)
+  {
+    output_label("_CMUNGE_message_file");
     outstring(opt.mfile,1,'\n',0);
-    fprintf(file, "\tALIGN\n");
+    output_align();
   }
 #endif
   flags();
@@ -1755,6 +2300,7 @@
   final();
   swi_handler();
   swi_decoder();
+  pdriver_handler();
   veneers();
   vector_traps();
   generics();
@@ -1764,4 +2310,3 @@
 
   file_close(file);
 }
-
Index: gfile.h
===================================================================
--- gfile.h	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ gfile.h	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -74,7 +74,7 @@
  Parameters:   none
  Returns:      pointer to filename, or NULL if failed
  ******************************************************************/
-char *file_temp(void);
+const char *file_temp(void);
 
 /*********************************************** <c> Gerph *********
  Function:     file_close
Index: Examples/pdriver.cmhg
===================================================================
--- Examples/pdriver.cmhg	(.../branches/CMungeImportBranch/cmunge)	(revision 0)
+++ Examples/pdriver.cmhg	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -0,0 +1,48 @@
+; Module header description file for a PDriver
+; Written by John Tytgat / BASS
+
+#include "oslib/pdriver.h"
+
+title-string: PDriverXX
+
+help-string:  Printer driver 0.01 
+
+initialisation-code: Module_Initialisation
+
+finalisation-code: Module_Finalisation
+
+; Service calls:
+;   &65: Service_PDriverStarting
+service-call-handler: Module_Service Service_PDriverStarting
+
+pdriver-handler: pdriver_entry,
+	PDriver_Info_Handler,
+	PDriver_SetInfo_Handler,
+	PDriver_CheckFeatures_Handler,
+	PDriver_PageSize_Handler,
+	PDriver_SetPageSize_Handler,
+	PDriver_CreateJob_Handler, /* SelectJob - shared with SelectIllustration */
+	PDriver_BadSWI_Handler, /* CurrentJob */
+	PDriver_FontSWI_Handler,
+	PDriver_EndJob_Handler,
+	PDriver_AbortJob_Handler,
+	PDriver_Reset_Handler,
+	PDriver_GiveRectangle_Handler,
+	PDriver_DrawPage_Handler,
+	PDriver_GetRectangle_Handler,
+	PDriver_CancelJob_Handler, /* CancelJob - shared with CancelJobWithError */
+	PDriver_BadSWI_Handler, /* ScreenDump: we don't support this */
+	PDriver_BadSWI_Handler, /* EnumerateJobs */
+	PDriver_BadSWI_Handler, /* SetPrinter */
+	PDriver_CancelJob_Handler, /* CancelJobWithError - shared with CancelJob */
+	PDriver_CreateJob_Handler, /* SelectIllustration - shared with SelectJob */
+	PDriver_BadSWI_Handler, /* InsertIllustrator: we don't support this */
+	PDriver_DeclareFont_Handler,
+	PDriver_BadSWI_Handler, /* DeclareDriver */
+	PDriver_BadSWI_Handler, /* RemoveDriver */
+	PDriver_BadSWI_Handler, /* SelectDriver */
+	PDriver_BadSWI_Handler, /* EnumerateDrivers */
+	PDriver_MiscOp_Handler,
+	PDriver_MiscOp_Handler, /* MiscOpDriver */
+	PDriver_BadSWI_Handler, /* SetDriver */
+	PDriver_JPEGSWI_Handler
Index: error.h
===================================================================
--- error.h	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ error.h	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -6,10 +6,10 @@
 
 #define ERROR_H
 
-void ErrorFatal(char *err, ...);
+void ErrorFatal(const char *err, ...);
 
-void Warning(char *err, ...);
+void Warning(const char *err, ...);
 
-void CMHGWarning(char *err, ...);
+void CMHGWarning(const char *err, ...);
 
 #endif
Index: writeheader.c
===================================================================
--- writeheader.c	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ writeheader.c	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -74,7 +74,7 @@
 #define MAXARGS (5)
 
 typedef struct prototypedef_s {
-  char *name;                         /* the function name */
+  const char *name;                   /* the function name */
   char *returntype;                   /* type of data returned */
   char *description;                  /* function description */
   char *note;                         /* Notes about this prototype */
@@ -377,7 +377,7 @@
         "pw",
         "private word for module" },
     },
-    "Return 0 for successful finalisation, or a pointer to an error block "
+    "Return NULL for successful finalisation, or a pointer to an error block "
     "if module was not shutdown properly."
   };
   header.name=opt.final;
@@ -549,7 +549,7 @@
   };
 
   swi_list l;
-  char *prefix=opt.swi_names->name;
+  const char *prefix = opt.swi_names->name;
   int swi=opt.swi_base;
 
   prototypedef_t header_proto;
@@ -596,7 +596,7 @@
   if (l)
     l = l->next;
   while (l) {
-    char *name=l->name;
+    const char *name = l->name;
     int startlen,len;
     startlen=len=strlen(prefix)+1+strlen(name);
     fprintf(file, "#undef %s_%s\n", prefix, name);
@@ -720,6 +720,78 @@
   }
 }
 
+static void pdriver_handler(void)
+{
+  static prototypedef_t header_entry =
+  {
+    NULL, /* Function name is filled in */
+    "extern void",
+    "Symbol for entry point to module - NOT a C function.\n"
+    "This name should be used as an argument to PDriver_DeclareDriver as "
+    "required, but should never be called from C.",
+    NULL, /* No note */
+    { { NULL } }, /* NO Entry parameters */
+    NULL
+  };
+
+  static prototypedef_t header_text =
+  {
+    NULL, /* Function name is filled in */
+    "%error%",
+    "PDriver handler routine.",
+    NULL, /* No note */
+    { /* Entry parameters */
+      {
+        "int",
+        "number",
+        "PDriver reason code (i.e. 0 to 63)" },
+      {
+        "%regs%",
+        "r",
+        "pointer to register block on entry" },
+      {
+        "void *",
+        "pw",
+        "private word for module" },
+    },
+    "Return NULL if PDriver SWI call handled sucessfully, setting return register "
+    "values (r0-r9) in r.\n"
+    "Return error_BAD_PDRIVER_SWI for out of range SWIs.\n"
+    "Return an error block for a custom error."
+  };
+
+  pdriver_list *l;
+  prototypedef_t header_proto;
+
+  header_entry.name = opt.pdriver_entry;
+  prototype_write(&header_entry);
+  
+  header_proto = header_text;
+  header_proto.description = NULL;
+
+#ifdef CLASSIC_HEADERS
+#else
+  prototype_write(&header_text);
+#endif
+
+  c_comment(file, "Functions called to handle particular PDriver SWI calls");
+  for (l = opt.pdriver_names; l; l = l->next)
+  {
+    header_proto.name = l->handler;
+    prototype_write(&header_proto);
+  }
+
+#ifdef CLASSIC_HEADERS
+  prototype_write(&header_text);
+#endif
+
+  fprintf(file, "\n");
+  c_comment(file, "Special error for 'PDriver SWI values out of range for "
+                  "this module'");
+  fprintf(file, "#define error_BAD_PDRIVER_SWI ((%s *) -1)\n", error);
+  fprintf(file, "\n");
+}
+
 static void event_handler(void) {
 
   static prototypedef_t header_entry =
@@ -829,8 +901,8 @@
       if (head != opt.irqs)
       {
         header_handler.exit = "Update r to alter return values\n"
-                              "Return VECTOR_PASS to claim (return via stack)\n"
-                              "Return VECTOR_CLAIM to pass on (return via r14)";
+                              "Return VECTOR_CLAIM to claim (return via stack)\n"
+                              "Return VECTOR_PASSON to pass on (return via r14)";
       }
       else
       {
@@ -1079,7 +1151,7 @@
 #else
     /* JRF: Changed my mind; we should emulate CMHG as closely as possible */
     {
-      char *str = opt.help;
+      const char *str = opt.help;
       fprintf(file, "#define Module_Help\t\t\"");
       while (*str!='\0' && *str!='\t')
       {
@@ -1107,7 +1179,7 @@
   fprintf(file, "#endif\n\n");
 
   if (opt.base)
-    fprintf(file, "extern int Image__RO_Base;\n\n");
+    fprintf(file, "extern const int Image__RO_Base;\n\n");
 
   if (opt.runnable == run_clib)
     mainp();
@@ -1123,6 +1195,8 @@
     swi_handler();
   if (opt.swi_decoder)
     swi_decoder();
+  if (opt.pdriver_entry)
+    pdriver_handler();
   if (opt.events)
     event_handler();
   if (opt.irqs)
Index: ChangeLog
===================================================================
--- ChangeLog	(.../branches/CMungeImportBranch/cmunge)	(revision 0)
+++ ChangeLog	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -0,0 +1,10 @@
+Thu Apr  5 01:18:12 CEST 2012  John Tytgat  <John.Tytgat@aaug.net>
+
+	* Makefile.am, VersionNum (GCCSDK_REVISION): Mention svn branch
+	name.
+	* copyright.h (Copyright_CMunge): Add 2012.
+
+Tue Jan 11 01:27:18 CET 2011  David Thomas  <dave@davespace.co.uk>
+
+	* readfile.c (preprocess): Fix sscanf() call.
+
Index: Docs/Copyright
===================================================================
--- Docs/Copyright	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ Docs/Copyright	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -41,3 +41,9 @@
 software created using this tool, but that seems a bit greedy! Anyone
 wishing to encourage future development however can feel free to offer us
 software out of the goodness of their hearts though :-)
+
+------------------------------------------------------------------------------
+
+This application contains not yet accepted upstream changes, fixes and
+improvements which are Copyright (c) 2007-2011 GCCSDK Developers and
+contributors.
Index: Docs/Manual
===================================================================
--- Docs/Manual	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ Docs/Manual	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -32,7 +32,7 @@
 ------------------------------------
 
 CMHG takes a textual input file, optionally preprocesses it, and produces an
-AOF output file.
+AOF or ELF output file.
 
 CMunge takes the same textual input file, again optionally preprocesses it,
 but produces a textual output file suitable for feeding to an assembler. The
@@ -54,7 +54,7 @@
 Options:
 
 -h              Output help about the command.
--o <file>       Name the output AOF file.
+-o <file>       Name the output AOF or ELF file.
 -s <file>       Name the output assembler file.
 -d <file>       Name a C header file that CMunge will generate.
 -x<type> <file> Name an export file to place SWI numbers in. Types can be :
@@ -74,15 +74,21 @@
 -throwback      Use throwback for error processing.
 -zbase          Define symbol Image__RO_Base in generated header.
 -zerrors        Define errors and veneers only (for use in applications).
--zoslib         Use '#include "os.h"' (OSLib) instead of '#include "kernel.h"'
-                (Acorn) in generated C header file.
+-zoslib         Use 'os_error *' instead of '_kernel_oserror *' to prototype
+                a pointer to a RISC OS error block. Use 'os_register_block'
+                instead of '_kernel_swi_regs' to represent a set of ARM
+                registers. Use '#include "oslib/os.h"' (OSLib) instead of
+                '#include "kernel.h"' (Shared C Library) in generated C header
+                file.
+-znoscl         Don't interface with Shared C Library, i.e. don't have
+                runtime support.
 -blank          Generate an empty CMunge file instead of reading one.
                 When in 'CMHG' mode this will generate a warning but will
                 generate a header containing only CMHG-based features.
 -cmhg           Give warnings about CMHG incompatibilities.
--tgcc           Use GCC tool chain to generate output.
--tlcc           Use LCC tool chain to generate output.
--tnorcroft      Use Norcroft tool chain to generate output (default).
+-tgcc           Use GCC tool chain to generate ELF output.
+-tlcc           Use LCC tool chain to generate AOF output.
+-tnorcroft      Use Norcroft tool chain to generate AOF output (default).
 -32bit          Generate 32bit code.
 -26bit          Generate 26bit code (default).
 -apcs 3/<flags> Specify APCS variant to use - see below for more details.
@@ -95,7 +101,7 @@
 From here it gets technical. If you are to the stage of generating modules
 then you should be competent enough to understand the following.
 
-Input to cmhg is given in the form of a text file. This text file is
+Input to CMunge is given in the form of a text file. This text file is
 relatively free form, but the following (insane) set of rules was laid
 down by Acorn.
 
@@ -218,7 +224,7 @@
     specified name is called. For instance, with the name 'init' this would
     be as follows.
     
-    _kernel_oserror *init(char *tail, int podule_base, void *pw);
+    _kernel_oserror *init(const char *tail, int podule_base, void *pw);
     
     This function should do any initialisation required (claiming memory etc).
     'tail' points to the string of arguments (if any) that the module was
@@ -250,7 +256,7 @@
     around. The generated header filters out calls for service calls that
     have not been declared to it. For C-function-name service, this gives:
 
-    void *service(int number, _kernel_swi_regs *r, void *pw);
+    void service(int number, _kernel_swi_regs *r, void *pw);
     
     If no service calls are specified, then all service calls are passed in.
     This is *not* recommended.
@@ -263,6 +269,11 @@
     
     extern int Image__RO_Base;
 
+  * title-string: ModuleName
+
+    This defines the module name.  Note that you must register the module
+    name before you distribute it.
+
   * help-string: <module-name> <version-number> <comment>
   
     This defines the help string in the module header. The name of the module
@@ -272,6 +283,15 @@
     The version-number field should be in the form d.dd where d is a decimal
     digit.
 
+  * date-string: <DD MMM YYYY>
+
+    The date-string is optional and should only be included if you feel that a
+    date is a different reference to the version number. Certain ports from
+    other platforms may wish to indicate their source base date using this
+    field.
+
+    You will probably never need this field.
+
   * command-keyword-table: <C-function-name> <command-description>+
 
     At least one command-description must be given.
@@ -295,7 +315,8 @@
     
     If it is an actual command to be run, then arg_string is the command
     string to be executed and argc is the argument count. Return NULL on
-    success or an error pointer.
+    success or an error pointer. Note that arg_string is not NUL terminated
+    string but control terminated.
 
     If its a *Configure option, and arg_string is set to arg_CONFIGURE_SYNTAX
     (as defined in the generated header file to be a cast of 0) then print the
@@ -355,6 +376,10 @@
     256, but CMunge will accept any alignment so that you can re-use areas
     of the blocks. You should inform the allocations service of any use of
     'sub-blocks'.
+
+  * error-base: <number>
+
+    An alias for error-chunk-base-number.
   
   * error-identifiers: <error description> ...
     
@@ -371,6 +396,24 @@
     [Note: The header defines these through a macro so that errors are not
      copied to the workspace]
   
+  * pdriver-handler: <entry point> [,<C-function-name>][,<C-function-name>] ...
+  
+    This is only to be used to define an interface for registering a printer
+    driver using SWI PDriver_DeclareDriver.  The first parameter is defining
+    a symbol whose value needs to be R0 of SWI PDriver_DeclareDriver. The
+    rest of the parameters specify the names of C routines one per reason
+    code from 0 onwards.  So, for
+    "pdriver-handler: pdentry,getinfo_handler,setinfo_handler" you get the
+    symbol:
+
+    extern int pdentry(void);
+    
+    defined (which is NOT a C function), and you need to provide the following
+    C functions:
+    
+    _kernel_oserror *getinfo_handler(int number, kernel_swi_regs *r, void *pw);
+    _kernel_oserror *setinfo_handler(int number, kernel_swi_regs *r, void *pw);    
+
   * swi-chunk-base-number: <number>
     
     This sets the SWI base number for the module. Do not specify the X-bit
@@ -454,7 +497,7 @@
          claimed and for an error to be returned in R0 with the V flag set.
          All other registers will be as returned in the parameter block.
 
-    So, for 'vector-handlers: irq1' the following function is expected:
+    So, for 'vector-handlers: wrch' the following function is expected:
     
     int wrch_handler(_kernel_swi_regs *r, void *pw);
 
@@ -492,8 +535,8 @@
     generate an entry point that calls a handler function under the same
     entry/exit conditions as above. If multiple event-handler entries are
     required, using the token again allows this. Multiple event-handlers
-    are accepted in cmhg mode, but only the last is processed fully in
-    order to follow cmhg's behaviour.
+    are accepted in CMHG mode, but only the last is processed fully in
+    order to follow CMHG's behaviour.
     
     Fast accept/reject code is generated for the given event numbers. The
     numbers are optional, but strongly recommended.
@@ -558,6 +601,10 @@
     the C library, it is essential that your routine call 
     _clib_initialisemodule before it returns.
 
+  * library-enter-code: <symbol-name>
+
+    Is an alias for library-initialisation-code.
+
   * international-help-file: <pathname>
 
     This option allows a literal pathname to be embedded in the header of the
@@ -618,6 +665,7 @@
   * Simple additive evaluation of integers (see below)
   * Simpler C++ module creation (module-is-c-plus-plus)
   * Command keyword handlers (handler) and handler omission (no-handler)
+  * Printer driver handler (pdriver-handler)
 
 The command line differs from CMHG in the following ways :
   * Exported header types (-x switch)
@@ -628,6 +676,7 @@
   * Multiple toolchain suport (-t switch)
   * Explicit APCS variant selection (-apcs switch)
   * Backwards compatibility with CMHG (-cmhg switch)
+  * Possibility to not use the Shared C Library runtime (-znoscl switch)
 
 Within the header produced, there are a couple of deviances :
 
@@ -643,6 +692,25 @@
 If these cause a problem, please let us know.
 
 
+Not using Shared C Library (option -znoscl)
+--------------------------
+
+This is one of the CMunge only features and allows you to build C based
+modules which are not using the Shared C Library runtime.  Apart from its
+lack of the Shared C Library dependency it also offers a smaller footprint.
+
+Note that apart from a run-time stack (the SVC one), you're on your own for
+memory management, I/O, etc and you can only rely on what RISC OS or third
+party modules provide, e.g. via their SWIs.
+
+It might be that the generated output of the C compiler contains calls to
+memcmp, memset, memcpy and memmove which you are required to provide yourself.
+
+Currently this feature has the following limitations : only GCC compiler is
+supported and it can not be combined with module-is-runnable nor
+module-is-c-plus-plus keywords.
+
+
 Evaluation of integer elements
 ------------------------------
 
Index: str.c
===================================================================
--- str.c	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ str.c	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -45,9 +45,10 @@
   return res;
 }
 
-const char *strduptok(const char *p, char **res) {
-
+const char *strduptok(const char *p, const char **resPP)
+{
   const char *s;
+  char *resP;
 
   /* Skip any prefix of whitespace */
   while (isspace(*p))
@@ -56,9 +57,10 @@
   while (!isspace(*p) && (*p != ',') && (*p != ')') &&
          (*p != '(') && (*p != 0))
     p++;
-  *res = Malloc(p-s+1);
-  strncpy(*res, s, p-s);
-  (*res)[p-s] = 0;
+  resP = Malloc(p-s+1);
+  memcpy(resP, s, p-s);
+  resP[p-s] = 0;
+  *resPP = resP;
   /* Skip any more whitespace */
   while (isspace(*p))
     p++;
@@ -84,9 +86,10 @@
   }
 }
 
-const char *strfindpair(const char *p, char **p1, char **p2) {
-
+const char *strfindpair(const char *p, const char **p1PP, const char **p2PP)
+{
   const char *s;
+  char *p1P, *p2P;
 
   /* Skip any whitespace */
   while (isspace(*p))
@@ -103,9 +106,10 @@
   if (p == 0)
     ErrorFatal("Failed to find handler name!");
   /* Copy the first name */
-  *p1 = Malloc(p-s+1);
-  strncpy(*p1, s, p-s);
-  (*p1)[p-s] = 0;
+  p1P = Malloc(p-s+1);
+  memcpy(p1P, s, p-s);
+  p1P[p-s] = 0;
+  *p1PP = p1P;
 
   /* Skip any more whitespace */
   while (isspace(*p))
@@ -113,7 +117,7 @@
 
   /* Did we find a / ? */
   if (*p != '/') {
-    *p2 = 0;
+    *p2PP = NULL;
     /* Skip over any comma */
     if (*p == ',') {
       p++;
@@ -137,9 +141,10 @@
   if (p == 0)
     ErrorFatal("Failed to find handler name!");
   /* Copy the second name */
-  *p2 = Malloc(p-s+1);
-  strncpy(*p2, s, p-s);
-  (*p2)[p-s] = 0;
+  p2P = Malloc(p-s+1);
+  memcpy(p2P, s, p-s);
+  p2P[p-s] = 0;
+  *p2PP = p2P;
 
   /* Skip any more whitespace */
   while (isspace(*p))
@@ -177,9 +182,10 @@
   return s;
 }
 
-const char *strstring(const char *s, char **res) {
-
+const char *strstring(const char *s, const char **resPP)
+{
   const char *p;
+  char *resP;
   int escape;
 
   while (isspace(*s))
@@ -196,9 +202,11 @@
       escape = 0;
     s++;
   }
-  *res = Malloc(s-p+1);
-    strncpy(*res, p, s-p);
-  (*res)[s-p] = 0;
+  resP = Malloc(s-p+1);
+  memcpy(resP, p, s-p);
+  resP[s-p] = 0;
+  *resPP = resP;
+  
   s++;
   while (isspace(*s))
     s++;
Index: GCCSDK-README
===================================================================
--- GCCSDK-README	(.../branches/CMungeImportBranch/cmunge)	(revision 0)
+++ GCCSDK-README	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -0,0 +1,39 @@
+Note for the GCCSDK developers:
+
+This is a copy of CMunge for use in the GCCSDK project.
+
+When importing a new version of CMunge:
+
+ * The original sources are and should first be stored in the
+   'svn://svn.riscos.info/gccsdk/branches/CMungeImportBranch/cmunge'
+   SVN branch. Then they are merged to the GCCSDK development/stable
+   branch (like 'svn://svn.riscos.info/gccsdk/gcc4/riscos/cmunge')
+   where all the GCCSDK changes & bug fixes are to be done.
+
+     $ svn merge svn://svn.riscos.info/gccsdk/branches/CMungeImportBranch/cmunge svn://svn.riscos.info/gccsdk/trunk/gcc4/riscos/cmunge
+
+   Do not make any bug fixes or changes in the 'CMungeImportBranch' branch
+   except for importing newer offical CMunge source releases.
+
+ * Then the official sources in the 'CMungeImportBranch' SVN branch are
+   tagged using 'svn://svn.riscos.info/gccsdk/tags/CMunge-X_YZ/cmunge' tags
+   where 'X_YZ' is the 'Module_MajorVersion_CMHG' #define value in the
+   'VersionNum' file but having its dot character changed into a
+   underscore character.
+
+     [ Replace 'X_YZ' in the following ! ]
+     $ svn copy svn://svn.riscos.info/gccsdk/branches/CMungeImportBranch/cmunge svn://svn.riscos.info/gccsdk/tags/CMunge-X_YZ/cmunge
+
+Doing this in a consistent way allows us to easily find out what the
+GCCSDK changes are in the CMunge GCCSDK version.
+
+An overview of all GCCSDK changes has to be kept up-to-date in
+'GCCSDK-CHANGES' file.
+
+When additional changes would be needed in the future, please read the
+CMunge licence (the 'Docs/Copyright' file) carefully and follow it, like
+submitting your changes back to the CMunge authors.  The CMunge authors
+expressed their wish not to make any incompatible changes to the GCCSDK
+CMunge version.
+
+-EOF-
Index: readfile.c
===================================================================
--- readfile.c	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ readfile.c	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -17,15 +17,6 @@
 #include "filename.h"
 #include "blank.h"
 
-/* JRF: I don't like the idea of the tool location being fixed at compile
-        time, but John Tytgat informs me that this is unavoidable in the
-        cross-compiling environment that GCC employs. You'll just have to
-        rebuild with a new location if you use CMunge on a different
-        system. */
-#ifndef GCC_BIN_DIR
-#define GCC_BIN_DIR ""
-#endif
-
 #define UNUSED(x) { x=x; }
 
 /*****************************************************************************
@@ -128,7 +119,7 @@
 
   /* Now we have the line in prelinebuf */
   /* Spot the preprocessor directives */
-  if (sscanf(prelinebuf," %i \"%[^\"]\"",&line,&filename)==2) {
+  if (sscanf(prelinebuf," %i \"%[^\"]\"",&line,filename)==2) {
     /* It appears that GCC always generates its filenames in unix-format,
        regardless of what you give it on the command line; to make the
        throwback work properly, we must convert this to RISC OS style
@@ -145,7 +136,7 @@
     Free(opt.infile);
     opt.infile = strdup_strip(nativefilename);
   }
-  else if (sscanf(prelinebuf,"line %i \"%[^\"]\"",&line,&filename)==2) {
+  else if (sscanf(prelinebuf,"line %i \"%[^\"]\"",&line,filename)==2) {
     /* Norcroft always generates the filenames in native-format which is
        correct for throwback. */
     opt.atline = line-1;
@@ -857,7 +848,7 @@
           case ft_label:
           case ft_quoted:
             {
-              char **value=(char **)valuep;
+              const char **value = (const char **)valuep;
               if (*value!=NULL)
                 ErrorFatal("Only supply one %s field in command-keyword-table!",field->name);
 
@@ -1028,8 +1019,43 @@
   *h = NULL;
 }
 
-static void read_swidec(const char *s, FILE *file) {
+static void read_pdriver(const char *s, FILE *file)
+{
+  pdriver_list **pl;
 
+  UNUSED(file);
+
+  if (opt.pdriver_entry)
+    ErrorFatal("Only supply one pdriver-handler!");
+
+  s = strduptok(s, &opt.pdriver_entry);
+  if (opt.pdriver_entry[0] == '\0')
+    ErrorFatal("No entry point defined for pdriver-handler!");
+  if (*s++ != ',')
+      ErrorFatal("Wrong separator found in pdriver-handler!");
+  while (isspace(*s))
+    ++s;
+
+  pl = &opt.pdriver_names;
+  while (*s)
+  {
+    (*pl) = Malloc(sizeof(**pl));
+    (*pl)->next = NULL;
+    s = strduptok(s, &(*pl)->handler);
+    if (*s == ',')
+    {
+      ++s;
+      while (isspace(*s))
+	++s;
+    }
+    else if (*s != '\0')
+      ErrorFatal("Wrong separator found in pdriver-handler!");
+    pl = &(*pl)->next;
+  }
+}
+
+static void read_swidec(const char *s, FILE *file)
+{
   handler_list h;
 
   UNUSED(file);
@@ -1042,35 +1068,28 @@
     ErrorFatal("Junk found at end of swi-decoding-code!");
 }
 
-
 static void read_generics(const char *s, FILE *file)
 {
-  UNUSED(file);
   read_handlers(s, &opt.generics, HANDLER_ALLOW_PW | HANDLER_ALLOW_CARRY, file);
 }
 
 static void read_irqs(const char *s, FILE *file)
 {
-  UNUSED(file);
   read_handlers(s, &opt.irqs, 0, file);
 }
 
 static void read_vectors(const char *s, FILE *file)
 {
-  UNUSED(file);
   read_handlers(s, &opt.vectors, HANDLER_ALLOW_ERROR, file);
 }
 
 static void read_vector_traps(const char *s, FILE *file)
 {
-  UNUSED(file);
   read_handlers(s, &opt.vector_traps, 0, file);
 }
 
 static void read_runnable(const char *s, FILE *file)
 {
-  UNUSED(file);
-  UNUSED(s);
   switch (opt.runnable)
   {
     case run_none:
@@ -1096,7 +1115,7 @@
        unwise. I've spent pretty much all day working on this and trying to
        get my head around a way to do the whole thing safely. The simple
        answer is that it's impossible to do properly under the current
-       implementation of RISCOS without some collusion over the taskhandles
+       implementation of RISC OS without some collusion over the taskhandles
        which I'm unwilling to incorporate because it means that some
        knowledge of the environment is required and it /still/ won't cope
        with a multiply threaded single-tasked module. There are a number of
@@ -1281,6 +1300,13 @@
       "file."
     }, IN_BOTH },
 
+  { "pdriver-handler",             { read_pdriver },
+     { "PDriver_Entry, PDReason00_Handler, PDReason01_Handler, PDReason02_Handler",
+       "The PDriver handler specifies the PDriver entry point for registering "
+       "with SWI PDriver_DeclareDriver and is followed by a list of C "
+       "routines one per PDriver reason code."
+     }, IN_CMUNGE | IN_ERRORS },
+    
   { "swi-handler-code",            { NULL, ft_label,    &opt.swi_handler },
     { "Mod_SWI",
       "The SWI handler is entered for every SWI the module provides. "
@@ -1556,7 +1582,7 @@
       case ft_label:
       case ft_quoted:
         {
-          char **value=(char **)field->values.value;
+          const char **value = (const char **)field->values.value;
           if (*value!=NULL)
             ErrorFatal("Only supply one %s field!",field->name);
 
@@ -1606,7 +1632,12 @@
         /* -xc hints that the input language is to be considered as C
            because that is not necessarily guessable with the usual
            cmhg extension. */
-        bufend = buf+sprintf(buf, GCC_BIN_DIR "gcc -E -nostdinc -xc");
+#ifdef __riscos
+#  define GCC_BINARY_NAME "gcc"
+#else
+#  define GCC_BINARY_NAME "arm-unknown-riscos-gcc"
+#endif
+        bufend = buf+sprintf(buf, GCC_BINARY_NAME " -E -nostdinc -xc");
         break;
       case tc_norcroft:
 #ifdef __riscos
@@ -1647,16 +1678,13 @@
     switch (opt.toolchain)
     {
       case tc_gcc:
-        /* Don't know how to do throwback with gcc on non-RISC OS platform */
         /* Don't know how to do dependencies with gcc -
              -M gives output in a mix of unix and RISC OS which isn't useful
          */
-#ifdef __riscos
         if (opt.throwback)
           bufend += sprintf(bufend," -mthrowback");
-#endif
         /* See the Options_CheckSanity in c.options for warnings about the
-           dependency and throwback usage. */
+           dependency usage. */
         break;
 
       case tc_norcroft:
@@ -1683,7 +1711,7 @@
       case tc_norcroft:
         if (opt.dfile)
         {
-          char *result_file = NULL;
+          const char *result_file = NULL;
           /* We have to provide the name of the file that is being generated
              so that we have a correct dependency in the !Depend file. */
           if (opt.ofile)
Index: str.h
===================================================================
--- str.h	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ str.h	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -9,17 +9,17 @@
 
 char *strdup_strip(const char *p);
 
-const char *strduptok(const char *p, char **res);
+const char *strduptok(const char *p, const char **res);
 
 int strprefix(const char *p, const char *q);
 
-const char *strfindpair(const char *p, char **p1, char **p2);
+const char *strfindpair(const char *p, const char **p1, const char **p2);
 
 const char *strcomma(const char *s);
 
 const char *strskip(const char *s, char c);
 
-const char *strstring(const char *s, char **res);
+const char *strstring(const char *s, const char **res);
 
 const char *strint(const char *s, unsigned int *i);
 
Index: datestamp.c
===================================================================
--- datestamp.c	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ datestamp.c	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -14,18 +14,21 @@
 
 void DateStamp(void) {
 
-  char *date, *date0;
-  char *s;
+  char *date;
+  const char *date0;
+  const char *s;
   char datebuf[24];
   int i;
 
   if (opt.mode_errors)
     return; /* No work is required if we're only generating error blocks */
 
-  i = 32;
   if (opt.datestring)
     i = 4 + strlen(opt.datestring)+1;
+  else
+    i = 32;
   date0 = date = Malloc(strlen(opt.help)+i);
+
   s = opt.help;
 
   /* Skip whitespace */
@@ -34,7 +37,7 @@
   /* Copy name, counting chars */
   i = 0;
   do {
-    while (!isspace(*s)) {
+    while (*s && !isspace(*s)) {
       *date++ = *s++;
       i++;
     }
@@ -76,7 +79,7 @@
 
   if (opt.datestring) {
     char *dptr = datebuf;
-    char *iptr = opt.datestring;
+    const char *iptr = opt.datestring;
     char c;
     int wrong = 0;
     *dptr++ = ' ';
Index: Makefile.am
===================================================================
--- Makefile.am	(.../branches/CMungeImportBranch/cmunge)	(revision 0)
+++ Makefile.am	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -0,0 +1,9 @@
+bin_PROGRAMS=cmunge
+
+SVN_ROOT := $(shell svn info ${srcdir} | grep "^Repository Root: " | sed -e "s/^Repository Root: //")
+SVN_BRANCH := $(shell svn info ${srcdir} | grep "^URL: " | sed -e "s/^URL: //")
+SVN_REV := r$(shell svnversion -n ${srcdir}) at $(subst $(SVN_ROOT),,$(SVN_BRANCH))
+
+cmunge_SOURCES=apcscli.c assemble.c blank.c comments.c datestamp.c error.c filename.c format.c gfile.c main.c mem.c options.c readfile.c str.c system.c throwback.c writeexport.c writefile.c writeheader.c apcscli.h assemble.h blank.h comments.h copyright.h datestamp.h error.h filename.h format.h gfile.h MemCheck.h mem.h options.h readfile.h str.h system.h throwback.h writeexport.h writefile.h writeheader.h
+
+cmunge_CFLAGS=-Wall -std=c99 -DGCCSDK_REVISION="\"$(SVN_REV)\""
Index: options.c
===================================================================
--- options.c	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ options.c	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -20,6 +20,11 @@
 void Options_Init(void) {
 
   opt.runnable    = run_none;
+  opt.apcs        = DEFAULT_APCS;
+  opt.apcs_used   = 0;
+  opt.toolchain_used = 0;
+  opt.toolchain   = tc_norcroft;
+  opt.no_scl      = 0;
   opt.reentrant   = 1;
   opt.cplusplus   = 0;
   opt.service     = NULL;
@@ -32,45 +37,45 @@
   opt.swi_base    = 0;
   opt.swi_handler = NULL;
   opt.swi_names   = NULL;
+  opt.swi_codesupplied = 0;
   opt.swi_decoder = NULL;
-  opt.swi_codesupplied = 0;
+  opt.pdriver_entry = NULL;
+  opt.pdriver_names = NULL;
+  opt.error_base  = 0;
   opt.irqs        = NULL;
   opt.events      = NULL;
   opt.init        = NULL;
+  opt.lib_init    = NULL;
   opt.final       = NULL;
-  opt.lib_init    = NULL;
   opt.generics    = NULL;
   opt.vectors     = NULL;
   opt.vector_traps = NULL; /* vectors which can be post processed */
-  opt.ofile       = NULL; /* AOF output */
+  opt.errors      = NULL;
+  opt.errors_special = 0;
+  opt.version     = 0;
+  opt.date        = NULL;
+  opt.datestring  = NULL;
+  opt.blank       = 0;
+  opt.ofile       = NULL; /* AOF or ELF output */
   opt.sfile       = NULL; /* Assembler output */
-  opt.pfile       = NULL; /* Pre-processor output */
-  opt.pextended   = 0;    /* Extended pre-processor input */
+  opt.stemp       = 0;
   opt.hfile       = NULL; /* Header output */
+  opt.x_hdr       = NULL;
+  opt.x_h         = NULL;
+  opt.mfile       = NULL;
+  opt.dfile       = NULL;
+  opt.oslib       = 0;
+  opt.base        = 0;
+  opt.mode_errors = 0; /* We're not in 'errors' mode */
   opt.throwback   = 0;
-  opt.rootinfile  = NULL;
   opt.infile      = NULL;
   opt.atline      = 0;
+  opt.rootinfile  = NULL;
+  opt.pfile       = NULL; /* Pre-processor output */
+  opt.pextended   = 0;    /* Extended pre-processor input */
   opt.defines     = NULL;
-  opt.version     = 0;
-  opt.date        = NULL;
-  opt.oslib       = 0;
-  opt.mfile       = NULL;
-  opt.dfile       = NULL;
   opt.includes    = NULL;
-  opt.base        = 0;
-  opt.mode_errors = 0; /* We're not in 'errors' mode */
-  opt.datestring  = NULL;
   opt.cmhg        = 0; /* We're not CMHG */
-  opt.errors      = NULL;
-  opt.errors_special = 0;
-  /* Export files */
-  opt.x_hdr       = NULL;
-  opt.x_h         = NULL;
-  opt.apcs        = DEFAULT_APCS;
-  opt.toolchain   = tc_norcroft;
-  opt.apcs_used   = 0;
-  opt.toolchain_used = 0;
   opt.help_requested = 0;
 }
 
@@ -90,7 +95,7 @@
 "Options:\n"
 "\n"
 "\t-h            \bOutput this information.\n"
-"\t-o <file>     \bName the output AOF file.\n"
+"\t-o <file>     \bName the output AOF or ELF file.\n"
 "\t-s <file>     \bName the output assembler file.\n"
 "\t-d <file>     \bName a C header file that CMunge will generate.\n"
 "\t-xhdr <file>  \bName a Assembler SWI header file that CMunge will generate.\n"
@@ -106,8 +111,14 @@
 "\t-throwback    \bUse throwback for error processing.\n"
 "\t-zbase        \bDefine symbol Image__RO_Base in generated header.\n"
 "\t-zerrors      \bDefine errors and veneers only (for use in applications).\n"
-"\t-zoslib       \bUse '#include \"oslib/os.h\"' (OSLib) instead of "
-                 "'#include \"kernel.h\"' (Acorn) in generated C header file.\n"
+"\t-zoslib       \bUse 'os_error *' instead of '_kernel_oserror *' to prototype "
+                 "a pointer to a RISC OS error block, 'os_register_block' "
+                 "instead of '_kernel_swi_regs' to represent a set of ARM "
+                 "registers, '#include \"oslib/os.h\"' (OSLib) instead of "
+                 "'#include \"kernel.h\"' (SCL) in generated C header "
+                 "file.\n"
+"\t-znoscl       \bDon't interface with Shared C Library, i.e. don't have "
+                 "runtime support.\n"
 "\t-blank        \bGenerate a blank cmhg file to infile.\n"
 "\t-cmhg         \bGive warnings for non-CMHG values.\n"
 "\t-tgcc         \bUse GCC tool chain to generate output.\n"
@@ -284,15 +295,16 @@
       }
     } else if (strncmp("-z", argv[i], sizeof("-z")-1)==0) { /* case sensitive */
       arg = &argv[i][sizeof("-z")-1];
-      if (stricmp("oslib", arg)) {
+      if (stricmp("noscl", arg))
+	opt.no_scl = 1;
+      else if (stricmp("oslib", arg))
         opt.oslib = 1;
-      } else if (stricmp("base", arg)) {
+      else if (stricmp("base", arg))
         opt.base = 1;
-      } else if (stricmp("errors", arg)) {
+      else if (stricmp("errors", arg))
         opt.mode_errors = 1;
-      } else {
+      else
         ErrorFatal("Unknown tweak option -z");
-      }
     } else if (strcmp("-32bit", argv[i])==0) { /* case sensitive */
       opt.apcs|= APCS_32BIT;
     } else if (strcmp("-26bit", argv[i])==0) { /* case sensitive */
@@ -388,12 +400,6 @@
   switch (opt.toolchain)
   {
     case tc_gcc:
-#ifdef __riscos
-      /* Throwback is supported on RISC OS builds of GCC */
-#else
-      if (opt.throwback)
-        Warning("GCC has no support for -throwback flag");
-#endif
       if (opt.dfile)
         Warning("GCC has no support for -depend flag");
       break;
@@ -454,6 +460,9 @@
       }
     }
 
+    if (opt.pdriver_entry && opt.pdriver_names == NULL)
+      Warning("PDriver entry point defined but no handlers");
+    
     if (opt.errors && opt.error_base == 0 && !opt.errors_special)
       ErrorFatal("Errors defined, but no error base");
   }
Index: assemble.c
===================================================================
--- assemble.c	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ assemble.c	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -14,10 +14,6 @@
 #include "system.h"
 #include "apcscli.h"
 
-#ifndef GCC_BIN_DIR
-#define GCC_BIN_DIR ""
-#endif
-
 static char buf[2048];
 
 void AssembleFile(void) {
@@ -28,8 +24,10 @@
     int throwback;
 #ifdef __riscos
     throwback = opt.throwback;
+#  define GCC_BINARY_NAME "gcc"
 #else
     throwback = 0;
+#  define GCC_BINARY_NAME "arm-unknown-riscos-gcc"
 #endif
 
     switch (opt.toolchain)
@@ -48,8 +46,7 @@
         break;
       case tc_gcc:
       case tc_lcc:
-        sprintf(buf, GCC_BIN_DIR "gcc -xassembler -mmodule %s %s -c %s -o %s",
-                          (CODE32) ? "-apcs32 -apcsfpv3" : "",
+        sprintf(buf, GCC_BINARY_NAME " -xassembler -mmodule %s -c %s -o %s",
                           throwback ? "-mthrowback" : "",
                           opt.sfile, opt.ofile);
         break;
Index: writeexport.c
===================================================================
--- writeexport.c	(.../branches/CMungeImportBranch/cmunge)	(revision 5742)
+++ writeexport.c	(.../trunk/gcc4/riscos/cmunge)	(revision 5742)
@@ -19,92 +19,89 @@
 
 static FILE *file;
 
-static void hdr_swis(void) {
+static void hdr_swis(void)
+{
+  const char * const prefix=opt.swi_names->name;
 
-  swi_list l;
-  char *prefix=opt.swi_names->name;
-  int swi=opt.swi_base;
+  if (!opt.swi_names)
+    return;
 
-  /* Non-X variants */
-  l = opt.swi_names;
-  if (l)
-    l = l->next;
-
   asm_comment(file, "SWI numbers");
+
+  /* Non-X variants */
+  if (opt.toolchain != tc_gcc)
   {
+    swi_list l;
     int len=0;
     while (len++<24) fputc(' ',file);
-    fprintf(file, "^ &%08x\n",swi);
-  }
+    fprintf(file, "^ &%08x\n",opt.swi_base);
 
-  while (l) {
-    char *name=l->name;
-    int startlen,len;
-    startlen=len=strlen(prefix)+1+strlen(name)+1;
-    fprintf(file, "%s_%s ", prefix, name);
-    while (len++<24) fputc(' ',file);
-    fprintf(file, "# 1\n");
-    swi++;
-    l=l->next;
+    for (l = opt.swi_names->next; l; l = l->next)
+    {
+      int len;
+      len = fprintf(file, "%s_%s ", prefix, l->name);
+      while (len++<24) fputc(' ',file);
+      fprintf(file, "# 1\n");
+    }
   }
+  else
+  {
+    swi_list l;
+    int swi;
+    for (l = opt.swi_names->next, swi=opt.swi_base; l; l = l->next, ++swi)
+      fprintf(file, ".set %s_%s,0x%x\n", prefix, l->name, swi);
+  }
 
   /* X variants */
-  swi=opt.swi_base;
-  l = opt.swi_names;
-  if (l)
-    l = l->next;
-
+  if (opt.toolchain != tc_gcc)
   {
+    swi_list l;
     int len=0;
     while (len++<24) fputc(' ',file);
-    fprintf(file, "^ &%08x\n",swi+(1<<17));
-  }
+    fprintf(file, "^ &%08x\n", opt.swi_base + (1<<17));
 
-  while (l) {
-    char *name=l->name;
-    int startlen,len;
-    startlen=len=1+strlen(prefix)+1+strlen(name)+1;
-    fprintf(file, "X%s_%s ", prefix, name);
-    while (len++<24) fputc(' ',file);
-    fprintf(file, "# 1\n");
-    swi++;
-    l=l->next;
+    for (l = opt.swi_names->next; l; l = l->next)
+    {
+      int len;
+      len = fprintf(file, "X%s_%s ", prefix, l->name);
+      while (len++<24) fputc(' ',file);
+      fprintf(file, "# 1\n");
+    }
   }
-
+  else
+  {
+    swi_list l;
+    int swi;
+    for (l = opt.swi_names->next, swi=opt.swi_base; l; l = l->next, ++swi)
+      fprintf(file, ".set X%s_%s,0x%x\n", prefix, l->name, swi+(1<<17));
+  }
 }
 
 static void h_swis(void) {
 
   swi_list l;
-  char *prefix=opt.swi_names->name;
-  int swi=opt.swi_base;
+  const char * const prefix=opt.swi_names->name;
+  int swi;
 
-  /* Non-X variants */
-  l = opt.swi_names;
-  if (l)
-    l = l->next;
+  if (!opt.swi_names)
+    return;
 
   c_comment(file, "SWI numbers");
 
-  while (l) {
-    char *name=l->name;
-    int startlen,len;
-    startlen=len=strlen(prefix)+1+strlen(name)+1;
-    fprintf(file, "#define %s_%s ", prefix, name);
-    while (len++<24) fputc(' ',file);
+  for (l = opt.swi_names->next, swi=opt.swi_base; l; l = l->next, ++swi) {
+    const char *name=l->name;
+    int len;
+    len = fprintf(file, "#define %s_%s ", prefix, name);
+    while (len++<32) fputc(' ',file);
     fprintf(file, "0x%x\n",swi);
-    len=startlen+1;
 #ifdef USE_X_IN_HFILE
-    fprintf(file, "#define X%s_%s ", prefix, name);
-    while (len++<24) fputc(' ',file);
+    len = fprintf(file, "#define X%s_%s ", prefix, name);
+    while (len++<32) fputc(' ',file);
     fprintf(file, "0x%x\n",0x20000+swi);
 #endif
-    swi++;
-    l=l->next;
   }
 
   fprintf(file, "\n");
-
 }
 
 /* we output an assembler hdr file sometimes, so that we don't have
@@ -128,7 +125,8 @@
   if (opt.swi_handler || opt.swi_codesupplied)
     hdr_swis();
 
-  fprintf(file, "\n\n\tEND\n");
+  if (opt.toolchain != tc_gcc)
+    fprintf(file, "\n\tEND\n");
   file_close(file);
 }
 

Property changes on: .
___________________________________________________________________
Added: svn:ignore
   + configure
Makefile.in
depcomp
autom4te.cache
missing
aclocal.m4
install-sh


