* src/SDCCcse.c (algebraicOpts): fix bug converting op from value to type
[fw/sdcc] / src / SDCCsymt.c
index a2c11a2aeb0635bd50685bab88e101ae311714a7..7b3b6f584df7c4e99041aa8523d06b735667f87a 100644 (file)
@@ -290,7 +290,7 @@ newSymbol (char *name, int scope)
   strncpyz (sym->name, name, sizeof(sym->name));       /* copy the name */
   sym->level = scope;          /* set the level    */
   sym->block = currBlockno;
-  sym->lineDef = yylineno;     /* set the line number */
+  sym->lineDef = mylineno;     /* set the line number */
   return sym;
 }
 
@@ -348,6 +348,8 @@ pointerTypes (sym_link * ptr, sym_link * type)
      storage class of the type */
   if (IS_SPEC (type))
     {
+      DCL_PTR_CONST (ptr) = SPEC_CONST (type);
+      DCL_PTR_VOLATILE (ptr) = SPEC_VOLATILE (type);
       switch (SPEC_SCLS (type))
        {
        case S_XDATA:
@@ -363,6 +365,7 @@ pointerTypes (sym_link * ptr, sym_link * type)
          DCL_TYPE (ptr) = POINTER;
          break;
        case S_CODE:
+         DCL_PTR_CONST (ptr) = port->mem.code_ro;
          DCL_TYPE (ptr) = CPOINTER;
          break;
        case S_EEPROM:
@@ -373,7 +376,7 @@ pointerTypes (sym_link * ptr, sym_link * type)
          break;
        }
       /* the storage class of type ends here */
-      SPEC_SCLS (type) =
+      SPEC_SCLS (type) = 
        SPEC_CONST (type) =
        SPEC_VOLATILE (type) = 0;
     }
@@ -455,25 +458,21 @@ addDecl (symbol * sym, int type, sym_link * p)
     }
 
   /* if the type is an unknown pointer and has
-     a tspec then take the const & volatile
+     a tspec then take the storage class const & volatile
      attribute from the tspec & make it those of this
      symbol */
-
   if (p &&
-      IS_DECL (p) &&
-      DCL_TYPE (p) == UPOINTER &&
+      !IS_SPEC (p) &&
+      //DCL_TYPE (p) == UPOINTER &&
       DCL_TSPEC (p))
     {
-      // only for declarators
-      wassert (IS_DECL(sym->type));
-
       if (!IS_SPEC (sym->etype))
        {
          sym->etype = sym->etype->next = newLink (SPECIFIER);
        }
-      
-      DCL_PTR_CONST (sym->type) = SPEC_CONST (DCL_TSPEC (p));
-      DCL_PTR_VOLATILE (sym->type) = SPEC_VOLATILE (DCL_TSPEC (p));
+      SPEC_SCLS (sym->etype) = SPEC_SCLS (DCL_TSPEC (p));
+      SPEC_CONST (sym->etype) = SPEC_CONST (DCL_TSPEC (p));
+      SPEC_VOLATILE (sym->etype) = SPEC_VOLATILE (DCL_TSPEC (p));
       DCL_TSPEC (p) = NULL;
     }
 
@@ -558,8 +557,6 @@ void checkTypeSanity(sym_link *etype, char *name) {
 sym_link *
 mergeSpec (sym_link * dest, sym_link * src, char *name)
 {
-  sym_link *symlink=dest;
-
   if (!IS_SPEC(dest) || !IS_SPEC(src)) {
 #if 0
     werror (E_INTERNAL_ERROR, __FILE__, __LINE__, "cannot merge declarator");
@@ -643,7 +640,7 @@ mergeSpec (sym_link * dest, sym_link * src, char *name)
   FUNC_INTNO(dest) |= FUNC_INTNO(src);
   FUNC_REGBANK(dest) |= FUNC_REGBANK(src);
 
-  return symlink;
+  return dest;
 }
 
 /*------------------------------------------------------------------*/
@@ -1137,29 +1134,19 @@ checkSClass (symbol * sym, int isProto)
   if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
     SPEC_SCLS (sym->etype) = S_AUTO;
   
-  /* if sfr or sbit then must also be */
-  /* volatile the initial value will be xlated */
-  /* to an absolute address */
+  /* if sfr or sbit then must also be volatile */
   if (SPEC_SCLS (sym->etype) == S_SBIT ||
       SPEC_SCLS (sym->etype) == S_SFR)
     {
       SPEC_VOLATILE (sym->etype) = 1;
-      /* if initial value given */
-      if (sym->ival)
-       {
-         SPEC_ABSA (sym->etype) = 1;
-         SPEC_ADDR (sym->etype) =
-           (int) list2int (sym->ival);
-         sym->ival = NULL;
-       }
     }
   
   /* if absolute address given then it mark it as
      volatile -- except in the PIC port */
 
-#if !OPT_DISABLE_PIC
+#if !OPT_DISABLE_PIC || !OPT_DISABLE_PIC16
   /* The PIC port uses a different peep hole optimizer based on "pCode" */
-  if (!TARGET_IS_PIC)
+  if (!TARGET_IS_PIC && !TARGET_IS_PIC16)
 #endif
 
     if (IS_ABSOLUTE (sym->etype))
@@ -1174,13 +1161,17 @@ checkSClass (symbol * sym, int isProto)
       !IS_FUNC(sym->type)) {
     SPEC_SCLS (sym->etype) = S_CODE;
   }
-  
+
   /* global variable in code space is a constant */
   if (sym->level == 0 &&
       SPEC_SCLS (sym->etype) == S_CODE &&
-      port->mem.code_ro)
-    SPEC_CONST (sym->etype) = 1;
-  
+      port->mem.code_ro) {
+    if (IS_SPEC(sym->type)) {
+      SPEC_CONST (sym->type) = 1;
+    } else {
+      DCL_PTR_CONST (sym->type) = 1;
+    }
+  }
 
   /* if bit variable then no storage class can be */
   /* specified since bit is already a storage */
@@ -1271,7 +1262,8 @@ checkSClass (symbol * sym, int isProto)
           * control this allcoation, but the code was originally that way, and
           * changing it for non-390 ports breaks the compiler badly.
           */
-         bool useXdata = TARGET_IS_DS390 ? 1 : options.useXstack;
+         bool useXdata = (TARGET_IS_DS390 || TARGET_IS_DS400) ? 
+               1 : options.useXstack;
          SPEC_SCLS (sym->etype) = (useXdata ?
                                    S_XDATA : S_FIXED);
        }
@@ -1424,13 +1416,13 @@ computeType (sym_link * type1, sym_link * type2)
   reType = getSpec (rType);
 
   /* if either of them unsigned but not val then make this unsigned */
-  if (((!IS_LITERAL(type1) && SPEC_USIGN (etype1)) || 
-       (!IS_LITERAL(type2) && SPEC_USIGN (etype2))) && 
+  if (((/*!IS_LITERAL(type1) &&*/ SPEC_USIGN (etype1)) ||
+       (/*!IS_LITERAL(type2) &&*/ SPEC_USIGN (etype2))) &&
       !IS_FLOAT (reType))
     SPEC_USIGN (reType) = 1;
   else
     SPEC_USIGN (reType) = 0;
-  
+
   /* if result is a literal then make not so */
   if (IS_LITERAL (reType))
     SPEC_SCLS (reType) = S_REGISTER;
@@ -1441,7 +1433,7 @@ computeType (sym_link * type1, sym_link * type2)
 /*--------------------------------------------------------------------*/
 /* compareType - will do type check return 1 if match, -1 if castable */
 /*--------------------------------------------------------------------*/
-int 
+int
 compareType (sym_link * dest, sym_link * src)
 {
   if (!dest && !src)
@@ -1538,17 +1530,18 @@ compareType (sym_link * dest, sym_link * src)
 /*------------------------------------------------------------------*/
 /* inCalleeSaveList - return 1 if found in callee save list          */
 /*------------------------------------------------------------------*/
-bool 
-inCalleeSaveList (char *s)
+static int
+calleeCmp(void *p1, void *p2)
 {
-  int i;
-
-  if (options.all_callee_saves) return 1;
-  for (i = 0; options.calleeSaves[i]; i++)
-    if (strcmp (options.calleeSaves[i], s) == 0)
-      return 1;
+  return (strcmp((char *)p1, (char *)(p2)) == 0);
+}
 
-  return 0;
+bool
+inCalleeSaveList(char *s)
+{
+  if (options.all_callee_saves)
+    return 1;
+  return isinSetWith(options.calleeSavesSet, s, calleeCmp);
 }
 
 /*-----------------------------------------------------------------*/
@@ -1779,6 +1772,29 @@ checkFunction (symbol * sym, symbol *csym)
   return 1;
 }
 
+/*------------------------------------------------------------------*/
+/* cdbStructBlock - calls struct printing for a blcks               */
+/*------------------------------------------------------------------*/
+void cdbStructBlock (int block)
+{
+  int i;
+  bucket **table = StructTab;
+  bucket *chain;
+
+  /* go thru the entire  table  */
+  for (i = 0; i < 256; i++)
+    {
+      for (chain = table[i]; chain; chain = chain->next)
+       {
+         if (chain->block >= block)
+           {
+             if(debugFile)
+               debugFile->writeType((structdef *)chain->sym, chain->block, 0, NULL);
+           }
+       }
+    }
+}
+
 /*-----------------------------------------------------------------*/
 /* processFuncArgs - does some processing with function args       */
 /*-----------------------------------------------------------------*/
@@ -1937,6 +1953,7 @@ printTypeChain (sym_link * start, FILE * of)
 {
   int nlr = 0;
   sym_link * type, * search;
+  STORAGE_CLASS scls;
 
   if (!of)
     {
@@ -1949,16 +1966,44 @@ printTypeChain (sym_link * start, FILE * of)
     return;
   }
 
-  /* print the chain as it is written in the source: */
-  /* start with the last entry                       */
+  /* Print the chain as it is written in the source: */
+  /* start with the last entry.                      */
+  /* However, the storage class at the end of the    */
+  /* chain reall applies to the first in the chain!  */
+
   for (type = start; type && type->next; type = type->next)
     ;
+  scls=SPEC_SCLS(type);
   while (type)
     {
+      if (type==start) {
+       switch (scls) 
+         {
+         case S_DATA: fprintf (of, "data-"); break;
+         case S_XDATA: fprintf (of, "xdata-"); break;
+         case S_SFR: fprintf (of, "sfr-"); break;
+         case S_SBIT: fprintf (of, "sbit-"); break;
+         case S_CODE: fprintf (of, "code-"); break;
+         case S_IDATA: fprintf (of, "idata-"); break;
+         case S_PDATA: fprintf (of, "pdata-"); break;
+         case S_LITERAL: fprintf (of, "literal-"); break;
+         case S_STACK: fprintf (of, "stack-"); break;
+         case S_XSTACK: fprintf (of, "xstack-"); break;
+         case S_BIT: fprintf (of, "bit-"); break;
+         case S_EEPROM: fprintf (of, "eeprom-"); break;
+         default: break;
+         }
+      }
+
       if (IS_DECL (type))
        {
-         if (DCL_PTR_VOLATILE (type)) {
-           fprintf (of, "volatile ");
+         if (!IS_FUNC(type)) {
+           if (DCL_PTR_VOLATILE (type)) {
+             fprintf (of, "volatile-");
+           }
+           if (DCL_PTR_CONST (type)) {
+             fprintf (of, "const-");
+           }
          }
          switch (DCL_TYPE (type))
            {
@@ -1968,45 +2013,28 @@ printTypeChain (sym_link * start, FILE * of)
                       (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
              break;
            case GPOINTER:
-             if (DCL_PTR_CONST (type))
-               fprintf (of, "const ");
-             fprintf (of, "generic * ");
+             fprintf (of, "generic* ");
              break;
            case CPOINTER:
-             if (DCL_PTR_CONST (type))
-               fprintf (of, "const ");
-             fprintf (of, "code * ");
+             fprintf (of, "code* ");
              break;
            case FPOINTER:
-             if (DCL_PTR_CONST (type))
-               fprintf (of, "const ");
-             fprintf (of, "xdata * ");
+             fprintf (of, "xdata* ");
              break;
            case EEPPOINTER:
-             if (DCL_PTR_CONST (type))
-               fprintf (of, "const ");
-             fprintf (of, "eeprom * ");
+             fprintf (of, "eeprom* ");
              break;
-
            case POINTER:
-             if (DCL_PTR_CONST (type))
-               fprintf (of, "const ");
-             fprintf (of, "near *");
+             fprintf (of, "near* ");
              break;
            case IPOINTER:
-             if (DCL_PTR_CONST (type))
-               fprintf (of, "const ");
-             fprintf (of, "idata * ");
+             fprintf (of, "idata* ");
              break;
            case PPOINTER:
-             if (DCL_PTR_CONST (type))
-               fprintf (of, "const ");
-             fprintf (of, "pdata * ");
+             fprintf (of, "pdata* ");
              break;
            case UPOINTER:
-             if (DCL_PTR_CONST (type))
-               fprintf (of, "const ");
-             fprintf (of, "unkown * ");
+             fprintf (of, "unkown* ");
              break;
            case ARRAY:
              if (DCL_ELEM(type)) {
@@ -2019,34 +2047,17 @@ printTypeChain (sym_link * start, FILE * of)
        }
       else
        {
-         switch (SPEC_SCLS(type)) 
-           {
-           case S_DATA: fprintf (of, "data "); break;
-           case S_XDATA: fprintf (of, "xdata "); break;
-           case S_SFR: fprintf (of, "sfr "); break;
-           case S_SBIT: fprintf (of, "sbit "); break;
-           case S_CODE: fprintf (of, "code "); break;
-           case S_IDATA: fprintf (of, "idata "); break;
-           case S_PDATA: fprintf (of, "pdata "); break;
-           case S_LITERAL: fprintf (of, "literal "); break;
-           case S_STACK: fprintf (of, "stack "); break;
-           case S_XSTACK: fprintf (of, "xstack "); break;
-           case S_BIT: fprintf (of, "bit "); break;
-           case S_EEPROM: fprintf (of, "eeprom "); break;
-           default: break;
-           }
-
          if (SPEC_VOLATILE (type))
-           fprintf (of, "volatile ");
-         if (SPEC_USIGN (type))
-           fprintf (of, "unsigned ");
+           fprintf (of, "volatile-");
          if (SPEC_CONST (type))
-           fprintf (of, "const ");
+           fprintf (of, "const-");
+         if (SPEC_USIGN (type))
+           fprintf (of, "unsigned-");
          switch (SPEC_NOUN (type))
            {
            case V_INT:
              if (IS_LONG (type))
-               fprintf (of, "long ");
+               fprintf (of, "long-");
              fprintf (of, "int");
              break;
 
@@ -2094,206 +2105,6 @@ printTypeChain (sym_link * start, FILE * of)
     fprintf (of, "\n");
 }
 
-/*-----------------------------------------------------------------*/
-/* cdbTypeInfo - print the type information for debugger           */
-/*-----------------------------------------------------------------*/
-void
-cdbTypeInfo (sym_link * type, FILE * of)
-{
-  fprintf (of, "{%d}", getSize (type));
-  while (type)
-    {
-      if (IS_DECL (type))
-       {
-         switch (DCL_TYPE (type))
-           {
-           case FUNCTION:
-             fprintf (of, "DF,");
-             break;
-           case GPOINTER:
-             fprintf (of, "DG,");
-             break;
-           case CPOINTER:
-             fprintf (of, "DC,");
-             break;
-           case FPOINTER:
-             fprintf (of, "DX,");
-             break;
-           case POINTER:
-             fprintf (of, "DD,");
-             break;
-           case IPOINTER:
-             fprintf (of, "DI,");
-             break;
-           case PPOINTER:
-             fprintf (of, "DP,");
-             break;
-           case EEPPOINTER:
-             fprintf (of, "DA,");
-             break;
-           case ARRAY:
-             fprintf (of, "DA%d,", DCL_ELEM (type));
-             break;
-           default:
-             break;
-           }
-       }
-      else
-       {
-         switch (SPEC_NOUN (type))
-           {
-           case V_INT:
-             if (IS_LONG (type))
-               fprintf (of, "SL");
-             else
-               fprintf (of, "SI");
-             break;
-
-           case V_CHAR:
-             fprintf (of, "SC");
-             break;
-
-           case V_VOID:
-             fprintf (of, "SV");
-             break;
-
-           case V_FLOAT:
-             fprintf (of, "SF");
-             break;
-
-           case V_STRUCT:
-             fprintf (of, "ST%s", SPEC_STRUCT (type)->tag);
-             break;
-
-           case V_SBIT:
-             fprintf (of, "SX");
-             break;
-
-           case V_BIT:
-             fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type));
-             break;
-
-           default:
-             break;
-           }
-         fputs (":", of);
-         if (SPEC_USIGN (type))
-           fputs ("U", of);
-         else
-           fputs ("S", of);
-       }
-      type = type->next;
-    }
-}
-/*-----------------------------------------------------------------*/
-/* cdbSymbol - prints a symbol & its type information for debugger */
-/*-----------------------------------------------------------------*/
-void 
-cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc)
-{
-  memmap *map;
-
-  if (!sym)
-    return;
-  if (!of)
-    of = stdout;
-
-  if (isFunc)
-    fprintf (of, "F:");
-  else
-    fprintf (of, "S:");                /* symbol record */
-  /* if this is not a structure symbol then
-     we need to figure out the scope information */
-  if (!isStructSym)
-    {
-      if (!sym->level)
-       {
-         /* global */
-         if (IS_STATIC (sym->etype))
-           fprintf (of, "F%s$", moduleName);   /* scope is file */
-         else
-           fprintf (of, "G$"); /* scope is global */
-       }
-      else
-       /* symbol is local */
-       fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
-    }
-  else
-    fprintf (of, "S$");                /* scope is structure */
-
-  /* print the name, & mangled name */
-  fprintf (of, "%s$%d$%d(", sym->name,
-          sym->level, sym->block);
-
-  cdbTypeInfo (sym->type, of);
-  fprintf (of, "),");
-
-  /* print the address space */
-  map = SPEC_OCLS (sym->etype);
-  fprintf (of, "%c,%d,%d",
-          (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype));
-
-  /* if assigned to registers then output register names */
-  /* if this is a function then print
-     if is it an interrupt routine & interrupt number
-     and the register bank it is using */
-  if (isFunc)
-    fprintf (of, ",%d,%d,%d", FUNC_ISISR (sym->type),
-            FUNC_INTNO (sym->type), FUNC_REGBANK (sym->type));
-  /* alternate location to find this symbol @ : eg registers
-     or spillication */
-
-  if (!isStructSym)
-    fprintf (of, "\n");
-}
-
-/*-----------------------------------------------------------------*/
-/* cdbStruct - print a structure for debugger                      */
-/*-----------------------------------------------------------------*/
-void 
-cdbStruct (structdef * sdef, int block, FILE * of,
-          int inStruct, char *tag)
-{
-  symbol *sym;
-
-  fprintf (of, "T:");
-  /* if block # then must have function scope */
-  fprintf (of, "F%s$", moduleName);
-  fprintf (of, "%s[", (tag ? tag : sdef->tag));
-  for (sym = sdef->fields; sym; sym = sym->next)
-    {
-      fprintf (of, "({%d}", sym->offset);
-      cdbSymbol (sym, of, TRUE, FALSE);
-      fprintf (of, ")");
-    }
-  fprintf (of, "]");
-  if (!inStruct)
-    fprintf (of, "\n");
-}
-
-/*------------------------------------------------------------------*/
-/* cdbStructBlock - calls struct printing for a blcks               */
-/*------------------------------------------------------------------*/
-void 
-cdbStructBlock (int block, FILE * of)
-{
-  int i;
-  bucket **table = StructTab;
-  bucket *chain;
-  wassert (of);
-
-  /* go thru the entire  table  */
-  for (i = 0; i < 256; i++)
-    {
-      for (chain = table[i]; chain; chain = chain->next)
-       {
-         if (chain->block >= block)
-           {
-             cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL);
-           }
-       }
-    }
-}
 
 /*-----------------------------------------------------------------*/
 /* powof2 - returns power of two for the number if number is pow 2 */
@@ -2540,13 +2351,14 @@ initCSupport ()
        }
     }
 
+/*
   for (muldivmod = 0; muldivmod < 3; muldivmod++)
     {
       for (bwd = 0; bwd < 3; bwd++)
        {
          for (su = 0; su < 2; su++)
            {
-             SNPRINTF (buffer, sizeof(buffer), 
+             SNPRINTF (buffer, sizeof(buffer),
                        "_%s%s%s",
                       smuldivmod[muldivmod],
                       ssu[su],
@@ -2557,13 +2369,66 @@ initCSupport ()
        }
     }
 
+  muluint() and mulsint() resp. mululong() and mulslong() return the same result.
+  Therefore they've been merged into mulint() and mullong().
+*/
+
+  for (bwd = 0; bwd < 3; bwd++)
+    {
+      for (su = 0; su < 2; su++)
+       {
+         for (muldivmod = 1; muldivmod < 3; muldivmod++)
+           {
+             /* div and mod */
+             SNPRINTF (buffer, sizeof(buffer),
+                       "_%s%s%s",
+                      smuldivmod[muldivmod],
+                      ssu[su],
+                      sbwd[bwd]);
+             __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
+             FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
+           }
+       }
+    }
+  /* mul only */
+  muldivmod = 0;
+  /* byte */
+  bwd = 0;
+  for (su = 0; su < 2; su++)
+    {
+      /* muluchar and mulschar are still separate functions, because e.g. the z80
+         port is sign/zero-extending to int before calling mulint() */
+      SNPRINTF (buffer, sizeof(buffer),
+               "_%s%s%s",
+               smuldivmod[muldivmod],
+               ssu[su],
+               sbwd[bwd]);
+      __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
+      FUNC_NONBANKED (__muldiv[muldivmod][bwd][su]->type) = 1;
+    }
+  /* signed only */
+  su = 0;
+  /* word and doubleword */
+  for (bwd = 1; bwd < 3; bwd++)
+    {
+      /* mul, int/long */
+      SNPRINTF (buffer, sizeof(buffer),
+               "_%s%s",
+               smuldivmod[muldivmod],
+               sbwd[bwd]);
+      __muldiv[muldivmod][bwd][0] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
+      FUNC_NONBANKED (__muldiv[muldivmod][bwd][0]->type) = 1;
+      /* signed = unsigned */
+      __muldiv[muldivmod][bwd][1] = __muldiv[muldivmod][bwd][0];
+    }
+
   for (rlrr = 0; rlrr < 2; rlrr++)
     {
       for (bwd = 0; bwd < 3; bwd++)
        {
          for (su = 0; su < 2; su++)
            {
-             SNPRINTF (buffer, sizeof(buffer), 
+             SNPRINTF (buffer, sizeof(buffer),
                        "_%s%s%s",
                       srlrr[rlrr],
                       ssu[su],