* as/mcs51/lkarea.c (lnkarea, lnkarea2): improved BSEG size calculation,
authormaartenbrock <maartenbrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 19 Jul 2005 17:26:34 +0000 (17:26 +0000)
committermaartenbrock <maartenbrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 19 Jul 2005 17:26:34 +0000 (17:26 +0000)
  (lnksect2): generate warnings for memory overlap
* src/SDCC.lex (doPragma, process_pragma): added pragma's codeseg and
  constseg to set the name of these segments so you can instruct the linker
  to place them in banks
* src/SDCCast.c (decorateType): use new macro IS_FUNCPTR()
* src/SDCCglobl.h: added MODEL_HUGE to enum,
  added code_seg and const_seg to options
* src/SDCCglue.c (emitMaps): use options.const_seg,
  (createInterruptVect): put interrupt vectors in segment HOME,
  (glue): put HOME before static segment and put the main glue in HOME,
  (glue): use options.code_seg
* src/SDCCicode.c (geniCodeCall): use new macro IS_FUNCPTR()
* src/SDCCmain.c: added option --codeseg and --constseg to set the name of
  these segments so you can instruct the linker to place them in banks
  (linkEdit): use code_loc for HOME segment which should be the first
  segment in code memory now
* src/SDCCmem.c: fixed more stuff like bug 1238386
* src/SDCCsymt.c (getSize): use generic pointer size for banked functions,
  (changePointer): don't change function pointers to code pointers for
  banked functions,
  (compareType): added exceptional check for banked function pointers
* src/SDCCsymt.h: changed IFFUNC_ISBANKEDCALL, added IS_FUNCPTR
* src/hc08/main.c (_hc08_genAssemblerPreamble): put HOME first, put CSEG
  after static in code memory
* src/mcs51/gen.c: added aopLiteralLong prototype,
  (aopForSym): use getSize for functions,
  (genCall): generate banked calls over one trampoline __sdcc_banked_call
  in HOME with lsb of address in r0, msb in r1 and bank in r2, use
  -Wl-bBANKSEG=0xbbaaaa option to set the address (aaaa) and bank (bb) of
  the segment,
  (genPcall): use call for literal function pointers and generate banked
  calls over the one trampoline so there's only one place for the user to
  modify according to his/hers hardware,
  (genEndFunction): jump to __sdcc_banked_ret in HOME for banked functions,
  (genPlusIncr): moved check icount>4 beyond inc dptr optimization
* src/mcs51/main.c: added keyword banked,
  (_mcs51_genExtraAreas): put HOME first followed by GSINIT, STATIC and CSEG
* support/Util/SDCCerr.c,
* support/Util/SDCCerr.h: added E_BANKED_WITH_CALLEESAVES, registers are
  needed for passing the bank and address to the trampoline
* device/lib/mcs51/crtbank.asm: added for bankswitching
* device/lib/mcs51/Makefile: added crtbank

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3804 4a8a32a2-be11-0410-ad9d-d568d2c75423

18 files changed:
ChangeLog
as/mcs51/lkarea.c
device/lib/mcs51/Makefile
device/lib/mcs51/crtbank.asm [new file with mode: 0644]
src/SDCC.lex
src/SDCCast.c
src/SDCCglobl.h
src/SDCCglue.c
src/SDCCicode.c
src/SDCCmain.c
src/SDCCmem.c
src/SDCCsymt.c
src/SDCCsymt.h
src/hc08/main.c
src/mcs51/gen.c
src/mcs51/main.c
support/Util/SDCCerr.c
support/Util/SDCCerr.h

index b6e9d1d673f0cc3251c74c2b64e655222001f24d..5be3170a6726ef36fe1f3e2670364f1ae7281c6b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,49 @@
+2005-07-19 Maarten Brock <sourceforge.brock AT dse.nl>
+
+       * as/mcs51/lkarea.c (lnkarea, lnkarea2): improved BSEG size calculation,
+         (lnksect2): generate warnings for memory overlap
+       * src/SDCC.lex (doPragma, process_pragma): added pragma's codeseg and
+         constseg to set the name of these segments so you can instruct the linker
+         to place them in banks
+       * src/SDCCast.c (decorateType): use new macro IS_FUNCPTR()
+       * src/SDCCglobl.h: added MODEL_HUGE to enum,
+         added code_seg and const_seg to options
+       * src/SDCCglue.c (emitMaps): use options.const_seg,
+         (createInterruptVect): put interrupt vectors in segment HOME,
+         (glue): put HOME before static segment and put the main glue in HOME,
+         (glue): use options.code_seg
+       * src/SDCCicode.c (geniCodeCall): use new macro IS_FUNCPTR()
+       * src/SDCCmain.c: added option --codeseg and --constseg to set the name of
+         these segments so you can instruct the linker to place them in banks
+         (linkEdit): use code_loc for HOME segment which should be the first
+         segment in code memory now
+       * src/SDCCmem.c: fixed more stuff like bug 1238386
+       * src/SDCCsymt.c (getSize): use generic pointer size for banked functions,
+         (changePointer): don't change function pointers to code pointers for
+         banked functions,
+         (compareType): added exceptional check for banked function pointers
+       * src/SDCCsymt.h: changed IFFUNC_ISBANKEDCALL, added IS_FUNCPTR
+       * src/hc08/main.c (_hc08_genAssemblerPreamble): put HOME first, put CSEG
+         after static in code memory
+       * src/mcs51/gen.c: added aopLiteralLong prototype,
+         (aopForSym): use getSize for functions,
+         (genCall): generate banked calls over one trampoline __sdcc_banked_call
+         in HOME with lsb of address in r0, msb in r1 and bank in r2, use
+         -Wl-bBANKSEG=0xbbaaaa option to set the address (aaaa) and bank (bb) of
+         the segment,
+         (genPcall): use call for literal function pointers and generate banked
+         calls over the one trampoline so there's only one place for the user to
+         modify according to his/hers hardware,
+         (genEndFunction): jump to __sdcc_banked_ret in HOME for banked functions,
+         (genPlusIncr): moved check icount>4 beyond inc dptr optimization
+       * src/mcs51/main.c: added keyword banked,
+         (_mcs51_genExtraAreas): put HOME first followed by GSINIT, STATIC and CSEG
+       * support/Util/SDCCerr.c,
+       * support/Util/SDCCerr.h: added E_BANKED_WITH_CALLEESAVES, registers are
+         needed for passing the bank and address to the trampoline
+       * device/lib/mcs51/crtbank.asm: added for bankswitching
+       * device/lib/mcs51/Makefile: added crtbank
+
 2005-07-16 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
 
        * src/SDCCcse.c (algebraicOpts): fixed loss of volatility
index 07b29fc1ddb410d61b557f849885eefe31938f97..4a8781bb6286ab49b2d73bcbd6ece6204a8ae07f 100644 (file)
@@ -198,6 +198,7 @@ lkparea(char *id)
 
     ap = areap;
     axp = (struct areax *) new (sizeof(struct areax));
+    axp->a_addr = -1; /* default: no address yet */
     while (ap) {
         if (symeq(id, ap->a_id)) {
             taxp = ap->a_axp;
@@ -381,7 +382,7 @@ lnkarea()
         /*JCF: Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
         to compute the byte size of BSEG_BYTES: */
         if (!strcmp(ap->a_id, "BSEG")) {
-            ap->a_ap->a_axp->a_size=(ap->a_addr/8)+((ap->a_size+7)/8); /*Bits to bytes*/
+            ap->a_ap->a_axp->a_size += ((ap->a_addr + ap->a_size + 7)/8); /*Bits to bytes*/
         }
         else if (!strcmp(ap->a_id, "REG_BANK_0")) ta[0]=ap;
         else if (!strcmp(ap->a_id, "REG_BANK_1")) ta[1]=ap;
@@ -484,6 +485,7 @@ lnksect(register struct area *tap)
 
 void lnksect2 (struct area *tap, int rloc);
 char idatamap[256];
+long codemap[2048];
 
 /*Modified version of the functions for packing variables in internal data memory*/
 VOID lnkarea2 (void)
@@ -497,6 +499,7 @@ VOID lnkarea2 (void)
     struct sym *sp_dseg_s=NULL, *sp_dseg_l=NULL;
 
     for(j=0; j<256; j++) idatamap[j]=' ';
+    memset(codemap, 0, sizeof(codemap));
 
     ap = areap;
     while (ap)
@@ -552,7 +555,7 @@ VOID lnkarea2 (void)
         to compute the byte size of BSEG_BYTES: */
         if (!strcmp(ap->a_id, "BSEG"))
         {
-            ap->a_ap->a_axp->a_size=(ap->a_addr/8)+((ap->a_size+7)/8); /*Bits to bytes*/
+                ap->a_ap->a_axp->a_size = ((ap->a_addr + ap->a_size + 7)/8); /*Bits to bytes*/
         }
         else if (!strcmp(ap->a_id, "DSEG"))
         {
@@ -801,7 +804,7 @@ void lnksect2 (struct area *tap, int rloc)
             {
                 if(taxp->a_size!=0)
                 {
-                    for(j=0x20+taxp->a_addr; j<((int)(0x20+taxp->a_addr+taxp->a_size)); j++)
+                    for(j=addr; j<((int)(addr+taxp->a_size)); j++)
                         idatamap[j]=fchar;
                 }
 
@@ -816,6 +819,32 @@ void lnksect2 (struct area *tap, int rloc)
                 {
                     taxp->a_size = 256-(addr & 0xFF);
                 }
+                //should find next unused address now!!!
+                //but let's first just warn for overlaps
+                if (rloc == 1)
+                {
+                    int a = addr;
+                    int i = addr >> 5;
+                    int j = (addr + taxp->a_size) >> 5;
+                    long mask = -(1 << (addr & 0x1F));
+
+                    while (i < j)
+                    {
+                        if (codemap[i] & mask)
+                        {
+                            fprintf(stderr, "memory overlap near 0x%X for %s\n", a, tap->a_id);
+                        }
+                        codemap[i++] |= mask;
+                        mask = 0xFFFFFFFF;
+                        a += 32;
+                    }
+                    mask &= (1 << ((addr + taxp->a_size) & 0x1F)) - 1;
+                    if (codemap[i] & mask)
+                    {
+                        fprintf(stderr, "memory overlap near 0x%X for %s\n", a, tap->a_id);
+                    }
+                    codemap[i] |= mask;
+                }
                 taxp->a_addr = addr;
                 addr += taxp->a_size;
                 size += taxp->a_size;
index 9476653fd74392dd582bb6a15bad240fe1bb0335..f0c2e6c7fe8b319f1b4110b6dab749bb96942d40 100644 (file)
@@ -5,8 +5,8 @@ SAS = $(TOPDIR)/bin/asx8051
 SCC = $(TOPDIR)/bin/sdcc
 
 OBJ = crtstart.rel crtxinit.rel crtxclear.rel crtclear.rel crtxstack.rel \
-      crtpagesfr.rel
-      
+      crtpagesfr.rel crtbank.rel
+
 LIB = mcs51.lib
 
 CC = $(SCC)
diff --git a/device/lib/mcs51/crtbank.asm b/device/lib/mcs51/crtbank.asm
new file mode 100644 (file)
index 0000000..38f0cdf
--- /dev/null
@@ -0,0 +1,69 @@
+; /*-------------------------------------------------------------------------
+;
+;   crtbank.asm :- C run-time: bank switching
+;
+;    This library is free software; you can redistribute it and/or modify it
+;    under the terms of the GNU Library General Public License as published by the
+;    Free Software Foundation; either version 2, or (at your option) any
+;    later version.
+;
+;    This library is distributed in the hope that it will be useful,
+;    but WITHOUT ANY WARRANTY; without even the implied warranty of
+;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;    GNU Library General Public License for more details.
+;
+;    You should have received a copy of the GNU Library General Public License
+;    along with this program; if not, write to the Free Software
+;    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+;
+;    In other words, you are welcome to use, share and improve this program.
+;    You are forbidden to forbid anyone else to use, share and improve
+;    what you give them.   Help stamp out software-hoarding!
+; -------------------------------------------------------------------------*/
+
+       .area HOME    (CODE)
+       .area GSINIT0 (CODE)
+       .area GSINIT1 (CODE)
+       .area GSINIT2 (CODE)
+       .area GSINIT3 (CODE)
+       .area GSINIT4 (CODE)
+       .area GSINIT5 (CODE)
+       .area GSINIT  (CODE)
+       .area GSFINAL (CODE)
+       .area CSEG    (CODE)
+
+; /*-------------------------------------------------------------------------
+;   Example for SiLabs C8051F12x / C8051F13x with 128kB code memory
+;   divided into 4 banks of 32kB
+;   These devices have an sfr called PSBANK containing two parts:
+;   COBANK (bit 5:4): Constant Operations Bank
+;   IFBANK (bit 1:0): Instruction Fetch Bank
+;   From 0x0000 to 0x7FFF bank 0 is always accessed
+;   From 0x8000 to 0xFFFF bank COBANK is accessed for reading with movc
+;   From 0x8000 to 0xFFFF bank IFBANK is accessed for executing instructions
+;
+;   Make your own copy of this file,
+;   adapt it to your situation,
+;   and compile/link it in your project
+; -------------------------------------------------------------------------*/
+
+       .globl _PSBANK
+
+       .area HOME    (CODE)
+
+__sdcc_banked_call::
+       push    _PSBANK         ;save return bank
+       xch     a,r0            ;save Acc in r0, do not assume any register bank
+       push    acc             ;push LSB address
+       mov     a,r1
+       push    acc             ;push MSB address
+       mov     a,r2            ;get new bank
+       anl     a,0x0F          ;remove storage class indicator
+       anl     _PSBANK,#0xF0
+       orl     _PSBANK,a       ;select bank
+       xch     a,r0            ;restore Acc
+       ret                     ;make the call
+
+__sdcc_banked_ret::
+       pop     _PSBANK         ;restore bank
+       ret                     ;return to caller
index c7bb9181c0d6ff9a0a45fe88a0dd6ff30d4c013f..d1214ac0826cac4331a8e707b9c204e30396c6f1 100644 (file)
@@ -469,7 +469,9 @@ enum pragma_id {
      P_STD_C89,
      P_STD_C99,
      P_STD_SDCC89,
-     P_STD_SDCC99
+     P_STD_SDCC99,
+     P_CODESEG,
+     P_CONSTSEG
 };
 
 
@@ -685,6 +687,28 @@ static void doPragma(int op, char *cp)
     options.std_c99 = 1;
     options.std_sdcc = 1;
     break;
+
+  case P_CODESEG:
+    {
+      char str[9];
+      char *segname = Safe_malloc(15);
+      sscanf(cp, " %8s", str);
+      str[8] = '\0';
+      sprintf(segname, "%-8.8s(CODE)", str);
+      options.code_seg = segname;
+    }
+    break;
+
+  case P_CONSTSEG:
+    {
+      char str[9];
+      char *segname = Safe_malloc(15);
+      sscanf(cp, " %8s", str);
+      str[8] = '\0';
+      sprintf(segname, "%-8.8s(CODE)", str);
+      options.const_seg = segname;
+    }
+    break;
   }
 }
 
@@ -719,10 +743,12 @@ static int process_pragma(char *s)
     { "opt_code_speed", P_OPTCODESPEED, 0 },
     { "opt_code_size",  P_OPTCODESIZE,  0 },
     { "opt_code_balanced",  P_OPTCODEBALANCED,  0 },
-    { "std_c89",       P_STD_C89, 0 },
-    { "std_c99",       P_STD_C99, 0 },
-    { "std_sdcc89",    P_STD_SDCC89, 0 },
-    { "std_sdcc99",    P_STD_SDCC99, 0 },
+    { "std_c89",        P_STD_C89,      0 },
+    { "std_c99",        P_STD_C99,      0 },
+    { "std_sdcc89",     P_STD_SDCC89,   0 },
+    { "std_sdcc99",     P_STD_SDCC99,   0 },
+    { "codeseg",        P_CODESEG,      0 },
+    { "constseg",       P_CONSTSEG,     0 },
 
     /*
      * The following lines are deprecated pragmas,
index 17cf692e85c6e33b8c9493bc1f44dee23f3ec6ad..3cfdde6a9c2754ad7548ec87b4ead54003e04547 100644 (file)
@@ -4178,8 +4178,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
         }
 
       /* require a function or pointer to function */
-      if (!IS_FUNC (LTYPE (tree))
-          && !(IS_CODEPTR (LTYPE (tree)) && IS_FUNC (LTYPE (tree)->next)))
+      if (!IS_FUNC (LTYPE (tree)) && !IS_FUNCPTR (LTYPE (tree)))
         {
           werrorfl (tree->filename, tree->lineno, E_FUNCTION_EXPECTED);
           goto errorTreeReturn;
@@ -4193,7 +4192,7 @@ decorateType (ast * tree, RESULT_TYPE resultType)
           sym_link *functype;      
           parmNumber = 1;
 
-          if (IS_CODEPTR(LTYPE(tree)))
+          if (IS_FUNCPTR (LTYPE (tree)))
             functype = LTYPE (tree)->next;
           else
             functype = LTYPE (tree);
index 8e4e7dc16acef2380ac7e6695b873425f512d807..51174ae3f618e93878f9fcc48ddb5a9733838790 100644 (file)
@@ -171,7 +171,8 @@ enum
     MODEL_MEDIUM = 4,
     MODEL_LARGE = 8,
     MODEL_FLAT24 = 16,
-    MODEL_PAGE0 = 32 /* for the xa51 port */
+    MODEL_PAGE0 = 32, /* for the xa51 port */
+    MODEL_HUGE = 64 /* for banked support */
   };
 
 /* overlay segment name and the functions
@@ -250,9 +251,11 @@ struct options
     int printSearchDirs;        /* display the directories in the compiler's search path */
     int vc_err_style;           /* errors and warnings are compatible with Micro$oft visual studio */
     int use_stdout;             /* send errors to stdout instead of stderr */
-    int no_std_crt0;            /*For the z80/gbz80 do not link default crt0.o*/
-    int std_c99;               /* enable C99 keywords/constructs */
-    int std_sdcc;              /* enable SDCC extensions to C */
+    int no_std_crt0;            /* for the z80/gbz80 do not link default crt0.o*/
+    int std_c99;                /* enable C99 keywords/constructs */
+    int std_sdcc;               /* enable SDCC extensions to C */
+    const char *code_seg;       /* segment name to use instead of CSEG */
+    const char *const_seg;      /* segment name to use instead of CONST */
     /* sets */
     set *calleeSavesSet;        /* list of functions using callee save */
     set *excludeRegsSet;        /* registers excluded from saving */
@@ -260,7 +263,7 @@ struct options
   };
 
 /* forward definition for variables accessed globally */
-extern int noAssemble;         /* no assembly, stop after code generation */
+extern int noAssemble;          /* no assembly, stop after code generation */
 extern char *yytext;
 extern char *currFname;
 extern char *fullSrcFileName;   /* full name for the source file; */
index 158d9fbb7ccafb62133807e1118519feef17222a..dd1f99a4d0a679ddf608e2865d46804a8678c6d2 100644 (file)
@@ -1330,8 +1330,8 @@ emitMaps (void)
   emitRegularMap (home, TRUE, FALSE);
   emitRegularMap (code, TRUE, FALSE);
 
-  if (CONST_NAME) {
-    tfprintf (code->oFile, "\t!area\n", CONST_NAME);
+  if (options.const_seg) {
+    tfprintf (code->oFile, "\t!area\n", options.const_seg);
   }
   emitStaticSeg (statsg, code->oFile);
   if (port->genXINIT) {
@@ -1378,7 +1378,7 @@ createInterruptVect (FILE * vFile)
       return;
     }
 
-  tfprintf (vFile, "\t!areacode\n", CODE_NAME);
+  tfprintf (vFile, "\t!areacode\n", HOME_NAME);
   fprintf (vFile, "__interrupt_vect:\n");
 
 
@@ -1816,7 +1816,7 @@ glue (void)
    * the post_static_name area will immediately follow the static_name
    * area.
    */
-  tfprintf (asmFile, "\t!area\n", port->mem.code_name);
+  tfprintf (asmFile, "\t!area\n", port->mem.home_name);
   tfprintf (asmFile, "\t!area\n", port->mem.static_name);       /* MOF */
   tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
   tfprintf (asmFile, "\t!area\n", port->mem.static_name);
@@ -1884,15 +1884,10 @@ glue (void)
   tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
   copyFile (asmFile, home->oFile);
 
-  /* copy over code */
-  fprintf (asmFile, "%s", iComments2);
-  fprintf (asmFile, "; code\n");
-  fprintf (asmFile, "%s", iComments2);
-  tfprintf (asmFile, "\t!areacode\n", CODE_NAME);
   if (mainf && IFFUNC_HASBODY(mainf->type))
     {
 
-      /* entry point @ start of CSEG */
+      /* entry point @ start of HOME */
       fprintf (asmFile, "__sdcc_program_startup:\n");
 
       /* put in jump or call to main */
@@ -1908,6 +1903,11 @@ glue (void)
           fprintf (asmFile, "\tsjmp .\n");
         }
     }
+  /* copy over code */
+  fprintf (asmFile, "%s", iComments2);
+  fprintf (asmFile, "; code\n");
+  fprintf (asmFile, "%s", iComments2);
+  tfprintf (asmFile, "\t!areacode\n", options.code_seg);
   copyFile (asmFile, code->oFile);
 
   if (port->genAssemblerEnd) {
index 5c38ec8f80937d5f2167fe196dbcd98b057f5332..2e0c1908705f3aa552582081c37b9b096c0413c7 100644 (file)
@@ -3341,7 +3341,7 @@ geniCodeCall (operand * left, ast * parms,int lvl)
   int stack = 0;
 
   if (!IS_FUNC(OP_SYMBOL(left)->type) &&
-      !IS_CODEPTR(OP_SYMBOL(left)->type)) {
+      !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
     werror (E_FUNCTION_EXPECTED);
     return operandFromValue(valueFromLit(0));
   }
@@ -3352,7 +3352,7 @@ geniCodeCall (operand * left, ast * parms,int lvl)
   geniCodeSEParms (parms,lvl);
 
   ftype = operandType (left);
-  if (IS_CODEPTR (ftype))
+  if (IS_FUNCPTR (ftype))
     ftype = ftype->next;
 
   /* first the parameters */
index 55338496184b6eee7e4be80eee4abfedbbe1cd8b..672d0621651bc74fc3fc25009f8932cf1f345b4b 100644 (file)
@@ -139,6 +139,8 @@ char buffer[PATH_MAX * 2];
 #define OPTION_STD_C99          "--std-c99"
 #define OPTION_STD_SDCC89       "--std-sdcc89"
 #define OPTION_STD_SDCC99       "--std-sdcc99"
+#define OPTION_CODE_SEG         "--codeseg"
+#define OPTION_CONST_SEG        "--constseg"
 
 static const OPTION
 optionsTable[] = {
@@ -215,6 +217,8 @@ optionsTable[] = {
     { 0,    "--no-std-crt0", &options.no_std_crt0, "For the z80/gbz80 do not link default crt0.o"},
 #endif
     { 0,    OPTION_SHORT_IS_8BITS,  NULL, "Make short 8 bits (for old times sake)" },
+    { 0,    OPTION_CODE_SEG,        NULL, "<name> use this name for the code segment" },
+    { 0,    OPTION_CONST_SEG,       NULL, "<name> use this name for the const segment" },
     
     { 0,    NULL,                   NULL, "Optimization options"},
     { 0,    "--nooverlay",          &options.noOverlay, "Disable overlaying leaf function auto variables" },
@@ -558,6 +562,8 @@ setDefaultOptions (void)
   options.shortis8bits = 0;
   options.std_sdcc = 1;         /* enable SDCC language extensions */
   options.std_c99 = 0;          /* default to C89 until more C99 support */
+  options.code_seg = CODE_NAME;   /* default to CSEG for generated code */
+  options.const_seg = CONST_NAME; /* default to CONST for generated code */
 
   options.stack10bit=0;
 
@@ -1116,6 +1122,18 @@ parseCmdLine (int argc, char **argv)
               continue;
             }
 
+          if (strcmp (argv[i], OPTION_CODE_SEG) == 0)
+            {
+              options.code_seg = getStringArg(OPTION_CODE_SEG, argv, &i, argc);
+              continue;
+            }
+
+          if (strcmp (argv[i], OPTION_CONST_SEG) == 0)
+            {
+              options.const_seg = getStringArg(OPTION_CONST_SEG, argv, &i, argc);
+              continue;
+            }
+
           if (!port->parseOption (&argc, argv, &i))
             {
               werror (W_UNKNOWN_OPTION, argv[i]);
@@ -1500,7 +1518,7 @@ linkEdit (char **envp)
         {
 
           /* code segment start */
-          WRITE_SEG_LOC (CODE_NAME, options.code_loc);
+          WRITE_SEG_LOC (HOME_NAME, options.code_loc);
 
           /* data segment start. If zero, the linker chooses
              the best place for data */
index bcd36d6a9bc5e7f046ffd71e22427ba3565ac8b7..8e0db0dce41649bf11c895a6cd7c55d11eba0ea0 100644 (file)
@@ -310,6 +310,58 @@ void deleteFromSeg(symbol *sym)
     }
 }
 
+/*-----------------------------------------------------------------*/
+/* allocDefault - assigns the output segment based on SCLASS       */
+/*-----------------------------------------------------------------*/
+bool
+allocDefault (symbol * sym)
+{
+  switch (SPEC_SCLS (sym->etype))
+    {
+    case S_SFR:
+      SPEC_OCLS (sym->etype) = sfr;
+      break;
+    case S_SBIT:
+      SPEC_OCLS (sym->etype) = sfrbit;
+      break;
+    case S_CODE:
+      if (sym->_isparm)
+        return FALSE;
+      /* if code change to constant */
+      SPEC_OCLS (sym->etype) = statsg;
+      break;
+    case S_XDATA:
+      // should we move this to the initialized data segment?
+      if (port->genXINIT &&
+          sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) {
+        SPEC_OCLS(sym->etype) = xidata;
+      } else {
+        SPEC_OCLS (sym->etype) = xdata;
+      }
+      break;
+    case S_DATA:
+      SPEC_OCLS (sym->etype) = data;
+      break;
+    case S_IDATA:
+      SPEC_OCLS (sym->etype) = idata;
+      sym->iaccess = 1;
+      break;
+    case S_PDATA:
+      SPEC_OCLS (sym->etype) = pdata;
+      sym->iaccess = 1;
+      break;
+    case S_BIT:
+      SPEC_OCLS (sym->etype) = bit;
+      break;
+    case S_EEPROM:
+      SPEC_OCLS (sym->etype) = eeprom;
+      break;
+    default:
+      return FALSE;
+    }
+  allocIntoSeg (sym);
+  return TRUE;
+}
 
 /*-----------------------------------------------------------------*/
 /* allocGlobal - assigns the output segment to a global var       */
@@ -363,29 +415,9 @@ allocGlobal (symbol * sym)
       return;
     }
 
-  /* if this is a  SFR or SBIT */
-  if (SPEC_SCLS (sym->etype) == S_SFR ||
-      SPEC_SCLS (sym->etype) == S_SBIT)
-    {
-
-      SPEC_OCLS (sym->etype) =
-        (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
-
-      allocIntoSeg (sym);
-      return;
-    }
-
   /* if this is a bit variable and no storage class */
   if (SPEC_NOUN (sym->etype) == V_BIT
-      && SPEC_SCLS (sym->etype) == S_BIT)
-    {
-      SPEC_OCLS (sym->etype) = bit;
-      allocIntoSeg (sym);
-      return;
-    }
-
-  /* if bit storage class */
-  if (SPEC_SCLS (sym->etype) == S_SBIT)
+      /*&& SPEC_SCLS (sym->etype) == S_BIT*/)
     {
       SPEC_OCLS (sym->etype) = bit;
       allocIntoSeg (sym);
@@ -397,16 +429,6 @@ allocGlobal (symbol * sym)
   if (SPEC_SCLS (sym->etype) == S_REGISTER)
     SPEC_SCLS (sym->etype) = S_FIXED;
 
-  /* if data specified then  */
-  if (SPEC_SCLS (sym->etype) == S_DATA)
-    {
-      /* set the output class */
-      SPEC_OCLS (sym->etype) = data;
-      /* generate the symbol  */
-      allocIntoSeg (sym);
-      return;
-    }
-
   /* if it is fixed, then allocate depending on the  */
   /* current memory model, same for automatics        */
   if (SPEC_SCLS (sym->etype) == S_FIXED ||
@@ -423,49 +445,7 @@ allocGlobal (symbol * sym)
     }
   }
 
-  /* if code change to constant */
-  if (SPEC_SCLS (sym->etype) == S_CODE) {
-    SPEC_OCLS (sym->etype) = statsg;
-    allocIntoSeg (sym);
-    return;
-  }
-
-  if (SPEC_SCLS (sym->etype) == S_XDATA)
-    {
-      // should we move this to the initialized data segment?
-      if (port->genXINIT &&
-          sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) {
-        SPEC_OCLS(sym->etype)=xidata;
-      } else {
-        SPEC_OCLS (sym->etype) = xdata;
-      }
-      allocIntoSeg (sym);
-      return;
-    }
-
-  if (SPEC_SCLS (sym->etype) == S_IDATA)
-    {
-      SPEC_OCLS (sym->etype) = idata;
-      sym->iaccess = 1;
-      allocIntoSeg (sym);
-      return;
-    }
-
-  if (SPEC_SCLS (sym->etype) == S_PDATA)
-    {
-      SPEC_OCLS (sym->etype) = pdata;
-      sym->iaccess = 1;
-      allocIntoSeg (sym);
-      return;
-    }
-
-  if (SPEC_SCLS (sym->etype) == S_EEPROM)
-    {
-      SPEC_OCLS (sym->etype) = eeprom;
-      allocIntoSeg (sym);
-      return;
-    }
-
+  allocDefault (sym);
   return;
 }
 
@@ -544,12 +524,13 @@ allocParms (value * val)
                     "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum);
           strncpyz (lval->name, lval->sym->rname, sizeof(lval->name));
 
-          /* if declared in external storage */
-          if (SPEC_SCLS (lval->etype) == S_XDATA)
-            SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata;
-          else if (SPEC_SCLS (lval->etype) == S_BIT)
-            SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = bit;
-          else
+          /* if declared in specific storage */
+          if (allocDefault (lval->sym))
+            {
+              SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype);
+              continue;
+            }
+
             /* otherwise depending on the memory model
                note here that we put it into the overlay segment
                first, we will remove it from the overlay segment
@@ -673,34 +654,6 @@ allocLocal (symbol * sym)
   }
 
   /* else depending on the storage class specified */
-  if (SPEC_SCLS (sym->etype) == S_XDATA)
-    {
-      SPEC_OCLS (sym->etype) = xdata;
-      allocIntoSeg (sym);
-      return;
-    }
-
-  if (SPEC_SCLS (sym->etype) == S_CODE && !sym->_isparm) {
-    SPEC_OCLS (sym->etype) = statsg;
-    allocIntoSeg (sym);
-    return;
-  }
-
-  if (SPEC_SCLS (sym->etype) == S_IDATA)
-    {
-      SPEC_OCLS (sym->etype) = idata;
-      sym->iaccess = 1;
-      allocIntoSeg (sym);
-      return;
-    }
-
-  if (SPEC_SCLS (sym->etype) == S_PDATA)
-    {
-      SPEC_OCLS (sym->etype) = pdata;
-      sym->iaccess = 1;
-      allocIntoSeg (sym);
-      return;
-    }
 
   /* if this is a function then assign code space    */
   if (IS_FUNC (sym->type))
@@ -709,17 +662,6 @@ allocLocal (symbol * sym)
       return;
     }
 
-  /* if this is a  SFR or SBIT */
-  if (SPEC_SCLS (sym->etype) == S_SFR ||
-      SPEC_SCLS (sym->etype) == S_SBIT)
-    {
-      SPEC_OCLS (sym->etype) =
-        (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit);
-
-      allocIntoSeg (sym);
-      return;
-    }
-
   /* if this is a bit variable and no storage class */
   if (SPEC_NOUN (sym->etype) == V_BIT
       && (SPEC_SCLS (sym->etype) == S_BIT))
@@ -736,10 +678,8 @@ allocLocal (symbol * sym)
       return;
     }
 
-  if (SPEC_SCLS (sym->etype) == S_EEPROM)
+  if (allocDefault (sym))
     {
-      SPEC_OCLS (sym->etype) = eeprom;
-      allocIntoSeg (sym);
       return;
     }
 
index fe796ebb42610ae515a405b50d78189337eb7596..91eb064fcfb71ccf79696f64a941cdfd8d4b68b2 100644 (file)
@@ -818,7 +818,7 @@ getSize (sym_link * p)
     case FPOINTER:
     case CPOINTER:
     case FUNCTION:
-      return (FPTRSIZE);
+      return (IFFUNC_BANKED (p) ? GPTRSIZE : FPTRSIZE);
     case GPOINTER:
       return (GPTRSIZE);
 
@@ -1545,13 +1545,14 @@ changePointer (sym_link * p)
 
   /* go thru the chain of declarations   */
   /* if we find a pointer to a function  */
-  /* unconditionally change it to a ptr  */
-  /* to code area                        */
+  /* change it to a ptr to code area     */
+  /* unless the function is banked.      */
   for (; p; p = p->next)
     {
       if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER)
         DCL_TYPE (p) = port->unqualified_pointer;
       if (IS_PTR (p) && IS_FUNC (p->next))
+        if (!IFFUNC_BANKED(p->next))
         DCL_TYPE (p) = CPOINTER;
     }
 }
@@ -1914,6 +1915,16 @@ compareType (sym_link * dest, sym_link * src)
     {
       if (IS_DECL (src))
         {
+          /* banked function pointer */
+          if (IS_GENPTR (dest) && IS_GENPTR (src))
+            {
+              if (IS_FUNC (src->next) && IS_VOID(dest->next))
+                return -1;
+              if (IS_FUNC (dest->next) && IS_VOID(src->next))
+                return -1;
+              return compareType (dest->next, src->next);
+            }
+
           if (DCL_TYPE (src) == DCL_TYPE (dest)) {
             if (IS_FUNC(src)) {
               //checkFunction(src,dest);
index cf8097ea7a94e6ea7606ae5e55fe13b6eae6de1f..4e3340dbe81dd59b997d165ee0b02e0d6fd3ae30 100644 (file)
@@ -380,8 +380,9 @@ extern sym_link *validateLink(sym_link      *l,
 #define IFFUNC_ISOVERLAY(x) (IS_FUNC(x) && FUNC_ISOVERLAY(x))
 
 #define IFFUNC_ISBANKEDCALL(x) (!IFFUNC_NONBANKED(x) && \
-  (options.model == MODEL_LARGE || \
-   options.model == MODEL_MEDIUM || \
+  (options.model == MODEL_HUGE || \
+   ((options.model == MODEL_LARGE || options.model == MODEL_MEDIUM) && \
+   (TARGET_IS_Z80 || TARGET_IS_GBZ80)) || \
   IFFUNC_BANKED(x)))
 
 #define SPEC_NOUN(x) validateLink(x, "SPEC_NOUN", #x, SPECIFIER, __FILE__, __LINE__)->select.s.noun
@@ -432,6 +433,7 @@ extern sym_link *validateLink(sym_link      *l,
 #define IS_FARPTR(x) (IS_DECL(x) && DCL_TYPE(x) == FPOINTER)
 #define IS_CODEPTR(x) (IS_DECL(x) && DCL_TYPE(x) == CPOINTER)
 #define IS_GENPTR(x) (IS_DECL(x) && DCL_TYPE(x) == GPOINTER)
+#define IS_FUNCPTR(x) (IS_DECL(x) && (DCL_TYPE(x) == CPOINTER || DCL_TYPE(x) == GPOINTER) && IS_FUNC(x->next))
 #define IS_FUNC(x)   (IS_DECL(x) && DCL_TYPE(x) == FUNCTION)
 #define IS_LONG(x)   (IS_SPEC(x) && x->select.s._long)
 #define IS_UNSIGNED(x) (IS_SPEC(x) && x->select.s._unsigned)
index 2e1c7cd055b33236e98505adc1d827ee16e2cc88..1e15fd5b32998683319029d086bc342e1d62c877 100644 (file)
@@ -164,10 +164,11 @@ _hc08_genAssemblerPreamble (FILE * of)
   symbol *mainExists=newSymbol("main", 0);
   mainExists->block=0;
 
-  fprintf (of, "\t.area %s\n",port->mem.code_name);
+  fprintf (of, "\t.area %s\n",HOME_NAME);
   fprintf (of, "\t.area GSINIT0 (CODE)\n");
   fprintf (of, "\t.area %s\n",port->mem.static_name);
   fprintf (of, "\t.area %s\n",port->mem.post_static_name);
+  fprintf (of, "\t.area %s\n",CODE_NAME);
   fprintf (of, "\t.area %s\n",port->mem.xinit_name);
   fprintf (of, "\t.area %s\n",port->mem.const_name);
   fprintf (of, "\t.area %s\n",port->mem.data_name);
index 23ac57d78e443298e6de456d2298e930b64cb224..43bd0949fb3dbfe1c61930e949ed88a4d4707b30 100644 (file)
@@ -44,6 +44,7 @@
 #include "gen.h"
 
 char *aopLiteral (value * val, int offset);
+char *aopLiteralLong (value * val, int offset, int size);
 extern int allocInfo;
 
 /* this is the down and dirty file with all kinds of
@@ -598,7 +599,7 @@ aopForSym (iCode * ic, symbol * sym, bool result)
       sym->aop = aop = newAsmop (AOP_IMMD);
       aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (sym->rname) + 1);
       strcpy (aop->aopu.aop_immd.aop_immd1, sym->rname);
-      aop->size = FPTRSIZE;
+      aop->size = getSize (sym->type);
       return aop;
     }
 
@@ -2044,9 +2045,11 @@ pushSide (operand * oper, int size)
           emitcode ("push", "acc");
         }
       else
+        {
           emitcode ("push", "%s", l);
         }
     }
+}
 
 /*-----------------------------------------------------------------*/
 /* assignResultValue - also indicates if acc is in use afterwards  */
@@ -2427,9 +2430,30 @@ genCall (iCode * ic)
   }
 
   /* make the call */
-  emitcode ("lcall", "%s", (OP_SYMBOL (IC_LEFT (ic))->rname[0] ?
-                            OP_SYMBOL (IC_LEFT (ic))->rname :
-                            OP_SYMBOL (IC_LEFT (ic))->name));
+  if (IFFUNC_ISBANKEDCALL (dtype) && !SPEC_STAT(getSpec(dtype)))
+    {
+      if (IFFUNC_CALLEESAVES(dtype))
+        {
+          werror (E_BANKED_WITH_CALLEESAVES);
+        }
+      else
+        {
+          char *l = (OP_SYMBOL (IC_LEFT (ic))->rname[0] ?
+                     OP_SYMBOL (IC_LEFT (ic))->rname :
+                     OP_SYMBOL (IC_LEFT (ic))->name);
+
+          emitcode ("mov", "r0,#%s", l);
+          emitcode ("mov", "r1,#(%s >> 8)", l);
+          emitcode ("mov", "r2,#(%s >> 16)", l);
+          emitcode ("lcall", "__sdcc_banked_call");
+        }
+    }
+  else
+    {
+      emitcode ("lcall", "%s", (OP_SYMBOL (IC_LEFT (ic))->rname[0] ?
+                                OP_SYMBOL (IC_LEFT (ic))->rname :
+                                OP_SYMBOL (IC_LEFT (ic))->name));
+    }
 
   if (swapBanks)
   {
@@ -2510,6 +2534,7 @@ static void
 genPcall (iCode * ic)
 {
   sym_link *dtype;
+  sym_link *etype;
   symbol *rlbl = newiTempLabel (NULL);
 //  bool restoreBank=FALSE;
   bool swapBanks = FALSE;
@@ -2534,37 +2559,121 @@ genPcall (iCode * ic)
       // need caution message to user here
   }
 
-  /* push the return address on to the stack */
-  emitcode ("mov", "a,#%05d$", (rlbl->key + 100));
-  emitcode ("push", "acc");
-  emitcode ("mov", "a,#(%05d$ >> 8)", (rlbl->key + 100));
-  emitcode ("push", "acc");
-
-  /* now push the calling address */
-  aopOp (IC_LEFT (ic), ic, FALSE);
+  etype = getSpec(dtype);
+  if (IS_LITERAL(etype))
+    {
+      /* if send set is not empty then assign */
+      if (_G.sendSet)
+        {
+          genSend(reverseSet(_G.sendSet));
+          _G.sendSet = NULL;
+        }
 
-  pushSide (IC_LEFT (ic), FPTRSIZE);
+      if (swapBanks)
+        {
+          emitcode ("mov", "psw,#0x%02x",
+           ((FUNC_REGBANK(dtype)) << 3) & 0xff);
+        }
 
-  freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+      if (IFFUNC_ISBANKEDCALL (dtype) && !SPEC_STAT(getSpec(dtype)))
+        {
+          if (IFFUNC_CALLEESAVES(dtype))
+            {
+              werror (E_BANKED_WITH_CALLEESAVES);
+            }
+          else
+            {
+              char *l = aopLiteralLong (OP_VALUE (IC_LEFT (ic)), 0, 2);
 
-  /* if send set is not empty the assign */
-  if (_G.sendSet)
-    {
-        genSend(reverseSet(_G.sendSet));
-        _G.sendSet = NULL;
+              emitcode ("mov", "r0,#%s", l);
+              emitcode ("mov", "r1,#(%s >> 8)", l);
+              emitcode ("mov", "r2,#(%s >> 16)", l);
+              emitcode ("lcall", "__sdcc_banked_call");
+            }
+        }
+      else
+        {
+          emitcode ("lcall", "%s", aopLiteralLong (OP_VALUE (IC_LEFT (ic)), 0, 2));
+        }
     }
+  else
+    {
+      if (IFFUNC_ISBANKEDCALL (dtype) && !SPEC_STAT(getSpec(dtype)))
+        {
+          if (IFFUNC_CALLEESAVES(dtype))
+            {
+              werror (E_BANKED_WITH_CALLEESAVES);
+            }
+          else
+            {
+              aopOp (IC_LEFT (ic), ic, FALSE);
 
-  if (swapBanks)
-  {
-        emitcode ("mov", "psw,#0x%02x",
-           ((FUNC_REGBANK(dtype)) << 3) & 0xff);
-  }
+              if (!swapBanks)
+                {
+                  emitcode ("mov", "ar0,%s", aopGet(IC_LEFT (ic), 0, FALSE, FALSE));
+                  emitcode ("mov", "ar1,%s", aopGet(IC_LEFT (ic), 1, FALSE, FALSE));
+                  emitcode ("mov", "ar2,%s", aopGet(IC_LEFT (ic), 2, FALSE, FALSE));
+                }
+              else
+                {
+                  int reg = ((FUNC_REGBANK(dtype)) << 3) & 0xff;
+                  emitcode ("mov", "0x%02x,%s", reg++, aopGet(IC_LEFT (ic), 0, FALSE, FALSE));
+                  emitcode ("mov", "0x%02x,%s", reg++, aopGet(IC_LEFT (ic), 1, FALSE, FALSE));
+                  emitcode ("mov", "0x%02x,%s", reg,   aopGet(IC_LEFT (ic), 2, FALSE, FALSE));
+                }
 
-  /* make the call */
-  emitcode ("ret", "");
-  emitcode ("", "%05d$:", (rlbl->key + 100));
+              freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+
+              /* if send set is not empty then assign */
+              if (_G.sendSet)
+                {
+                  genSend(reverseSet(_G.sendSet));
+                  _G.sendSet = NULL;
+                }
+
+              if (swapBanks)
+                {
+                  emitcode ("mov", "psw,#0x%02x",
+                   ((FUNC_REGBANK(dtype)) << 3) & 0xff);
+                }
+
+              /* make the call */
+              emitcode ("lcall", "__sdcc_banked_call");
+            }
+        }
+      else
+        {
+          /* push the return address on to the stack */
+          emitcode ("mov", "a,#%05d$", (rlbl->key + 100));
+          emitcode ("push", "acc");
+          emitcode ("mov", "a,#(%05d$ >> 8)", (rlbl->key + 100));
+          emitcode ("push", "acc");
+
+          /* now push the calling address */
+          aopOp (IC_LEFT (ic), ic, FALSE);
+
+          pushSide (IC_LEFT (ic), FPTRSIZE);
 
+          freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
 
+          /* if send set is not empty the assign */
+          if (_G.sendSet)
+            {
+              genSend(reverseSet(_G.sendSet));
+              _G.sendSet = NULL;
+            }
+
+          if (swapBanks)
+            {
+              emitcode ("mov", "psw,#0x%02x",
+               ((FUNC_REGBANK(dtype)) << 3) & 0xff);
+            }
+
+          /* make the call */
+          emitcode ("ret", "");
+          emitcode ("", "%05d$:", (rlbl->key + 100));
+        }
+    }
   if (swapBanks)
   {
        emitcode ("mov", "psw,#0x%02x",
@@ -3256,7 +3365,14 @@ genEndFunction (iCode * ic)
           debugFile->writeEndFunction (currFunc, ic, 1);
         }
 
-      emitcode ("ret", "");
+      if (IFFUNC_ISBANKEDCALL (sym->type) && !SPEC_STAT(getSpec(sym->type)))
+        {
+          emitcode ("ljmp", "__sdcc_banked_ret");
+        }
+      else
+        {
+          emitcode ("ret", "");
+        }
     }
 
   if (!port->peep.getRegsRead || !port->peep.getRegsWritten || options.nopeep)
@@ -3486,10 +3602,7 @@ genPlusIncr (iCode * ic)
   if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
     return FALSE;
 
-  /* if the literal value of the right hand side
-     is greater than 4 then it is not worth it */
-  if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
-    return FALSE;
+  icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit);
 
   D(emitcode (";     genPlusIncr",""));
 
@@ -3596,6 +3709,11 @@ genPlusIncr (iCode * ic)
       return TRUE;
     }
 
+  /* if the literal value of the right hand side
+     is greater than 4 then it is not worth it */
+  if (icount > 4)
+    return FALSE;
+
   /* if the sizes are greater than 1 then we cannot */
   if (AOP_SIZE (IC_RESULT (ic)) > 1 ||
       AOP_SIZE (IC_LEFT (ic)) > 1)
index 61ca32eda749b51b77c0f69f041a85f273d99035..bed2b95e289917882d66857bff613c8f5617ecd5 100644 (file)
@@ -19,6 +19,7 @@ static char _defaultRules[] =
 static char *_mcs51_keywords[] =
 {
   "at",
+  "banked",
   "bit",
   "code",
   "critical",
@@ -181,13 +182,16 @@ _mcs51_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
 static void
 _mcs51_genExtraAreas(FILE *of, bool hasMain)
 {
-  tfprintf (of, "\t!area\n", port->mem.code_name);
+  tfprintf (of, "\t!area\n", HOME_NAME);
   tfprintf (of, "\t!area\n", "GSINIT0 (CODE)");
   tfprintf (of, "\t!area\n", "GSINIT1 (CODE)");
   tfprintf (of, "\t!area\n", "GSINIT2 (CODE)");
   tfprintf (of, "\t!area\n", "GSINIT3 (CODE)");
   tfprintf (of, "\t!area\n", "GSINIT4 (CODE)");
   tfprintf (of, "\t!area\n", "GSINIT5 (CODE)");
+  tfprintf (of, "\t!area\n", STATIC_NAME);
+  tfprintf (of, "\t!area\n", port->mem.post_static_name);
+  tfprintf (of, "\t!area\n", CODE_NAME);
 }
 
 static void
index 93cd49653647a2fef57690b2dace6080e12a76d9..19548189fe670d7b3174a173b882b61ea0a328f4 100644 (file)
@@ -418,6 +418,8 @@ struct
    "ISR function attribute 'shadowregs' following non-ISR function '%s'" },
 { W_SFR_ABSRANGE, ERROR_LEVEL_WARNING,
    "absolute address for sfr '%s' probably out of range." },
+{ E_BANKED_WITH_CALLEESAVES, ERROR_LEVEL_ERROR,
+   "Both banked and callee-saves cannot be used together." },
 };
 
 /*
index df65977642f7d82e2c0d3b8cb90d201ac8f3a455..8d7e29562db5333b22cdb43a50ae96f26031fc6e 100644 (file)
@@ -198,6 +198,7 @@ SDCCERR - SDCC Standard error handler
 #define W_COMPLEMENT                  180 /* ~bit can give unexpected results */
 #define E_SHADOWREGS_NO_ISR           181 /* shadowregs keyword following non-ISR function */
 #define W_SFR_ABSRANGE                182 /* sfr at address out of range */
+#define E_BANKED_WITH_CALLEESAVES     183 /* banked and callee-saves mixed */
 
 #define MAX_ERROR_WARNING             256 /* size of disable warnings array */