* src/*.c, src/pic16/{gen.c,glue.c,main.c}: applied Vangelis
[fw/sdcc] / src / pic16 / main.c
index 606eea417a79be65a18493b63ab09a2b68861d7d..4eb914b6369877b60d7b3e94db321afa5fb24747 100644 (file)
@@ -62,6 +62,7 @@ static char *_pic16_keywords[] =
   "_naked",
   "shadowregs",
   "wparam",
+  "fixed16x16",
   
 //  "bit",
 //  "idata",
@@ -80,7 +81,7 @@ extern char *pic16_processor_base_name(void);
 
 void  pic16_pCodeInitRegisters(void);
 
-void pic16_assignRegisters (eBBlock ** ebbs, int count);
+void pic16_assignRegisters (ebbIndex *);
 
 static int regParmFlg = 0;     /* determine if we can register a parameter */
 
@@ -140,7 +141,11 @@ set *sectNames=NULL;                       /* list of section listed in pragma directives */
 set *sectSyms=NULL;                    /* list of symbols set in a specific section */
 set *wparamList=NULL;
 
+#if 0
+/* This is an experimental code for #pragma inline
+   and is temporarily disabled for 2.5.0 release */
 set *asmInlineMap=NULL;
+#endif  /* 0 */
 
 struct {
   unsigned ignore: 1;
@@ -183,6 +188,12 @@ _process_pragma(const char *sz)
     regs *reg;
     symbol *sym;
 
+      if (!stackPosS) {
+        fprintf (stderr, "%s:%d: #pragma stack [stack-pos] [stack-length] -- stack-position missing\n", filename, lineno-1);
+
+        return 0; /* considered an error */
+      }
+
       stackPosVal = constVal( stackPosS );
       stackPos = (unsigned int)floatFromVal( stackPosVal );
 
@@ -200,7 +211,32 @@ _process_pragma(const char *sz)
       }
 
 //      fprintf(stderr, "Initializing stack pointer at 0x%x len 0x%x\n", stackPos, stackLen);
-        
+
+      /* check sanity of stack */
+      if ((stackPos >> 8) != ((stackPos+stackLen) >> 8)) {
+        fprintf (stderr, "%s:%u: warning: stack [0x%03X,0x%03X] crosses memory bank boundaries (not fully tested)\n",
+               filename,lineno-1, stackPos, stackPos+stackLen-1);
+      }
+
+      if (pic16) {
+        if (stackPos < pic16->acsSplitOfs) {
+          fprintf (stderr, "%s:%u: warning: stack [0x%03X, 0x%03X] intersects with the access bank [0x000,0x%03x] -- this is highly discouraged!\n",
+               filename, lineno-1, stackPos, stackPos+stackLen-1, pic16->acsSplitOfs);
+        }
+
+        if (stackPos+stackLen > 0xF00 + pic16->acsSplitOfs) {
+          fprintf (stderr, "%s:%u: warning: stack [0x%03X,0x%03X] intersects with special function registers [0x%03X,0xFFF]-- this is highly discouraged!\n",
+               filename, lineno-1, stackPos, stackPos+stackLen-1, 0xF00 + pic16->acsSplitOfs);
+        }
+
+        if (stackPos+stackLen > pic16->RAMsize) {
+          fprintf (stderr, "%s:%u: error: stack [0x%03X,0x%03X] is placed outside available memory [0x000,0x%03X]!\n",
+               filename, lineno-1, stackPos, stackPos+stackLen-1, pic16->RAMsize-1);
+          exit(-1);
+          return 1;    /* considered an error, but this reports "invalid pragma stack"... */
+        }
+      }
+
       reg=newReg(REG_SFR, PO_SFR_REGISTER, stackPos, "_stack", stackLen-1, 0, NULL);
       addSet(&pic16_fix_udata, reg);
     
@@ -227,6 +263,12 @@ _process_pragma(const char *sz)
     absSym *absS;
     value *addr;
 
+      if (!symname || !location) {
+        fprintf (stderr, "%s:%d: #pragma code [symbol] [location] -- symbol or location missing\n", filename, lineno-1);
+       exit (-1);
+        return 1; /* considered an error, but this reports "invalid pragma code"... */
+      }
+
       absS = Safe_calloc(1, sizeof(absSym));
       sprintf(absS->name, "_%s", symname);
     
@@ -255,10 +297,16 @@ _process_pragma(const char *sz)
     sectName *snam;
     int found=0;
     
+      if (!symname || !sectname) {
+        fprintf (stderr, "%s:%d: #pragma udata [section-name] [symbol] -- section-name or symbol missing!\n", filename, lineno-1);
+       exit (-1);
+        return 1; /* considered an error, but this reports "invalid pragma code"... */
+      }
+    
       while(symname) {
         ssym = Safe_calloc(1, sizeof(sectSym));
         ssym->name = Safe_calloc(1, strlen(symname)+2);
-        sprintf(ssym->name, "_%s", symname);
+        sprintf(ssym->name, "%s%s", port->fun_prefix, symname);
         ssym->reg = NULL;
 
         addSet(&sectSyms, ssym);
@@ -339,7 +387,10 @@ _process_pragma(const char *sz)
     
     return 0;
   }
-      
+   
+#if 0
+  /* This is an experimental code for #pragma inline
+     and is temporarily disabled for 2.5.0 release */
   if(startsWith(ptr, "inline")) {
     char *tmp = strtok((char *)NULL, WHITECOMMA);
 
@@ -358,7 +409,8 @@ _process_pragma(const char *sz)
       
       return 0;
   }
-  
+#endif  /* 0 */
+
   return 1;
 }
 
@@ -381,6 +433,7 @@ _process_pragma(const char *sz)
 
 #define OPTIMIZE_GOTO   "--optimize-goto"
 #define        OPTIMIZE_CMP    "--optimize-cmp"
+#define        OPTIMIZE_DF     "--optimize-df"
 
 char *alt_asm=NULL;
 char *alt_link=NULL;
@@ -423,6 +476,7 @@ OPTION pic16_optionsTable[]= {
        { 0,    "--gstack",     &pic16_options.gstack,  "trace stack pointer push/pop to overflow"},
        { 0,    OPTIMIZE_GOTO,  NULL,                   "try to use (conditional) BRA instead of GOTO"},
        { 0,    OPTIMIZE_CMP,   NULL,                   "try to optimize some compares"},
+       { 0,    OPTIMIZE_DF,    NULL,                   "thoroughly analyze data flow (memory and time intensive!)"},
        { 0,    NULL,           NULL,   NULL}
        };
 
@@ -524,6 +578,11 @@ _pic16_parseOptions (int *pargc, char **argv, int *i)
       pic16_options.opt_flags |= OF_OPTIMIZE_CMP;
       return TRUE;
     }
+
+    if (ISOPT(OPTIMIZE_DF)) {
+      pic16_options.opt_flags |= OF_OPTIMIZE_DF;
+      return TRUE;
+    }
     
 
   return FALSE;
@@ -694,12 +753,11 @@ _pic16_finaliseOptions (void)
     {
       char buf[128];
 
-        sprintf(buf, "-D%s -D%s", pic16->name[2], pic16->name[1]);
+        sprintf(buf, "-D%s -D__%s", pic16->name[2], pic16->name[1]);
         *(strrchr(buf, 'f')) = 'F';
         addSet(&asmOptionsSet, Safe_strdup( buf ));
     }
     
-    
     if(STACK_MODEL_LARGE) {
       addSet(&preArgvSet, Safe_strdup("-DSTACK_MODEL_LARGE"));
       addSet(&asmOptionsSet, Safe_strdup("-DSTACK_MODEL_LARGE"));
@@ -1021,6 +1079,7 @@ PORT pic16_port =
     "HOME    (CODE)",  // home
     NULL,                      // xidata
     NULL,                      // xinit
+    "CONST   (CODE)",          // const_name - const data (code or not)
     NULL,                      // default location for auto vars
     NULL,                      // default location for global vars
     1                          // code is read only 1=yes