* support/regression/fwk/lib/testfwk.c: printn is recursive and thus needs
[fw/sdcc] / src / SDCCast.c
index 35d8cc821da279764a34f5514304bc86cef38edb..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)
@@ -192,7 +185,7 @@ copyAstValues (ast * dest, ast * src)
     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));
@@ -209,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;
 
@@ -266,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)
@@ -563,7 +556,7 @@ funcOfTypeVarg (char *name, char * rtype, int nArgs , char **atypes)
            args = args->next = newValue ();
        }
     }
-    
+
     /* save it */
     addSymChain (sym);
     sym->cdef = 1;
@@ -575,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;
@@ -666,7 +659,7 @@ processParms (ast * func,
       if (IS_INTEGRAL (ftype)
          && (getSize (ftype) < (unsigned) INTSIZE))
        {
-         if (IS_AST_OP(actParm) && 
+         if (IS_AST_OP(actParm) &&
              (actParm->opval.op == LEFT_OP ||
               actParm->opval.op == '*' ||
               actParm->opval.op == '+' ||
@@ -1023,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
@@ -1211,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);
     }
@@ -1228,6 +1221,7 @@ processBlockVars (ast * tree, int *stack, int action)
   return tree;
 }
 
+
 /*-------------------------------------------------------------*/
 /* constExprTree - returns TRUE if this tree is a constant     */
 /*                 expression                                  */
@@ -1239,7 +1233,7 @@ bool constExprTree (ast *cexpr) {
   }
 
   cexpr = decorateType (resolveSymbols (cexpr));
-  
+
   switch (cexpr->type) 
     {
     case EX_VALUE:
@@ -1259,6 +1253,7 @@ bool constExprTree (ast *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;
@@ -1275,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=='&') { 
@@ -1287,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     */
@@ -1322,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");
@@ -1595,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 */
@@ -1663,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;
@@ -1681,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);
@@ -1702,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;
        }
       }
@@ -1776,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)
 {
@@ -1860,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)),
@@ -1876,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);
-  
+
+}
+
+/*-----------------------------------------------------------------*/
+/* 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 cheking */
+/* 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  */
 /*-----------------------------------------------------------------*/
@@ -1998,11 +2058,13 @@ 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)) < INTSIZE)) {
+       (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) &&
@@ -2106,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; 
@@ -2114,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; 
@@ -2125,10 +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;
 
@@ -2136,12 +2235,12 @@ 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 (TTYPE (tree)))
+        if (!tree->initMode && IS_CONSTANT(TTYPE(tree)))
          werror (E_CODE_WRITE, tree->opval.op==INC_OP ? "++" : "--");
 
        if (tree->right)
@@ -2197,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;
        }
@@ -2262,6 +2386,22 @@ decorateType (ast * tree)
       TETYPE (tree) = getSpec (TTYPE (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;
 
       /*------------------------------------------------------------------*/
@@ -2274,8 +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               */
@@ -2305,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),
@@ -2332,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;
 
       /*------------------------------------------------------------------*/
@@ -2389,9 +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));
+         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;
        }
 
@@ -2426,6 +2689,23 @@ 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),
@@ -2518,6 +2798,46 @@ 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)) || IS_AGGREGATE (LTYPE (tree)) )
@@ -2555,7 +2875,7 @@ decorateType (ast * tree)
              return tree;
            }
          LRVAL (tree) = 1;
-         TTYPE (tree) = LTYPE (tree);
+         TETYPE(tree) = getSpec (TTYPE (tree) = LTYPE (tree));
          return tree;
        }
 
@@ -2626,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 */
@@ -2687,6 +3049,7 @@ decorateType (ast * tree)
       /*----------------------------*/
     case RRC:
     case RLC:
+    case SWAP:
       TTYPE (tree) = LTYPE (tree);
       TETYPE (tree) = LETYPE (tree);
       return tree;
@@ -2741,14 +3104,9 @@ decorateType (ast * 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;
 
       /*------------------------------------------------------------------*/
@@ -2762,7 +3120,7 @@ decorateType (ast * tree)
          werror (E_CAST_ILLEGAL);
          goto errorTreeReturn;
        }
-      
+
       /* make sure the type is complete and sane */
       checkTypeSanity(LETYPE(tree), "(cast)");
 
@@ -2778,10 +3136,10 @@ 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);                      
+                     werror(W_LITERAL_GENERIC);
                      TTYPE(tree) = newLink(DECLARATOR);
                      DCL_TYPE(TTYPE(tree)) = FPOINTER;
                      TTYPE(tree)->next = rest;
@@ -2800,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;
@@ -2885,7 +3331,7 @@ 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 && 
+         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;
@@ -2922,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 == '<') {
@@ -2991,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;
@@ -3116,7 +3565,7 @@ decorateType (ast * tree)
       RRVAL (tree) = 1;
       TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree));
 
-      if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
+      if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
        werror (E_CODE_WRITE, "&= or |= or ^= or >>= or <<=");
 
       if (LRVAL (tree))
@@ -3151,7 +3600,7 @@ decorateType (ast * tree)
                               computeType (LTYPE (tree),
                                            RTYPE (tree)));
 
-      if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
+      if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
        werror (E_CODE_WRITE, "-=");
 
       if (LRVAL (tree))
@@ -3192,7 +3641,7 @@ decorateType (ast * tree)
                               computeType (LTYPE (tree),
                                            RTYPE (tree)));
 
-      if (!tree->initMode && IS_CONSTANT (LTYPE (tree)))
+      if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
        werror (E_CODE_WRITE, "+=");
 
       if (LRVAL (tree))
@@ -3224,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
@@ -3240,7 +3688,7 @@ decorateType (ast * tree)
       RRVAL (tree) = 1;
       LLVAL (tree) = 1;
       if (!tree->initMode ) {
-       if (IS_CONSTANT (LTYPE (tree)))
+        if (IS_CONSTANT(LTYPE(tree)))
          werror (E_CODE_WRITE, "=");
       }
       if (LRVAL (tree))
@@ -3275,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;
 
       /*------------------------------------------------------------------*/
@@ -3322,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;
        }
 
@@ -3532,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;
@@ -3937,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));
 
@@ -3989,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);
     }
@@ -4019,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);
 
@@ -4050,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);
 
@@ -4080,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);
 
@@ -4089,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     */
 /*-----------------------------------------------------------------*/
@@ -4310,7 +4841,7 @@ createFunction (symbol * name, ast * body)
       addSymChain (name);
       allocVariables (name);
     }
-  name->lastLine = yylineno;
+  name->lastLine = mylineno;
   currFunc = name;
 
   /* set the stack pointer */
@@ -4389,6 +4920,7 @@ skipall:
 
   /* dealloc the block variables */
   processBlockVars (body, &stack, DEALLOCATE);
+  outputDebugStackSymbols();
   /* deallocate paramaters */
   deallocParms (FUNC_ARGS(name->type));
 
@@ -4404,7 +4936,7 @@ skipall:
   applyToSet (operKeyReset, resetParmKey);
 
   if (options.debug)
-    cdbStructBlock (1, cdbFile);
+    cdbStructBlock(1);
 
   cleanUpLevel (LabelTab, 0);
   cleanUpBlock (StructTab, 1);
@@ -4423,7 +4955,7 @@ skipall:
 
 void ast_print (ast * tree, FILE *outfile, int indent)
 {
-       
+
        if (!tree) return ;
 
        /* can print only decorated trees */
@@ -4436,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 &&
@@ -4444,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) {
@@ -4475,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);
@@ -4498,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) {
@@ -4533,7 +5068,7 @@ void ast_print (ast * tree, FILE *outfile, int indent)
 
 
        /* depending on type of operator do */
-       
+
        switch (tree->opval.op) {
                /*------------------------------------------------------------------*/
                /*----------------------------*/
@@ -4575,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);
@@ -4629,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                  */
@@ -4759,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);
@@ -5085,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 ;
        }