First pass at DS80C390 flat mode support
authorkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 9 Feb 2000 18:09:01 +0000 (18:09 +0000)
committerkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 9 Feb 2000 18:09:01 +0000 (18:09 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@91 4a8a32a2-be11-0410-ad9d-d568d2c75423

12 files changed:
device/lib/incl.mk
src/SDCCerr.c
src/SDCCerr.h
src/SDCCglobl.h
src/SDCCglue.c
src/SDCCmain.c
src/common.h
src/mcs51/gen.c
src/mcs51/main.c
src/mcs51/ralloc.c
src/port.h
src/z80/main.c

index e1cae0c347af586690f72e6d8571582801c0e730..18caa5eb5b34e21b08cdde7b33d9a792e87a673e 100644 (file)
@@ -1 +1 @@
-MODELS         = small large
+MODELS         = small large flat24
index de85badcc56a948b859febc7eaf89fe713bf1eac..61f0b5e4e4fd1ad70e29e59b104bdbdadf558327 100644 (file)
@@ -142,7 +142,8 @@ struct  {
 { WARNING,"warning *** unreachable code %s(%d)\n"},
 { WARNING,"warning *** non-pointer type cast to _generic pointer\n"},
 { WARNING,"warning *** possible code generation error at line %d,\n send source to sandeep.dutta@usa.net\n"},
-{ WARNING,"warning *** pointer types incompatible \n" }
+{ WARNING,"warning *** pointer types incompatible \n" },
+{ WARNING,"warning *** unknown memory model at %s : %d\n" },
 };
 
 /****************************************************************************/
index 61207652a82f2d8ee7d3cc2e5c313f79f5bfb5da..136d7a5f054838c37be60de9ec1320e7c1f70937 100644 (file)
 #define  W_NONPTR2_GENPTR   127         /* non pointer cast to generic pointer */
 #define  W_POSSBUG          128         /* possible code generation error */
 #define  W_PTR_ASSIGN       129         /* incampatible pointer assignment */
+#define  W_UNKNOWN_MODEL    130                /* Unknown memory model */
 void werror(int, ...);
index 4b9e21cc4cbb511b2daf9377cd46ab623ba74834..3f0c4bddba4ddcc8d9e4eb34aec5b123b6da06f3 100644 (file)
@@ -163,9 +163,14 @@ struct optimize {
     unsigned    noLoopReverse :1;
 } ;
 
+/* Values for options.model. */
+#define MODEL_SMALL    0
+#define MODEL_LARGE    1
+#define MODEL_FLAT24   2
+
 /* other command line options */
 struct options {
-    int model  : 1     ; /* LARGE == 1 */
+    int model  : 3     ; /* see MODEL_* defines above */
     int stackAuto : 3  ; /* Stack Automatic  */
     int useXstack : 3  ; /* use Xternal Stack */
     int genericPtr: 1  ; /* use generic pointers */
index 22db18f9080f7104ded458951d28190f6eab27f9..131a958fb176ae8a76f249a9e053c853a6b212e4 100644 (file)
@@ -30,6 +30,8 @@ symbol *interrupts[256];
 void printIval (symbol *, link *, initList *, FILE *);
 extern int noAlloc;
 set *publics = NULL;           /* public variables */
+
+/* TODO: this should be configurable (DS803C90 uses more than 6) */
 int maxInterrupts = 6;
 extern int maxRegBank ;
 symbol *mainf;
@@ -719,16 +721,25 @@ void createInterruptVect (FILE * vFile)
     
     fprintf (vFile, "\t.area\t%s\n", CODE_NAME);
     fprintf (vFile, "__interrupt_vect:\n");
+
     
-    fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n");
+    if (!port->genIVT || ! (port->genIVT(vFile, interrupts, maxInterrupts)))
+    {
+        /* "generic" interrupt table header (if port doesn't specify one).
+         *
+         * Look suspiciously like 8051 code to me...
+         */
     
+       fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n");
     
-    /* now for the other interrupts */
-    for (; i < maxInterrupts; i++) {
-       if (interrupts[i])
-           fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
-       else
-           fprintf (vFile, "\treti\n\t.ds\t7\n");
+    
+       /* now for the other interrupts */
+       for (; i < maxInterrupts; i++) {
+               if (interrupts[i])
+                       fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
+               else
+                       fprintf (vFile, "\treti\n\t.ds\t7\n");
+       }
     }
 }
 
@@ -902,6 +913,12 @@ void glue ()
     /* print module name */
     fprintf (asmFile, "\t.module %s\n", moduleName);
     
+    /* Let the port generate any global directives, etc. */
+    if (port->genAssemblerPreamble)
+    {
+       port->genAssemblerPreamble(asmFile);
+    }
+    
     /* print the global variables in this module */
     printPublics (asmFile);
 
index 12d340dad22a6450ebb45e738899dcf584493f96..65ddc3c4b582a5d4274b18838a3e2c7ea318223d 100644 (file)
@@ -71,6 +71,7 @@ char    *preOutName;
 
 #define OPTION_LARGE_MODEL "-model-large"
 #define OPTION_SMALL_MODEL "-model-small"
+#define OPTION_FLAT24_MODEL "-model-flat24"
 #define OPTION_STACK_AUTO  "-stack-auto"
 #define OPTION_XSTACK      "-xstack"
 #define OPTION_GENERIC     "-generic"
@@ -296,8 +297,8 @@ static void setDefaultOptions()
     int i ;
 
     for ( i = 0 ; i < 128 ; i++)
-       preArgv[i] = linkOptions [i] =
-           asmOptions[i] = relFiles[i] = libFiles[i] =
+       preArgv[i] = asmOptions [i] =
+           linkOptions[i] = relFiles[i] = libFiles[i] =
            libPaths[i] = NULL ;
 
     /* first the options part */
@@ -439,14 +440,19 @@ int   parseCmdLine ( int argc, char **argv )
            }
 
            if (strcmp(&argv[i][1],OPTION_LARGE_MODEL) == 0) {
-               options.model = 1;
+               options.model = MODEL_LARGE;
                 continue;
            }
            
            if (strcmp(&argv[i][1],OPTION_SMALL_MODEL) == 0) {
-               options.model = 0;
+               options.model = MODEL_SMALL;
                 continue;
            }
+           
+           if (strcmp(&argv[i][1],OPTION_FLAT24_MODEL) == 0) {
+               options.model = MODEL_FLAT24;
+                continue;
+           }       
 
            if (strcmp(&argv[i][1],OPTION_STACK_AUTO) == 0) {
                options.stackAuto = 1;
@@ -716,8 +722,14 @@ int   parseCmdLine ( int argc, char **argv )
                 continue;
            }
 
-           if (!port->parseOption(&argc, argv))
+           if (!port->parseOption(&argc, argv, &i))
+           {
                werror(W_UNKNOWN_OPTION,argv[i]);
+           }
+           else
+           {
+               continue;
+           }
        }      
 
        /* these are undocumented options */
@@ -904,13 +916,13 @@ int   parseCmdLine ( int argc, char **argv )
                break ;
 
            default:
-               if (!port->parseOption(&argc, argv))
+               if (!port->parseOption(&argc, argv, &i))
                    werror(W_UNKNOWN_OPTION,argv[i]);
            }
            continue ;
        }
 
-       if (!port->parseOption(&argc, argv)) {
+       if (!port->parseOption(&argc, argv, &i)) {
            /* no option must be a filename */
            processFile(argv[i]);
        }
@@ -979,6 +991,7 @@ static void linkEdit (char **envp)
 {
     FILE *lnkfile ;
     char *argv[128];
+    char *segName, *c;
 
     int i;
     if (!srcFileName)
@@ -1000,24 +1013,50 @@ static void linkEdit (char **envp)
     
     /*if (options.debug) */
     fprintf(lnkfile,"-z\n");
+
+#define WRITE_SEG_LOC(N, L) \
+    segName = strdup(N); \
+    c = strtok(segName, " \t"); \
+    fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
+    if (segName) { free(segName); } 
+    
     /* code segment start */
-    fprintf (lnkfile,"-b CODE = 0x%04x\n",options.code_loc);
-    /* data segment start */
-    fprintf (lnkfile,"-b DSEG = 0x%04x\n",options.data_loc);
+    WRITE_SEG_LOC(CODE_NAME, options.code_loc);
+    
+     /* data segment start */
+     WRITE_SEG_LOC(DATA_NAME, options.data_loc);
+                 
     /* xdata start */
-    fprintf (lnkfile,"-b XSEG = 0x%04x\n",options.xdata_loc);
+    WRITE_SEG_LOC(XDATA_NAME, options. xdata_loc);
+
     /* indirect data */
-    fprintf (lnkfile,"-b ISEG = 0x%04x\n",options.idata_loc);
+    WRITE_SEG_LOC(IDATA_NAME, options.idata_loc);
+
     /* bit segment start */
-    fprintf (lnkfile,"-b BSEG = 0x%04x\n",0);
+    WRITE_SEG_LOC(BIT_NAME, 0);
     
     /* add the extra linker options */
     for (i=0; linkOptions[i] ; i++)
        fprintf(lnkfile,"%s\n",linkOptions[i]);
 
     /* standard library path */
-    fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,
-            ( (options.model==0) ? "small": "large"));
+    switch(options.model)
+    {
+        case MODEL_SMALL:
+                   c = "small";
+                   break;
+               case MODEL_LARGE:
+                   c = "large";
+                   break;
+               case MODEL_FLAT24:
+                   c = "flat24";
+                   break;
+        default:
+            werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
+            c = "unknown";
+            break;
+    }
+    fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
            
     /* other library paths if specified */
     for (i = 0 ; i < nlibPaths ; i++ )
@@ -1096,10 +1135,22 @@ static int preProcess (char **envp)
        _addToList(preArgv, "-DSDCC_STACK_AUTO");
     
     /* set the macro for large model   */
-    if ( options.model )
-       _addToList(preArgv, "-DSDCC_MODEL_LARGE");
-    else
-       _addToList(preArgv, "-DSDCC_MODEL_SMALL");
+    switch(options.model)
+    {
+        case MODEL_LARGE:
+           _addToList(preArgv, "-DSDCC_MODEL_LARGE");
+           break;
+       case MODEL_SMALL:
+           _addToList(preArgv, "-DSDCC_MODEL_SMALL");
+           break;
+       case MODEL_FLAT24:
+           _addToList(preArgv, "-DSDCC_MODEL_FLAT24");
+           break;
+       default:
+           werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
+           break;
+    }      
+           
     
     /* add port (processor information to processor */
     sprintf(procDef,"-DSDCC_%s",port->target);
index 30872eae1dcbd1922ca795c874faea1e9635908b..ea5ac522f587ddccecd84c3304555b195b701456 100644 (file)
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
+#include <string.h>
 #include <assert.h>
 
 #include "SDCCglobl.h"
index 47758e7093341de3988b0f64070803b820be764b..6f3190ff23142cea7592d74e77c72a467679af5a 100644 (file)
@@ -145,8 +145,9 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
     instruction, in which case we are in trouble */
     if ((r0iu = bitVectBitValue(ic->rUsed,R0_IDX)) &&
         (r1iu = bitVectBitValue(ic->rUsed,R1_IDX))) 
+    {
         goto endOfWorld;      
-
+    }
 
     r0ou = bitVectBitValue(ic->rMask,R0_IDX);
     r1ou = bitVectBitValue(ic->rMask,R1_IDX);
@@ -155,6 +156,7 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
     if (!r0iu && !r0ou) {
         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
         (*aopp)->type = AOP_R0;
+        
         return (*aopp)->aopu.aop_ptr = mcs51_regWithIdx(R0_IDX);
     }
 
@@ -162,6 +164,7 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
     if (!r1iu && !r1ou) {
         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
         (*aopp)->type = AOP_R1;
+
         return (*aopp)->aopu.aop_ptr = mcs51_regWithIdx(R1_IDX);
     }    
 
@@ -174,7 +177,7 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
                       mcs51_regWithIdx(R0_IDX)->dname);
             _G.r0Pushed++ ;
         }
-
+        
         ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX);
         (*aopp)->type = AOP_R0;
 
@@ -190,16 +193,15 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result)
                       mcs51_regWithIdx(R1_IDX)->dname);
             _G.r1Pushed++ ;
         }
-
+        
         ic->rUsed = bitVectSetBit(ic->rUsed,R1_IDX);
         (*aopp)->type = AOP_R1;
         return mcs51_regWithIdx(R1_IDX);
     }
 
-
 endOfWorld :
     /* I said end of world but not quite end of world yet */
-    /* if this is a result then we canpush it on the stack*/
+    /* if this is a result then we can push it on the stack*/
     if (result) {
         (*aopp)->type = AOP_STK;    
         return NULL;
@@ -1904,7 +1906,8 @@ static void genFunction (iCode *ic)
            emitcode ("push","dpl");
        if (!inExcludeList("dph"))
            emitcode ("push","dph");
-       
+       if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
+           emitcode ("push", "dpx");   
        /* if this isr has no bank i.e. is going to
           run with bank 0 , then we need to save more
           registers :-) */
@@ -2068,6 +2071,8 @@ static void genEndFunction (iCode *ic)
            }       
        }
 
+       if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
+           emitcode ("pop", "dpx");
        if (!inExcludeList("dph"))
            emitcode ("pop","dph");
        if (!inExcludeList("dpl"))
@@ -5910,6 +5915,10 @@ static void genFarPointerGet (operand *left,
         else { /* we need to get it byte by byte */
             emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
             emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
+            if (options.model == MODEL_FLAT24)
+            {
+               emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
+            }
         }
     }
     /* so dptr know contains the address */
@@ -5954,6 +5963,10 @@ static void emitcodePointerGet (operand *left,
         else { /* we need to get it byte by byte */
             emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
             emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
+            if (options.model == MODEL_FLAT24)
+            {
+               emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
+            }
         }
     }
     /* so dptr know contains the address */
@@ -6001,7 +6014,15 @@ static void genGenPointerGet (operand *left,
         else { /* we need to get it byte by byte */
             emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE));
             emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE));
-            emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
+            if (options.model == MODEL_FLAT24)
+            {
+               emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE));
+               emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE));
+            }
+            else
+            {
+               emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE));
+            }
         }
     }
     /* so dptr know contains the address */
@@ -6463,6 +6484,10 @@ static void genFarPointerSet (operand *right,
         else { /* we need to get it byte by byte */
             emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
             emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
+            if (options.model == MODEL_FLAT24)
+            {
+               emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
+            }
         }
     }
     /* so dptr know contains the address */
@@ -6510,7 +6535,15 @@ static void genGenPointerSet (operand *right,
         else { /* we need to get it byte by byte */
             emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE));
             emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE));
-            emitcode("mov","b,%s",aopGet(AOP(result),2,FALSE,FALSE));
+            if (options.model == MODEL_FLAT24)
+            {
+               emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE));
+               emitcode("mov","b,%s",aopGet(AOP(result),3,FALSE,FALSE));
+            }
+            else
+            {
+               emitcode("mov","b,%s",aopGet(AOP(result),2,FALSE,FALSE));
+            }
         }
     }
     /* so dptr know contains the address */
@@ -6928,7 +6961,7 @@ static void genCast (iCode *ic)
                }
                
                /* the first two bytes are known */
-               size = 2;
+               size = GPTRSIZE - 1; 
                offset = 0 ;
                while (size--) {
                        aopPut(AOP(result),
@@ -6958,7 +6991,7 @@ static void genCast (iCode *ic)
                               "got unknown pointer type");
                        exit(1);
                }
-               aopPut(AOP(result),l,2);            
+               aopPut(AOP(result),l, GPTRSIZE - 1);        
                goto release ;
        }
        
index 1e487e928b6c131fe759556aba66be381b5381b2..2f22fd76d0c61fcaad3f69e0a8742bcf64a08513 100644 (file)
@@ -38,17 +38,28 @@ static char *_mcs51_keywords[] =     {
 
 void mcs51_assignRegisters (eBBlock **ebbs, int count);
 
-static bool _mcs51_parseOptions(int *pargc, char **argv)
+static bool _mcs51_parseOptions(int *pargc, char **argv, int *i)
 {
+    /* TODO: allow port-specific command line options to specify
+     * segment names here.
+     */
     return FALSE;
 }
 
 static void _mcs51_finaliseOptions(void)
 {
+    /* Hack-o-matic: if we are using the flat24 model,
+     * adjust pointer sizes.
+     */
+    if (options.model == MODEL_FLAT24)
+    {
+        port->s.fptr_size = 3;
+        port->s.gptr_size = 4;
+    } 
 }
 
 static void _mcs51_setDefaultOptions(void)
-{    
+{
 }
 
 static const char *_mcs51_getRegName(struct regs *reg)
@@ -58,6 +69,45 @@ static const char *_mcs51_getRegName(struct regs *reg)
     return "err";
 }
 
+static void _mcs51_genAssemblerPreamble(FILE *of)
+{
+   if (options.model == MODEL_FLAT24)
+   {
+       fputs(".flat24 on\t\t; 24 bit flat addressing\n", of);
+       fputs("dpx = 0x93\t\t; dpx register unknown to assembler\n", of);
+
+   }
+}
+
+/* Generate interrupt vector table. */
+static int _mcs51_genIVT(FILE *of, symbol **interrupts, int maxInterrupts)
+{
+    int i;
+    
+    if (options.model != MODEL_FLAT24)
+    {
+        /* Let the default code handle it. */
+       return FALSE;
+    }
+    
+    fprintf (of, "\tajmp\t__sdcc_gsinit_startup\n");
+    
+    /* now for the other interrupts */
+    for (i = 0; i < maxInterrupts; i++) 
+    {
+       if (interrupts[i])
+       {
+           fprintf(of, "\tljmp\t%s\n\t.ds\t4\n", interrupts[i]->rname);
+       }
+       else
+       {
+           fprintf(of, "\treti\n\t.ds\t7\n");
+       }
+    }
+    
+    return TRUE;
+}
+
 /** $1 is always the basename.
     $2 is always the output file.
     $3 varies
@@ -112,6 +162,8 @@ PORT mcs51_port = {
     _mcs51_setDefaultOptions,
     mcs51_assignRegisters,
     _mcs51_getRegName ,
-    _mcs51_keywords
-
+    _mcs51_keywords,
+    _mcs51_genAssemblerPreamble,
+    _mcs51_genIVT
 };
+
index 931179053d48f138e7cee0ff793918a98e7c288d..11d2216b9f075b1dfb669329fdd0675c0dbd2467 100644 (file)
@@ -768,7 +768,7 @@ static regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym)
     if (!mcs51_ptrRegReq)
        if ((reg = allocReg(REG_PTR)))
            return reg ;
-
+       
     /* we have to spil */
     if (!spilSomething (ic,ebp,sym))
        return NULL ;
@@ -1069,7 +1069,9 @@ static void serialRegAssign (eBBlock **ebbs, int count)
                
                /* if we need ptr regs for the right side
                   then mark it */
-               if (POINTER_GET(ic) && getSize(OP_SYMBOL(IC_LEFT(ic))->type) < 2) {
+               if (POINTER_GET(ic) && getSize(OP_SYMBOL(IC_LEFT(ic))->type) 
+                   <= PTRSIZE) 
+               {
                    mcs51_ptrRegReq++;
                    ptrRegSet = 1;
                }
index 87c6a90537d5669b758b767ef66abe3a294c61d6..6c9983720dc69cb4f6d3bfca139a6855f8448d66 100644 (file)
@@ -79,7 +79,7 @@ typedef struct {
     } muldiv;
 
     /** Parses one option + its arguments */
-    bool (*parseOption)(int *pargc, char **argv);
+    bool (*parseOption)(int *pargc, char **argv, int *i);
     /** Called after all the options have been parsed. */
     void (*finaliseOptions)(void);
     /** Called after the port has been selected but before any
@@ -95,6 +95,15 @@ typedef struct {
     /* list of keywords that are used by this
        target (used by lexer) */
     char **keywords; 
+    
+    /* Write any port specific assembler output. */
+    void (*genAssemblerPreamble)(FILE *of);
+    
+    /* Write the port specific IVT. If genIVT is NULL or if
+     * it returns zero, default (8051) IVT generation code
+     * will be used. 
+     */
+    int (*genIVT)(FILE *of, symbol **intTable, int intCount); 
 } PORT;
 
 extern PORT *port;
index 9bd1d14c9d25f539537063f2d0a28b59de6ecb45..c508a6baf3811d0cf6ff17686a491fea6c308bed 100644 (file)
@@ -5,7 +5,7 @@ static char *_z80_keywords[] = { NULL };
 
 void z80_assignRegisters (eBBlock **ebbs, int count);
 
-static bool _z80_parseOptions(int *pargc, char **argv)
+static bool _z80_parseOptions(int *pargc, char **argv, int *i)
 {
     return FALSE;
 }
@@ -95,6 +95,8 @@ PORT z80_port = {
     _z80_setDefaultOptions,
     z80_assignRegisters,
     _z80_getRegName,
-    _z80_keywords
+    _z80_keywords,
+    0, /* no assembler preamble */
+    0, /* no local IVT generation code */
 };