This makes the dump files more readable
[fw/sdcc] / src / SDCCicode.c
index 0b74ff45a9344a0228e1b27fae27f0b738fc3dd6..9c37fe0a2d5f22cdc4197ffc06ea11eb134f0c4f 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "common.h"
 #include "newalloc.h"
+#include "math.h"
 
 /*-----------------------------------------------------------------*/
 /* global variables       */
@@ -37,21 +38,22 @@ char *filename;
 int lineno;
 int block;
 int scopeLevel;
-int lvaluereq;
 
 symbol *returnLabel;           /* function return label */
 symbol *entryLabel;            /* function entry  label */
+
 /*-----------------------------------------------------------------*/
 /* forward definition of some functions */
 operand *geniCodeDivision (operand *, operand *);
 operand *geniCodeAssign (operand *, operand *, int);
-operand *geniCodeArray (operand *, operand *);
+operand *geniCodeArray (operand *, operand *,int);
 operand *geniCodeArray2Ptr (operand *);
 operand *geniCodeRValue (operand *, bool);
-operand *geniCodeDerefPtr (operand *);
+operand *geniCodeDerefPtr (operand *,int);
+int isLvaluereq(int lvl);
 
 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
-/* forward definition of print functions */
+/* forward definition of ic print functions */
 PRINTFUNC (picGetValueAtAddr);
 PRINTFUNC (picSetValueAtAddr);
 PRINTFUNC (picAddrOf);
@@ -109,9 +111,85 @@ iCodeTable codeTable[] =
   {IFX, "if", picIfx, NULL},
   {INLINEASM, "", picInline, NULL},
   {RECEIVE, "recv", picReceive, NULL},
-  {SEND, "send", picGenericOne, NULL}
+  {SEND, "send", picGenericOne, NULL},
+  {ARRAYINIT, "arrayInit", picGenericOne, NULL},
 };
 
+/*-----------------------------------------------------------------*/
+/* checkConstantRange: check a constant against the type           */
+/*-----------------------------------------------------------------*/
+
+/*   pedantic=0: allmost anything is allowed as long as the absolute
+       value is within the bit range of the type, and -1 is treated as
+       0xf..f for unsigned types (e.g. in assign)
+     pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
+     pedantic>1: "char c=200" is not allowed (evaluates to -56)
+*/
+
+void checkConstantRange(sym_link *ltype, value *val, char *msg, 
+                       int pedantic) {
+  double max;
+  int warnings=0;
+  int negative=0;
+  long v;
+
+  max = pow ((double)2.0, (double)bitsForType(ltype));
+
+  if (SPEC_LONG(val->type)) {
+    if (SPEC_USIGN(val->type)) {
+      v=SPEC_CVAL(val->type).v_ulong;
+    } else {
+      v=SPEC_CVAL(val->type).v_long;
+    }
+  } else {
+    if (SPEC_USIGN(val->type)) {
+      v=SPEC_CVAL(val->type).v_uint;
+    } else {
+      v=SPEC_CVAL(val->type).v_int;
+    }
+  }
+
+
+#if 0
+  // this could be a good idea
+  if (options.pedantic)
+    pedantic=2;
+#endif
+
+  if (SPEC_NOUN(ltype)==FLOAT) {
+    // anything will do
+    return;
+  }
+
+  if (!SPEC_USIGN(val->type) && v<0) {
+    negative=1;
+    if (SPEC_USIGN(ltype) && (pedantic>1)) {
+      warnings++;
+    }
+    v=-v;
+  }
+
+  // if very pedantic: "char c=200" is not allowed
+  if (pedantic>1 && !SPEC_USIGN(ltype)) {
+    max = max/2 + negative;
+  }
+
+  if (v >= max) {
+    warnings++;
+  }
+
+#if 0 // temporary disabled, leaving the warning as a reminder
+  if (warnings) {
+    SNPRINTF (message, sizeof(message), "for %s %s in %s", 
+            SPEC_USIGN(ltype) ? "unsigned" : "signed",
+            nounName(ltype), msg);
+    werror (W_CONST_RANGE, message);
+
+    if (pedantic>1)
+      fatalError++;
+  }
+#endif
+}
 
 /*-----------------------------------------------------------------*/
 /* operandName - returns the name of the operand                   */
@@ -146,12 +224,14 @@ printOperand (operand * op, FILE * file)
     case SYMBOL:
 #define REGA 1
 #ifdef REGA
-      fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d}",                /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}"  , */
+      fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d ru%d dp%d}",                /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}"  , */
               (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
               op->key,
               OP_LIVEFROM (op), OP_LIVETO (op),
               OP_SYMBOL (op)->stack,
-              op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat
+              op->isaddr, OP_SYMBOL (op)->isreqv, 
+              OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
+              OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
        );
       {
        fprintf (file, "{");
@@ -306,6 +386,9 @@ PRINTFUNC (picGenericOne)
   if (!IC_RESULT (ic) && !IC_LEFT (ic))
     fprintf (of, s);
 
+  if (ic->op == SEND || ic->op == RECEIVE) {
+      fprintf(of,"{argreg = %d}",ic->argreg);
+  }
   fprintf (of, "\n");
 }
 
@@ -398,6 +481,10 @@ piCode (void *item, FILE * of)
   return 1;
 }
 
+void PICC(iCode *ic)
+{
+       printiCChain(ic,stdout);
+}
 /*-----------------------------------------------------------------*/
 /* printiCChain - prints intermediate code for humans              */
 /*-----------------------------------------------------------------*/
@@ -413,7 +500,7 @@ printiCChain (iCode * icChain, FILE * of)
     {
       if ((icTab = getTableEntry (loop->op)))
        {
-         fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
+         fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
                   loop->filename, loop->lineno,
                   loop->seq, loop->key, loop->depth, loop->supportRtn);
 
@@ -431,7 +518,7 @@ newOperand ()
 {
   operand *op;
 
-  op = Safe_calloc (1, sizeof (operand));
+  op = Safe_alloc ( sizeof (operand));
 
   op->key = 0;
   return op;
@@ -445,7 +532,7 @@ newiCode (int op, operand * left, operand * right)
 {
   iCode *ic;
 
-  ic = Safe_calloc (1, sizeof (iCode));
+  ic = Safe_alloc ( sizeof (iCode));
 
   ic->lineno = lineno;
   ic->filename = filename;
@@ -469,6 +556,10 @@ newiCodeCondition (operand * condition,
 {
   iCode *ic;
 
+  if (IS_VOID(operandType(condition))) {
+    werror(E_VOID_VALUE_USED);
+  }
+
   ic = newiCode (IFX, NULL, NULL);
   IC_COND (ic) = condition;
   IC_TRUE (ic) = trueLabel;
@@ -486,7 +577,7 @@ newiCodeLabelGoto (int op, symbol * label)
 
   ic = newiCode (op, NULL, NULL);
   ic->op = op;
-  ic->argLabel.label = label;
+  ic->label = label;
   IC_LEFT (ic) = NULL;
   IC_RIGHT (ic) = NULL;
   IC_RESULT (ic) = NULL;
@@ -502,11 +593,16 @@ newiTemp (char *s)
   symbol *itmp;
 
   if (s)
-    sprintf (buffer, "%s", s);
+  {
+      SNPRINTF (buffer, sizeof(buffer), "%s", s);
+  }
   else
-    sprintf (buffer, "iTemp%d", iTempNum++);
+  {
+      SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
+  }
+    
   itmp = newSymbol (buffer, 1);
-  strcpy (itmp->rname, itmp->name);
+  strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
   itmp->isitmp = 1;
 
   return itmp;
@@ -525,17 +621,19 @@ newiTempLabel (char *s)
     return itmplbl;
 
   if (s)
-    itmplbl = newSymbol (s, 1);
+    {
+       itmplbl = newSymbol (s, 1);
+    }
   else
     {
-      sprintf (buffer, "iTempLbl%d", iTempLblNum++);
+      SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
       itmplbl = newSymbol (buffer, 1);
     }
 
   itmplbl->isitmp = 1;
   itmplbl->islbl = 1;
   itmplbl->key = labelKey++;
-  addSym (LabelTab, itmplbl, itmplbl->name, 0, 0);
+  addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
   return itmplbl;
 }
 
@@ -547,13 +645,13 @@ newiTempPreheaderLabel ()
 {
   symbol *itmplbl;
 
-  sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
+  SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
   itmplbl = newSymbol (buffer, 1);
 
   itmplbl->isitmp = 1;
   itmplbl->islbl = 1;
   itmplbl->key = labelKey++;
-  addSym (LabelTab, itmplbl, itmplbl->name, 0, 0);
+  addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
   return itmplbl;
 }
 
@@ -579,6 +677,7 @@ copyiCode (iCode * ic)
   nic->filename = ic->filename;
   nic->block = ic->block;
   nic->level = ic->level;
+  nic->parmBytes = ic->parmBytes;
 
   /* deal with the special cases first */
   switch (ic->op)
@@ -598,13 +697,16 @@ copyiCode (iCode * ic)
     case PCALL:
       IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
       IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
-      IC_ARGS (nic) = IC_ARGS (ic);
       break;
 
     case INLINEASM:
       IC_INLINE (nic) = IC_INLINE (ic);
       break;
 
+    case ARRAYINIT:
+      IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
+      break;
+
     default:
       IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
       IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
@@ -697,6 +799,8 @@ isParameterToCall (value * args, operand * op)
 {
   value *tval = args;
 
+  wassert (IS_SYMOP(op));
+    
   while (tval)
     {
       if (tval->sym &&
@@ -719,7 +823,7 @@ isOperandGlobal (operand * op)
   if (IS_ITEMP (op))
     return 0;
 
-  if (op->type == SYMBOL &&
+  if (IS_SYMOP(op) &&
       (op->operand.symOperand->level == 0 ||
        IS_STATIC (op->operand.symOperand->etype) ||
        IS_EXTERN (op->operand.symOperand->etype))
@@ -769,6 +873,7 @@ isOperandLiteral (operand * op)
 
   return 0;
 }
+
 /*-----------------------------------------------------------------*/
 /* isOperandInFarSpace - will return true if operand is in farSpace */
 /*-----------------------------------------------------------------*/
@@ -797,6 +902,64 @@ isOperandInFarSpace (operand * op)
   return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
 }
 
+/*------------------------------------------------------------------*/
+/* isOperandInDirSpace - will return true if operand is in dirSpace */
+/*------------------------------------------------------------------*/
+bool 
+isOperandInDirSpace (operand * op)
+{
+  sym_link *etype;
+
+  if (!op)
+    return FALSE;
+
+  if (!IS_SYMOP (op))
+    return FALSE;
+
+  if (!IS_TRUE_SYMOP (op))
+    {
+      if (SPIL_LOC (op))
+       etype = SPIL_LOC (op)->etype;
+      else
+       return FALSE;
+    }
+  else
+    {
+      etype = getSpec (operandType (op));
+    }
+  return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
+}
+
+/*--------------------------------------------------------------------*/
+/* isOperandInCodeSpace - will return true if operand is in codeSpace */
+/*--------------------------------------------------------------------*/
+bool 
+isOperandInCodeSpace (operand * op)
+{
+  sym_link *etype;
+
+  if (!op)
+    return FALSE;
+
+  if (!IS_SYMOP (op))
+    return FALSE;
+
+  etype = getSpec (operandType (op));
+
+  if (!IS_TRUE_SYMOP (op))
+    {
+      if (SPIL_LOC (op))
+       etype = SPIL_LOC (op)->etype;
+      else
+       return FALSE;
+    }
+  else
+    {
+      etype = getSpec (operandType (op));
+    }
+  return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
+}
+
 /*-----------------------------------------------------------------*/
 /* isOperandOnStack - will return true if operand is on stack      */
 /*-----------------------------------------------------------------*/
@@ -812,8 +975,12 @@ isOperandOnStack (operand * op)
     return FALSE;
 
   etype = getSpec (operandType (op));
+  if (IN_STACK (etype) ||
+      OP_SYMBOL(op)->onStack ||
+      (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
+    return TRUE;
 
-  return ((IN_STACK (etype)) ? TRUE : FALSE);
+  return FALSE;
 }
 
 /*-----------------------------------------------------------------*/
@@ -827,6 +994,31 @@ operandLitValue (operand * op)
   return floatFromVal (op->operand.valOperand);
 }
 
+/*-----------------------------------------------------------------*/
+/* getBuiltInParms - returns parameters to a builtin functions     */
+/*-----------------------------------------------------------------*/
+iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
+{
+    sym_link *ftype;
+
+    *pcount = 0;
+    /* builtin functions uses only SEND for parameters */
+    while (ic->op != CALL) {
+       assert(ic->op == SEND && ic->builtinSEND);
+       ic->generated = 1;    /* mark the icode as generated */
+       parms[*pcount] = IC_LEFT(ic);
+       ic = ic->next;
+       (*pcount)++;
+    }
+    
+    ic->generated = 1;
+    /* make sure this is a builtin function call */
+    assert(IS_SYMOP(IC_LEFT(ic)));
+    ftype = operandType(IC_LEFT(ic));
+    assert(IFFUNC_ISBUILTIN(ftype));
+    return ic;
+}
+
 /*-----------------------------------------------------------------*/
 /* operandOperation - perforoms operations on operands             */
 /*-----------------------------------------------------------------*/
@@ -834,11 +1026,15 @@ operand *
 operandOperation (operand * left, operand * right,
                  int op, sym_link * type)
 {
+  sym_link *let , *ret=NULL;
   operand *retval = (operand *) 0;
-
+  
   assert (isOperandLiteral (left));
-  if (right)
+  let = getSpec(operandType(left));
+  if (right) {
     assert (isOperandLiteral (right));
+    ret = getSpec(operandType(left));
+  }
 
   switch (op)
     {
@@ -870,23 +1066,48 @@ operandOperation (operand * left, operand * right,
                                                   operandLitValue (right)));
       break;
     case '%':
-      if ((unsigned long) operandLitValue (right) == 0)
-       {
+      if ((unsigned long) operandLitValue (right) == 0) {
          werror (E_DIVIDE_BY_ZERO);
          retval = right;
-       }
-      else
-       retval = operandFromLit ((unsigned long) operandLitValue (left) %
-                                (unsigned long) operandLitValue (right));
+      }
+      else 
+       retval = operandFromLit ((SPEC_USIGN(let) ? 
+                                 (unsigned long) operandLitValue (left) :
+                                 (long) operandLitValue (left)) %
+                                (SPEC_USIGN(ret) ? 
+                                 (unsigned long) operandLitValue (right) :
+                                 (long) operandLitValue (right)));
+
       break;
     case LEFT_OP:
-      retval = operandFromLit ((unsigned long) operandLitValue (left) <<
-                              (unsigned long) operandLitValue (right));
+      retval = operandFromLit ((SPEC_USIGN(let) ? 
+                                 (unsigned long) operandLitValue (left) :
+                                 (long) operandLitValue (left)) <<
+                                (SPEC_USIGN(ret) ? 
+                                 (unsigned long) operandLitValue (right) :
+                                 (long) operandLitValue (right)));
       break;
-    case RIGHT_OP:
-      retval = operandFromLit ((unsigned long) operandLitValue (left) >>
-                              (unsigned long) operandLitValue (right));
+    case RIGHT_OP: {
+      double lval = operandLitValue(left), rval = operandLitValue(right);
+      double res=0;
+      switch ((SPEC_USIGN(let) ? 2 : 0) + (SPEC_USIGN(ret) ? 1 : 0)) 
+       {
+       case 0: // left=unsigned right=unsigned
+         res=(unsigned long)lval >> (unsigned long)rval;
+         break;
+       case 1: // left=unsigned right=signed
+         res=(unsigned long)lval >> (signed long)rval;
+         break;
+       case 2: // left=signed right=unsigned
+         res=(signed long)lval >> (unsigned long)rval;
+         break;
+       case 3: // left=signed right=signed
+         res=(signed long)lval >> (signed long)rval;
+         break;
+       }
+      retval = operandFromLit (res);
       break;
+    }
     case EQ_OP:
       retval = operandFromLit (operandLitValue (left) ==
                               operandLitValue (right));
@@ -912,16 +1133,16 @@ operandOperation (operand * left, operand * right,
                               operandLitValue (right));
       break;
     case BITWISEAND:
-      retval = operandFromLit ((unsigned long) operandLitValue (left) &
-                              (unsigned long) operandLitValue (right));
+      retval = operandFromLit ((long)operandLitValue(left) & 
+                              (long)operandLitValue(right));
       break;
     case '|':
-      retval = operandFromLit ((unsigned long) operandLitValue (left) |
-                              (unsigned long) operandLitValue (right));
+      retval = operandFromLit ((long)operandLitValue (left) |
+                              (long)operandLitValue (right));
       break;
     case '^':
-      retval = operandFromLit ((unsigned long) operandLitValue (left) ^
-                              (unsigned long) operandLitValue (right));
+      retval = operandFromLit ((long)operandLitValue (left) ^
+                              (long)operandLitValue (right));
       break;
     case AND_OP:
       retval = operandFromLit (operandLitValue (left) &&
@@ -933,7 +1154,7 @@ operandOperation (operand * left, operand * right,
       break;
     case RRC:
       {
-       long i = operandLitValue (left);
+       long i = (long) operandLitValue (left);
 
        retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
                                 (i << 1));
@@ -941,7 +1162,7 @@ operandOperation (operand * left, operand * right,
       break;
     case RLC:
       {
-       long i = operandLitValue (left);
+       long i = (long) operandLitValue (left);
 
        retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
                                 (i >> 1));
@@ -1000,7 +1221,7 @@ isOperandEqual (operand * left, operand * right)
       return (floatFromVal (left->operand.valOperand) ==
              floatFromVal (right->operand.valOperand));
     case TYPE:
-      if (checkType (left->operand.typeOperand,
+      if (compareType (left->operand.typeOperand,
                     right->operand.typeOperand) == 1)
        return 1;
     }
@@ -1008,9 +1229,9 @@ isOperandEqual (operand * left, operand * right)
   return 0;
 }
 
-/*-----------------------------------------------------------------*/
-/* isiCodeEqual - comapres two iCodes are returns true if yes      */
-/*-----------------------------------------------------------------*/
+/*-------------------------------------------------------------------*/
+/* isiCodeEqual - compares two iCodes are equal, returns true if yes */
+/*-------------------------------------------------------------------*/
 int 
 isiCodeEqual (iCode * left, iCode * right)
 {
@@ -1044,6 +1265,7 @@ isiCodeEqual (iCode * left, iCode * right)
          if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
            return 0;
        }
+      
       return 1;
     }
   return 0;
@@ -1068,10 +1290,8 @@ newiTempFromOp (operand * op)
   nop->isvolatile = op->isvolatile;
   nop->isGlobal = op->isGlobal;
   nop->isLiteral = op->isLiteral;
-  nop->noSpilLoc = op->noSpilLoc;
   nop->usesDefs = op->usesDefs;
   nop->isParm = op->isParm;
-  nop->parmBytes = op->parmBytes;
   return nop;
 }
 
@@ -1092,10 +1312,8 @@ operandFromOperand (operand * op)
   nop->isvolatile = op->isvolatile;
   nop->isGlobal = op->isGlobal;
   nop->isLiteral = op->isLiteral;
-  nop->noSpilLoc = op->noSpilLoc;
   nop->usesDefs = op->usesDefs;
   nop->isParm = op->isParm;
-  nop->parmBytes = op->parmBytes;
 
   switch (nop->type)
     {
@@ -1157,14 +1375,14 @@ operandFromSymbol (symbol * sym)
       op->key = sym->key;
       op->isvolatile = isOperandVolatile (op, TRUE);
       op->isGlobal = isOperandGlobal (op);
-      op->parmBytes = sym->argStack;
       return op;
     }
 
   /* under the following conditions create a
      register equivalent for a local symbol */
   if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
-      (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!IS_DS390_PORT)) &&
+      (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
+      (!(options.model == MODEL_FLAT24)) ) &&
       options.stackAuto == 0)
     ok = 0;
 
@@ -1173,7 +1391,7 @@ operandFromSymbol (symbol * sym)
       !sym->_isparm &&         /* not a parameter  */
       sym->level &&            /* is a local variable */
       !sym->addrtaken &&       /* whose address has not been taken */
-      !sym->reqv &&            /* does not already have a register euivalence */
+      !sym->reqv &&            /* does not already have a reg equivalence */
       !IS_VOLATILE (sym->etype) &&     /* not declared as volatile */
       !IS_STATIC (sym->etype) &&       /* and not declared static  */
       !sym->islbl &&           /* not a label */
@@ -1189,6 +1407,7 @@ operandFromSymbol (symbol * sym)
       OP_SYMBOL (sym->reqv)->key = sym->key;
       OP_SYMBOL (sym->reqv)->isreqv = 1;
       OP_SYMBOL (sym->reqv)->islocal = 1;
+      OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
       SPIL_LOC (sym->reqv) = sym;
     }
 
@@ -1227,8 +1446,6 @@ operandFromSymbol (symbol * sym)
   else
     IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
 
-  IC_RESULT (ic)->operand.symOperand->args = sym->args;
-
   ADDTOCHAIN (ic);
 
   return IC_RESULT (ic);
@@ -1276,7 +1493,7 @@ operandFromLink (sym_link * type)
 /* operandFromLit - makes an operand from a literal value          */
 /*-----------------------------------------------------------------*/
 operand *
-operandFromLit (float i)
+operandFromLit (double i)
 {
   return operandFromValue (valueFromLit (i));
 }
@@ -1285,7 +1502,7 @@ operandFromLit (float i)
 /* operandFromAst - creates an operand from an ast                 */
 /*-----------------------------------------------------------------*/
 operand *
-operandFromAst (ast * tree)
+operandFromAst (ast * tree,int lvl)
 {
 
   if (!tree)
@@ -1295,7 +1512,7 @@ operandFromAst (ast * tree)
   switch (tree->type)
     {
     case EX_OP:
-      return ast2iCode (tree);
+      return ast2iCode (tree,lvl+1);
       break;
 
     case EX_VALUE:
@@ -1343,6 +1560,43 @@ setOperandType (operand * op, sym_link * type)
     }
 
 }
+/*-----------------------------------------------------------------*/
+/* Get size in byte of ptr need to access an array                 */
+/*-----------------------------------------------------------------*/
+int
+getArraySizePtr (operand * op)
+{
+  sym_link *ltype = operandType(op);
+
+  if(IS_PTR(ltype))
+    {
+      int size = getSize(ltype);
+      return(IS_GENPTR(ltype)?(size-1):size);
+    }
+
+  if(IS_ARRAY(ltype))
+    {
+      sym_link *letype = getSpec(ltype);
+      switch (PTR_TYPE (SPEC_OCLS (letype)))
+       {
+       case IPOINTER:
+       case PPOINTER:
+       case POINTER:
+         return (PTRSIZE);
+       case EEPPOINTER:
+       case FPOINTER:
+       case CPOINTER:
+       case FUNCTION:
+         return (FPTRSIZE);
+       case GPOINTER:
+         return (GPTRSIZE-1);
+
+       default:
+         return (FPTRSIZE);
+       }
+    }
+  return (FPTRSIZE);
+}
 
 /*-----------------------------------------------------------------*/
 /* perform "usual unary conversions"                               */
@@ -1352,7 +1606,7 @@ usualUnaryConversions (operand * op)
 {
   if (IS_INTEGRAL (operandType (op)))
     {
-      if (getSize (operandType (op)) < INTSIZE)
+      if (getSize (operandType (op)) < (unsigned int) INTSIZE)
        {
          /* Widen to int. */
          return geniCodeCast (INTTYPE, op, TRUE);
@@ -1367,122 +1621,18 @@ usualUnaryConversions (operand * op)
 sym_link *
 usualBinaryConversions (operand ** op1, operand ** op2)
 {
-  if (!options.ANSIint)
-    {
-      /* "Classic" SDCC behavior. */
-      sym_link *ctype;
-      sym_link *rtype = operandType (*op2);
-      sym_link *ltype = operandType (*op1);
-
-      ctype = computeType (ltype, rtype);
-      *op1 = geniCodeCast (ctype, *op1, TRUE);
-      *op2 = geniCodeCast (ctype, *op2, TRUE);
-
-      return ctype;
-    }
-
-  *op1 = usualUnaryConversions (*op1);
-  *op2 = usualUnaryConversions (*op2);
-
-  /* Try to make the two operands of the same type, following
-   * the "usual binary conversions" promotion rules.
-   *
-   * NB: floating point types are not yet properly handled; we
-   * follow the "classic" behavior.
-   */
-
-  if (IS_FLOAT (operandType (*op1)) || IS_FLOAT (operandType (*op2)))
-    {
-      return newFloatLink ();
-    }
-
-  if (!IS_INTEGRAL (operandType (*op1)) || !IS_INTEGRAL (operandType (*op2)))
-    {
-      /* if either is not an integer type, we're done. */
-      return copyLinkChain (operandType (*op1));       /* Punt! we should never get here. */
-    }
-
-  /* If either is an unsigned long, make sure both are. */
-  if (SPEC_USIGN (operandType (*op1)) && IS_LONG (operandType (*op1)))
-    {
-      if (!SPEC_USIGN (operandType (*op2)) || !IS_LONG (operandType (*op2)))
-       {
-         *op2 = geniCodeCast (ULONGTYPE, *op2, TRUE);
-       }
-      return copyLinkChain (operandType (*op1));
-    }
-
-  if (SPEC_USIGN (operandType (*op2)) && IS_LONG (operandType (*op2)))
-    {
-      if (!SPEC_USIGN (operandType (*op1)) || !IS_LONG (operandType (*op1)))
-       {
-         *op1 = geniCodeCast (ULONGTYPE, *op1, TRUE);
-       }
-      return copyLinkChain (operandType (*op2));
-    }
-
-  /* Next, if one is long and the other is int (signed or un),
-   * cast both to long.
-   *
-   * Note that because in our environment a long can hold all
-   * the values of an unsigned int, the "long/unsigned int" pair
-   * in the ANSI conversion table is unnecessary; this test
-   * handles that case implicitly.
-   */
-  if (IS_LONG (operandType (*op1)))
-    {
-      /* NB: because of the unary conversions, op2 cannot
-       * be smaller than int. Therefore, if it is not
-       * long, it is a regular int.
-       */
-      if (!IS_LONG (operandType (*op2)))
-       {
-         *op2 = geniCodeCast (LONGTYPE, *op2, TRUE);
-       }
-      return copyLinkChain (operandType (*op1));
-    }
-
-  if (IS_LONG (operandType (*op2)))
-    {
-      /* NB: because of the unary conversions, op2 cannot
-       * be smaller than int. Therefore, if it is not
-       * long, it is a regular int.
-       */
-      if (!IS_LONG (operandType (*op1)))
-       {
-         *op1 = geniCodeCast (LONGTYPE, *op1, TRUE);
-       }
-      return copyLinkChain (operandType (*op2));
-    }
-
-  /* All right, neither is long; they must both be integers.
-
-   * Only remaining issue is signed vs. unsigned; if one is unsigned
-   * and the other isn't, convert both to unsigned.
-   */
-  if (SPEC_USIGN (operandType (*op1)))
-    {
-      if (!SPEC_USIGN (operandType (*op2)))
-       {
-         *op2 = geniCodeCast (UINTTYPE, *op2, TRUE);
-       }
-      return copyLinkChain (operandType (*op1));
-    }
-
-  if (SPEC_USIGN (operandType (*op2)))
-    {
-      if (!SPEC_USIGN (operandType (*op1)))
-       {
-         *op1 = geniCodeCast (UINTTYPE, *op1, TRUE);
-       }
-      return copyLinkChain (operandType (*op2));
-    }
+  sym_link *ctype;
+  sym_link *rtype = operandType (*op2);
+  sym_link *ltype = operandType (*op1);
+  
+  ctype = computeType (ltype, rtype);
 
-  /* Done! */
-  return copyLinkChain (operandType (*op1));
+  *op1 = geniCodeCast (ctype, *op1, TRUE);
+  *op2 = geniCodeCast (ctype, *op2, TRUE);
+  
+  return ctype;
 }
 
-
 /*-----------------------------------------------------------------*/
 /* geniCodeValueAtAddress - generate intermeditate code for value  */
 /*                          at address                             */
@@ -1517,7 +1667,8 @@ geniCodeRValue (operand * op, bool force)
 
   if (IS_SPEC (type) &&
       IS_TRUE_SYMOP (op) &&
-      (!IN_FARSPACE (SPEC_OCLS (etype)) || IS_DS390_PORT))
+      (!IN_FARSPACE (SPEC_OCLS (etype)) ||
+      (options.model == MODEL_FLAT24) ))
     {
       op = operandFromOperand (op);
       op->isaddr = 0;
@@ -1535,10 +1686,6 @@ geniCodeRValue (operand * op, bool force)
 
 /*     ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
 
-  /* if the right is a symbol */
-  if (op->type == SYMBOL)
-    IC_RESULT (ic)->operand.symOperand->args =
-      op->operand.symOperand->args;
   ADDTOCHAIN (ic);
 
   return IC_RESULT (ic);
@@ -1554,6 +1701,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
   sym_link *optype;
   sym_link *opetype = getSpec (optype = operandType (op));
   sym_link *restype;
+  int errors=0;
 
   /* one of them has size zero then error */
   if (IS_VOID (optype))
@@ -1563,7 +1711,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
     }
 
   /* if the operand is already the desired type then do nothing */
-  if (checkType (type, optype) == 1)
+  if (compareType (type, optype) == 1)
     return op;
 
   /* if this is a literal then just change the type & return */
@@ -1571,20 +1719,63 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
     return operandFromValue (valCastLiteral (type,
                                             operandLitValue (op)));
 
-  /* if casting to some pointer type &&
-     the destination is not a generic pointer
-     then give a warning : (only for implicit casts) */
-  if (IS_PTR (optype) && implicit &&
-      (DCL_TYPE (optype) != DCL_TYPE (type)) &&
-      !IS_GENPTR (type))
-    {
-      werror (E_INCOMPAT_CAST);
-      werror (E_CONTINUE, "from type '");
-      printTypeChain (optype, stderr);
-      fprintf (stderr, "' to type '");
-      printTypeChain (type, stderr);
-      fprintf (stderr, "'\n");
+  /* if casting to/from pointers, do some checking */
+  if (IS_PTR(type)) { // to a pointer
+    if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
+      if (IS_INTEGRAL(optype)) { 
+       // maybe this is NULL, than it's ok. 
+       if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
+         if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
+           // no way to set the storage
+           if (IS_LITERAL(optype)) {
+             werror(E_LITERAL_GENERIC);
+             errors++;
+           } else {
+             werror(E_NONPTR2_GENPTR);
+             errors++;
+           }
+         } else if (implicit) {
+           werror(W_INTEGRAL2PTR_NOCAST);
+           errors++;
+         }
+       }
+      }        else { 
+       // shouldn't do that with float, array or structure unless to void
+       if (!IS_VOID(getSpec(type)) && 
+           !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
+         werror(E_INCOMPAT_TYPES);
+         errors++;
+       }
+      }
+    } else { // from a pointer to a pointer
+      if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
+       // if not a pointer to a function
+       if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
+         if (implicit) { // if not to generic, they have to match 
+           if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
+             werror(E_INCOMPAT_PTYPES);
+             errors++;
+           }
+         }
+       }
+      }
+    }
+  } else { // to a non pointer
+    if (IS_PTR(optype)) { // from a pointer
+      if (implicit) { // sneaky
+       if (IS_INTEGRAL(type)) {
+         werror(W_PTR2INTEGRAL_NOCAST);
+         errors++;
+       } else { // shouldn't do that with float, array or structure
+         werror(E_INCOMPAT_TYPES);
+         errors++;
+       }
+      }
     }
+  }
+  if (errors) {
+    printFromToType (optype, type);
+  }
 
   /* if they are the same size create an assignment */
   if (getSize (type) == getSize (optype) &&
@@ -1612,7 +1803,8 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
   /* preserve the storage class & output class */
   /* of the original variable                  */
   restype = getSpec (operandType (IC_RESULT (ic)));
-  SPEC_SCLS (restype) = SPEC_SCLS (opetype);
+  if (!IS_LITERAL(opetype))
+      SPEC_SCLS (restype) = SPEC_SCLS (opetype);
   SPEC_OCLS (restype) = SPEC_OCLS (opetype);
 
   ADDTOCHAIN (ic);
@@ -1647,11 +1839,10 @@ geniCodeGoto (symbol * label)
 /* geniCodeMultiply - gen intermediate code for multiplication     */
 /*-----------------------------------------------------------------*/
 operand *
-geniCodeMultiply (operand * left, operand * right, bool ptrSizeCalculation)
+geniCodeMultiply (operand * left, operand * right,int resultIsInt)
 {
   iCode *ic;
   int p2 = 0;
-  int saveOption;
   sym_link *resType;
   LRTYPE;
 
@@ -1660,38 +1851,38 @@ geniCodeMultiply (operand * left, operand * right, bool ptrSizeCalculation)
     return operandFromValue (valMult (left->operand.valOperand,
                                      right->operand.valOperand));
 
+  if (IS_LITERAL(retype)) {
+    p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
+  }
 
-  //Force 1 byte * 1 byte = 2 bytes result if we are computing ptr size
-  if ((ptrSizeCalculation) && (1 == getSize (rtype)) &&
-      (1 == getSize (ltype)))
+  resType = usualBinaryConversions (&left, &right);
+#if 1
+  rtype = operandType (right);
+  retype = getSpec (rtype);
+  ltype = operandType (left);
+  letype = getSpec (ltype);
+#endif
+  if (resultIsInt)
     {
-      saveOption = options.ANSIint;
-      options.ANSIint = 0;
-      resType = usualBinaryConversions (&left, &right);
-      ltype = operandType (left);
-      rtype = operandType (right);
-      SPEC_SHORT (getSpec (resType)) = 0;
-      options.ANSIint = saveOption;
+      SPEC_NOUN(getSpec(resType))=V_INT;
     }
-  else
-    resType = usualBinaryConversions (&left, &right);
 
   /* if the right is a literal & power of 2 */
   /* then make it a left shift              */
-  /*If we are computing  ptr size then normal multiplication */
-  /*code generated for 1 byte * 1 byte literal = 2 bytes result is more efficient in most cases */
-  /*than 2 bytes result = 2 bytes << literal if port as 1 byte muldiv */
-  if (IS_LITERAL (retype) && !IS_FLOAT (letype) &&
-      !((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)) && (1 == port->muldiv.native_below)) &&
-   (p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand))))
-    {
-      if ((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)))
+  /* code generated for 1 byte * 1 byte literal = 2 bytes result is more 
+     efficient in most cases than 2 bytes result = 2 bytes << literal 
+     if port has 1 byte muldiv */
+  if (p2 && !IS_FLOAT (letype) &&
+      !((resultIsInt) && (getSize (resType) != getSize (ltype)) && 
+       (port->support.muldiv == 1)))
+    {
+      if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
        {
          /* LEFT_OP need same size for left and result, */
          left = geniCodeCast (resType, left, TRUE);
          ltype = operandType (left);
        }
-      ic = newiCode (LEFT_OP, left, operandFromLit (p2));      /* left shift */
+      ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
     }
   else
     {
@@ -1723,13 +1914,16 @@ geniCodeDivision (operand * left, operand * right)
 
   resType = usualBinaryConversions (&left, &right);
 
-  /* if the right is a literal & power of 2 */
-  /* then make it a right shift             */
+  /* if the right is a literal & power of 2 
+     and left is unsigned then make it a    
+     right shift */
   if (IS_LITERAL (retype) &&
       !IS_FLOAT (letype) &&
+      SPEC_USIGN(letype) &&
       (p2 = powof2 ((unsigned long)
-                   floatFromVal (right->operand.valOperand))))
-    ic = newiCode (RIGHT_OP, left, operandFromLit (p2));       /* right shift */
+                   floatFromVal (right->operand.valOperand)))) {
+    ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
+  }
   else
     {
       ic = newiCode ('/', left, right);                /* normal division */
@@ -1795,6 +1989,11 @@ geniCodePtrPtrSubtract (operand * left, operand * right)
   ADDTOCHAIN (ic);
 
 subtractExit:
+  if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
+    return result;
+  }
+
+  // should we really do this? is this ANSI?
   return geniCodeDivision (result,
                           operandFromLit (getSize (ltype->next)));
 }
@@ -1826,7 +2025,7 @@ geniCodeSubtract (operand * left, operand * right)
     {
       isarray = left->isaddr;
       right = geniCodeMultiply (right,
-                             operandFromLit (getSize (ltype->next)), TRUE);
+                               operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
       resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
     }
   else
@@ -1851,7 +2050,7 @@ geniCodeSubtract (operand * left, operand * right)
 /* geniCodeAdd - generates iCode for addition                      */
 /*-----------------------------------------------------------------*/
 operand *
-geniCodeAdd (operand * left, operand * right)
+geniCodeAdd (operand * left, operand * right, int lvl)
 {
   iCode *ic;
   sym_link *resType;
@@ -1859,9 +2058,11 @@ geniCodeAdd (operand * left, operand * right)
   int isarray = 0;
   LRTYPE;
 
+#if 0
   /* if left is an array then array access */
   if (IS_ARRAY (ltype))
-    return geniCodeArray (left, right);
+    return geniCodeArray (left, right,lvl);
+#endif
 
   /* if the right side is LITERAL zero */
   /* return the left side              */
@@ -1872,20 +2073,19 @@ geniCodeAdd (operand * left, operand * right)
   if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
     return right;
 
-  /* if left is an array or pointer then size */
-  if (IS_PTR (ltype))
+  /* if left is a pointer then size */
+  if (IS_PTR (ltype) || IS_ARRAY(ltype))
     {
-
       isarray = left->isaddr;
-      size =
-       operandFromLit (getSize (ltype->next));
-
-      right = geniCodeMultiply (right, size, (getSize (ltype) != 1));
-
+      // there is no need to multiply with 1
+      if (getSize(ltype->next)!=1) {
+       size  = operandFromLit (getSize (ltype->next));
+       right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
+      }
       resType = copyLinkChain (ltype);
     }
   else
-    {                          /* make them the same size */
+    { // make them the same size
       resType = usualBinaryConversions (&left, &right);
     }
 
@@ -1974,7 +2174,7 @@ geniCodeArray2Ptr (operand * op)
 /* geniCodeArray - array access                                    */
 /*-----------------------------------------------------------------*/
 operand *
-geniCodeArray (operand * left, operand * right)
+geniCodeArray (operand * left, operand * right,int lvl)
 {
   iCode *ic;
   sym_link *ltype = operandType (left);
@@ -1985,12 +2185,11 @@ geniCodeArray (operand * left, operand * right)
        {
          left = geniCodeRValue (left, FALSE);
        }
-      return geniCodeDerefPtr (geniCodeAdd (left, right));
+      return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
     }
 
-  /* array access */
   right = geniCodeMultiply (right,
-                           operandFromLit (getSize (ltype->next)), TRUE);
+                           operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
 
   /* we can check for limits here */
   if (isOperandLiteral (right) &&
@@ -2027,6 +2226,8 @@ geniCodeStruct (operand * left, operand * right, bool islval)
   symbol *element = getStructElement (SPEC_STRUCT (etype),
                                      right->operand.symOperand);
 
+  wassert(IS_SYMOP(right));
+    
   /* add the offset */
   ic = newiCode ('+', left, operandFromLit (element->offset));
 
@@ -2073,10 +2274,10 @@ geniCodePostInc (operand * op)
     }
 
   rOp = newiTempOperand (rvtype, 0);
-  rOp->noSpilLoc = 1;
+  OP_SYMBOL(rOp)->noSpilLoc = 1;
 
   if (IS_ITEMP (rv))
-    rv->noSpilLoc = 1;
+    OP_SYMBOL(rv)->noSpilLoc = 1;
 
   geniCodeAssign (rOp, rv, 0);
 
@@ -2148,15 +2349,15 @@ geniCodePostDec (operand * op)
   /* if this is not an address we have trouble */
   if (!op->isaddr)
     {
-      werror (E_LVALUE_REQUIRED, "++");
+      werror (E_LVALUE_REQUIRED, "--");
       return op;
     }
 
   rOp = newiTempOperand (rvtype, 0);
-  rOp->noSpilLoc = 1;
+  OP_SYMBOL(rOp)->noSpilLoc = 1;
 
   if (IS_ITEMP (rv))
-    rv->noSpilLoc = 1;
+    OP_SYMBOL(rv)->noSpilLoc = 1;
 
   geniCodeAssign (rOp, rv, 0);
 
@@ -2192,7 +2393,7 @@ geniCodePreDec (operand * op)
 
   if (!op->isaddr)
     {
-      werror (E_LVALUE_REQUIRED, "++");
+      werror (E_LVALUE_REQUIRED, "--");
       return op;
     }
 
@@ -2324,7 +2525,7 @@ setOClass (sym_link * ptr, sym_link * spec)
 /* geniCodeDerefPtr - dereference pointer with '*'                 */
 /*-----------------------------------------------------------------*/
 operand *
-geniCodeDerefPtr (operand * op)
+geniCodeDerefPtr (operand * op,int lvl)
 {
   sym_link *rtype, *retype;
   sym_link *optype = operandType (op);
@@ -2342,7 +2543,7 @@ geniCodeDerefPtr (operand * op)
     }
 
   /* now get rid of the pointer part */
-  if (lvaluereq && IS_ITEMP (op))
+  if (isLvaluereq(lvl) && IS_ITEMP (op))
     {
       retype = getSpec (rtype = copyLinkChain (optype));
     }
@@ -2368,7 +2569,7 @@ geniCodeDerefPtr (operand * op)
                IS_CHAR (rtype) ||
                IS_FLOAT (rtype));
 
-  if (!lvaluereq)
+  if (!isLvaluereq(lvl))
     op = geniCodeRValue (op, TRUE);
 
   setOperandType (op, rtype);
@@ -2402,16 +2603,6 @@ geniCodeLeftShift (operand * left, operand * right)
 {
   iCode *ic;
 
-
-  /* Note that we don't use the usual binary conversions for the
-   * shift operations, in accordance with our ANSI friends.
-   */
-  if (options.ANSIint)
-    {
-      right = usualUnaryConversions (right);
-      left = usualUnaryConversions (left);
-    }
-
   ic = newiCode (LEFT_OP, left, right);
   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
   ADDTOCHAIN (ic);
@@ -2426,28 +2617,12 @@ geniCodeRightShift (operand * left, operand * right)
 {
   iCode *ic;
 
-
-  /* Note that we don't use the usual binary conversions for the
-   * shift operations, in accordance with our ANSI friends.
-   */
-  if (options.ANSIint)
-    {
-      right = usualUnaryConversions (right);
-      left = usualUnaryConversions (left);
-    }
-
   ic = newiCode (RIGHT_OP, left, right);
   IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
   ADDTOCHAIN (ic);
   return IC_RESULT (ic);
 }
 
-#if defined(__BORLANDC__) || defined(_MSC_VER)
-#define LONG_LONG __int64
-#else
-#define LONG_LONG long long
-#endif
-
 /*-----------------------------------------------------------------*/
 /* geniCodeLogic- logic code                                       */
 /*-----------------------------------------------------------------*/
@@ -2461,13 +2636,10 @@ geniCodeLogic (operand * left, operand * right, int op)
 
   /* left is integral type and right is literal then
      check if the literal value is within bounds */
-  if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
+  if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
     {
-      int nbits = bitsForType (ltype);
-      long v = operandLitValue (right);
-
-      if (v > ((LONG_LONG) 1 << nbits) && v > 0)
-       werror (W_CONST_RANGE, " compare operation ");
+      checkConstantRange(ltype, 
+                        OP_VALUE(right), "compare operation", 1);
     }
 
   ctype = usualBinaryConversions (&left, &right);
@@ -2475,10 +2647,10 @@ geniCodeLogic (operand * left, operand * right, int op)
   ic = newiCode (op, left, right);
   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
 
-  /* if comparing anything greater than one byte
+  /* if comparing float
      and not a '==' || '!=' || '&&' || '||' (these
      will be inlined */
-  if (getSize (ctype) > 1 &&
+  if (IS_FLOAT(ctype) &&
       op != EQ_OP &&
       op != NE_OP &&
       op != AND_OP &&
@@ -2506,22 +2678,22 @@ geniCodeUnary (operand * op, int oper)
 /* geniCodeConditional - geniCode for '?' ':' operation            */
 /*-----------------------------------------------------------------*/
 operand *
-geniCodeConditional (ast * tree)
+geniCodeConditional (ast * tree,int lvl)
 {
   iCode *ic;
   symbol *falseLabel = newiTempLabel (NULL);
   symbol *exitLabel = newiTempLabel (NULL);
-  operand *cond = ast2iCode (tree->left);
+  operand *cond = ast2iCode (tree->left,lvl+1);
   operand *true, *false, *result;
 
   ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
                          NULL, falseLabel);
   ADDTOCHAIN (ic);
 
-  true = ast2iCode (tree->right->left);
+  true = ast2iCode (tree->right->left,lvl+1);
 
   /* move the value to a new Operand */
-  result = newiTempOperand (operandType (true), 0);
+  result = newiTempOperand (tree->right->ftype, 0);
   geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
 
   /* generate an unconditional goto */
@@ -2530,7 +2702,7 @@ geniCodeConditional (ast * tree)
   /* now for the right side */
   geniCodeLabel (falseLabel);
 
-  false = ast2iCode (tree->right->right);
+  false = ast2iCode (tree->right->right,lvl+1);
   geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
 
   /* create the exit label */
@@ -2559,11 +2731,8 @@ geniCodeAssign (operand * left, operand * right, int nosupdate)
      check if the literal value is within bounds */
   if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
     {
-      int nbits = bitsForType (ltype);
-      long v = operandLitValue (right);
-
-      if (v > ((LONG_LONG) 1 << nbits) && v > 0)
-       werror (W_CONST_RANGE, " = operation");
+      checkConstantRange(ltype, 
+                        OP_VALUE(right), "= operation", 0);
     }
 
   /* if the left & right type don't exactly match */
@@ -2573,12 +2742,12 @@ geniCodeAssign (operand * left, operand * right, int nosupdate)
 
   /* first check the type for pointer assignement */
   if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
-      checkType (ltype, rtype) < 0)
+      compareType (ltype, rtype) <= 0)
     {
-      if (checkType (ltype->next, rtype) < 0)
+      if (compareType (ltype->next, rtype) < 0)
        right = geniCodeCast (ltype->next, right, TRUE);
     }
-  else if (checkType (ltype, rtype) < 0)
+  else if (compareType (ltype, rtype) < 0)
     right = geniCodeCast (ltype, right, TRUE);
 
   /* if left is a true symbol & ! volatile
@@ -2617,15 +2786,15 @@ geniCodeAssign (operand * left, operand * right, int nosupdate)
 /* geniCodeSEParms - generate code for side effecting fcalls       */
 /*-----------------------------------------------------------------*/
 static void 
-geniCodeSEParms (ast * parms)
+geniCodeSEParms (ast * parms,int lvl)
 {
   if (!parms)
     return;
 
   if (parms->type == EX_OP && parms->opval.op == PARAM)
     {
-      geniCodeSEParms (parms->left);
-      geniCodeSEParms (parms->right);
+      geniCodeSEParms (parms->left,lvl);
+      geniCodeSEParms (parms->right,lvl);
       return;
     }
 
@@ -2639,30 +2808,38 @@ geniCodeSEParms (ast * parms)
       IS_ADDRESS_OF_OP (parms->right))
     parms->right->left->lvalue = 1;
 
-  parms->opval.oprnd =
-    geniCodeRValue (ast2iCode (parms), FALSE);
-
+  parms->opval.oprnd = 
+    geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
+               
   parms->type = EX_OPERAND;
+  AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
+               SPEC_ARGREG(parms->ftype);
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeParms - generates parameters                            */
 /*-----------------------------------------------------------------*/
-static void 
-geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func)
+value *
+geniCodeParms (ast * parms, value *argVals, int *stack, 
+              sym_link * fetype, symbol * func,int lvl)
 {
   iCode *ic;
   operand *pval;
 
   if (!parms)
-    return;
+    return argVals;
+
+  if (argVals==NULL) {
+    // first argument
+    argVals=FUNC_ARGS(func->type);
+  }
 
   /* if this is a param node then do the left & right */
   if (parms->type == EX_OP && parms->opval.op == PARAM)
     {
-      geniCodeParms (parms->left, stack, fetype, func);
-      geniCodeParms (parms->right, stack, fetype, func);
-      return;
+      argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
+      argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
+      return argVals;
     }
 
   /* get the parameter value */
@@ -2681,24 +2858,28 @@ geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func)
          IS_ADDRESS_OF_OP (parms->right))
        parms->right->left->lvalue = 1;
 
-      pval = geniCodeRValue (ast2iCode (parms), FALSE);
+      pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
     }
 
   /* if register parm then make it a send */
-  if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) ||
-       IS_REGPARM (parms->etype)) && !func->hasVargs)
+  if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
+      IFFUNC_ISBUILTIN(func->type))
     {
       ic = newiCode (SEND, pval, NULL);
+      ic->argreg = SPEC_ARGREG(parms->etype);
+      ic->builtinSEND = FUNC_ISBUILTIN(func->type);
       ADDTOCHAIN (ic);
     }
   else
     {
       /* now decide whether to push or assign */
-      if (!(options.stackAuto || IS_RENT (fetype)))
+      if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
        {
 
          /* assign */
-         operand *top = operandFromSymbol (parms->argSym);
+         operand *top = operandFromSymbol (argVals->sym);
+         /* clear useDef and other bitVectors */
+         OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
          geniCodeAssign (top, pval, 1);
        }
       else
@@ -2713,34 +2894,42 @@ geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func)
        }
     }
 
+  argVals=argVals->next;
+  return argVals;
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeCall - generates temp code for calling                  */
 /*-----------------------------------------------------------------*/
 operand *
-geniCodeCall (operand * left, ast * parms)
+geniCodeCall (operand * left, ast * parms,int lvl)
 {
   iCode *ic;
   operand *result;
   sym_link *type, *etype;
   int stack = 0;
 
+  if (!IS_FUNC(OP_SYMBOL(left)->type) && 
+      !IS_CODEPTR(OP_SYMBOL(left)->type)) {
+    werror (E_FUNCTION_EXPECTED);
+    return NULL;
+  }
+
   /* take care of parameters with side-effecting
      function calls in them, this is required to take care
      of overlaying function parameters */
-  geniCodeSEParms (parms);
+  geniCodeSEParms (parms,lvl);
 
   /* first the parameters */
-  geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left));
+  geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
 
   /* now call : if symbol then pcall */
-  if (IS_ITEMP (left))
+  if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
     ic = newiCode (PCALL, left, NULL);
-  else
+  } else {
     ic = newiCode (CALL, left, NULL);
+  }
 
-  IC_ARGS (ic) = left->operand.symOperand->args;
   type = copyLinkChain (operandType (left)->next);
   etype = getSpec (type);
   SPEC_EXTR (etype) = 0;
@@ -2749,7 +2938,7 @@ geniCodeCall (operand * left, ast * parms)
   ADDTOCHAIN (ic);
 
   /* stack adjustment after call */
-  left->parmBytes = stack;
+  ic->parmBytes = stack;
 
   return result;
 }
@@ -2763,7 +2952,7 @@ geniCodeReceive (value * args)
   /* for all arguments that are passed in registers */
   while (args)
     {
-
+      int first = 1;
       if (IS_REGPARM (args->etype))
        {
          operand *opr = operandFromValue (args);
@@ -2778,7 +2967,7 @@ geniCodeReceive (value * args)
 
              if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
                  options.stackAuto == 0 &&
-                 !IS_DS390_PORT)
+                 (!(options.model == MODEL_FLAT24)) )
                {
                }
              else
@@ -2793,8 +2982,12 @@ geniCodeReceive (value * args)
                }
            }
 
-         ic = newiCode (RECEIVE, NULL, NULL);
-         currFunc->recvSize = getSize (sym->etype);
+         ic = newiCode (RECEIVE, NULL, NULL);    
+         ic->argreg = SPEC_ARGREG(args->etype);
+         if (first) {
+             currFunc->recvSize = getSize (sym->type);
+             first = 0;
+         }
          IC_RESULT (ic) = opr;
          ADDTOCHAIN (ic);
        }
@@ -2807,7 +3000,7 @@ geniCodeReceive (value * args)
 /* geniCodeFunctionBody - create the function body                 */
 /*-----------------------------------------------------------------*/
 void 
-geniCodeFunctionBody (ast * tree)
+geniCodeFunctionBody (ast * tree,int lvl)
 {
   iCode *ic;
   operand *func;
@@ -2820,7 +3013,7 @@ geniCodeFunctionBody (ast * tree)
   iTempLblNum = 0;
   operandKey = 0;
   iCodeKey = 0;
-  func = ast2iCode (tree->left);
+  func = ast2iCode (tree->left,lvl+1);
   fetype = getSpec (operandType (func));
 
   savelineno = lineno;
@@ -2831,10 +3024,7 @@ geniCodeFunctionBody (ast * tree)
 
   /* create a proc icode */
   ic = newiCode (FUNCTION, func, NULL);
-  /* if the function has parmas   then */
-  /* save the parameters information    */
-  ic->argLabel.args = tree->values.args;
-  ic->lineno = OP_SYMBOL (func)->lineDef;
+  lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
 
   ADDTOCHAIN (ic);
 
@@ -2843,7 +3033,7 @@ geniCodeFunctionBody (ast * tree)
   geniCodeReceive (tree->values.args);
 
   /* generate code for the body */
-  ast2iCode (tree->right);
+  ast2iCode (tree->right,lvl+1);
 
   /* create a label for return */
   geniCodeLabel (returnLabel);
@@ -2874,10 +3064,10 @@ geniCodeReturn (operand * op)
 /* geniCodeIfx - generates code for extended if statement          */
 /*-----------------------------------------------------------------*/
 void 
-geniCodeIfx (ast * tree)
+geniCodeIfx (ast * tree,int lvl)
 {
   iCode *ic;
-  operand *condition = ast2iCode (tree->left);
+  operand *condition = ast2iCode (tree->left,lvl+1);
   sym_link *cetype;
 
   /* if condition is null then exit */
@@ -2895,14 +3085,14 @@ geniCodeIfx (ast * tree)
          if (tree->trueLabel)
            geniCodeGoto (tree->trueLabel);
          else
-           assert (1);
+           assert (0);
        }
       else
        {
          if (tree->falseLabel)
            geniCodeGoto (tree->falseLabel);
          else
-           assert (1);
+           assert (0);
        }
       goto exit;
     }
@@ -2926,7 +3116,7 @@ geniCodeIfx (ast * tree)
     }
 
 exit:
-  ast2iCode (tree->right);
+  ast2iCode (tree->right,lvl+1);
 }
 
 /*-----------------------------------------------------------------*/
@@ -2949,7 +3139,8 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
   /* all integer numbers between the maximum & minimum must */
   /* be present , the maximum value should not exceed 255 */
   min = max = (int) floatFromVal (vch = caseVals);
-  sprintf (buffer, "_case_%d_%d",
+  SNPRINTF (buffer, sizeof(buffer), 
+           "_case_%d_%d",
           tree->values.switchVals.swNum,
           min);
   addSet (&labels, newiTempLabel (buffer));
@@ -2962,7 +3153,8 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
     {
       if (((t = (int) floatFromVal (vch)) - max) != 1)
        return 0;
-      sprintf (buffer, "_case_%d_%d",
+      SNPRINTF (buffer, sizeof(buffer), 
+               "_case_%d_%d",
               tree->values.switchVals.swNum,
               t);
       addSet (&labels, newiTempLabel (buffer));
@@ -2978,9 +3170,14 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
     return 0;
 
   if (tree->values.switchVals.swDefault)
-    sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
+    {
+       SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
+    }
   else
-    sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
+    {
+       SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
+    }
+    
 
   falseLabel = newiTempLabel (buffer);
 
@@ -3024,10 +3221,10 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
 /* geniCodeSwitch - changes a switch to a if statement             */
 /*-----------------------------------------------------------------*/
 void 
-geniCodeSwitch (ast * tree)
+geniCodeSwitch (ast * tree,int lvl)
 {
   iCode *ic;
-  operand *cond = geniCodeRValue (ast2iCode (tree->left), FALSE);
+  operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
   value *caseVals = tree->values.switchVals.swVals;
   symbol *trueLabel, *falseLabel;
 
@@ -3043,7 +3240,7 @@ geniCodeSwitch (ast * tree)
                                        operandFromValue (caseVals),
                                        EQ_OP);
 
-      sprintf (buffer, "_case_%d_%d",
+      SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
               tree->values.switchVals.swNum,
               (int) floatFromVal (caseVals));
       trueLabel = newiTempLabel (buffer);
@@ -3057,15 +3254,19 @@ geniCodeSwitch (ast * tree)
 
   /* if default is present then goto break else break */
   if (tree->values.switchVals.swDefault)
-    sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
+    {
+       SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
+    }
   else
-    sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
+    {
+       SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
+    }
 
   falseLabel = newiTempLabel (buffer);
   geniCodeGoto (falseLabel);
 
 jumpTable:
-  ast2iCode (tree->right);
+  ast2iCode (tree->right,lvl+1);
 }
 
 /*-----------------------------------------------------------------*/
@@ -3081,15 +3282,97 @@ geniCodeInline (ast * tree)
   ADDTOCHAIN (ic);
 }
 
+/*-----------------------------------------------------------------*/
+/* geniCodeArrayInit - intermediate code for array initializer     */
+/*-----------------------------------------------------------------*/
+static void 
+geniCodeArrayInit (ast * tree, operand *array)
+{
+  iCode *ic;
+
+  if (!getenv("TRY_THE_NEW_INITIALIZER")) {
+    ic = newiCode (ARRAYINIT, array, NULL);
+    IC_ARRAYILIST (ic) = tree->values.constlist;
+  } else {
+    operand *left=newOperand(), *right=newOperand();
+    left->type=right->type=SYMBOL;
+    OP_SYMBOL(left)=AST_SYMBOL(tree->left);
+    OP_SYMBOL(right)=AST_SYMBOL(tree->right);
+    ic = newiCode (ARRAYINIT, left, right);
+  }
+  ADDTOCHAIN (ic);
+}
+
+/*-----------------------------------------------------------------*/
+/* Stuff used in ast2iCode to modify geniCodeDerefPtr in some      */
+/* particular case. Ie : assigning or dereferencing array or ptr   */
+/*-----------------------------------------------------------------*/
+set * lvaluereqSet = NULL;
+typedef struct lvalItem
+  {
+    int req;
+    int lvl;
+  }
+lvalItem;
+
+/*-----------------------------------------------------------------*/
+/* addLvaluereq - add a flag for lvalreq for current ast level     */
+/*-----------------------------------------------------------------*/
+void addLvaluereq(int lvl)
+{
+  lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
+  lpItem->req=1;
+  lpItem->lvl=lvl;
+  addSetHead(&lvaluereqSet,lpItem);
+
+}
+/*-----------------------------------------------------------------*/
+/* delLvaluereq - del a flag for lvalreq for current ast level     */
+/*-----------------------------------------------------------------*/
+void delLvaluereq()
+{
+  lvalItem * lpItem;
+  lpItem = getSet(&lvaluereqSet);
+  if(lpItem) Safe_free(lpItem);
+}
+/*-----------------------------------------------------------------*/
+/* clearLvaluereq - clear lvalreq flag                            */
+/*-----------------------------------------------------------------*/
+void clearLvaluereq()
+{
+  lvalItem * lpItem;
+  lpItem = peekSet(lvaluereqSet);
+  if(lpItem) lpItem->req = 0;
+}
+/*-----------------------------------------------------------------*/
+/* getLvaluereq - get the last lvalreq level                      */
+/*-----------------------------------------------------------------*/
+int getLvaluereqLvl()
+{
+  lvalItem * lpItem;
+  lpItem = peekSet(lvaluereqSet);
+  if(lpItem) return lpItem->lvl;
+  return 0;
+}
+/*-----------------------------------------------------------------*/
+/* isLvaluereq - is lvalreq valid for this level ?                */
+/*-----------------------------------------------------------------*/
+int isLvaluereq(int lvl)
+{
+  lvalItem * lpItem;
+  lpItem = peekSet(lvaluereqSet);
+  if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
+  return 0;
+}
+
 /*-----------------------------------------------------------------*/
 /* ast2iCode - creates an icodeList from an ast                    */
 /*-----------------------------------------------------------------*/
 operand *
-ast2iCode (ast * tree)
+ast2iCode (ast * tree,int lvl)
 {
   operand *left = NULL;
   operand *right = NULL;
-
   if (!tree)
     return NULL;
 
@@ -3111,11 +3394,11 @@ ast2iCode (ast * tree)
 
   /* if we find a nullop */
   if (tree->type == EX_OP &&
-      (tree->opval.op == NULLOP ||
-       tree->opval.op == BLOCK))
+     (tree->opval.op == NULLOP ||
+     tree->opval.op == BLOCK))
     {
-      ast2iCode (tree->left);
-      ast2iCode (tree->right);
+      ast2iCode (tree->left,lvl+1);
+      ast2iCode (tree->right,lvl+1);
       return NULL;
     }
 
@@ -3131,44 +3414,37 @@ ast2iCode (ast * tree)
       tree->opval.op != INLINEASM)
     {
 
-      if (IS_ASSIGN_OP (tree->opval.op) ||
-         IS_DEREF_OP (tree) ||
-         (tree->opval.op == '&' && !tree->right) ||
-         tree->opval.op == PTR_OP)
-       {
-         lvaluereq++;
-         if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
-             (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
-           {
-             int olvr = lvaluereq;
-             lvaluereq = 0;
-             left = operandFromAst (tree->left);
-             lvaluereq = olvr - 1;
-           }
-         else
-           {
-             left = operandFromAst (tree->left);
-             lvaluereq--;
-           }
-         if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
-           left = geniCodeRValue (left, TRUE);
-       }
-      else
-       {
-         left = operandFromAst (tree->left);
-       }
-      if (tree->opval.op == INC_OP ||
-         tree->opval.op == DEC_OP)
-       {
-         lvaluereq++;
-         right = operandFromAst (tree->right);
-         lvaluereq--;
-       }
-      else
-       {
-         right = operandFromAst (tree->right);
-       }
-    }
+        if (IS_ASSIGN_OP (tree->opval.op) ||
+           IS_DEREF_OP (tree) ||
+           (tree->opval.op == '&' && !tree->right) ||
+           tree->opval.op == PTR_OP)
+          {
+            addLvaluereq(lvl);
+            if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
+               (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
+              clearLvaluereq();
+
+            left = operandFromAst (tree->left,lvl);
+            delLvaluereq();
+            if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
+             left = geniCodeRValue (left, TRUE);
+          }
+        else
+          {
+           left = operandFromAst (tree->left,lvl);
+          }
+        if (tree->opval.op == INC_OP ||
+           tree->opval.op == DEC_OP)
+          {
+           addLvaluereq(lvl);
+           right = operandFromAst (tree->right,lvl);
+           delLvaluereq();
+          }
+        else
+          {
+           right = operandFromAst (tree->right,lvl);
+          }
+      }
 
   /* now depending on the type of operand */
   /* this will be a biggy                 */
@@ -3177,12 +3453,13 @@ ast2iCode (ast * tree)
 
     case '[':                  /* array operation */
       {
-       sym_link *ltype = operandType (left);
-       left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
+       //sym_link *ltype = operandType (left);
+       //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
+       left = geniCodeRValue (left, FALSE);
        right = geniCodeRValue (right, TRUE);
       }
 
-      return geniCodeArray (left, right);
+      return geniCodeArray (left, right,lvl);
 
     case '.':                  /* structure dereference */
       if (IS_PTR (operandType (left)))
@@ -3242,9 +3519,9 @@ ast2iCode (ast * tree)
     case '*':
       if (right)
        return geniCodeMultiply (geniCodeRValue (left, FALSE),
-                                geniCodeRValue (right, FALSE), FALSE);
+                                geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
       else
-       return geniCodeDerefPtr (geniCodeRValue (left, FALSE));
+       return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
 
     case '-':
       if (right)
@@ -3256,7 +3533,7 @@ ast2iCode (ast * tree)
     case '+':
       if (right)
        return geniCodeAdd (geniCodeRValue (left, FALSE),
-                           geniCodeRValue (right, FALSE));
+                           geniCodeRValue (right, FALSE),lvl);
       else
        return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
 
@@ -3295,7 +3572,7 @@ ast2iCode (ast * tree)
                            geniCodeRValue (right, FALSE),
                            tree->opval.op);
     case '?':
-      return geniCodeConditional (tree);
+      return geniCodeConditional (tree,lvl);
 
     case SIZEOF:
       return operandFromLit (getSize (tree->right->ftype));
@@ -3305,7 +3582,7 @@ ast2iCode (ast * tree)
        sym_link *rtype = operandType (right);
        sym_link *ltype = operandType (left);
        if (IS_PTR (rtype) && IS_ITEMP (right)
-           && right->isaddr && checkType (rtype->next, ltype) == 1)
+           && right->isaddr && compareType (rtype->next, ltype) == 1)
          right = geniCodeRValue (right, TRUE);
        else
          right = geniCodeRValue (right, FALSE);
@@ -3318,7 +3595,7 @@ ast2iCode (ast * tree)
        geniCodeAssign (left,
                geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
                                                  FALSE),
-                                 geniCodeRValue (right, FALSE), FALSE), 0);
+                                 geniCodeRValue (right, FALSE),FALSE), 0);
 
     case DIV_ASSIGN:
       return
@@ -3337,7 +3614,7 @@ ast2iCode (ast * tree)
        sym_link *rtype = operandType (right);
        sym_link *ltype = operandType (left);
        if (IS_PTR (rtype) && IS_ITEMP (right)
-           && right->isaddr && checkType (rtype->next, ltype) == 1)
+           && right->isaddr && compareType (rtype->next, ltype) == 1)
          right = geniCodeRValue (right, TRUE);
        else
          right = geniCodeRValue (right, FALSE);
@@ -3346,14 +3623,14 @@ ast2iCode (ast * tree)
        return geniCodeAssign (left,
                     geniCodeAdd (geniCodeRValue (operandFromOperand (left),
                                                  FALSE),
-                                 right), 0);
+                                 right,lvl), 0);
       }
     case SUB_ASSIGN:
       {
        sym_link *rtype = operandType (right);
        sym_link *ltype = operandType (left);
        if (IS_PTR (rtype) && IS_ITEMP (right)
-           && right->isaddr && checkType (rtype->next, ltype) == 1)
+           && right->isaddr && compareType (rtype->next, ltype) == 1)
          {
            right = geniCodeRValue (right, TRUE);
          }
@@ -3407,18 +3684,18 @@ ast2iCode (ast * tree)
       return geniCodeRValue (right, FALSE);
 
     case CALL:
-      return geniCodeCall (ast2iCode (tree->left),
-                          tree->right);
+      return geniCodeCall (ast2iCode (tree->left,lvl+1),
+                          tree->right,lvl);
     case LABEL:
-      geniCodeLabel (ast2iCode (tree->left)->operand.symOperand);
-      return ast2iCode (tree->right);
+      geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
+      return ast2iCode (tree->right,lvl+1);
 
     case GOTO:
-      geniCodeGoto (ast2iCode (tree->left)->operand.symOperand);
-      return ast2iCode (tree->right);
+      geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
+      return ast2iCode (tree->right,lvl+1);
 
     case FUNCTION:
-      geniCodeFunctionBody (tree);
+      geniCodeFunctionBody (tree,lvl);
       return NULL;
 
     case RETURN:
@@ -3426,16 +3703,20 @@ ast2iCode (ast * tree)
       return NULL;
 
     case IFX:
-      geniCodeIfx (tree);
+      geniCodeIfx (tree,lvl);
       return NULL;
 
     case SWITCH:
-      geniCodeSwitch (tree);
+      geniCodeSwitch (tree,lvl);
       return NULL;
 
     case INLINEASM:
       geniCodeInline (tree);
       return NULL;
+       
+    case ARRAYINIT:
+       geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
+       return NULL;
     }
 
   return NULL;
@@ -3470,6 +3751,38 @@ iCodeFromAst (ast * tree)
 {
   returnLabel = newiTempLabel ("_return");
   entryLabel = newiTempLabel ("_entry");
-  ast2iCode (tree);
+  ast2iCode (tree,0);
   return reverseiCChain ();
 }
+
+static const char *opTypeToStr(OPTYPE op)
+{
+    switch(op)
+    {
+      case SYMBOL: return "symbol";
+      case VALUE: return "value";
+      case TYPE: return "type";
+    }
+    return "undefined type";    
+}
+
+
+operand *validateOpType(operand        *op, 
+                       const char      *macro,
+                       const char      *args,
+                       OPTYPE          type,
+                       const char      *file, 
+                       unsigned        line)
+{    
+    if (op && op->type == type)
+    {
+       return op;
+    }
+    fprintf(stderr, 
+           "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
+           " expected %s, got %s\n",
+           macro, args, file, line, 
+           opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
+    exit(-1);
+    return op; // never reached, makes compiler happy.
+}