* support/regression/fwk/lib/testfwk.c: printn is recursive and thus needs
[fw/sdcc] / src / SDCCast.c
index 871bf9045acce4bb9a01f77a11557a5a53f8214b..354a70b2e99e0dbed33c6c9ddf7594e1ebe3f3f2 100644 (file)
@@ -47,11 +47,12 @@ int labelKey = 1;
 
 int noLineno = 0;
 int noAlloc = 0;
-symbol *currFunc;
+symbol *currFunc=NULL;
 static ast *createIval (ast *, sym_link *, initList *, ast *);
 static ast *createIvalCharPtr (ast *, sym_link *, ast *);
 static ast *optimizeCompare (ast *);
 ast *optimizeRRCRLC (ast *);
+ast *optimizeSWAP (ast *);
 ast *optimizeGetHbit (ast *);
 ast *backPatchLabels (ast *, symbol *, symbol *);
 void PA(ast *t);
@@ -78,7 +79,7 @@ newAst_ (unsigned type)
   ex = Safe_alloc ( sizeof (ast));
 
   ex->type = type;
-  ex->lineno = (noLineno ? oldLineno : yylineno);
+  ex->lineno = (noLineno ? oldLineno : mylineno);
   ex->filename = currFname;
   ex->level = NestLevel;
   ex->block = currBlockno;
@@ -110,14 +111,6 @@ newAst_LINK (sym_link * val)
   return ex;
 }
 
-ast *
-newAst_STMNT (unsigned val)
-{
-  ast *ex = newAst_ (EX_STMNT);
-  ex->opval.stmnt = val;
-  return ex;
-}
-
 /*-----------------------------------------------------------------*/
 /* newNode - creates a new node                                    */
 /*-----------------------------------------------------------------*/
@@ -167,7 +160,7 @@ newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel)
 /*-----------------------------------------------------------------*/
 /* copyAstValues - copies value portion of ast if needed     */
 /*-----------------------------------------------------------------*/
-void 
+void
 copyAstValues (ast * dest, ast * src)
 {
   switch (src->opval.op)
@@ -186,14 +179,13 @@ copyAstValues (ast * dest, ast * src)
       break;
 
     case INLINEASM:
-      dest->values.inlineasm = Safe_alloc (strlen (src->values.inlineasm) + 1);
-      strcpy (dest->values.inlineasm, src->values.inlineasm);
+      dest->values.inlineasm =  Safe_strdup(src->values.inlineasm);
       break;
 
     case ARRAYINIT:
        dest->values.constlist = copyLiteralList(src->values.constlist);
        break;
-       
+
     case FOR:
       AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel));
       AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel));
@@ -210,7 +202,7 @@ copyAstValues (ast * dest, ast * src)
 /* copyAst - makes a copy of a given astession                     */
 /*-----------------------------------------------------------------*/
 ast *
-copyAst (ast * src) 
+copyAst (ast * src)
 {
   ast *dest;
 
@@ -267,24 +259,24 @@ ast *removeIncDecOps (ast * tree) {
   if (!tree)
     return NULL;
 
-  if (tree->type == EX_OP && 
+  if (tree->type == EX_OP &&
       (tree->opval.op == INC_OP || tree->opval.op == DEC_OP)) {
     if (tree->left)
       tree=tree->left;
-    else 
+    else
       tree=tree->right;
   }
 
   tree->left=removeIncDecOps(tree->left);
   tree->right=removeIncDecOps(tree->right);
+
  return tree;
 }
 
 /*-----------------------------------------------------------------*/
 /* hasSEFcalls - returns TRUE if tree has a function call          */
 /*-----------------------------------------------------------------*/
-bool 
+bool
 hasSEFcalls (ast * tree)
 {
   if (!tree)
@@ -367,6 +359,7 @@ resolveSymbols (ast * tree)
   if (tree == NULL)
     return tree;
 
+#if 0
   /* print the line          */
   /* if not block & function */
   if (tree->type == EX_OP &&
@@ -377,6 +370,7 @@ resolveSymbols (ast * tree)
       filename = tree->filename;
       lineno = tree->lineno;
     }
+#endif
 
   /* make sure we resolve the true & false labels for ifx */
   if (tree->type == EX_OP && tree->opval.op == IFX)
@@ -447,7 +441,7 @@ resolveSymbols (ast * tree)
          /* mark it as returning an int     */
          if (tree->funcName)
            {
-             tree->opval.val->sym->type = newLink ();
+             tree->opval.val->sym->type = newLink (DECLARATOR);
              DCL_TYPE (tree->opval.val->sym->type) = FUNCTION;
              tree->opval.val->sym->type->next =
                tree->opval.val->sym->etype = newIntLink ();
@@ -500,7 +494,7 @@ funcOfType (char *name, sym_link * type, sym_link * argType,
   sym = newSymbol (name, 0);
 
   /* setup return value */
-  sym->type = newLink ();
+  sym->type = newLink (DECLARATOR);
   DCL_TYPE (sym->type) = FUNCTION;
   sym->type->next = copyLinkChain (type);
   sym->etype = getSpec (sym->type);
@@ -544,7 +538,7 @@ funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
     sym = newSymbol (name, 0);
     
     /* setup return value */
-    sym->type = newLink ();
+    sym->type = newLink (DECLARATOR);
     DCL_TYPE (sym->type) = FUNCTION;
     sym->type->next = typeFromStr(rtype);
     sym->etype = getSpec (sym->type);
@@ -562,7 +556,7 @@ funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
            args = args->next = newValue ();
        }
     }
-    
+
     /* save it */
     addSymChain (sym);
     sym->cdef = 1;
@@ -574,7 +568,7 @@ funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
 /*-----------------------------------------------------------------*/
 /* reverseParms - will reverse a parameter tree                    */
 /*-----------------------------------------------------------------*/
-static void 
+static void
 reverseParms (ast * ptree)
 {
   ast *ttree;
@@ -665,7 +659,20 @@ processParms (ast * func,
       if (IS_INTEGRAL (ftype)
          && (getSize (ftype) < (unsigned) INTSIZE))
        {
-         newType = newAst_LINK(INTTYPE);
+         if (IS_AST_OP(actParm) &&
+             (actParm->opval.op == LEFT_OP ||
+              actParm->opval.op == '*' ||
+              actParm->opval.op == '+' ||
+              actParm->opval.op == '-') &&
+             actParm->right) {
+           // we should cast an operand instead of the result
+           actParm->decorated = 0;
+           actParm->left = newNode( CAST, newAst_LINK(newIntLink()),
+                                        actParm->left);
+           actParm = decorateType(actParm);
+         } else {
+           newType = newAst_LINK(INTTYPE);
+         }
        }
 
       if (IS_PTR(ftype) && !IS_GENPTR(ftype))
@@ -951,12 +958,9 @@ createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr)
                                   newAst_VALUE (valueFromLit ((float) i))),
                               newAst_VALUE (valueFromLit (*s))));
 
-      // now we don't need iexpr's symbol anymore
-      {
-       symbol *sym=AST_SYMBOL(iexpr);
-       memmap *segment=SPEC_OCLS(sym->etype);
-       deleteSetItem(&segment->syms, sym);
-      }
+      // now WE don't need iexpr's symbol anymore
+      freeStringSymbol(AST_SYMBOL(iexpr));
+
       return decorateType (resolveSymbols (rast));
     }
 
@@ -1012,7 +1016,7 @@ createIval (ast * sym, sym_link * type, initList * ilist, ast * wid)
     /* if type is SPECIFIER */
   if (IS_SPEC (type))
     rast = createIvalType (sym, type, ilist);
-  
+
   if (wid)
     return decorateType (resolveSymbols (newNode (NULLOP, wid, rast)));
   else
@@ -1085,6 +1089,16 @@ gatherAutoInit (symbol * autoChain)
       /* if there is an initial value */
       if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE)
        {
+         initList *ilist=sym->ival;
+         
+         while (ilist->type == INIT_DEEP) {
+           ilist = ilist->init.deep;
+         }
+
+         /* update lineno for error msg */
+         lineno=sym->lineDef;
+         setAstLineno (ilist->init.node, lineno);
+         
          if (IS_AGGREGATE (sym->type)) {
            work = initAggregates (sym, sym->ival, NULL);
          } else {
@@ -1095,8 +1109,10 @@ gatherAutoInit (symbol * autoChain)
            work = newNode ('=', newAst_VALUE (symbolVal (sym)),
                            list2expr (sym->ival));
          }
-
+         
+         // just to be sure
          setAstLineno (work, sym->lineDef);
+
          sym->ival = NULL;
          if (init)
            init = newNode (NULLOP, init, work);
@@ -1108,6 +1124,20 @@ gatherAutoInit (symbol * autoChain)
   return init;
 }
 
+/*-----------------------------------------------------------------*/
+/* freeStringSymbol - delete a literal string if no more usage     */
+/*-----------------------------------------------------------------*/
+void freeStringSymbol(symbol *sym) {
+  /* make sure this is a literal string */
+  assert (sym->isstrlit);
+  if (--sym->isstrlit == 0) { // lower the usage count
+    memmap *segment=SPEC_OCLS(sym->etype);
+    if (segment) {
+      deleteSetItem(&segment->syms, sym);
+    }
+  }
+}
+  
 /*-----------------------------------------------------------------*/
 /* stringToSymbol - creates a symbol from a literal string         */
 /*-----------------------------------------------------------------*/
@@ -1117,10 +1147,22 @@ stringToSymbol (value * val)
   char name[SDCC_NAME_MAX + 1];
   static int charLbl = 0;
   symbol *sym;
+  set *sp;
+
+  // have we heard this before?
+  for (sp=statsg->syms; sp; sp=sp->next) {
+    sym=sp->item;
+    if (sym->isstrlit && 
+       !strcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char)) {
+      // yes, this is old news. Don't publish it again.
+      sym->isstrlit++; // but raise the usage count
+      return symbolVal(sym);
+    }
+  }
 
-  sprintf (name, "_str_%d", charLbl++);
+  SNPRINTF (name, sizeof(name), "_str_%d", charLbl++);
   sym = newSymbol (name, 0);   /* make it @ level 0 */
-  strcpy (sym->rname, name);
+  strncpyz (sym->rname, name, SDCC_NAME_MAX);
 
   /* copy the type from the value passed */
   sym->type = copyLinkChain (val->type);
@@ -1162,14 +1204,14 @@ processBlockVars (ast * tree, int *stack, int action)
       ast *autoInit;
 
       if (action == ALLOCATE)
-       {
+        {
          *stack += allocVariables (tree->values.sym);
          autoInit = gatherAutoInit (tree->values.sym);
-
+       
          /* if there are auto inits then do them */
          if (autoInit)
            tree->left = newNode (NULLOP, autoInit, tree->left);
-       }
+        }
       else                     /* action is deallocate */
        deallocLocal (tree->values.sym);
     }
@@ -1179,6 +1221,7 @@ processBlockVars (ast * tree, int *stack, int action)
   return tree;
 }
 
+
 /*-------------------------------------------------------------*/
 /* constExprTree - returns TRUE if this tree is a constant     */
 /*                 expression                                  */
@@ -1190,7 +1233,7 @@ bool constExprTree (ast *cexpr) {
   }
 
   cexpr = decorateType (resolveSymbols (cexpr));
-  
+
   switch (cexpr->type) 
     {
     case EX_VALUE:
@@ -1202,10 +1245,15 @@ bool constExprTree (ast *cexpr) {
        // a function's address will never change
        return TRUE;
       }
+      if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
+       // an array's address will never change
+       return TRUE;
+      }
       if (IS_AST_SYM_VALUE(cexpr) && 
          IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
        // a symbol in code space will never change
        // This is only for the 'char *s="hallo"' case and will have to leave
+        //printf(" code space symbol");
        return TRUE;
       }
       return FALSE;
@@ -1222,7 +1270,7 @@ bool constExprTree (ast *cexpr) {
        return constExprTree(cexpr->right);
       }
       if (cexpr->opval.op==CAST) {
-       // jwk: cast ignored, maybe we should throw a warning here
+       // cast ignored, maybe we should throw a warning here?
        return constExprTree(cexpr->right);
       }
       if (cexpr->opval.op=='&') { 
@@ -1234,9 +1282,12 @@ bool constExprTree (ast *cexpr) {
       if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
        return TRUE;
       }
+      return FALSE;
+    case EX_OPERAND:
+      return IS_CONSTANT(operandType(cexpr->opval.oprnd));
     }
   return FALSE;
-}  
+}
     
 /*-----------------------------------------------------------------*/
 /* constExprValue - returns the value of a constant expression     */
@@ -1261,7 +1312,7 @@ constExprValue (ast * cexpr, int check)
          val->sym = cexpr->opval.val->sym;
          val->sym->type = copyLinkChain (cexpr->ftype);
          val->sym->etype = getSpec (val->sym->type);
-         strcpy (val->name, cexpr->opval.val->sym->rname);
+         strncpyz (val->name, cexpr->opval.val->sym->rname, SDCC_NAME_MAX);
          return val;
        }
 
@@ -1269,11 +1320,15 @@ constExprValue (ast * cexpr, int check)
       if (IS_AST_OP (cexpr) &&
          cexpr->opval.op == CAST &&
          IS_LITERAL (cexpr->right->ftype))
+        {
        return valCastLiteral (cexpr->ftype,
                               floatFromVal (cexpr->right->opval.val));
+        }
 
       if (IS_AST_VALUE (cexpr))
+        {
        return cexpr->opval.val;
+        }
 
       if (check)
        werror (E_CONST_EXPECTED, "found expression");
@@ -1542,7 +1597,7 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
       return TRUE;
 
 /*------------------------------------------------------------------*/
-    case INC_OP:               /* incerement operator unary so left only */
+    case INC_OP:
     case DEC_OP:
 
       /* sure we are not sym is not modified */
@@ -1610,6 +1665,7 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
     case RRC:
     case RLC:
     case GETHBIT:
+    case SWAP:
       if (IS_AST_SYM_VALUE (pbody->left) &&
          isSymbolEqual (AST_SYMBOL (pbody->left), sym))
        return FALSE;
@@ -1628,6 +1684,14 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
     case '?':
     case ':':
     case SIZEOF:               /* evaluate wihout code generation */
+      
+      if (IS_AST_SYM_VALUE (pbody->left) &&
+         isSymbolEqual (AST_SYMBOL (pbody->left), sym))
+       return FALSE;
+
+      if (IS_AST_SYM_VALUE (pbody->right) &&
+         isSymbolEqual (AST_SYMBOL (pbody->right), sym))
+       return FALSE;
 
       return isConformingBody (pbody->left, sym, body) &&
        isConformingBody (pbody->right, sym, body);
@@ -1649,7 +1713,7 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
          return FALSE;
        // if the loopvar is used in another (maybe conditional) block
        if (astHasSymbol (pbody->right, sym) &&
-           (pbody->level > body->level)) {
+           (pbody->level >= body->level)) {
          return FALSE;
        }
       }
@@ -1723,7 +1787,7 @@ isConformingBody (ast * pbody, symbol * sym, ast * body)
 /* if the for loop is reversible. If yes will set the value of     */
 /* the loop control var & init value & termination value           */
 /*-----------------------------------------------------------------*/
-bool 
+bool
 isLoopReversible (ast * loop, symbol ** loopCntrl,
                  ast ** init, ast ** end)
 {
@@ -1807,10 +1871,10 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
                   newNode ('=',
                            newAst_VALUE (symbolVal (sym)),
                            end));
-  
+
   replLoopSym (loop->left, sym);
   setAstLineno (rloop, init->lineno);
-  
+
   rloop = newNode (NULLOP,
                   newNode ('=',
                            newAst_VALUE (symbolVal (sym)),
@@ -1823,14 +1887,63 @@ reverseLoop (ast * loop, symbol * sym, ast * init, ast * end)
                                                           newAst_VALUE (symbolVal (sym)),
                                                           newAst_VALUE (constVal ("1"))),
                                                  rloop))));
-  
+
   rloop->lineno=init->lineno;
   return decorateType (rloop);
-  
+
 }
 
 /*-----------------------------------------------------------------*/
-/* decorateType - compute type for this tree also does type cheking */
+/* searchLitOp - search tree (*ops only) for an ast with literal */
+/*-----------------------------------------------------------------*/
+static ast *
+searchLitOp (ast *tree, ast **parent, const char *ops)
+{
+  ast *ret;
+
+  if (tree && optimize.global_cse)
+    {
+      /* is there a literal operand? */
+      if (tree->right &&
+          IS_AST_OP(tree->right) &&
+          tree->right->right &&
+          (tree->right->opval.op == ops[0] || tree->right->opval.op == ops[1]))
+       {
+         if (IS_LITERAL (RTYPE (tree->right)) ^
+             IS_LITERAL (LTYPE (tree->right)))
+           {
+             tree->right->decorated = 0;
+             tree->decorated = 0;
+             *parent = tree;
+             return tree->right;
+           }
+         ret = searchLitOp (tree->right, parent, ops);
+         if (ret)
+           return ret;
+        }
+      if (tree->left &&
+          IS_AST_OP(tree->left) &&
+          tree->left->right &&
+         (tree->left->opval.op == ops[0] || tree->left->opval.op == ops[1]))
+       {
+         if (IS_LITERAL (RTYPE (tree->left)) ^
+             IS_LITERAL (LTYPE (tree->left)))
+           {
+             tree->left->decorated = 0;
+             tree->decorated = 0;
+             *parent = tree;
+             return tree->left;
+           }
+         ret = searchLitOp (tree->left, parent, ops);
+         if (ret)
+           return ret;
+       }
+    }
+  return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/* decorateType - compute type for this tree also does type checking */
 /*          this is done bottom up, since type have to flow upwards */
 /*          it also does constant folding, and paramater checking  */
 /*-----------------------------------------------------------------*/
@@ -1849,6 +1962,7 @@ decorateType (ast * tree)
 
   tree->decorated = 1;
 
+#if 0
   /* print the line          */
   /* if not block & function */
   if (tree->type == EX_OP &&
@@ -1859,6 +1973,7 @@ decorateType (ast * tree)
       filename = tree->filename;
       lineno = tree->lineno;
     }
+#endif
 
   /* if any child is an error | this one is an error do nothing */
   if (tree->isError ||
@@ -1870,6 +1985,7 @@ decorateType (ast * tree)
 /*----------------------------*/
   /*   leaf has been reached    */
 /*----------------------------*/
+  lineno=tree->lineno;
   /* if this is of type value */
   /* just get the type        */
   if (tree->type == EX_VALUE)
@@ -1942,6 +2058,28 @@ decorateType (ast * tree)
       tree->left = dtl;
     if (dtr != tree->right)
       tree->right = dtr;
+    if ((dtl && dtl->isError) || (dtr && dtr->isError))
+      return tree;
+
+    if (IS_AST_OP(tree) &&
+       (tree->opval.op == CAST || tree->opval.op == '=') &&
+       (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) &&
+       (getSize(RTYPE(tree)) < (unsigned) INTSIZE)) {
+      // this is a cast/assign to a bigger type
+      if (IS_AST_OP(tree->right) &&
+         IS_INTEGRAL(tree->right->ftype) &&
+         (tree->right->opval.op == LEFT_OP ||
+          tree->right->opval.op == '*' ||
+          tree->right->opval.op == '+' ||
+          tree->right->opval.op == '-') &&
+         tree->right->right) {
+       // we should cast an operand instead of the result
+       tree->right->decorated = 0;
+       tree->right->left = newNode( CAST, newAst_LINK(newIntLink()),
+                                    tree->right->left);
+       tree->right = decorateType(tree->right);
+      }
+    }
   }
 
   /* depending on type of operator do */
@@ -1985,9 +2123,6 @@ decorateType (ast * tree)
        }
       RRVAL (tree) = 1;
       COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next);
-      if (IS_PTR(LTYPE(tree))) {
-             SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
-      }
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -2013,7 +2148,7 @@ decorateType (ast * tree)
       /*----------------------------*/
     case PTR_OP:
       /* if not pointer to a structure */
-      if (!IS_PTR (LTYPE (tree)))
+      if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE(tree)))
        {
          werror (E_PTR_REQD);
          goto errorTreeReturn;
@@ -2033,6 +2168,7 @@ decorateType (ast * tree)
       /* adjust the storage class */
       switch (DCL_TYPE(tree->left->ftype)) {
       case POINTER:
+               SPEC_SCLS(TETYPE(tree)) = S_DATA; 
        break;
       case FPOINTER:
                SPEC_SCLS(TETYPE(tree)) = S_XDATA; 
@@ -2041,6 +2177,7 @@ decorateType (ast * tree)
                SPEC_SCLS(TETYPE(tree)) = S_CODE; 
        break;
       case GPOINTER:
+       SPEC_SCLS (TETYPE (tree)) = 0;
        break;
       case PPOINTER:
                SPEC_SCLS(TETYPE(tree)) = S_XSTACK; 
@@ -2052,9 +2189,45 @@ decorateType (ast * tree)
                SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
        break;
       case UPOINTER:
+       SPEC_SCLS (TETYPE (tree)) = 0;
+       break;
       case ARRAY:
       case FUNCTION:
+       break;
       }
+      
+      if (IS_ADDRESS_OF_OP (tree->left) && IS_AST_SYM_VALUE(tree->left->left)
+          && SPEC_ABSA (AST_SYMBOL (tree->left->left)->etype))
+        {
+            /* If defined    struct type at addr var
+               then rewrite  (&struct var)->member
+               as            temp
+               and define    membertype at (addr+offsetof(struct var,member)) temp
+            */
+            symbol *sym;
+            symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree)),
+                                               AST_SYMBOL(tree->right));
+
+            sym = newSymbol(genSymName (0), 0);
+            sym->type = TTYPE (tree);
+            sym->etype = getSpec(sym->type);
+            sym->lineDef = tree->lineno;
+            sym->cdef = 1;
+            sym->isref = 1;
+            SPEC_STAT (sym->etype) = 1;
+            SPEC_ADDR (sym->etype) = SPEC_ADDR (AST_SYMBOL (tree->left->left)->etype)
+                                     + element->offset;
+            SPEC_ABSA(sym->etype) = 1;
+            addSym (SymbolTab, sym, sym->name, 0, 0, 0);
+            allocGlobal (sym);
+            
+            AST_VALUE (tree) = symbolVal(sym);
+            TLVAL (tree) = 1;
+            TRVAL (tree) = 0;
+            tree->type = EX_VALUE;
+            tree->left = NULL;
+            tree->right = NULL;
+        }
 
       return tree;
 
@@ -2062,13 +2235,13 @@ decorateType (ast * tree)
       /*----------------------------*/
       /*  ++/-- operation           */
       /*----------------------------*/
-    case INC_OP:               /* incerement operator unary so left only */
+    case INC_OP:
     case DEC_OP:
       {
        sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree));
        COPYTYPE (TTYPE (tree), TETYPE (tree), ltc);
-       if (!tree->initMode && IS_CONSTANT(TETYPE(tree)))
-         werror (E_CODE_WRITE, "++/--");
+        if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
+         werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
 
        if (tree->right)
          RLVAL (tree) = 1;
@@ -2123,6 +2296,31 @@ decorateType (ast * tree)
            computeType (LTYPE (tree), RTYPE (tree));
          TETYPE (tree) = getSpec (TTYPE (tree));
 
+          /* if left is a literal exchange left & right */
+          if (IS_LITERAL (LTYPE (tree)))
+           {
+             ast *tTree = tree->left;
+             tree->left = tree->right;
+             tree->right = tTree;
+           }
+
+         /* if right is a literal and */
+         /* we can find a 2nd literal in a and-tree then */
+         /* rearrange the tree */
+         if (IS_LITERAL (RTYPE (tree)))
+           {
+             ast *parent;
+             ast *litTree = searchLitOp (tree, &parent, "&");
+             if (litTree)
+               {
+                 ast *tTree = litTree->left;
+                 litTree->left = tree->right;
+                 tree->right = tTree;
+                 /* both operands in tTree are literal now */
+                 decorateType (parent);
+               }
+           }
+
          LRVAL (tree) = RRVAL (tree) = 1;
          return tree;
        }
@@ -2131,8 +2329,7 @@ decorateType (ast * tree)
       /*----------------------------*/
       /*  address of                */
       /*----------------------------*/
-      p = newLink ();
-      p->class = DECLARATOR;
+      p = newLink (DECLARATOR);
       /* if bit field then error */
       if (IS_BITVAR (tree->left->etype))
        {
@@ -2164,10 +2361,7 @@ decorateType (ast * tree)
          goto errorTreeReturn;
        }
       if (SPEC_SCLS (tree->left->etype) == S_CODE)
-       {
-         DCL_TYPE (p) = CPOINTER;
-         DCL_PTR_CONST (p) = port->mem.code_ro;
-       }
+       DCL_TYPE (p) = CPOINTER;
       else if (SPEC_SCLS (tree->left->etype) == S_XDATA)
        DCL_TYPE (p) = FPOINTER;
       else if (SPEC_SCLS (tree->left->etype) == S_XSTACK)
@@ -2190,10 +2384,24 @@ decorateType (ast * tree)
       p->next = LTYPE (tree);
       TTYPE (tree) = p;
       TETYPE (tree) = getSpec (TTYPE (tree));
-      DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree));
-      DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree));
       LLVAL (tree) = 1;
       TLVAL (tree) = 1;
+
+      #if 0
+      if (IS_AST_OP (tree->left) && tree->left->opval.op == PTR_OP
+          && IS_AST_VALUE (tree->left->left) && !IS_AST_SYM_VALUE (tree->left->left))
+        {
+          symbol *element = getStructElement (SPEC_STRUCT (LETYPE(tree->left)),
+                                     AST_SYMBOL(tree->left->right));
+         AST_VALUE(tree) = valPlus(AST_VALUE(tree->left->left),
+                                    valueFromLit(element->offset));
+         tree->left = NULL;
+         tree->right = NULL;
+         tree->type = EX_VALUE;
+         tree->values.literalFromCast = 1;
+        }
+      #endif
+
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -2206,7 +2414,38 @@ decorateType (ast * tree)
        ast *wtree = optimizeRRCRLC (tree);
        if (wtree != tree)
          return decorateType (wtree);
+       
+       wtree = optimizeSWAP (tree);
+       if (wtree != tree)
+         return decorateType (wtree);
+        
+       // fall through
       }
+
+      /* if left is a literal exchange left & right */
+      if (IS_LITERAL (LTYPE (tree)))
+       {
+         ast *tTree = tree->left;
+         tree->left = tree->right;
+         tree->right = tTree;
+       }
+
+      /* if right is a literal and */
+      /* we can find a 2nd literal in a or-tree then */
+      /* rearrange the tree */
+      if (IS_LITERAL (RTYPE (tree)))
+       {
+         ast *parent;
+         ast *litTree = searchLitOp (tree, &parent, "|");
+         if (litTree)
+           {
+             ast *tTree = litTree->left;
+             litTree->left = tree->right;
+             tree->right = tTree;
+             /* both operands in tTree are literal now */
+             decorateType (parent);
+           }
+        }
       /*------------------------------------------------------------------*/
       /*----------------------------*/
       /*  bitwise xor               */
@@ -2236,6 +2475,32 @@ decorateType (ast * tree)
          TTYPE (tree) = tree->opval.val->type;
          return tree;
        }
+
+      /* if left is a literal exchange left & right */
+      if (IS_LITERAL (LTYPE (tree)))
+       {
+         ast *tTree = tree->left;
+         tree->left = tree->right;
+         tree->right = tTree;
+       }
+
+      /* if right is a literal and */
+      /* we can find a 2nd literal in a xor-tree then */
+      /* rearrange the tree */
+      if (IS_LITERAL (RTYPE (tree)))
+       {
+         ast *parent;
+         ast *litTree = searchLitOp (tree, &parent, "^");
+         if (litTree)
+           {
+             ast *tTree = litTree->left;
+             litTree->left = tree->right;
+             tree->right = tTree;
+             /* both operands in litTree are literal now */
+             decorateType (parent);
+           }
+        }
+
       LRVAL (tree) = RRVAL (tree) = 1;
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
@@ -2263,10 +2528,43 @@ decorateType (ast * tree)
                                   tree->opval.val->type);
          return tree;
        }
+
       LRVAL (tree) = RRVAL (tree) = 1;
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
                                            RTYPE (tree)));
+
+      /* if right is a literal and */
+      /* left is also a division by a literal then */
+      /* rearrange the tree */
+      if (IS_LITERAL (RTYPE (tree))
+          /* avoid infinite loop */
+          && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 1)
+       {
+         ast *parent;
+         ast *litTree = searchLitOp (tree, &parent, "/");
+         if (litTree)
+           {
+             if (IS_LITERAL (RTYPE (litTree)))
+               {
+                 /* foo_div */
+                 litTree->right = newNode ('*', litTree->right, tree->right);
+                 litTree->right->lineno = tree->lineno;
+
+                 tree->right->opval.val = constVal ("1");
+                 decorateType (parent);
+               }
+             else
+               {
+                 /* litTree->left is literal: no gcse possible.
+                    We can't call decorateType(parent), because
+                    this would cause an infinit loop. */
+                 parent->decorated = 1;
+                 decorateType (litTree);
+               }
+           }
+       }
+
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -2320,10 +2618,43 @@ decorateType (ast * tree)
              werror (E_LVALUE_REQUIRED, "pointer deref");
              goto errorTreeReturn;
            }
-         TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ?
-                                       LTYPE (tree)->next : NULL);
-         TETYPE (tree) = getSpec (TTYPE (tree));
-         SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE(tree));
+         if (IS_ADDRESS_OF_OP(tree->left))
+            {
+              /* replace *&obj with obj */
+              return tree->left->left;
+            }
+          TTYPE (tree) = copyLinkChain (LTYPE (tree)->next);
+         TETYPE (tree) = getSpec (TTYPE (tree));
+         /* adjust the storage class */
+         switch (DCL_TYPE(tree->left->ftype)) {
+           case POINTER:
+             SPEC_SCLS(TETYPE(tree)) = S_DATA;
+             break;
+           case FPOINTER:
+             SPEC_SCLS(TETYPE(tree)) = S_XDATA; 
+             break;
+           case CPOINTER:
+             SPEC_SCLS(TETYPE(tree)) = S_CODE; 
+             break;
+           case GPOINTER:
+             SPEC_SCLS (TETYPE (tree)) = 0;
+             break;
+           case PPOINTER:
+             SPEC_SCLS(TETYPE(tree)) = S_XSTACK; 
+             break;
+           case IPOINTER:
+             SPEC_SCLS(TETYPE(tree)) = S_IDATA;
+             break;
+           case EEPPOINTER:
+             SPEC_SCLS(TETYPE(tree)) = S_EEPROM;
+             break;
+           case UPOINTER:
+             SPEC_SCLS (TETYPE (tree)) = 0;
+              break;
+           case ARRAY:
+           case FUNCTION:
+             break;
+         }
          return tree;
        }
 
@@ -2358,19 +2689,34 @@ decorateType (ast * tree)
          tree->right = tTree;
        }
 
+      /* if right is a literal and */
+      /* we can find a 2nd literal in a mul-tree then */
+      /* rearrange the tree */
+      if (IS_LITERAL (RTYPE (tree)))
+       {
+         ast *parent;
+         ast *litTree = searchLitOp (tree, &parent, "*");
+         if (litTree)
+           {
+             ast *tTree = litTree->left;
+             litTree->left = tree->right;
+             tree->right = tTree;
+             /* both operands in litTree are literal now */
+             decorateType (parent);
+           }
+        }
+
       LRVAL (tree) = RRVAL (tree) = 1;
+      TETYPE (tree) = getSpec (TTYPE (tree) =
+                              computeType (LTYPE (tree),
+                                           RTYPE (tree)));
+
       /* promote result to int if left & right are char
         this will facilitate hardware multiplies 8bit x 8bit = 16bit */
       if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) {
-       TETYPE (tree) = getSpec (TTYPE (tree) =
-                                computeType (LTYPE (tree),
-                                             RTYPE (tree)));
        SPEC_NOUN(TETYPE(tree)) = V_INT;
-      } else {
-       TETYPE (tree) = getSpec (TTYPE (tree) =
-                                computeType (LTYPE (tree),
-                                             RTYPE (tree)));
       }
+
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -2452,9 +2798,49 @@ decorateType (ast * tree)
          tree->right = tTree;
        }
 
+      /* if right is a literal and */
+      /* left is also an addition/subtraction with a literal then */
+      /* rearrange the tree */
+      if (IS_LITERAL (RTYPE (tree)))
+       {
+         ast *litTree, *parent;
+         litTree = searchLitOp (tree, &parent, "+-");
+         if (litTree)
+           {
+             if (litTree->opval.op == '+')
+               {
+                 /* foo_aa */
+                 ast *tTree = litTree->left;
+                 litTree->left = tree->right;
+                 tree->right = tree->left;
+                 tree->left = tTree;
+               }
+             else if (litTree->opval.op == '-')
+               {
+                 if (IS_LITERAL (RTYPE (litTree)))
+                   {
+                     /* foo_asr */
+                     ast *tTree = litTree->left;
+                     litTree->left = tree->right;
+                     tree->right = tTree;
+                   }
+                 else
+                   {
+                     /* foo_asl */
+                     ast *tTree = litTree->right;
+                     litTree->right = tree->right;
+                     tree->right = tTree;
+                     litTree->opval.op = '+';
+                     tree->opval.op = '-';
+                   }
+               }
+             decorateType (parent);
+           }
+       }
+
       LRVAL (tree) = RRVAL (tree) = 1;
       /* if the left is a pointer */
-      if (IS_PTR (LTYPE (tree)))
+      if (IS_PTR (LTYPE (tree)) || IS_AGGREGATE (LTYPE (tree)) )
        TETYPE (tree) = getSpec (TTYPE (tree) =
                                 LTYPE (tree));
       else
@@ -2489,7 +2875,7 @@ decorateType (ast * tree)
              return tree;
            }
          LRVAL (tree) = 1;
-         TTYPE (tree) = LTYPE (tree);
+         TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
          return tree;
        }
 
@@ -2560,12 +2946,54 @@ decorateType (ast * tree)
        TETYPE (tree) = getSpec (TTYPE (tree) =
                                 computeType (LTYPE (tree),
                                              RTYPE (tree)));
+
       LRVAL (tree) = RRVAL (tree) = 1;
+
+      /* if right is a literal and */
+      /* left is also an addition/subtraction with a literal then */
+      /* rearrange the tree */
+      if (IS_LITERAL (RTYPE (tree))
+          /* avoid infinite loop */
+          && (TYPE_UDWORD) floatFromVal (tree->right->opval.val) != 0)
+       {
+         ast *litTree, *litParent;
+         litTree = searchLitOp (tree, &litParent, "+-");
+         if (litTree)
+           {
+             if (litTree->opval.op == '+')
+               {
+                 /* foo_sa */
+                 litTree->right = newNode ('-', litTree->right, tree->right);
+                 litTree->right->lineno = tree->lineno;
+
+                 tree->right->opval.val = constVal ("0");
+               }
+             else if (litTree->opval.op == '-')
+               {
+                 if (IS_LITERAL (RTYPE (litTree)))
+                   {
+                     /* foo_ssr */
+                     litTree->right = newNode ('+', tree->right, litTree->right);
+                     litTree->right->lineno = tree->lineno;
+
+                     tree->right->opval.val = constVal ("0");
+                   }
+                 else
+                   {
+                     /* foo_ssl */
+                     ast *tTree = litTree->right;
+                     litTree->right = tree->right;
+                     tree->right = tTree;
+                   }
+               }
+             decorateType (litParent);
+           }
+       }
       return tree;
 
       /*------------------------------------------------------------------*/
       /*----------------------------*/
-      /*    compliment              */
+      /*    complement              */
       /*----------------------------*/
     case '~':
       /* can be only integral type */
@@ -2621,6 +3049,7 @@ decorateType (ast * tree)
       /*----------------------------*/
     case RRC:
     case RLC:
+    case SWAP:
       TTYPE (tree) = LTYPE (tree);
       TETYPE (tree) = LETYPE (tree);
       return tree;
@@ -2655,43 +3084,29 @@ decorateType (ast * tree)
                                   tree->opval.val->type);
          return tree;
        }
-      /* a left shift must be done with at least 16bits */
-      if ((tree->opval.op==LEFT_OP) && (getSize(LTYPE(tree))<2)) {
-       // insert a cast
-       if (IS_AST_SYM_VALUE(tree->left)) {
-         tree->left = 
-           decorateType (newNode (CAST,
-                                  newAst_LINK(copyLinkChain(LTYPE(tree))),
-                                  tree->left));
-         SPEC_NOUN(tree->left->left->ftype)=V_INT;
-       } else {
-         // must be a literal, we can do it right away
-         SPEC_NOUN(tree->left->opval.val->type)=V_INT;
-       }
-      }
+
       /* if only the right side is a literal & we are
          shifting more than size of the left operand then zero */
       if (IS_LITERAL (RTYPE (tree)) &&
          ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >=
          (getSize (LTYPE (tree)) * 8))
        {
-         werror (W_SHIFT_CHANGED,
-                 (tree->opval.op == LEFT_OP ? "left" : "right"));
-         tree->type = EX_VALUE;
-         tree->left = tree->right = NULL;
-         tree->opval.val = constVal ("0");
-         TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
-         return tree;
+         if (tree->opval.op==LEFT_OP ||
+             (tree->opval.op==RIGHT_OP && SPEC_USIGN(LETYPE(tree)))) {
+           lineno=tree->lineno;
+           werror (W_SHIFT_CHANGED,
+                   (tree->opval.op == LEFT_OP ? "left" : "right"));
+           tree->type = EX_VALUE;
+           tree->left = tree->right = NULL;
+           tree->opval.val = constVal ("0");
+           TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
+           return tree;
+         }
        }
       LRVAL (tree) = RRVAL (tree) = 1;
-      if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree)))
-       {
-         COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree));
-       }
-      else
-       {
-         COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
-       }
+      TTYPE (tree) = TETYPE (tree) = copyLinkChain (LTYPE (tree));
+      if (IS_LITERAL (TTYPE (tree)))
+        SPEC_SCLS (TTYPE (tree)) &= ~S_LITERAL;
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -2705,7 +3120,7 @@ decorateType (ast * tree)
          werror (E_CAST_ILLEGAL);
          goto errorTreeReturn;
        }
-      
+
       /* make sure the type is complete and sane */
       checkTypeSanity(LETYPE(tree), "(cast)");
 
@@ -2721,11 +3136,11 @@ decorateType (ast * tree)
                      tree->right = NULL;
                      TTYPE (tree) = tree->opval.val->type;
                      tree->values.literalFromCast = 1;
-             } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) && 
+             } else if (IS_GENPTR(LTYPE(tree)) && !IS_PTR(RTYPE(tree)) &&
                         ((int)floatFromVal(valFromType(RETYPE(tree)))) !=0 ) /* special case of NULL */  {
                      sym_link *rest = LTYPE(tree)->next;
-                     werror(W_LITERAL_GENERIC);                      
-                     TTYPE(tree) = newLink();
+                     werror(W_LITERAL_GENERIC);
+                     TTYPE(tree) = newLink(DECLARATOR);
                      DCL_TYPE(TTYPE(tree)) = FPOINTER;
                      TTYPE(tree)->next = rest;
                      tree->left->opval.lnk = TTYPE(tree);
@@ -2743,27 +3158,115 @@ decorateType (ast * tree)
       /* if pointer to struct then check names */
       if (IS_PTR(LTYPE(tree)) && IS_STRUCT(LTYPE(tree)->next) &&
          IS_PTR(RTYPE(tree)) && IS_STRUCT(RTYPE(tree)->next) &&
-         strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag)) 
+         strcmp(SPEC_STRUCT(LETYPE(tree))->tag,SPEC_STRUCT(RETYPE(tree))->tag))
        {
          werror(W_CAST_STRUCT_PTR,SPEC_STRUCT(RETYPE(tree))->tag,
                 SPEC_STRUCT(LETYPE(tree))->tag);
        }
 #endif
-      /* if the right is a literal replace the tree */
-      if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) {
-       tree->type = EX_VALUE;
+      if (IS_ADDRESS_OF_OP(tree->right)
+          && IS_AST_SYM_VALUE (tree->right->left)
+          && SPEC_ABSA (AST_SYMBOL (tree->right->left)->etype)) {
+
+        tree->type = EX_VALUE;
        tree->opval.val =
          valCastLiteral (LTYPE (tree),
-                         floatFromVal (valFromType (RETYPE (tree))));
+                         SPEC_ADDR (AST_SYMBOL (tree->right->left)->etype));
+       TTYPE (tree) = tree->opval.val->type;
+        TETYPE (tree) = getSpec (TTYPE (tree));
        tree->left = NULL;
        tree->right = NULL;
-       TTYPE (tree) = tree->opval.val->type;
        tree->values.literalFromCast = 1;
-      } else {
-       TTYPE (tree) = LTYPE (tree);
-       LRVAL (tree) = 1;
+        return tree;
+      }
+
+      /* handle offsetof macro:            */
+      /* #define offsetof(TYPE, MEMBER) \  */
+      /* ((unsigned) &((TYPE *)0)->MEMBER) */
+      if (IS_ADDRESS_OF_OP(tree->right)
+          && IS_AST_OP (tree->right->left)
+          && tree->right->left->opval.op == PTR_OP
+          && IS_AST_OP (tree->right->left->left)
+          && tree->right->left->left->opval.op == CAST
+          && IS_AST_LIT_VALUE(tree->right->left->left->right)) {
+
+        symbol *element = getStructElement (
+          SPEC_STRUCT (LETYPE(tree->right->left)),
+         AST_SYMBOL(tree->right->left->right)
+        );
+
+        if (element) {
+          tree->type = EX_VALUE;
+         tree->opval.val = valCastLiteral (
+           LTYPE (tree),
+           element->offset
+            + floatFromVal (valFromType (RETYPE (tree->right->left->left)))
+          );
+
+         TTYPE (tree) = tree->opval.val->type;
+          TETYPE (tree) = getSpec (TTYPE (tree));
+         tree->left = NULL;
+         tree->right = NULL;
+          return tree;
+        }
+      }
+
+      /* if the right is a literal replace the tree */
+      if (IS_LITERAL (RETYPE (tree))) {
+        if (IS_PTR (LTYPE (tree)) && !IS_GENPTR (LTYPE (tree)) ) {
+          /* rewrite      (type *)litaddr
+             as           &temp
+             and define   type at litaddr temp
+             (but only if type's storage class is not generic)
+          */
+          ast *newTree = newNode ('&', NULL, NULL);
+          symbol *sym;
+
+          TTYPE (newTree) = LTYPE (tree);
+          TETYPE (newTree) = getSpec(LTYPE (tree));
+
+          /* define a global symbol at the casted address*/
+          sym = newSymbol(genSymName (0), 0);
+          sym->type = LTYPE (tree)->next;
+          if (!sym->type)
+            sym->type = newLink (V_VOID);
+          sym->etype = getSpec(sym->type);
+          SPEC_SCLS (sym->etype) = sclsFromPtr (LTYPE (tree));
+          sym->lineDef = tree->lineno;
+          sym->cdef = 1;
+          sym->isref = 1;
+          SPEC_STAT (sym->etype) = 1;
+          SPEC_ADDR(sym->etype) = floatFromVal (valFromType (RETYPE (tree)));
+          SPEC_ABSA(sym->etype) = 1;
+          addSym (SymbolTab, sym, sym->name, 0, 0, 0);
+          allocGlobal (sym);
+
+          newTree->left = newAst_VALUE(symbolVal(sym));
+          newTree->left->lineno = tree->lineno;
+          LTYPE (newTree) = sym->type;
+          LETYPE (newTree) = sym->etype;
+         LLVAL (newTree) = 1;
+          LRVAL (newTree) = 0;
+          TLVAL (newTree) = 1;
+          return newTree;
+        }
+        if (!IS_PTR (LTYPE (tree))) {
+         tree->type = EX_VALUE;
+         tree->opval.val =
+         valCastLiteral (LTYPE (tree),
+                         floatFromVal (valFromType (RETYPE (tree))));
+         TTYPE (tree) = tree->opval.val->type;
+         tree->left = NULL;
+         tree->right = NULL;
+         tree->values.literalFromCast = 1;
+         TETYPE (tree) = getSpec (TTYPE (tree));
+          return tree;
+        }
       }
-#endif      
+      TTYPE (tree) = LTYPE (tree);
+      LRVAL (tree) = 1;
+
+#endif
       TETYPE (tree) = getSpec (TTYPE (tree));
 
       return tree;
@@ -2828,10 +3331,17 @@ decorateType (ast * tree)
       /* if they are pointers they must be castable */
       if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)))
        {
+         if (tree->opval.op==EQ_OP &&
+             !IS_GENPTR(LTYPE(tree)) && IS_GENPTR(RTYPE(tree))) {
+           // we cannot cast a gptr to a !gptr: switch the leaves
+           struct ast *s=tree->left;
+           tree->left=tree->right;
+           tree->right=s;
+         }
          if (compareType (LTYPE (tree), RTYPE (tree)) == 0)
            {
              werror (E_COMPARE_OP);
-             fprintf (stderr, "comparing type ");
+             fprintf (stderr, "comparring type ");
              printTypeChain (LTYPE (tree), stderr);
              fprintf (stderr, "to type ");
              printTypeChain (RTYPE (tree), stderr);
@@ -2858,7 +3368,7 @@ decorateType (ast * tree)
        }
       /* if unsigned value < 0  then always false */
       /* if (unsigned value) > 0 then (unsigned value) */
-      if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) && 
+      if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree))  && 
          ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
 
          if (tree->opval.op == '<') {
@@ -2893,7 +3403,7 @@ decorateType (ast * tree)
     case SIZEOF:               /* evaluate wihout code generation */
       /* change the type to a integer */
       tree->type = EX_VALUE;
-      sprintf (buffer, "%d", (getSize (tree->right->ftype)));
+      SNPRINTF(buffer, sizeof(buffer), "%d", (getSize (tree->right->ftype)));
       tree->opval.val = constVal (buffer);
       tree->right = tree->left = NULL;
       TETYPE (tree) = getSpec (TTYPE (tree) =
@@ -2927,6 +3437,9 @@ decorateType (ast * tree)
                case V_STRUCT:
                    typeofv = TYPEOF_STRUCT;
                    break;
+               case V_BITFIELD:
+                   typeofv = TYPEOF_BITFIELD;
+                   break;
                case V_BIT:
                    typeofv = TYPEOF_BIT;
                    break;
@@ -2966,7 +3479,7 @@ decorateType (ast * tree)
                    break;
                }
            }
-           sprintf (buffer, "%d", typeofv);
+           SNPRINTF (buffer, sizeof(buffer), "%d", typeofv);
            tree->opval.val = constVal (buffer);
            tree->right = tree->left = NULL;
            TETYPE (tree) = getSpec (TTYPE (tree) =
@@ -3025,12 +3538,12 @@ decorateType (ast * tree)
       RRVAL (tree) = 1;
       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
 
-      if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
-       werror (E_CODE_WRITE, ");
+      if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
+       werror (E_CODE_WRITE, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
 
       if (LRVAL (tree))
        {
-         werror (E_LVALUE_REQUIRED, "*= or /=");
+         werror (E_LVALUE_REQUIRED, *tree->opval.op==MUL_ASSIGN ? "*=" : "/=");
          goto errorTreeReturn;
        }
       LLVAL (tree) = 1;
@@ -3053,7 +3566,7 @@ decorateType (ast * tree)
       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
 
       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
-       werror (E_CODE_WRITE, " ");
+       werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
 
       if (LRVAL (tree))
        {
@@ -3088,7 +3601,7 @@ decorateType (ast * tree)
                                            RTYPE (tree)));
 
       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
-       werror (E_CODE_WRITE, " ");
+       werror (E_CODE_WRITE, "-=");
 
       if (LRVAL (tree))
        {
@@ -3129,7 +3642,7 @@ decorateType (ast * tree)
                                            RTYPE (tree)));
 
       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
-       werror (E_CODE_WRITE, " ");
+       werror (E_CODE_WRITE, "+=");
 
       if (LRVAL (tree))
        {
@@ -3160,7 +3673,6 @@ decorateType (ast * tree)
        {
          werror (E_TYPE_MISMATCH, "assignment", " ");
          printFromToType(RTYPE(tree),LTYPE(tree));
-         //goto errorTreeReturn;
        }
 
       /* if the left side of the tree is of type void
@@ -3176,8 +3688,8 @@ decorateType (ast * tree)
       RRVAL (tree) = 1;
       LLVAL (tree) = 1;
       if (!tree->initMode ) {
-       if ((IS_SPEC(LETYPE(tree)) && IS_CONSTANT (LETYPE (tree))))
-         werror (E_CODE_WRITE, " ");
+        if (IS_CONSTANT(LTYPE(tree)))
+         werror (E_CODE_WRITE, "=");
       }
       if (LRVAL (tree))
        {
@@ -3211,12 +3723,15 @@ decorateType (ast * tree)
       if ((options.stackAuto || IFFUNC_ISREENT (LTYPE (tree))) && 
          !IFFUNC_ISBUILTIN(LTYPE(tree)))
        {
-         //FUNC_ARGS(tree->left->ftype) = 
-         //reverseVal (FUNC_ARGS(tree->left->ftype));
          reverseParms (tree->right);
        }
 
-      TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
+      if (IS_CODEPTR(LTYPE(tree))) {
+       TTYPE(tree) = LTYPE(tree)->next->next;
+      } else {
+       TTYPE(tree) = LTYPE(tree)->next;
+      }
+      TETYPE (tree) = getSpec (TTYPE (tree));
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -3258,7 +3773,7 @@ decorateType (ast * tree)
 
       if (!IS_VOID (currFunc->type->next) && tree->right == NULL)
        {
-         werror (E_VOID_FUNC, currFunc->name);
+         werror (W_VOID_FUNC, currFunc->name);
          goto errorTreeReturn;
        }
 
@@ -3346,7 +3861,7 @@ sizeofOp (sym_link * type)
   checkTypeSanity(type, "(sizeof)");
 
   /* get the size and convert it to character  */
-  sprintf (buff, "%d", getSize (type));
+  SNPRINTF (buff, sizeof(buff), "%d", getSize (type));
 
   /* now convert into value  */
   return constVal (buff);
@@ -3380,7 +3895,7 @@ backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
       static int localLbl = 0;
       symbol *localLabel;
 
-      sprintf (buffer, "_and_%d", localLbl++);
+      SNPRINTF(buffer, sizeof(buffer), "_andif_%d", localLbl++);
       localLabel = newSymbol (buffer, NestLevel);
 
       tree->left = backPatchLabels (tree->left, localLabel, falseLabel);
@@ -3406,7 +3921,7 @@ backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel)
       static int localLbl = 0;
       symbol *localLabel;
 
-      sprintf (buffer, "_or_%d", localLbl++);
+      SNPRINTF(buffer, sizeof(buffer), "_orif_%d", localLbl++);
       localLabel = newSymbol (buffer, NestLevel);
 
       tree->left = backPatchLabels (tree->left, trueLabel, localLabel);
@@ -3468,12 +3983,12 @@ createBlock (symbol * decl, ast * body)
   ast *ex;
 
   /* if the block has nothing */
-  if (!body)
+  if (!body && !decl)
     return NULL;
 
   ex = newNode (BLOCK, NULL, body);
   ex->values.sym = decl;
-
+  
   ex->right = ex->right;
   ex->level++;
   ex->lineno = 0;
@@ -3498,7 +4013,7 @@ createLabel (symbol * label, ast * stmnt)
     label = newSymbol (label->name, label->level);
 
   /* change the name before putting it in add _ */
-  sprintf (name, "%s", label->name);
+  SNPRINTF(name, sizeof(name), "%s", label->name);
 
   /* put the label in the LabelSymbol table    */
   /* but first check if a label of the same    */
@@ -3586,7 +4101,8 @@ createCase (ast * swStat, ast * caseVal, ast * stmnt)
     }
 
   /* create the case label   */
-  sprintf (caseLbl, "_case_%d_%d",
+  SNPRINTF(caseLbl, sizeof(caseLbl), 
+          "_case_%d_%d",
           swStat->values.switchVals.swNum,
           (int) floatFromVal (caseVal->opval.val));
 
@@ -3615,7 +4131,8 @@ createDefault (ast * swStat, ast * stmnt)
   swStat->values.switchVals.swDefault = 1;
 
   /* create the label  */
-  sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum);
+  SNPRINTF (defLbl, sizeof(defLbl),
+           "_default_%d", swStat->values.switchVals.swNum);
   return createLabel (newSymbol (defLbl, 0), stmnt);
 }
 
@@ -3638,18 +4155,18 @@ createIf (ast * condAst, ast * ifBody, ast * elseBody)
   }
 
   /* create the labels */
-  sprintf (buffer, "_iffalse_%d", Lblnum);
+  SNPRINTF (buffer, sizeof(buffer), "_iffalse_%d", Lblnum);
   ifFalse = newSymbol (buffer, NestLevel);
   /* if no else body then end == false */
   if (!elseBody)
     ifEnd = ifFalse;
   else
     {
-      sprintf (buffer, "_ifend_%d", Lblnum);
+      SNPRINTF(buffer, sizeof(buffer), "_ifend_%d", Lblnum);
       ifEnd = newSymbol (buffer, NestLevel);
     }
 
-  sprintf (buffer, "_iftrue_%d", Lblnum);
+  SNPRINTF (buffer, sizeof(buffer), "_iftrue_%d", Lblnum);
   ifTrue = newSymbol (buffer, NestLevel);
 
   Lblnum++;
@@ -3871,6 +4388,11 @@ optimizeGetHbit (ast * tree)
   if ((i = (int) AST_LIT_VALUE (tree->left->right)) !=
       (j = (getSize (TTYPE (tree->left->left)) * 8 - 1)))
     return tree;
+      
+  /* make sure the port supports GETHBIT */
+  if (port->hasExtBitOp
+      && !port->hasExtBitOp(GETHBIT, getSize (TTYPE (tree->left->left))))
+    return tree;
 
   return decorateType (newNode (GETHBIT, tree->left->left, NULL));
 
@@ -3923,6 +4445,11 @@ optimizeRRCRLC (ast * root)
          (getSize (TTYPE (root->left->left)) * 8 - 1))
        goto tryNext0;
 
+      /* make sure the port supports RLC */
+      if (port->hasExtBitOp
+          && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
+        return root;
+
       /* whew got the first case : create the AST */
       return newNode (RLC, root->left->left, NULL);
     }
@@ -3953,6 +4480,11 @@ tryNext0:
          (getSize (TTYPE (root->left->left)) * 8 - 1))
        goto tryNext1;
 
+      /* make sure the port supports RLC */
+      if (port->hasExtBitOp
+          && !port->hasExtBitOp(RLC, getSize (TTYPE (root->left->left))))
+        return root;
+
       /* whew got the first case : create the AST */
       return newNode (RLC, root->left->left, NULL);
 
@@ -3984,6 +4516,11 @@ tryNext1:
          (getSize (TTYPE (root->left->left)) * 8 - 1))
        goto tryNext2;
 
+      /* make sure the port supports RRC */
+      if (port->hasExtBitOp
+          && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
+        return root;
+
       /* whew got the first case : create the AST */
       return newNode (RRC, root->left->left, NULL);
 
@@ -4014,6 +4551,11 @@ tryNext2:
          (getSize (TTYPE (root->left->left)) * 8 - 1))
        return root;
 
+      /* make sure the port supports RRC */
+      if (port->hasExtBitOp
+          && !port->hasExtBitOp(RRC, getSize (TTYPE (root->left->left))))
+        return root;
+
       /* whew got the first case : create the AST */
       return newNode (RRC, root->left->left, NULL);
 
@@ -4023,6 +4565,61 @@ tryNext2:
   return root;
 }
 
+/*-----------------------------------------------------------------*/
+/* optimizeSWAP :- optimize for nibble/byte/word swaps             */
+/*-----------------------------------------------------------------*/
+ast *
+optimizeSWAP (ast * root)
+{
+  /* will look for trees of the form
+     (?expr << 4) | (?expr >> 4) or
+     (?expr >> 4) | (?expr << 4) will make that
+     into a SWAP : operation ..
+     note : by 4 I mean (number of bits required to hold the
+     variable /2 ) */
+  /* if the root operations is not a | operation the not */
+  if (!IS_BITOR (root))
+    return root;
+
+  /* (?expr << 4) | (?expr >> 4) */
+  if ((IS_LEFT_OP (root->left) && IS_RIGHT_OP (root->right))
+      || (IS_RIGHT_OP (root->left) && IS_LEFT_OP (root->right)))
+    {
+
+      if (!SPEC_USIGN (TETYPE (root->left->left)))
+       return root;
+
+      if (!IS_AST_LIT_VALUE (root->left->right) ||
+         !IS_AST_LIT_VALUE (root->right->right))
+       return root;
+
+      /* make sure it is the same expression */
+      if (!isAstEqual (root->left->left,
+                      root->right->left))
+       return root;
+
+      if (AST_LIT_VALUE (root->left->right) !=
+         (getSize (TTYPE (root->left->left)) * 4))
+       return root;
+
+      if (AST_LIT_VALUE (root->right->right) !=
+         (getSize (TTYPE (root->left->left)) * 4))
+       return root;
+
+      /* make sure the port supports SWAP */
+      if (port->hasExtBitOp
+          && !port->hasExtBitOp(SWAP, getSize (TTYPE (root->left->left))))
+        return root;
+
+      /* found it : create the AST */
+      return newNode (SWAP, root->left->left, NULL);
+    }
+
+
+  /* not found return root */
+  return root;
+}
+
 /*-----------------------------------------------------------------*/
 /* optimizeCompare - otimizes compares for bit variables     */
 /*-----------------------------------------------------------------*/
@@ -4244,7 +4841,7 @@ createFunction (symbol * name, ast * body)
       addSymChain (name);
       allocVariables (name);
     }
-  name->lastLine = yylineno;
+  name->lastLine = mylineno;
   currFunc = name;
 
   /* set the stack pointer */
@@ -4281,7 +4878,7 @@ createFunction (symbol * name, ast * body)
     name->stack = SPEC_STAK (fetype) = stack;
 
   /* name needs to be mangled */
-  sprintf (name->rname, "%s%s", port->fun_prefix, name->name);
+  SNPRINTF (name->rname, sizeof(name->rname), "%s%s", port->fun_prefix, name->name);
 
   body = resolveSymbols (body);        /* resolve the symbols */
   body = decorateType (body);  /* propagateType & do semantic checks */
@@ -4323,6 +4920,7 @@ skipall:
 
   /* dealloc the block variables */
   processBlockVars (body, &stack, DEALLOCATE);
+  outputDebugStackSymbols();
   /* deallocate paramaters */
   deallocParms (FUNC_ARGS(name->type));
 
@@ -4338,7 +4936,7 @@ skipall:
   applyToSet (operKeyReset, resetParmKey);
 
   if (options.debug)
-    cdbStructBlock (1, cdbFile);
+    cdbStructBlock(1);
 
   cleanUpLevel (LabelTab, 0);
   cleanUpBlock (StructTab, 1);
@@ -4350,14 +4948,14 @@ skipall:
 }
 
 
-#define INDENT(x,f) { int i ; for (i=0;i < x; i++) fprintf(f," "); }
+#define INDENT(x,f) { int i ; fprintf (f, "%d:", tree->lineno); for (i=0;i < x; i++) fprintf(f," "); }
 /*-----------------------------------------------------------------*/
 /* ast_print : prints the ast (for debugging purposes)             */
 /*-----------------------------------------------------------------*/
 
 void ast_print (ast * tree, FILE *outfile, int indent)
 {
-       
+
        if (!tree) return ;
 
        /* can print only decorated trees */
@@ -4370,7 +4968,7 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                fprintf(outfile,"ERROR_NODE(%p)\n",tree);
        }
 
-       
+
        /* print the line          */
        /* if not block & function */
        if (tree->type == EX_OP &&
@@ -4378,13 +4976,13 @@ void ast_print (ast * tree, FILE *outfile, int indent)
             tree->opval.op != BLOCK &&
             tree->opval.op != NULLOP)) {
        }
-       
+
        if (tree->opval.op == FUNCTION) {
                int arg=0;
                value *args=FUNC_ARGS(tree->left->opval.val->type);
-               fprintf(outfile,"FUNCTION (%s=%p) type (", 
+               fprintf(outfile,"FUNCTION (%s=%p) type (",
                        tree->left->opval.val->name, tree);
-               printTypeChain (tree->ftype,outfile);
+               printTypeChain (tree->left->opval.val->type->next,outfile);
                fprintf(outfile,") args (");
                do {
                  if (arg) {
@@ -4409,8 +5007,8 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                                decls->name, decls);
                        printTypeChain(decls->type,outfile);
                        fprintf(outfile,")\n");
-                       
-                       decls = decls->next;                    
+
+                       decls = decls->next;
                }
                ast_print(tree->right,outfile,indent+2);
                INDENT(indent,outfile);
@@ -4418,9 +5016,7 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                return;
        }
        if (tree->opval.op == NULLOP) {
-               fprintf(outfile,"\n");
                ast_print(tree->left,outfile,indent);
-               fprintf(outfile,"\n");
                ast_print(tree->right,outfile,indent);
                return ;
        }
@@ -4434,11 +5030,14 @@ void ast_print (ast * tree, FILE *outfile, int indent)
        /* just get the type        */
        if (tree->type == EX_VALUE) {
 
-               if (IS_LITERAL (tree->opval.val->etype)) {                      
-                       fprintf(outfile,"CONSTANT (%p) value = %d, 0x%x, %g", tree,
-                               (int) floatFromVal(tree->opval.val),
-                               (int) floatFromVal(tree->opval.val),
-                               floatFromVal(tree->opval.val));
+               if (IS_LITERAL (tree->opval.val->etype)) {
+                       fprintf(outfile,"CONSTANT (%p) value = ", tree);
+                       if (SPEC_USIGN (tree->opval.val->etype))
+                               fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val));
+                       else
+                               fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val));
+                       fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val),
+                                                     floatFromVal(tree->opval.val));
                } else if (tree->opval.val->sym) {
                        /* if the undefined flag is set then give error message */
                        if (tree->opval.val->sym->undefined) {
@@ -4469,7 +5068,7 @@ void ast_print (ast * tree, FILE *outfile, int indent)
 
 
        /* depending on type of operator do */
-       
+
        switch (tree->opval.op) {
                /*------------------------------------------------------------------*/
                /*----------------------------*/
@@ -4511,25 +5110,35 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                /*----------------------------*/
                /*  ++/-- operation           */
                /*----------------------------*/
-       case INC_OP:            /* incerement operator unary so left only */
+       case INC_OP:
+               if (tree->left)
+                 fprintf(outfile,"post-");
+               else
+                 fprintf(outfile,"pre-");
                fprintf(outfile,"INC_OP (%p) type (",tree);
                printTypeChain(tree->ftype,outfile);
                fprintf(outfile,")\n");
-               ast_print(tree->left,outfile,indent+2);
+               ast_print(tree->left,outfile,indent+2); /* postincrement case */
+               ast_print(tree->right,outfile,indent+2); /* preincrement case */
                return ;
 
        case DEC_OP:
+               if (tree->left)
+                 fprintf(outfile,"post-");
+               else
+                 fprintf(outfile,"pre-");
                fprintf(outfile,"DEC_OP (%p) type (",tree);
                printTypeChain(tree->ftype,outfile);
                fprintf(outfile,")\n");
-               ast_print(tree->left,outfile,indent+2);
+               ast_print(tree->left,outfile,indent+2); /* postdecrement case */
+               ast_print(tree->right,outfile,indent+2); /* predecrement case */
                return ;
 
                /*------------------------------------------------------------------*/
                /*----------------------------*/
                /*  bitwise and               */
                /*----------------------------*/
-       case '&':                       
+       case '&':
                if (tree->right) {
                        fprintf(outfile,"& (%p) type (",tree);
                        printTypeChain(tree->ftype,outfile);
@@ -4565,7 +5174,7 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                ast_print(tree->left,outfile,indent+2);
                ast_print(tree->right,outfile,indent+2);
                return ;
-               
+
                /*------------------------------------------------------------------*/
                /*----------------------------*/
                /*  division                  */
@@ -4695,6 +5304,12 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                fprintf(outfile,")\n");
                ast_print(tree->left,outfile,indent+2);
                return ;
+       case SWAP:
+               fprintf(outfile,"SWAP (%p) type (",tree);
+               printTypeChain(tree->ftype,outfile);
+               fprintf(outfile,")\n");
+               ast_print(tree->left,outfile,indent+2);
+               return ;
        case GETHBIT:
                fprintf(outfile,"GETHBIT (%p) type (",tree);
                printTypeChain(tree->ftype,outfile);
@@ -4842,14 +5457,14 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                ast_print(tree->right,outfile,indent+2);
                return;
        case OR_ASSIGN:
-               fprintf(outfile,"ORASS(*=) (%p) type (",tree);
+               fprintf(outfile,"ORASS(|=) (%p) type (",tree);
                printTypeChain(tree->ftype,outfile);
                fprintf(outfile,")\n");
                ast_print(tree->left,outfile,indent+2);
                ast_print(tree->right,outfile,indent+2);
                return;
        case XOR_ASSIGN:
-               fprintf(outfile,"XORASS(*=) (%p) type (",tree);
+               fprintf(outfile,"XORASS(^=) (%p) type (",tree);
                printTypeChain(tree->ftype,outfile);
                fprintf(outfile,")\n");
                ast_print(tree->left,outfile,indent+2);
@@ -4863,7 +5478,7 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                ast_print(tree->right,outfile,indent+2);
                return;
        case LEFT_ASSIGN:
-               fprintf(outfile,"LSHFTASS(*=) (%p) type (",tree);
+               fprintf(outfile,"LSHFTASS(<<=) (%p) type (",tree);
                printTypeChain(tree->ftype,outfile);
                fprintf(outfile,")\n");
                ast_print(tree->left,outfile,indent+2);
@@ -4980,15 +5595,23 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                fprintf(outfile,"IF (%p) \n",tree);
                ast_print(tree->left,outfile,indent+2);
                if (tree->trueLabel) {
-                       INDENT(indent,outfile);
+                       INDENT(indent+2,outfile);
                        fprintf(outfile,"NE(!=) 0 goto %s\n",tree->trueLabel->name);
                }
                if (tree->falseLabel) {
-                       INDENT(indent,outfile);
+                       INDENT(indent+2,outfile);
                        fprintf(outfile,"EQ(==) 0 goto %s\n",tree->falseLabel->name);
                }
                ast_print(tree->right,outfile,indent+2);
                return ;
+               /*----------------------------*/
+               /* goto Statement              */
+               /*----------------------------*/
+       case GOTO:
+               fprintf(outfile,"GOTO (%p) \n",tree);
+               ast_print(tree->left,outfile,indent+2);
+               fprintf(outfile,"\n");
+               return ;
                /*------------------------------------------------------------------*/
                /*----------------------------*/
                /* for Statement              */
@@ -5013,6 +5636,9 @@ void ast_print (ast * tree, FILE *outfile, int indent)
                fprintf(outfile,"FOR LOOP BODY \n");
                ast_print(tree->left,outfile,indent+2);
                return ;
+       case CRITICAL:
+               fprintf(outfile,"CRITICAL (%p) \n",tree);
+               ast_print(tree->left,outfile,indent+2);
        default:
            return ;
        }