See Changelog 1.204
[fw/sdcc] / src / SDCCicode.c
index 2a8b24d0b9f1e7c7bdac9bb30ccd1f23ddfd12e1..3a24fbd4a6ab0a298f42f9a6c3401742f329514a 100644 (file)
 /*-------------------------------------------------------------------------
 
 /*-------------------------------------------------------------------------
 
-  SDCCicode.c - intermediate code generation etc.                  
+  SDCCicode.c - intermediate code generation etc.
                 Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
                 Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
 
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
    later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-   
+
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
    In other words, you are welcome to use, share and improve this program.
    You are forbidden to forbid anyone else to use, share and improve
-   what you give them.   Help stamp out software-hoarding!  
+   what you give them.   Help stamp out software-hoarding!
 -------------------------------------------------------------------------*/
 
 #include "common.h"
 -------------------------------------------------------------------------*/
 
 #include "common.h"
+#include "newalloc.h"
+#include "math.h"
 
 /*-----------------------------------------------------------------*/
 /* global variables       */
 
 
 /*-----------------------------------------------------------------*/
 /* global variables       */
 
-set *iCodeChain = NULL ;
+set *iCodeChain = NULL;
 int iTempNum = 0;
 int iTempLblNum = 0;
 int iTempNum = 0;
 int iTempLblNum = 0;
-int operandKey = 0 ;
+int operandKey = 0;
 int iCodeKey = 0;
 int iCodeKey = 0;
-char *filename ;
-int lineno ;
+char *filename;
+int lineno;
 int block;
 int scopeLevel;
 int block;
 int scopeLevel;
-int lvaluereq;
 
 
-symbol *returnLabel ; /* function return label */
-symbol *entryLabel  ; /* function entry  label */
+symbol *returnLabel;           /* function return label */
+symbol *entryLabel;            /* function entry  label */
+
 /*-----------------------------------------------------------------*/
 /* forward definition of some functions */
 /*-----------------------------------------------------------------*/
 /* forward definition of some functions */
-operand *geniCodeDivision (operand *,operand *);
-operand *geniCodeAssign   (operand *,operand *,int);
-operand *geniCodeArray (operand *,operand *);
+operand *geniCodeDivision (operand *, operand *);
+operand *geniCodeAssign (operand *, operand *, int);
+operand *geniCodeArray (operand *, operand *,int);
 operand *geniCodeArray2Ptr (operand *);
 operand *geniCodeArray2Ptr (operand *);
-operand *geniCodeRValue (operand *, bool );
-operand *geniCodeDerefPtr (operand *);
+operand *geniCodeRValue (operand *, bool);
+operand *geniCodeDerefPtr (operand *,int);
+int isLvaluereq(int lvl);
 
 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
 
 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
-/* forward definition of print functions */
-PRINTFUNC(picGetValueAtAddr);
-PRINTFUNC(picSetValueAtAddr);
-PRINTFUNC(picAddrOf);
-PRINTFUNC(picGeneric);
-PRINTFUNC(picGenericOne);
-PRINTFUNC(picCast);
-PRINTFUNC(picAssign);
-PRINTFUNC(picLabel);
-PRINTFUNC(picGoto);
-PRINTFUNC(picIfx);
-PRINTFUNC(picJumpTable);
-PRINTFUNC(picInline);
-PRINTFUNC(picReceive);
-
-iCodeTable codeTable[] = {
-  { '!'                 ,  "not", picGenericOne    , NULL },
-  { '~'                 ,  "~"  , picGenericOne    , NULL },
-  { RRC                 ,  "rrc", picGenericOne    , NULL },
-  { RLC                 ,  "rlc", picGenericOne    , NULL },
-  { GETHBIT             ,"ghbit", picGenericOne    , NULL },
-  { UNARYMINUS          ,  "-"  , picGenericOne    , NULL },
-  { IPUSH               ,  "push",picGenericOne    , NULL },
-  { IPOP                ,  "pop", picGenericOne    , NULL },
-  { CALL                ,  "call",picGenericOne    , NULL },
-  { PCALL               , "pcall",picGenericOne    , NULL }, 
-  { FUNCTION            , "proc", picGenericOne    , NULL },
-  { ENDFUNCTION         ,"eproc", picGenericOne    , NULL },
-  { RETURN              ,  "ret", picGenericOne    , NULL },
-  { '+'                 ,  "+"  , picGeneric       , NULL },
-  { '-'                 ,  "-"  , picGeneric       , NULL },
-  { '*'                 ,  "*"  , picGeneric       , NULL },
-  { '/'                 ,  "/"  , picGeneric       , NULL },
-  { '%'                 ,  "%"  , picGeneric       , NULL },
-  { '>'                 ,  ">"  , picGeneric       , NULL },
-  { '<'                 ,  "<"  , picGeneric       , NULL },
-  { LE_OP               ,  "<=" , picGeneric       , NULL },
-  { GE_OP               ,  ">=" , picGeneric       , NULL },
-  { EQ_OP               ,  "==" , picGeneric       , NULL },
-  { NE_OP               ,  "!=" , picGeneric       , NULL },  
-  { AND_OP              ,  "&&" , picGeneric       , NULL },
-  { OR_OP               ,  "||" , picGeneric       , NULL },
-  { '^'                 ,  "^"  , picGeneric       , NULL },
-  { '|'                 ,  "|"  , picGeneric       , NULL },
-  { BITWISEAND          ,  "&"  , picGeneric       , NULL },
-  { LEFT_OP             ,  "<<" , picGeneric       , NULL },
-  { RIGHT_OP            ,  ">>" , picGeneric       , NULL },
-  { GET_VALUE_AT_ADDRESS,  "@"  , picGetValueAtAddr, NULL },
-  { ADDRESS_OF          ,  "&"  , picAddrOf        , NULL },
-  { CAST                ,  "<>" , picCast          , NULL },
-  { '='                 ,  ":=" , picAssign        , NULL },
-  { LABEL               ,  ""   , picLabel         , NULL },
-  { GOTO                ,  ""   , picGoto          , NULL },
-  { JUMPTABLE           ,"jtab" , picJumpTable     , NULL },
-  { IFX                 ,  "if" , picIfx           , NULL },
-  { INLINEASM           , ""    , picInline        , NULL },
-  { RECEIVE             , "recv", picReceive       , NULL },
-  { SEND                , "send", picGenericOne    , NULL }
+/* forward definition of ic print functions */
+PRINTFUNC (picGetValueAtAddr);
+PRINTFUNC (picSetValueAtAddr);
+PRINTFUNC (picAddrOf);
+PRINTFUNC (picGeneric);
+PRINTFUNC (picGenericOne);
+PRINTFUNC (picCast);
+PRINTFUNC (picAssign);
+PRINTFUNC (picLabel);
+PRINTFUNC (picGoto);
+PRINTFUNC (picIfx);
+PRINTFUNC (picJumpTable);
+PRINTFUNC (picInline);
+PRINTFUNC (picReceive);
+
+iCodeTable codeTable[] =
+{
+  {'!', "not", picGenericOne, NULL},
+  {'~', "~", picGenericOne, NULL},
+  {RRC, "rrc", picGenericOne, NULL},
+  {RLC, "rlc", picGenericOne, NULL},
+  {GETHBIT, "ghbit", picGenericOne, NULL},
+  {UNARYMINUS, "-", picGenericOne, NULL},
+  {IPUSH, "push", picGenericOne, NULL},
+  {IPOP, "pop", picGenericOne, NULL},
+  {CALL, "call", picGenericOne, NULL},
+  {PCALL, "pcall", picGenericOne, NULL},
+  {FUNCTION, "proc", picGenericOne, NULL},
+  {ENDFUNCTION, "eproc", picGenericOne, NULL},
+  {RETURN, "ret", picGenericOne, NULL},
+  {'+', "+", picGeneric, NULL},
+  {'-', "-", picGeneric, NULL},
+  {'*', "*", picGeneric, NULL},
+  {'/', "/", picGeneric, NULL},
+  {'%', "%", picGeneric, NULL},
+  {'>', ">", picGeneric, NULL},
+  {'<', "<", picGeneric, NULL},
+  {LE_OP, "<=", picGeneric, NULL},
+  {GE_OP, ">=", picGeneric, NULL},
+  {EQ_OP, "==", picGeneric, NULL},
+  {NE_OP, "!=", picGeneric, NULL},
+  {AND_OP, "&&", picGeneric, NULL},
+  {OR_OP, "||", picGeneric, NULL},
+  {'^', "^", picGeneric, NULL},
+  {'|', "|", picGeneric, NULL},
+  {BITWISEAND, "&", picGeneric, NULL},
+  {LEFT_OP, "<<", picGeneric, NULL},
+  {RIGHT_OP, ">>", picGeneric, NULL},
+  {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
+  {ADDRESS_OF, "&", picAddrOf, NULL},
+  {CAST, "<>", picCast, NULL},
+  {'=', ":=", picAssign, NULL},
+  {LABEL, "", picLabel, NULL},
+  {GOTO, "", picGoto, NULL},
+  {JUMPTABLE, "jtab", picJumpTable, NULL},
+  {IFX, "if", picIfx, NULL},
+  {INLINEASM, "", picInline, NULL},
+  {RECEIVE, "recv", picReceive, 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                   */
 /*-----------------------------------------------------------------*/
 
 /*-----------------------------------------------------------------*/
 /* operandName - returns the name of the operand                   */
 /*-----------------------------------------------------------------*/
-int printOperand (operand *op, FILE *file)
+int 
+printOperand (operand * op, FILE * file)
 {
 {
-    sym_link *opetype;
-    int pnl = 0;
+  sym_link *opetype;
+  int pnl = 0;
 
 
-    if (!op)
-       return 1;
+  if (!op)
+    return 1;
 
 
-    if (!file) {
-       file = stdout;
-       pnl = 1;
+  if (!file)
+    {
+      file = stdout;
+      pnl = 1;
     }
     }
-    switch (op->type) {
-       
+  switch (op->type)
+    {
+
     case VALUE:
     case VALUE:
-       opetype = getSpec (operandType(op));
-       if (SPEC_NOUN(opetype) == V_FLOAT)
-           fprintf (file,"%g {", SPEC_CVAL(opetype).v_float);
-       else 
-           fprintf (file,"0x%x {",(int) floatFromVal(op->operand.valOperand));
-       printTypeChain(operandType(op),file);
-       fprintf(file,"}");
-       break;
-       
-    case SYMBOL :
+      opetype = getSpec (operandType (op));
+      if (SPEC_NOUN (opetype) == V_FLOAT)
+       fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
+      else
+       fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
+      printTypeChain (operandType (op), file);
+      fprintf (file, "}");
+      break;
+
+    case SYMBOL:
 #define REGA 1
 #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}"  ,*/
-                (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
-                );
+#ifdef REGA
+      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_SYMBOL(op)->noSpilLoc,
+              OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
+       );
+      {
+       fprintf (file, "{");
+       printTypeChain (operandType (op), file);
+       if (SPIL_LOC (op) && IS_ITEMP (op))
+         fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
+       fprintf (file, "}");
+
+      }
+
+      /* if assigned to registers */
+      if (OP_SYMBOL (op)->nRegs)
        {
        {
-           fprintf(file,"{"); printTypeChain(operandType(op),file); 
-           if (SPIL_LOC(op) && IS_ITEMP(op))
-               fprintf(file,"}{ sir@ %s",SPIL_LOC(op)->rname);
-           fprintf(file,"}");
-
-       }
-       
-       /* if assigned to registers */
-       if (OP_SYMBOL(op)->nRegs) {
-           if (OP_SYMBOL(op)->isspilt) {
-               if (!OP_SYMBOL(op)->remat)
-                   if (OP_SYMBOL(op)->usl.spillLoc)
-                       fprintf(file,"[%s]",(OP_SYMBOL(op)->usl.spillLoc->rname[0] ?
-                                            OP_SYMBOL(op)->usl.spillLoc->rname :
-                                            OP_SYMBOL(op)->usl.spillLoc->name));
-                   else
-                       fprintf(file,"[err]");
+         if (OP_SYMBOL (op)->isspilt)
+           {
+             if (!OP_SYMBOL (op)->remat)
+               if (OP_SYMBOL (op)->usl.spillLoc)
+                 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
+                                      OP_SYMBOL (op)->usl.spillLoc->rname :
+                                      OP_SYMBOL (op)->usl.spillLoc->name));
                else
                else
-                   fprintf(file,"[remat]");
+                 fprintf (file, "[err]");
+             else
+               fprintf (file, "[remat]");
            }
            }
-           else {
-               int i;
-               fprintf(file,"[");
-               for(i=0;i<OP_SYMBOL(op)->nRegs;i++)
-                   fprintf(file,"%s ", port->getRegName(OP_SYMBOL(op)->regs[i]));
-               fprintf(file,"]");
+         else
+           {
+             int i;
+             fprintf (file, "[");
+             for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
+               fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
+             fprintf (file, "]");
            }
            }
-       } 
+       }
 #else
 #else
-       fprintf(file,"%s",(OP_SYMBOL(op)->rname[0] ?
-                          OP_SYMBOL(op)->rname : OP_SYMBOL(op)->name));
-       /* if assigned to registers */
-       if (OP_SYMBOL(op)->nRegs && !OP_SYMBOL(op)->isspilt) {
-           int i;
-           fprintf(file,"[");
-           for(i=0;i<OP_SYMBOL(op)->nRegs;i++)
-               fprintf(file,"%s ",(OP_SYMBOL(op)->regs[i] ? 
-                                   OP_SYMBOL(op)->regs[i]->name :
-                                   "err"));
-           fprintf(file,"]");
-       } 
+      fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
+                           OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
+      /* if assigned to registers */
+      if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
+       {
+         int i;
+         fprintf (file, "[");
+         for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
+           fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
+                                  OP_SYMBOL (op)->regs[i]->name :
+                                  "err"));
+         fprintf (file, "]");
+       }
 #endif
 #endif
-       break ;
-       
+      break;
+
     case TYPE:
     case TYPE:
-       fprintf(file,"(");
-       printTypeChain(op->operand.typeOperand,file);
-       fprintf(file,")");
-       break;
+      fprintf (file, "(");
+      printTypeChain (op->operand.typeOperand, file);
+      fprintf (file, ")");
+      break;
     }
     }
-    
-    if (pnl)
-       fprintf(file,"\n");
-    return 0;
+
+  if (pnl)
+    fprintf (file, "\n");
+  return 0;
 }
 
 
 /*-----------------------------------------------------------------*/
 /*                    print functions                              */
 /*-----------------------------------------------------------------*/
 }
 
 
 /*-----------------------------------------------------------------*/
 /*                    print functions                              */
 /*-----------------------------------------------------------------*/
-PRINTFUNC(picGetValueAtAddr)
+PRINTFUNC (picGetValueAtAddr)
 {
 {
-    fprintf(of,"\t");
-    printOperand (IC_RESULT(ic),of);
-    fprintf (of," = ");
-    fprintf (of,"@[");
-    printOperand (IC_LEFT(ic), of);
-    fprintf (of,"]");
-    
-    fprintf(of,"\n");
+  fprintf (of, "\t");
+  printOperand (IC_RESULT (ic), of);
+  fprintf (of, " = ");
+  fprintf (of, "@[");
+  printOperand (IC_LEFT (ic), of);
+  fprintf (of, "]");
+
+  fprintf (of, "\n");
 }
 
 }
 
-PRINTFUNC(picSetValueAtAddr)
+PRINTFUNC (picSetValueAtAddr)
 {
 {
-    fprintf(of,"\t");
-    fprintf(of,"*[");
-    printOperand(IC_LEFT(ic),of);
-    fprintf(of,"] = ");
-    printOperand(IC_RIGHT(ic),of);
-    fprintf (of,"\n");
+  fprintf (of, "\t");
+  fprintf (of, "*[");
+  printOperand (IC_LEFT (ic), of);
+  fprintf (of, "] = ");
+  printOperand (IC_RIGHT (ic), of);
+  fprintf (of, "\n");
 }
 
 }
 
-PRINTFUNC(picAddrOf)
+PRINTFUNC (picAddrOf)
 {
 {
-    fprintf(of,"\t");
-    printOperand(IC_RESULT(ic),of);
-    if (IS_ITEMP(IC_LEFT(ic)))
-       fprintf(of," = ");
-    else
-       fprintf(of," = &[");
-    printOperand(IC_LEFT(ic),of);
-    if (IC_RIGHT(ic)) {
-       if (IS_ITEMP(IC_LEFT(ic)))
-           fprintf(of," offsetAdd ");
-       else
-           fprintf(of," , ");
-       printOperand(IC_RIGHT(ic),of);
+  fprintf (of, "\t");
+  printOperand (IC_RESULT (ic), of);
+  if (IS_ITEMP (IC_LEFT (ic)))
+    fprintf (of, " = ");
+  else
+    fprintf (of, " = &[");
+  printOperand (IC_LEFT (ic), of);
+  if (IC_RIGHT (ic))
+    {
+      if (IS_ITEMP (IC_LEFT (ic)))
+       fprintf (of, " offsetAdd ");
+      else
+       fprintf (of, " , ");
+      printOperand (IC_RIGHT (ic), of);
     }
     }
-    if (IS_ITEMP(IC_LEFT(ic)))
-       fprintf (of,"\n");
-    else
-       fprintf (of,"]\n");
+  if (IS_ITEMP (IC_LEFT (ic)))
+    fprintf (of, "\n");
+  else
+    fprintf (of, "]\n");
 }
 
 }
 
-PRINTFUNC(picJumpTable)
+PRINTFUNC (picJumpTable)
 {
 {
-    symbol *sym;
+  symbol *sym;
 
 
-    fprintf(of,"\t");
-    fprintf(of,"%s\t",s);
-    printOperand(IC_JTCOND(ic),of);
-    fprintf(of,"\n");
-    for ( sym = setFirstItem(IC_JTLABELS(ic)); sym;
-         sym = setNextItem(IC_JTLABELS(ic))) 
-       fprintf(of,"\t\t\t%s\n",sym->name);
+  fprintf (of, "\t");
+  fprintf (of, "%s\t", s);
+  printOperand (IC_JTCOND (ic), of);
+  fprintf (of, "\n");
+  for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
+       sym = setNextItem (IC_JTLABELS (ic)))
+    fprintf (of, "\t\t\t%s\n", sym->name);
 }
 
 }
 
-PRINTFUNC(picGeneric)
+PRINTFUNC (picGeneric)
 {
 {
-    fprintf(of,"\t");
-    printOperand(IC_RESULT(ic),of);
-    fprintf(of," = ");
-    printOperand(IC_LEFT(ic),of);
-    fprintf(of," %s ",s);
-    printOperand(IC_RIGHT(ic),of);
-    fprintf(of,"\n");
+  fprintf (of, "\t");
+  printOperand (IC_RESULT (ic), of);
+  fprintf (of, " = ");
+  printOperand (IC_LEFT (ic), of);
+  fprintf (of, " %s ", s);
+  printOperand (IC_RIGHT (ic), of);
+  fprintf (of, "\n");
 }
 
 }
 
-PRINTFUNC(picGenericOne)
+PRINTFUNC (picGenericOne)
 {
 {
-    fprintf(of,"\t");
-    if ( IC_RESULT(ic) ) {
-       printOperand(IC_RESULT(ic),of);
-       fprintf (of," = ");
+  fprintf (of, "\t");
+  if (IC_RESULT (ic))
+    {
+      printOperand (IC_RESULT (ic), of);
+      fprintf (of, " = ");
     }
     }
-    
-    if (IC_LEFT(ic)) {
-       fprintf (of,"%s ",s);
-       printOperand(IC_LEFT(ic),of);     
+
+  if (IC_LEFT (ic))
+    {
+      fprintf (of, "%s ", s);
+      printOperand (IC_LEFT (ic), of);
     }
     }
-    
-    if (! IC_RESULT(ic) && !IC_LEFT(ic))
-       fprintf (of,s);
-    
-    fprintf(of,"\n");
+
+  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");
 }
 
 }
 
-PRINTFUNC(picCast)
+PRINTFUNC (picCast)
 {
 {
-    fprintf(of,"\t");
-    printOperand(IC_RESULT(ic),of);
-    fprintf (of," = ");
-    printOperand(IC_LEFT(ic),of);
-    printOperand(IC_RIGHT(ic),of);
-    fprintf(of,"\n");
+  fprintf (of, "\t");
+  printOperand (IC_RESULT (ic), of);
+  fprintf (of, " = ");
+  printOperand (IC_LEFT (ic), of);
+  printOperand (IC_RIGHT (ic), of);
+  fprintf (of, "\n");
 }
 
 
 }
 
 
-PRINTFUNC(picAssign)
+PRINTFUNC (picAssign)
 {
 {
-    fprintf(of,"\t");
-    
-    if (IC_RESULT(ic)->isaddr && IS_ITEMP(IC_RESULT(ic)))
-       fprintf(of,"*(");
-    
-    printOperand(IC_RESULT(ic),of);  
-    
-    if (IC_RESULT(ic)->isaddr && IS_ITEMP(IC_RESULT(ic)))
-       fprintf(of,")");
-    
-    fprintf(of," %s ", s);
-    printOperand (IC_RIGHT(ic),of);
-    
-    fprintf(of,"\n");
+  fprintf (of, "\t");
+
+  if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
+    fprintf (of, "*(");
+
+  printOperand (IC_RESULT (ic), of);
+
+  if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
+    fprintf (of, ")");
+
+  fprintf (of, " %s ", s);
+  printOperand (IC_RIGHT (ic), of);
+
+  fprintf (of, "\n");
 }
 
 }
 
-PRINTFUNC(picLabel)
+PRINTFUNC (picLabel)
 {
 {
-    fprintf(of," %s($%d) :\n",IC_LABEL(ic)->name,IC_LABEL(ic)->key);
+  fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
 }
 
 }
 
-PRINTFUNC(picGoto)
+PRINTFUNC (picGoto)
 {
 {
-   fprintf(of,"\t");
-   fprintf (of," goto %s($%d)\n", IC_LABEL(ic)->name,IC_LABEL(ic)->key);
+  fprintf (of, "\t");
+  fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
 }
 
 }
 
-PRINTFUNC(picIfx)
-{    
-    fprintf(of,"\t");
-    fprintf (of,"if ");
-    printOperand(IC_COND(ic),of);
-    
-    if ( ! IC_TRUE(ic) ) 
-       fprintf (of," == 0 goto %s($%d)\n",IC_FALSE(ic)->name,IC_FALSE(ic)->key);
-    else {
-       fprintf (of," != 0 goto %s($%d)\n",IC_TRUE(ic)->name,IC_TRUE(ic)->key);
-       if (IC_FALSE(ic))
-           fprintf (of,"\tzzgoto %s\n",IC_FALSE(ic)->name);
+PRINTFUNC (picIfx)
+{
+  fprintf (of, "\t");
+  fprintf (of, "if ");
+  printOperand (IC_COND (ic), of);
+
+  if (!IC_TRUE (ic))
+    fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
+  else
+    {
+      fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
+      if (IC_FALSE (ic))
+       fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
     }
 }
 
     }
 }
 
-PRINTFUNC(picInline)
+PRINTFUNC (picInline)
 {
 {
-    fprintf(of,"%s",IC_INLINE(ic));
+  fprintf (of, "%s", IC_INLINE (ic));
 }
 
 }
 
-PRINTFUNC(picReceive)
+PRINTFUNC (picReceive)
 {
 {
-    printOperand(IC_RESULT(ic),of);
-    fprintf(of," = %s ",s);
-    printOperand(IC_LEFT(ic),of);
-    fprintf(of,"\n");
+  printOperand (IC_RESULT (ic), of);
+  fprintf (of, " = %s ", s);
+  printOperand (IC_LEFT (ic), of);
+  fprintf (of, "\n");
 }
 
 /*-----------------------------------------------------------------*/
 /* piCode - prints one iCode                                       */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* piCode - prints one iCode                                       */
 /*-----------------------------------------------------------------*/
-int piCode (void *item, FILE *of)
+int 
+piCode (void *item, FILE * of)
 {
 {
-    iCode *ic = item;
-    iCodeTable *icTab ;
-    
-    if (!of)
-       of = stdout;
-
-    icTab = getTableEntry(ic->op) ;
-    fprintf(stdout,"%s(%d:%d:%d:%d:%d)\t",
-                   ic->filename,ic->lineno,
-                   ic->seq,ic->key,ic->depth,ic->supportRtn);
-    icTab->iCodePrint(of,ic,icTab->printName);
-    return 1;
+  iCode *ic = item;
+  iCodeTable *icTab;
+
+  if (!of)
+    of = stdout;
+
+  icTab = getTableEntry (ic->op);
+  fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
+          ic->filename, ic->lineno,
+          ic->seq, ic->key, ic->depth, ic->supportRtn);
+  icTab->iCodePrint (of, ic, icTab->printName);
+  return 1;
 }
 
 }
 
+void PICC(iCode *ic)
+{
+       printiCChain(ic,stdout);
+}
 /*-----------------------------------------------------------------*/
 /* printiCChain - prints intermediate code for humans              */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* printiCChain - prints intermediate code for humans              */
 /*-----------------------------------------------------------------*/
-void printiCChain (iCode *icChain, FILE *of)
+void 
+printiCChain (iCode * icChain, FILE * of)
 {
 {
-    iCode *loop ;
-    iCodeTable *icTab ;
+  iCode *loop;
+  iCodeTable *icTab;
 
 
-    if (!of)
-       of = stdout;
-    for ( loop = icChain ; loop ; loop = loop->next ) {
-       if ((icTab = getTableEntry (loop->op ))) {
-           fprintf(of,"%s(%d:%d:%d:%d:%d)\t",
-                   loop->filename,loop->lineno,
-                   loop->seq,loop->key,loop->depth,loop->supportRtn);
+  if (!of)
+    of = stdout;
+  for (loop = icChain; loop; loop = loop->next)
+    {
+      if ((icTab = getTableEntry (loop->op)))
+       {
+         fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
+                  loop->filename, loop->lineno,
+                  loop->seq, loop->key, loop->depth, loop->supportRtn);
 
 
-           icTab->iCodePrint (of,loop,icTab->printName);
+         icTab->iCodePrint (of, loop, icTab->printName);
        }
     }
 }
        }
     }
 }
@@ -408,134 +513,154 @@ void printiCChain (iCode *icChain, FILE *of)
 /*-----------------------------------------------------------------*/
 /* newOperand - allocate, init & return a new iCode                */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* newOperand - allocate, init & return a new iCode                */
 /*-----------------------------------------------------------------*/
-operand *newOperand ()
+operand *
+newOperand ()
 {
 {
-    operand *op ;
-    
-    ALLOC(op,sizeof(operand));
-    
-    op->key = 0 ;
-    return op;
+  operand *op;
+
+  op = Safe_alloc ( sizeof (operand));
+
+  op->key = 0;
+  return op;
 }
 
 /*-----------------------------------------------------------------*/
 /* newiCode - create and return a new iCode entry initialised      */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* newiCode - create and return a new iCode entry initialised      */
 /*-----------------------------------------------------------------*/
-iCode *newiCode (int op, operand *left, operand *right)
+iCode *
+newiCode (int op, operand * left, operand * right)
 {
 {
-    iCode *ic ;
-    
-    ALLOC(ic,sizeof(iCode));
-   
-    ic->lineno = lineno ;
-    ic->filename= filename ;
-    ic->block = block;
-    ic->level = scopeLevel;
-    ic->op = op;
-    ic->key= iCodeKey++ ;
-    IC_LEFT(ic) = left;
-    IC_RIGHT(ic)= right;
+  iCode *ic;
 
 
-    return ic;
-}      
+  ic = Safe_alloc ( sizeof (iCode));
+
+  ic->lineno = lineno;
+  ic->filename = filename;
+  ic->block = block;
+  ic->level = scopeLevel;
+  ic->op = op;
+  ic->key = iCodeKey++;
+  IC_LEFT (ic) = left;
+  IC_RIGHT (ic) = right;
+
+  return ic;
+}
 
 /*-----------------------------------------------------------------*/
 /* newiCode for conditional statements                             */
 /*-----------------------------------------------------------------*/
 
 /*-----------------------------------------------------------------*/
 /* newiCode for conditional statements                             */
 /*-----------------------------------------------------------------*/
-iCode *newiCodeCondition (operand *condition,
-                         symbol  *trueLabel, 
-                         symbol  *falseLabel )
+iCode *
+newiCodeCondition (operand * condition,
+                  symbol * trueLabel,
+                  symbol * falseLabel)
 {
 {
-    iCode *ic ;
-    
-    ic = newiCode(IFX,NULL,NULL);
-    IC_COND(ic) = condition ;
-    IC_TRUE(ic) = trueLabel ;
-    IC_FALSE(ic) = falseLabel;
-    return ic;
+  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;
+  IC_FALSE (ic) = falseLabel;
+  return ic;
 }
 
 /*-----------------------------------------------------------------*/
 /* newiCodeLabelGoto - unconditional goto statement| label stmnt   */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* newiCodeLabelGoto - unconditional goto statement| label stmnt   */
 /*-----------------------------------------------------------------*/
-iCode *newiCodeLabelGoto (int op, symbol *label)
+iCode *
+newiCodeLabelGoto (int op, symbol * label)
 {
 {
-    iCode *ic ;
-    
-    ic = newiCode(op,NULL,NULL);
-    ic->op = op ;
-    ic->argLabel.label = label ;
-    IC_LEFT(ic) = NULL ;
-    IC_RIGHT(ic) = NULL ;
-    IC_RESULT(ic) = NULL ;
-    return ic;
+  iCode *ic;
+
+  ic = newiCode (op, NULL, NULL);
+  ic->op = op;
+  ic->label = label;
+  IC_LEFT (ic) = NULL;
+  IC_RIGHT (ic) = NULL;
+  IC_RESULT (ic) = NULL;
+  return ic;
 }
 
 /*-----------------------------------------------------------------*/
 /* newiTemp - allocate & return a newItemp Variable                */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* newiTemp - allocate & return a newItemp Variable                */
 /*-----------------------------------------------------------------*/
-symbol *newiTemp (char *s)
-{ 
-    symbol *itmp;
-    
-    if (s) 
-       sprintf(buffer,"%s",s);
-    else
-       sprintf (buffer,"iTemp%d",iTempNum++);  
-    itmp =  newSymbol (buffer,1);
-    strcpy(itmp->rname,itmp->name);
-    itmp->isitmp = 1;
+symbol *
+newiTemp (char *s)
+{
+  symbol *itmp;
+
+  if (s)
+  {
+      SNPRINTF (buffer, sizeof(buffer), "%s", s);
+  }
+  else
+  {
+      SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
+  }
     
     
-    return itmp;
+  itmp = newSymbol (buffer, 1);
+  strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
+  itmp->isitmp = 1;
+
+  return itmp;
 }
 
 /*-----------------------------------------------------------------*/
 /* newiTempLabel - creates a temp variable label                   */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* newiTempLabel - creates a temp variable label                   */
 /*-----------------------------------------------------------------*/
-symbol *newiTempLabel (char *s)
+symbol *
+newiTempLabel (char *s)
 {
 {
-    symbol *itmplbl;
+  symbol *itmplbl;
 
 
-    /* check if this alredy exists */
-    if (s && (itmplbl = findSym(LabelTab, NULL, s)))
-       return itmplbl ;
+  /* check if this alredy exists */
+  if (s && (itmplbl = findSym (LabelTab, NULL, s)))
+    return itmplbl;
 
 
-    if (s) 
-       itmplbl = newSymbol(s,1);
-    else {
-       sprintf(buffer,"iTempLbl%d",iTempLblNum++);
-       itmplbl = newSymbol(buffer,1);  
+  if (s)
+    {
+       itmplbl = newSymbol (s, 1);
     }
     }
-    
-    itmplbl->isitmp = 1;
-    itmplbl->islbl = 1;
-    itmplbl->key = labelKey++ ;
-    addSym (LabelTab, itmplbl, itmplbl->name,0,0);
-    return itmplbl ;  
+  else
+    {
+      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, 0);
+  return itmplbl;
 }
 
 /*-----------------------------------------------------------------*/
 /* newiTempPreheaderLabel - creates a new preheader label          */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* newiTempPreheaderLabel - creates a new preheader label          */
 /*-----------------------------------------------------------------*/
-symbol *newiTempPreheaderLabel()
+symbol *
+newiTempPreheaderLabel ()
 {
 {
-    symbol *itmplbl ;
+  symbol *itmplbl;
 
 
-    sprintf(buffer,"preHeaderLbl%d",iTempLblNum++);
-    itmplbl = newSymbol(buffer,1);    
-    
-    itmplbl->isitmp = 1;
-    itmplbl->islbl = 1;
-    itmplbl->key = labelKey++ ;
-    addSym (LabelTab, itmplbl, itmplbl->name,0,0);
-    return itmplbl ;  
+  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, 0);
+  return itmplbl;
 }
 
 
 /*-----------------------------------------------------------------*/
 /* initiCode - initialises some iCode related stuff                */
 /*-----------------------------------------------------------------*/
 }
 
 
 /*-----------------------------------------------------------------*/
 /* initiCode - initialises some iCode related stuff                */
 /*-----------------------------------------------------------------*/
-void initiCode ()
+void 
+initiCode ()
 {
 
 }
 {
 
 }
@@ -543,1623 +668,1855 @@ void initiCode ()
 /*-----------------------------------------------------------------*/
 /* copyiCode - make a copy of the iCode given                      */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* copyiCode - make a copy of the iCode given                      */
 /*-----------------------------------------------------------------*/
-iCode *copyiCode (iCode *ic)
+iCode *
+copyiCode (iCode * ic)
 {
 {
-    iCode *nic = newiCode(ic->op,NULL,NULL);
+  iCode *nic = newiCode (ic->op, NULL, NULL);
 
 
-    nic->lineno = ic->lineno ;
-    nic->filename= ic->filename ;
-    nic->block = ic->block;
-    nic->level = ic->level;
+  nic->lineno = ic->lineno;
+  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) {
+  /* deal with the special cases first */
+  switch (ic->op)
+    {
     case IFX:
     case IFX:
-       IC_COND(nic) = operandFromOperand(IC_COND(ic));
-       IC_TRUE(nic) = IC_TRUE(ic);
-       IC_FALSE(nic)= IC_FALSE(ic);
-       break;
+      IC_COND (nic) = operandFromOperand (IC_COND (ic));
+      IC_TRUE (nic) = IC_TRUE (ic);
+      IC_FALSE (nic) = IC_FALSE (ic);
+      break;
 
     case JUMPTABLE:
 
     case JUMPTABLE:
-       IC_JTCOND(nic) = operandFromOperand(IC_JTCOND(ic));
-       IC_JTLABELS(nic) = IC_JTLABELS(ic);
-       break;
+      IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
+      IC_JTLABELS (nic) = IC_JTLABELS (ic);
+      break;
 
     case CALL:
     case PCALL:
 
     case CALL:
     case PCALL:
-       IC_RESULT(nic) = operandFromOperand(IC_RESULT(ic));
-       IC_LEFT(nic)   = operandFromOperand(IC_LEFT(ic));
-       IC_ARGS(nic)   = IC_ARGS(ic);
-       break;
+      IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
+      IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
+      break;
 
     case INLINEASM:
 
     case INLINEASM:
-       IC_INLINE(nic) = IC_INLINE(ic);
-       break;
-       
+      IC_INLINE (nic) = IC_INLINE (ic);
+      break;
+
+    case ARRAYINIT:
+      IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
+      break;
+
     default:
     default:
-       IC_RESULT(nic) = operandFromOperand(IC_RESULT(ic));
-       IC_LEFT(nic) = operandFromOperand(IC_LEFT(ic));
-       IC_RIGHT(nic)= operandFromOperand(IC_RIGHT(ic));
+      IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
+      IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
+      IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
     }
 
     }
 
-    return nic;
+  return nic;
 }
 
 /*-----------------------------------------------------------------*/
 /* getTableEntry - gets the table entry for the given operator     */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* getTableEntry - gets the table entry for the given operator     */
 /*-----------------------------------------------------------------*/
-iCodeTable *getTableEntry (int oper )
+iCodeTable *
+getTableEntry (int oper)
 {
 {
-    int i ;
-    
-    for ( i = 0 ; i < (sizeof(codeTable)/sizeof(iCodeTable)); i++ ) 
-       if (oper == codeTable[i].icode)
-           return &codeTable[i] ;
-    
-    return NULL ;
+  int i;
+
+  for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
+    if (oper == codeTable[i].icode)
+      return &codeTable[i];
+
+  return NULL;
 }
 
 /*-----------------------------------------------------------------*/
 /* newiTempOperand - new intermediate temp operand                 */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* newiTempOperand - new intermediate temp operand                 */
 /*-----------------------------------------------------------------*/
-operand *newiTempOperand (sym_link *type, char throwType)
+operand *
+newiTempOperand (sym_link * type, char throwType)
 {
 {
-    symbol *itmp;
-    operand *op = newOperand();
-    sym_link *etype;
+  symbol *itmp;
+  operand *op = newOperand ();
+  sym_link *etype;
 
 
-    op->type = SYMBOL ;
-    itmp = newiTemp(NULL);
+  op->type = SYMBOL;
+  itmp = newiTemp (NULL);
 
 
-    etype = getSpec(type);
+  etype = getSpec (type);
 
 
-    if (IS_LITERAL(etype) )
-       throwType = 0 ;
+  if (IS_LITERAL (etype))
+    throwType = 0;
 
 
-    /* copy the type information */
-    if (type) 
-       itmp->etype = getSpec (itmp->type = (throwType ? type :
-                                            copyLinkChain(type)));
-    if (IS_LITERAL(itmp->etype)) {
-       SPEC_SCLS(itmp->etype) = S_REGISTER ;
-       SPEC_OCLS(itmp->etype) = reg;
+  /* copy the type information */
+  if (type)
+    itmp->etype = getSpec (itmp->type = (throwType ? type :
+                                        copyLinkChain (type)));
+  if (IS_LITERAL (itmp->etype))
+    {
+      SPEC_SCLS (itmp->etype) = S_REGISTER;
+      SPEC_OCLS (itmp->etype) = reg;
     }
     }
-       
-    op->operand.symOperand = itmp;
-    op->key = itmp->key = ++operandKey ;
-    return op;
+
+  op->operand.symOperand = itmp;
+  op->key = itmp->key = ++operandKey;
+  return op;
 }
 
 /*-----------------------------------------------------------------*/
 /* operandType - returns the type chain for an operand             */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* operandType - returns the type chain for an operand             */
 /*-----------------------------------------------------------------*/
-sym_link *operandType (operand *op) 
+sym_link *
+operandType (operand * op)
 {
 {
-    /* depending on type of operand */
-    switch (op->type) {
-       
-    case VALUE :
-       return op->operand.valOperand->type ;
-       
+  /* depending on type of operand */
+  switch (op->type)
+    {
+
+    case VALUE:
+      return op->operand.valOperand->type;
+
     case SYMBOL:
     case SYMBOL:
-       return op->operand.symOperand->type ;
-       
-    case TYPE :
-       return op->operand.typeOperand ;
+      return op->operand.symOperand->type;
+
+    case TYPE:
+      return op->operand.typeOperand;
     default:
     default:
-       werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
-               " operand type not known ");
-       assert (0) ; /* should never come here */
-       /*  Just to keep the compiler happy */
-       return (sym_link *)0;
+      werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+             " operand type not known ");
+      assert (0);              /* should never come here */
+      /*  Just to keep the compiler happy */
+      return (sym_link *) 0;
     }
 }
 
 /*-----------------------------------------------------------------*/
 /* isParamterToCall - will return 1 if op is a parameter to args   */
 /*-----------------------------------------------------------------*/
     }
 }
 
 /*-----------------------------------------------------------------*/
 /* isParamterToCall - will return 1 if op is a parameter to args   */
 /*-----------------------------------------------------------------*/
-int isParameterToCall (value *args, operand *op)
+int 
+isParameterToCall (value * args, operand * op)
 {
 {
-    value *tval = args ;
+  value *tval = args;
 
 
-    while (tval) {
-       if (tval->sym && 
-           isSymbolEqual(op->operand.symOperand,tval->sym))
-           return 1;
-       tval = tval->next ;
+  wassert (IS_SYMOP(op));
+    
+  while (tval)
+    {
+      if (tval->sym &&
+         isSymbolEqual (op->operand.symOperand, tval->sym))
+       return 1;
+      tval = tval->next;
     }
     }
-    return 0;
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* isOperandGlobal   - return 1 if operand is a global variable    */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* isOperandGlobal   - return 1 if operand is a global variable    */
 /*-----------------------------------------------------------------*/
-int isOperandGlobal ( operand *op )
+int 
+isOperandGlobal (operand * op)
 {
 {
-    if (!op)
-       return 0;
-
-    if (IS_ITEMP(op))
-       return 0;
+  if (!op)
+    return 0;
 
 
-    if (op->type == SYMBOL &&       
-        (op->operand.symOperand->level == 0 ||  
-        IS_STATIC(op->operand.symOperand->etype) ||
-        IS_EXTERN(op->operand.symOperand->etype))
-         )
-       return 1;
-    
+  if (IS_ITEMP (op))
     return 0;
     return 0;
+
+  if (IS_SYMOP(op) &&
+      (op->operand.symOperand->level == 0 ||
+       IS_STATIC (op->operand.symOperand->etype) ||
+       IS_EXTERN (op->operand.symOperand->etype))
+    )
+    return 1;
+
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* isOperandVolatile - return 1 if the operand is volatile         */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* isOperandVolatile - return 1 if the operand is volatile         */
 /*-----------------------------------------------------------------*/
-int isOperandVolatile ( operand *op , bool chkTemp)
+int 
+isOperandVolatile (operand * op, bool chkTemp)
 {
 {
-    sym_link *optype ;
-    sym_link *opetype ;
+  sym_link *optype;
+  sym_link *opetype;
 
 
-    if (IS_ITEMP(op) && !chkTemp)
-       return 0;
+  if (IS_ITEMP (op) && !chkTemp)
+    return 0;
 
 
-    opetype = getSpec(optype = operandType(op));
-    
-    if (IS_PTR(optype) && DCL_PTR_VOLATILE(optype))
-       return 1;
+  opetype = getSpec (optype = operandType (op));
 
 
-    if (IS_VOLATILE(opetype))
-       return 1;
-    return 0;
+  if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
+    return 1;
+
+  if (IS_VOLATILE (opetype))
+    return 1;
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* isOperandLiteral - returns 1 if an operand contains a literal   */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* isOperandLiteral - returns 1 if an operand contains a literal   */
 /*-----------------------------------------------------------------*/
-int isOperandLiteral ( operand *op )
+int 
+isOperandLiteral (operand * op)
 {
 {
-    sym_link *opetype ;
-    
-    if (!op)
-       return 0;
-    
-    opetype = getSpec (operandType(op));
-
-    if (IS_LITERAL(opetype))
-       return 1;
+  sym_link *opetype;
 
 
+  if (!op)
     return 0;
     return 0;
+
+  opetype = getSpec (operandType (op));
+
+  if (IS_LITERAL (opetype))
+    return 1;
+
+  return 0;
 }
 }
+
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-/* isOperandInFarSpace - will return true if operand is in farSpace*/
+/* isOperandInFarSpace - will return true if operand is in farSpace */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-bool isOperandInFarSpace (operand *op)
+bool 
+isOperandInFarSpace (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_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
+}
+
+/*------------------------------------------------------------------*/
+/* isOperandInDirSpace - will return true if operand is in dirSpace */
+/*------------------------------------------------------------------*/
+bool 
+isOperandInDirSpace (operand * op)
 {
 {
-    sym_link *etype;
+  sym_link *etype;
+
+  if (!op)
+    return FALSE;
 
 
-    if (!op)
+  if (!IS_SYMOP (op))
+    return FALSE;
+
+  if (!IS_TRUE_SYMOP (op))
+    {
+      if (SPIL_LOC (op))
+       etype = SPIL_LOC (op)->etype;
+      else
        return FALSE;
        return FALSE;
+    }
+  else
+    {
+      etype = getSpec (operandType (op));
+    }
+  return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
+}
 
 
-    if (!IS_SYMOP(op))
-       return 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;
+  if (!IS_TRUE_SYMOP (op))
+    {
+      if (SPIL_LOC (op))
+       etype = SPIL_LOC (op)->etype;
+      else
+       return FALSE;
     }
     }
-    else
+  else
     {
     {
-       etype = getSpec(operandType(op));
+      etype = getSpec (operandType (op));
     }
     }
-    return (IN_FARSPACE(SPEC_OCLS(etype)) ? TRUE : FALSE);
+  return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
 }
 
 /*-----------------------------------------------------------------*/
 /* isOperandOnStack - will return true if operand is on stack      */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* isOperandOnStack - will return true if operand is on stack      */
 /*-----------------------------------------------------------------*/
-bool isOperandOnStack(operand *op)
+bool 
+isOperandOnStack (operand * op)
 {
 {
-    sym_link *etype;
+  sym_link *etype;
 
 
-    if (!op)
-       return FALSE;
+  if (!op)
+    return FALSE;
 
 
-    if (!IS_SYMOP(op))
-       return FALSE ;
+  if (!IS_SYMOP (op))
+    return FALSE;
 
 
-    etype = getSpec(operandType(op));
+  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;
 }
 
 /*-----------------------------------------------------------------*/
 /* operandLitValue - literal value of an operand                   */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* operandLitValue - literal value of an operand                   */
 /*-----------------------------------------------------------------*/
-double operandLitValue ( operand *op )
+double 
+operandLitValue (operand * op)
 {
 {
-    assert(isOperandLiteral(op));
-    
-    return floatFromVal(op->operand.valOperand);    
+  assert (isOperandLiteral (op));
+
+  return floatFromVal (op->operand.valOperand);
 }
 
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
-/* operandOperation - perforoms operations on operands             */
+/* getBuiltInParms - returns parameters to a builtin functions     */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-operand *operandOperation (operand *left,operand *right,
-                          int op, sym_link *type)
+iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
 {
 {
-    operand *retval = (operand *)0;
-        
-    assert(isOperandLiteral(left));
-    if (right) 
-       assert(isOperandLiteral(right));
+    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)++;
+    }
     
     
-    switch (op) {
-    case '+' :
-       retval =  operandFromValue (valCastLiteral(type,
-                                                  operandLitValue(left) + 
-                                                  operandLitValue(right)));
-       break ;
-    case '-' :
-       retval = operandFromValue(valCastLiteral(type,
-                                                operandLitValue(left) -
-                                                operandLitValue(right)));
-       break;
+    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             */
+/*-----------------------------------------------------------------*/
+operand *
+operandOperation (operand * left, operand * right,
+                 int op, sym_link * type)
+{
+  sym_link *let , *ret=NULL;
+  operand *retval = (operand *) 0;
+  
+  assert (isOperandLiteral (left));
+  let = getSpec(operandType(left));
+  if (right) {
+    assert (isOperandLiteral (right));
+    ret = getSpec(operandType(left));
+  }
+
+  switch (op)
+    {
+    case '+':
+      retval = operandFromValue (valCastLiteral (type,
+                                                operandLitValue (left) +
+                                                operandLitValue (right)));
+      break;
+    case '-':
+      retval = operandFromValue (valCastLiteral (type,
+                                                operandLitValue (left) -
+                                                operandLitValue (right)));
+      break;
     case '*':
     case '*':
-       retval = operandFromValue(valCastLiteral(type,
-                                                operandLitValue(left) *
-                                                operandLitValue(right)));
-       break;
+      retval = operandFromValue (valCastLiteral (type,
+                                                operandLitValue (left) *
+                                                operandLitValue (right)));
+      break;
     case '/':
     case '/':
-       if ((unsigned long) operandLitValue(right) == 0){           
-           werror(E_DIVIDE_BY_ZERO);
-           retval = right;
-           
+      if ((unsigned long) operandLitValue (right) == 0)
+       {
+         werror (E_DIVIDE_BY_ZERO);
+         retval = right;
+
        }
        }
-       else
-           retval = operandFromValue (valCastLiteral(type,
-                                                     operandLitValue(left) /
-                                                     operandLitValue(right)));
-       break;
-    case '%':      
-       if ((unsigned long) operandLitValue(right) == 0){           
-           werror(E_DIVIDE_BY_ZERO);
-           retval = right;         
+      else
+       retval = operandFromValue (valCastLiteral (type,
+                                                  operandLitValue (left) /
+                                                  operandLitValue (right)));
+      break;
+    case '%':
+      if ((unsigned long) operandLitValue (right) == 0) {
+         werror (E_DIVIDE_BY_ZERO);
+         retval = 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 ((SPEC_USIGN(let) ? 
+                                 (unsigned long) operandLitValue (left) :
+                                 (long) operandLitValue (left)) <<
+                                (SPEC_USIGN(ret) ? 
+                                 (unsigned long) operandLitValue (right) :
+                                 (long) operandLitValue (right)));
+      break;
+    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;
        }
        }
-       else
-           retval = operandFromLit ((unsigned long) operandLitValue(left) %
-                                    (unsigned long) operandLitValue(right));
-       break;
-    case LEFT_OP :
-       retval = operandFromLit ((unsigned long) operandLitValue(left) <<
-                                (unsigned long) operandLitValue(right));
-       break;
-    case RIGHT_OP :
-       retval = operandFromLit ((unsigned long) operandLitValue(left) >>
-                                (unsigned long) operandLitValue(right));
-       break;
-    case EQ_OP :
-       retval = operandFromLit (operandLitValue(left) ==
-                                operandLitValue(right));
-       break;
-    case '<' :
-       retval = operandFromLit (operandLitValue(left) <
-                                operandLitValue(right));
-       break;
-    case LE_OP :
-       retval = operandFromLit (operandLitValue(left) <=
-                                operandLitValue(right));
-       break;
-    case NE_OP :
-       retval = operandFromLit (operandLitValue(left) !=
-                                operandLitValue(right));
-       break;
-    case '>' :
-       retval = operandFromLit (operandLitValue(left) >
-                                operandLitValue(right));
-       break;
-    case GE_OP :
-       retval = operandFromLit (operandLitValue(left) >=
-                                operandLitValue(right));
-       break;
-    case BITWISEAND :
-       retval = operandFromLit ((unsigned long) operandLitValue(left) &
-                                (unsigned long) operandLitValue(right));
-       break;
-    case '|' :
-       retval = operandFromLit ((unsigned long) operandLitValue(left) |
-                                (unsigned long) operandLitValue(right));       
-       break;
-    case '^' :
-       retval = operandFromLit ((unsigned long) operandLitValue(left) ^
-                                (unsigned long) operandLitValue(right));
-       break;
+      retval = operandFromLit (res);
+      break;
+    }
+    case EQ_OP:
+      retval = operandFromLit (operandLitValue (left) ==
+                              operandLitValue (right));
+      break;
+    case '<':
+      retval = operandFromLit (operandLitValue (left) <
+                              operandLitValue (right));
+      break;
+    case LE_OP:
+      retval = operandFromLit (operandLitValue (left) <=
+                              operandLitValue (right));
+      break;
+    case NE_OP:
+      retval = operandFromLit (operandLitValue (left) !=
+                              operandLitValue (right));
+      break;
+    case '>':
+      retval = operandFromLit (operandLitValue (left) >
+                              operandLitValue (right));
+      break;
+    case GE_OP:
+      retval = operandFromLit (operandLitValue (left) >=
+                              operandLitValue (right));
+      break;
+    case BITWISEAND:
+      retval = operandFromLit ((long)operandLitValue(left) & 
+                              (long)operandLitValue(right));
+      break;
+    case '|':
+      retval = operandFromLit ((long)operandLitValue (left) |
+                              (long)operandLitValue (right));
+      break;
+    case '^':
+      retval = operandFromLit ((long)operandLitValue (left) ^
+                              (long)operandLitValue (right));
+      break;
     case AND_OP:
     case AND_OP:
-       retval = operandFromLit (operandLitValue(left) &&
-                                operandLitValue(right));
-       break;
+      retval = operandFromLit (operandLitValue (left) &&
+                              operandLitValue (right));
+      break;
     case OR_OP:
     case OR_OP:
-       retval = operandFromLit (operandLitValue(left) ||
-                                operandLitValue(right));
-       break;
+      retval = operandFromLit (operandLitValue (left) ||
+                              operandLitValue (right));
+      break;
     case RRC:
     case RRC:
-       {
-           long i = operandLitValue(left);
-           
-           retval = operandFromLit ((i >> (getSize(operandType(left))*8 - 1)) |
-                                    (i << 1));
-       }
-       break;
+      {
+       long i = (long) operandLitValue (left);
+
+       retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
+                                (i << 1));
+      }
+      break;
     case RLC:
     case RLC:
-       {
-           long i = operandLitValue(left);
-           
-           retval = operandFromLit ((i << (getSize(operandType(left))*8 - 1)) |
-                                    (i >> 1));
-       }
-       break;
-       
+      {
+       long i = (long) operandLitValue (left);
+
+       retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
+                                (i >> 1));
+      }
+      break;
+
     case UNARYMINUS:
     case UNARYMINUS:
-       retval = operandFromLit(-1 * operandLitValue(left));
-       break;
-       
+      retval = operandFromLit (-1 * operandLitValue (left));
+      break;
+
     case '~':
     case '~':
-       retval = operandFromLit(~ ((long) operandLitValue(left)));
-       break;
+      retval = operandFromLit (~((long) operandLitValue (left)));
+      break;
 
     case '!':
 
     case '!':
-       retval = operandFromLit(! operandLitValue(left));
-       break;
+      retval = operandFromLit (!operandLitValue (left));
+      break;
 
 
-    default :
-       werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-              " operandOperation invalid operator ");
-       assert (0);
+    default:
+      werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+             " operandOperation invalid operator ");
+      assert (0);
     }
     }
-    
-    return retval;
+
+  return retval;
 }
 
 
 /*-----------------------------------------------------------------*/
 /* isOperandEqual - compares two operand & return 1 if they r =    */
 /*-----------------------------------------------------------------*/
 }
 
 
 /*-----------------------------------------------------------------*/
 /* isOperandEqual - compares two operand & return 1 if they r =    */
 /*-----------------------------------------------------------------*/
-int isOperandEqual (operand *left, operand *right)
+int 
+isOperandEqual (operand * left, operand * right)
 {
 {
-    /* if the pointers are equal then they are equal */
-    if ( left == right )
-       return 1;
-    
-    /* if either of them null then false */
-    if ( !left || !right)
-       return 0;
+  /* if the pointers are equal then they are equal */
+  if (left == right)
+    return 1;
 
 
-    if (left->type != right->type)
-       return 0;
+  /* if either of them null then false */
+  if (!left || !right)
+    return 0;
+
+  if (left->type != right->type)
+    return 0;
 
 
-    if (IS_SYMOP(left) && IS_SYMOP(right))
-       return left->key == right->key ;
+  if (IS_SYMOP (left) && IS_SYMOP (right))
+    return left->key == right->key;
 
 
-    /* if types are the same */
-    switch (left->type) {
-    case SYMBOL :
-       return isSymbolEqual(left->operand.symOperand,
-                            right->operand.symOperand);
-    case VALUE :
-       return (floatFromVal(left->operand.valOperand) ==
-               floatFromVal(right->operand.valOperand));
-    case TYPE :
-       if (checkType(left->operand.typeOperand,
-                     right->operand.typeOperand) == 1)
-           return 1;      
+  /* if types are the same */
+  switch (left->type)
+    {
+    case SYMBOL:
+      return isSymbolEqual (left->operand.symOperand,
+                           right->operand.symOperand);
+    case VALUE:
+      return (floatFromVal (left->operand.valOperand) ==
+             floatFromVal (right->operand.valOperand));
+    case TYPE:
+      if (compareType (left->operand.typeOperand,
+                    right->operand.typeOperand) == 1)
+       return 1;
     }
 
     }
 
-    return 0;
+  return 0;
 }
 
 }
 
-/*-----------------------------------------------------------------*/
-/* isiCodeEqual - comapres two iCodes are returns true if yes      */
-/*-----------------------------------------------------------------*/
-int isiCodeEqual (iCode *left, iCode *right)
+/*-------------------------------------------------------------------*/
+/* isiCodeEqual - compares two iCodes are equal, returns true if yes */
+/*-------------------------------------------------------------------*/
+int 
+isiCodeEqual (iCode * left, iCode * right)
 {
 {
-    /* if the same pointer */
-    if (left == right)
-       return 1;
-    
-    /* if either of them null */
-    if (!left || !right)
-       return 0;
+  /* if the same pointer */
+  if (left == right)
+    return 1;
+
+  /* if either of them null */
+  if (!left || !right)
+    return 0;
+
+  /* if operand are the same */
+  if (left->op == right->op)
+    {
+
+      /* compare all the elements depending on type */
+      if (left->op != IFX)
+       {
+         if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
+           return 0;
+         if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
+           return 0;
 
 
-    /* if operand are the same */
-    if ( left->op == right->op ) {
-       
-       /* compare all the elements depending on type */
-       if (left->op != IFX ) {
-           if (!isOperandEqual(IC_LEFT(left),IC_LEFT(right)))
-               return 0;
-           if (!isOperandEqual(IC_RIGHT(left),IC_RIGHT(right)))
-               return 0;
-
-       } else {
-           if (!isOperandEqual(IC_COND(left),IC_COND(right)))
-               return 0;
-           if (!isSymbolEqual (IC_TRUE(left),IC_TRUE(right)))
-               return 0;
-           if (!isSymbolEqual(IC_FALSE(left),IC_FALSE(right)))
-               return 0;
        }
        }
-       return 1;
+      else
+       {
+         if (!isOperandEqual (IC_COND (left), IC_COND (right)))
+           return 0;
+         if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
+           return 0;
+         if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
+           return 0;
+       }
+      
+      return 1;
     }
     }
-    return 0;
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* newiTempFromOp - create a temp Operand with same attributes     */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* newiTempFromOp - create a temp Operand with same attributes     */
 /*-----------------------------------------------------------------*/
-operand *newiTempFromOp (operand *op)
+operand *
+newiTempFromOp (operand * op)
 {
 {
-    operand *nop;
+  operand *nop;
 
 
-    if (!op)
-       return NULL;
-    
-    if (!IS_ITEMP(op))
-       return op;
+  if (!op)
+    return NULL;
 
 
-    nop = newiTempOperand(operandType(op),TRUE);
-    nop->isaddr = op->isaddr ;
-    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;
+  if (!IS_ITEMP (op))
+    return op;
+
+  nop = newiTempOperand (operandType (op), TRUE);
+  nop->isaddr = op->isaddr;
+  nop->isvolatile = op->isvolatile;
+  nop->isGlobal = op->isGlobal;
+  nop->isLiteral = op->isLiteral;
+  nop->usesDefs = op->usesDefs;
+  nop->isParm = op->isParm;
+  return nop;
 }
 
 /*-----------------------------------------------------------------*/
 /* operand from operand - creates an operand holder for the type   */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* operand from operand - creates an operand holder for the type   */
 /*-----------------------------------------------------------------*/
-operand *operandFromOperand (operand *op)
+operand *
+operandFromOperand (operand * op)
 {
 {
-    operand *nop ;
-    
-    if (!op)
-       return NULL;
-    nop = newOperand();
-    nop->type = op->type;
-    nop->isaddr = op->isaddr ;
-    nop->key = op->key ;
-    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) {
-    case SYMBOL :
-       nop->operand.symOperand = op->operand.symOperand ;      
-       break;
-    case VALUE :
-       nop->operand.valOperand = op->operand.valOperand;
-       break;
-    case TYPE :
-       nop->operand.typeOperand = op->operand.typeOperand ;
-       break ;
-    }   
-
-    return nop;
+  operand *nop;
+
+  if (!op)
+    return NULL;
+  nop = newOperand ();
+  nop->type = op->type;
+  nop->isaddr = op->isaddr;
+  nop->key = op->key;
+  nop->isvolatile = op->isvolatile;
+  nop->isGlobal = op->isGlobal;
+  nop->isLiteral = op->isLiteral;
+  nop->usesDefs = op->usesDefs;
+  nop->isParm = op->isParm;
+
+  switch (nop->type)
+    {
+    case SYMBOL:
+      nop->operand.symOperand = op->operand.symOperand;
+      break;
+    case VALUE:
+      nop->operand.valOperand = op->operand.valOperand;
+      break;
+    case TYPE:
+      nop->operand.typeOperand = op->operand.typeOperand;
+      break;
+    }
+
+  return nop;
 }
 
 /*-----------------------------------------------------------------*/
 /* opFromOpWithDU - makes a copy of the operand and DU chains      */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* opFromOpWithDU - makes a copy of the operand and DU chains      */
 /*-----------------------------------------------------------------*/
-operand *opFromOpWithDU (operand *op, bitVect *defs, bitVect *uses)
+operand *
+opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
 {
 {
-    operand *nop = operandFromOperand(op);
+  operand *nop = operandFromOperand (op);
 
 
-    if (nop->type == SYMBOL) {
-       OP_SYMBOL(nop)->defs = bitVectCopy(defs);
-       OP_SYMBOL(nop)->uses = bitVectCopy(uses);
+  if (nop->type == SYMBOL)
+    {
+      OP_SYMBOL (nop)->defs = bitVectCopy (defs);
+      OP_SYMBOL (nop)->uses = bitVectCopy (uses);
     }
 
     }
 
-    return nop;
+  return nop;
 }
 
 /*-----------------------------------------------------------------*/
 /* operandFromSymbol - creates an operand from a symbol            */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* operandFromSymbol - creates an operand from a symbol            */
 /*-----------------------------------------------------------------*/
-operand *operandFromSymbol (symbol *sym)
-{
-    operand *op ;
-    iCode *ic ;
-    int ok =1 ;
-    /* if the symbol's type is a literal */
-    /* then it is an enumerator type     */
-    if (IS_LITERAL(sym->etype) && SPEC_ENUM(sym->etype)) 
-       return operandFromValue (valFromType(sym->etype));
-
-    if (!sym->key)
-       sym->key = ++operandKey ;
-
-    /* if this an implicit variable, means struct/union */
-    /* member so just return it                         */
-    if (sym->implicit || IS_FUNC(sym->type)) {
-       op = newOperand();
-       op->type = SYMBOL ;
-       op->operand.symOperand = sym;
-       op->key = sym->key ;
-       op->isvolatile = isOperandVolatile(op,TRUE);
-       op->isGlobal   = isOperandGlobal(op);
-       op->parmBytes  = sym->argStack;
-       return op;
+operand *
+operandFromSymbol (symbol * sym)
+{
+  operand *op;
+  iCode *ic;
+  int ok = 1;
+  /* if the symbol's type is a literal */
+  /* then it is an enumerator type     */
+  if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
+    return operandFromValue (valFromType (sym->etype));
+
+  if (!sym->key)
+    sym->key = ++operandKey;
+
+  /* if this an implicit variable, means struct/union */
+  /* member so just return it                         */
+  if (sym->implicit || IS_FUNC (sym->type))
+    {
+      op = newOperand ();
+      op->type = SYMBOL;
+      op->operand.symOperand = sym;
+      op->key = sym->key;
+      op->isvolatile = isOperandVolatile (op, TRUE);
+      op->isGlobal = isOperandGlobal (op);
+      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)) &&
+      (!(options.model == MODEL_FLAT24)) ) &&
+      options.stackAuto == 0)
+    ok = 0;
+
+  if (!IS_AGGREGATE (sym->type) &&     /* not an aggregate */
+      !IS_FUNC (sym->type) &&  /* not a function   */
+      !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 reg equivalence */
+      !IS_VOLATILE (sym->etype) &&     /* not declared as volatile */
+      !IS_STATIC (sym->etype) &&       /* and not declared static  */
+      !sym->islbl &&           /* not a label */
+      ok &&                    /* farspace check */
+      !IS_BITVAR (sym->etype)  /* not a bit variable */
+    )
+    {
+
+      /* we will use it after all optimizations
+         and before liveRange calculation */
+      sym->reqv = newiTempOperand (sym->type, 0);
+      sym->reqv->key = sym->key;
+      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;
     }
     }
-    
-    /* 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)) &&
-       options.stackAuto == 0)
-       ok =0;
-
-    if (!IS_AGGREGATE(sym->type) &&     /* not an aggregate */
-       !IS_FUNC(sym->type)      &&     /* not a function   */
-       !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 */
-       !IS_VOLATILE(sym->etype) &&     /* not declared as volatile */
-       !IS_STATIC(sym->etype)   &&     /* and not declared static  */
-       !sym->islbl              &&     /* not a label */
-       ok                       &&     /* farspace check */
-       !IS_BITVAR(sym->etype)          /* not a bit variable */
-       ) {
-       
-       /* we will use it after all optimizations
-          and before liveRange calculation */
-       sym->reqv = newiTempOperand(sym->type,0);       
-       sym->reqv->key = sym->key ;
-       OP_SYMBOL(sym->reqv)->key = sym->key;
-       OP_SYMBOL(sym->reqv)->isreqv = 1;
-       OP_SYMBOL(sym->reqv)->islocal = 1;
-       SPIL_LOC(sym->reqv) = sym;
-    }
-   
-    if (!IS_AGGREGATE(sym->type)) {
-       op = newOperand();
-       op->type = SYMBOL;
-       op->operand.symOperand = sym;
-       op->isaddr = 1;
-       op->key = sym->key;
-       op->isvolatile = isOperandVolatile(op,TRUE);
-       op->isGlobal   = isOperandGlobal(op);
-       op->isPtr = IS_PTR(operandType(op));
-       op->isParm = sym->_isparm ;
-       return op;
+
+  if (!IS_AGGREGATE (sym->type))
+    {
+      op = newOperand ();
+      op->type = SYMBOL;
+      op->operand.symOperand = sym;
+      op->isaddr = 1;
+      op->key = sym->key;
+      op->isvolatile = isOperandVolatile (op, TRUE);
+      op->isGlobal = isOperandGlobal (op);
+      op->isPtr = IS_PTR (operandType (op));
+      op->isParm = sym->_isparm;
+      return op;
+    }
+
+  /* create :-                     */
+  /*    itemp = &[_symbol]         */
+
+  ic = newiCode (ADDRESS_OF, newOperand (), NULL);
+  IC_LEFT (ic)->type = SYMBOL;
+  IC_LEFT (ic)->operand.symOperand = sym;
+  IC_LEFT (ic)->key = sym->key;
+  (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
+  (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
+  IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
+
+  /* create result */
+  IC_RESULT (ic) = newiTempOperand (sym->type, 0);
+  if (IS_ARRAY (sym->type))
+    {
+      IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
+      IC_RESULT (ic)->isaddr = 0;
     }
     }
-    
-    /* create :-                     */
-    /*    itemp = &[_symbol]         */
-    
-    ic = newiCode(ADDRESS_OF,newOperand(),NULL);
-    IC_LEFT(ic)->type = SYMBOL ;
-    IC_LEFT(ic)->operand.symOperand = sym ;
-    IC_LEFT(ic)->key = sym->key;    
-    (IC_LEFT(ic))->isvolatile = isOperandVolatile(IC_LEFT(ic),TRUE);
-    (IC_LEFT(ic))->isGlobal   = isOperandGlobal(IC_LEFT(ic));
-    IC_LEFT(ic)->isPtr = IS_PTR(operandType(IC_LEFT(ic)));
-
-    /* create result */
-    IC_RESULT(ic) = newiTempOperand(sym->type,0);
-    if (IS_ARRAY(sym->type)) {
-       IC_RESULT(ic) = geniCodeArray2Ptr (IC_RESULT(ic));
-       IC_RESULT(ic)->isaddr = 0;
-    } else
-       IC_RESULT(ic)->isaddr = (!IS_AGGREGATE(sym->type));
-
-    IC_RESULT(ic)->operand.symOperand->args = sym->args;
-
-    ADDTOCHAIN(ic);
-    
-    return IC_RESULT(ic) ;
+  else
+    IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
+
+  ADDTOCHAIN (ic);
+
+  return IC_RESULT (ic);
 }
 
 /*-----------------------------------------------------------------*/
 /* operandFromValue - creates an operand from value                */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* operandFromValue - creates an operand from value                */
 /*-----------------------------------------------------------------*/
-operand *operandFromValue (value *val)
+operand *
+operandFromValue (value * val)
 {
 {
-    operand *op ;
-    
-    /* if this is a symbol then do the symbol thing */
-    if (val->sym)
-       return operandFromSymbol (val->sym);
-    
-    /* this is not a symbol */
-    op = newOperand();
-    op->type = VALUE ;
-    op->operand.valOperand = val ;
-    op->isLiteral = isOperandLiteral(op);
-    return op;
+  operand *op;
+
+  /* if this is a symbol then do the symbol thing */
+  if (val->sym)
+    return operandFromSymbol (val->sym);
+
+  /* this is not a symbol */
+  op = newOperand ();
+  op->type = VALUE;
+  op->operand.valOperand = val;
+  op->isLiteral = isOperandLiteral (op);
+  return op;
 }
 
 /*-----------------------------------------------------------------*/
 /* operandFromLink - operand from typeChain                        */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* operandFromLink - operand from typeChain                        */
 /*-----------------------------------------------------------------*/
-operand *operandFromLink (sym_link *type)
+operand *
+operandFromLink (sym_link * type)
 {
 {
-    operand *op ;
-    
-    /* operand from sym_link */
-    if ( ! type )
-       return NULL ;
-    
-    op = newOperand();
-    op->type = TYPE ;
-    op->operand.typeOperand = copyLinkChain(type);
-    return op;
+  operand *op;
+
+  /* operand from sym_link */
+  if (!type)
+    return NULL;
+
+  op = newOperand ();
+  op->type = TYPE;
+  op->operand.typeOperand = copyLinkChain (type);
+  return op;
 }
 
 /*-----------------------------------------------------------------*/
 /* operandFromLit - makes an operand from a literal value          */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* operandFromLit - makes an operand from a literal value          */
 /*-----------------------------------------------------------------*/
-operand *operandFromLit ( float i)
+operand *
+operandFromLit (double i)
 {
 {
-    return operandFromValue (valueFromLit (i));
+  return operandFromValue (valueFromLit (i));
 }
 
 /*-----------------------------------------------------------------*/
 /* operandFromAst - creates an operand from an ast                 */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* operandFromAst - creates an operand from an ast                 */
 /*-----------------------------------------------------------------*/
-operand *operandFromAst ( ast *tree )
+operand *
+operandFromAst (ast * tree,int lvl)
 {
 {
-    
-    if (! tree )
-       return NULL ;
-    
-    /* depending on type do */
-    switch (tree->type ) {     
-    case EX_OP : 
-       return ast2iCode (tree) ;    
-       break ;
-       
-    case EX_VALUE :
-       return operandFromValue(tree->opval.val) ;
-       break ;
-       
-    case EX_LINK :
-       return operandFromLink (tree->opval.lnk) ; 
+
+  if (!tree)
+    return NULL;
+
+  /* depending on type do */
+  switch (tree->type)
+    {
+    case EX_OP:
+      return ast2iCode (tree,lvl+1);
+      break;
+
+    case EX_VALUE:
+      return operandFromValue (tree->opval.val);
+      break;
+
+    case EX_LINK:
+      return operandFromLink (tree->opval.lnk);
     }
     }
-    
-    assert(0);
-    /*  Just to keep the comiler happy */
-    return (operand *)0;
+
+  assert (0);
+  /*  Just to keep the comiler happy */
+  return (operand *) 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* setOperandType - sets the operand's type to the given type      */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* setOperandType - sets the operand's type to the given type      */
 /*-----------------------------------------------------------------*/
-void setOperandType (operand *op, sym_link *type)
+void 
+setOperandType (operand * op, sym_link * type)
 {
 {
-    /* depending on the type of operand */
-    switch (op->type) {
-       
-    case VALUE :
-       op->operand.valOperand->etype = 
-           getSpec( op->operand.valOperand->type = 
-                    copyLinkChain (type )) ;
-       return ;
-       
-    case SYMBOL :
-       if (op->operand.symOperand->isitmp )
-           op->operand.symOperand->etype = 
-               getSpec( op->operand.symOperand->type = 
-                        copyLinkChain (type )) ;
-       else
-           werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
-                   "attempt to modify type of source");
-       return;
-       
+  /* depending on the type of operand */
+  switch (op->type)
+    {
+
+    case VALUE:
+      op->operand.valOperand->etype =
+       getSpec (op->operand.valOperand->type =
+                copyLinkChain (type));
+      return;
+
+    case SYMBOL:
+      if (op->operand.symOperand->isitmp)
+       op->operand.symOperand->etype =
+         getSpec (op->operand.symOperand->type =
+                  copyLinkChain (type));
+      else
+       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+               "attempt to modify type of source");
+      return;
+
     case TYPE:
     case TYPE:
-       op->operand.typeOperand = copyLinkChain (type);
-       return ;
+      op->operand.typeOperand = copyLinkChain (type);
+      return;
     }
     }
-    
+
+}
+/*-----------------------------------------------------------------*/
+/* 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"                               */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* perform "usual unary conversions"                               */
 /*-----------------------------------------------------------------*/
-operand *usualUnaryConversions(operand *op)
+operand *
+usualUnaryConversions (operand * op)
 {
 {
-    if (IS_INTEGRAL(operandType(op)))
+  if (IS_INTEGRAL (operandType (op)))
     {
     {
-        if (getSize(operandType(op)) < INTSIZE) 
-        {
-            /* Widen to int. */
-           return geniCodeCast(INTTYPE,op,TRUE);           
-        }    
+      if (getSize (operandType (op)) < (unsigned int) INTSIZE)
+       {
+         /* Widen to int. */
+         return geniCodeCast (INTTYPE, op, TRUE);
+       }
     }
     }
-    return op;
+  return op;
 }
 
 /*-----------------------------------------------------------------*/
 /* perform "usual binary conversions"                              */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* perform "usual binary conversions"                              */
 /*-----------------------------------------------------------------*/
-sym_link * usualBinaryConversions(operand **op1, operand **op2)
+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);
+  sym_link *ctype;
+  sym_link *rtype = operandType (*op2);
+  sym_link *ltype = operandType (*op1);
+  
+  ctype = computeType (ltype, rtype);
 
 
-    /* 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));
-    }         
-    
-    /* 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                             */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* geniCodeValueAtAddress - generate intermeditate code for value  */
 /*                          at address                             */
 /*-----------------------------------------------------------------*/
-operand *geniCodeRValue (operand *op, bool force)
+operand *
+geniCodeRValue (operand * op, bool force)
 {
 {
-    iCode *ic ;
-    sym_link *type = operandType(op);
-    sym_link *etype= getSpec(type);
-    
-    /* if this is an array & already */
-    /* an address then return this   */
-    if (IS_AGGREGATE(type) || 
-       (IS_PTR(type) && !force && !op->isaddr))
-       return operandFromOperand(op);
-        
-    /* if this is not an address then must be */
-    /* rvalue already so return this one      */
-    if (!op->isaddr)
-       return op ;
-    
-    /* if this is not a temp symbol then */
-    if (!IS_ITEMP(op) && 
-       !force        && 
-       !IN_FARSPACE(SPEC_OCLS(etype))) {
-       op = operandFromOperand(op);
-       op->isaddr = 0;
-       return op;
+  iCode *ic;
+  sym_link *type = operandType (op);
+  sym_link *etype = getSpec (type);
+
+  /* if this is an array & already */
+  /* an address then return this   */
+  if (IS_AGGREGATE (type) ||
+      (IS_PTR (type) && !force && !op->isaddr))
+    return operandFromOperand (op);
+
+  /* if this is not an address then must be */
+  /* rvalue already so return this one      */
+  if (!op->isaddr)
+    return op;
+
+  /* if this is not a temp symbol then */
+  if (!IS_ITEMP (op) &&
+      !force &&
+      !IN_FARSPACE (SPEC_OCLS (etype)))
+    {
+      op = operandFromOperand (op);
+      op->isaddr = 0;
+      return op;
     }
     }
-    
-    if (IS_SPEC(type) && 
-       IS_TRUE_SYMOP(op) &&
-       !IN_FARSPACE(SPEC_OCLS(etype))) {
-       op = operandFromOperand(op);
-       op->isaddr = 0;
-       return op;
+
+  if (IS_SPEC (type) &&
+      IS_TRUE_SYMOP (op) &&
+      (!IN_FARSPACE (SPEC_OCLS (etype)) ||
+      (options.model == MODEL_FLAT24) ))
+    {
+      op = operandFromOperand (op);
+      op->isaddr = 0;
+      return op;
     }
 
     }
 
-    ic = newiCode(GET_VALUE_AT_ADDRESS,op,NULL);
-    if (IS_PTR(type) && op->isaddr && force) 
-       type = type->next;
-    
-    type = copyLinkChain(type);
+  ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
+  if (IS_PTR (type) && op->isaddr && force)
+    type = type->next;
+
+  type = copyLinkChain (type);
+
+  IC_RESULT (ic) = newiTempOperand (type, 1);
+  IC_RESULT (ic)->isaddr = 0;
 
 
-    IC_RESULT(ic) = newiTempOperand (type,1);
-    IC_RESULT(ic)->isaddr = 0;
 /*     ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
 
 /*     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) ;
+  ADDTOCHAIN (ic);
+
+  return IC_RESULT (ic);
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeCast - changes the value from one type to another       */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeCast - changes the value from one type to another       */
 /*-----------------------------------------------------------------*/
-operand *geniCodeCast (sym_link *type, operand *op, bool implicit) 
+operand *
+geniCodeCast (sym_link * type, operand * op, bool implicit)
 {
 {
-    iCode *ic ;
-    sym_link *optype ;
-    sym_link *opetype = getSpec(optype = operandType(op));
-    sym_link *restype ;
-    
-    /* one of them has size zero then error */
-    if (IS_VOID(optype)) {
-       werror(E_CAST_ZERO);
-       return op;
+  iCode *ic;
+  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))
+    {
+      werror (E_CAST_ZERO);
+      return op;
     }
 
     }
 
-    /* if the operand is already the desired type then do nothing */
-    if ( checkType (type,optype) == 1) 
-       return op;
-    
-    /* if this is a literal then just change the type & return */
-    if (IS_LITERAL(opetype) && op->type == VALUE && !IS_PTR(type) && !IS_PTR(optype))
-       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 they are the same size create an assignment */
-    if (getSize(type) == getSize(optype) && 
-       !IS_BITFIELD(type)               &&
-       !IS_FLOAT(type)                  &&
-       !IS_FLOAT(optype)                &&
-       ((IS_SPEC(type) && IS_SPEC(optype)) ||
-        (!IS_SPEC(type) && !IS_SPEC(optype)))) {
-
-       ic = newiCode('=',NULL,op);     
-       IC_RESULT(ic) = newiTempOperand(type,0);
-        SPIL_LOC(IC_RESULT(ic))  =
-            (IS_TRUE_SYMOP(op) ? OP_SYMBOL(op) : NULL);
-       IC_RESULT(ic)->isaddr = 0;
-    } else { 
-       ic = newiCode(CAST,operandFromLink(type),
-                     geniCodeRValue(op,FALSE));
-       
-       IC_RESULT(ic)= newiTempOperand(type,0);
+  /* if the operand is already the desired type then do nothing */
+  if (compareType (type, optype) == 1)
+    return op;
+
+  /* if this is a literal then just change the type & return */
+  if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
+    return operandFromValue (valCastLiteral (type,
+                                            operandLitValue (op)));
+
+  /* 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) &&
+      !IS_BITFIELD (type) &&
+      !IS_FLOAT (type) &&
+      !IS_FLOAT (optype) &&
+      ((IS_SPEC (type) && IS_SPEC (optype)) ||
+       (!IS_SPEC (type) && !IS_SPEC (optype))))
+    {
+
+      ic = newiCode ('=', NULL, op);
+      IC_RESULT (ic) = newiTempOperand (type, 0);
+      SPIL_LOC (IC_RESULT (ic)) =
+       (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
+      IC_RESULT (ic)->isaddr = 0;
     }
     }
-    
-    /* preserve the storage class & output class */
-    /* of the original variable                  */
-    restype = getSpec(operandType(IC_RESULT(ic)));
-    SPEC_SCLS(restype) = SPEC_SCLS(opetype);
-    SPEC_OCLS(restype) = SPEC_OCLS(opetype);
-    
-    ADDTOCHAIN(ic);
-    return IC_RESULT(ic) ;
+  else
+    {
+      ic = newiCode (CAST, operandFromLink (type),
+                    geniCodeRValue (op, FALSE));
+
+      IC_RESULT (ic) = newiTempOperand (type, 0);
+    }
+
+  /* preserve the storage class & output class */
+  /* of the original variable                  */
+  restype = getSpec (operandType (IC_RESULT (ic)));
+  if (!IS_LITERAL(opetype))
+      SPEC_SCLS (restype) = SPEC_SCLS (opetype);
+  SPEC_OCLS (restype) = SPEC_OCLS (opetype);
+
+  ADDTOCHAIN (ic);
+  return IC_RESULT (ic);
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeLabel - will create a Label                             */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeLabel - will create a Label                             */
 /*-----------------------------------------------------------------*/
-void geniCodeLabel (symbol *label)
+void 
+geniCodeLabel (symbol * label)
 {
 {
-    iCode *ic;
-    
-    ic = newiCodeLabelGoto(LABEL,label);
-    ADDTOCHAIN(ic);
+  iCode *ic;
+
+  ic = newiCodeLabelGoto (LABEL, label);
+  ADDTOCHAIN (ic);
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeGoto  - will create a Goto                              */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeGoto  - will create a Goto                              */
 /*-----------------------------------------------------------------*/
-void geniCodeGoto (symbol *label)
+void 
+geniCodeGoto (symbol * label)
 {
 {
-    iCode *ic;
-    
-    ic = newiCodeLabelGoto(GOTO,label);
-    ADDTOCHAIN(ic);
+  iCode *ic;
+
+  ic = newiCodeLabelGoto (GOTO, label);
+  ADDTOCHAIN (ic);
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeMultiply - gen intermediate code for multiplication     */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeMultiply - gen intermediate code for multiplication     */
 /*-----------------------------------------------------------------*/
-operand *geniCodeMultiply (operand *left, operand *right)
-{ 
-    iCode *ic ;
-    int p2 = 0;
-    sym_link *resType ;
-    LRTYPE ;
-    
-    /* if they are both literal then we know the result */
-    if (IS_LITERAL(letype) && IS_LITERAL(retype)) 
-       return operandFromValue (valMult(left->operand.valOperand,
-                                        right->operand.valOperand));
-        
-    resType = usualBinaryConversions(&left, &right);
-    
-    /* if the right is a literal & power of 2 */
-    /* then make it a left shift              */
-    if (IS_LITERAL(retype) && !IS_FLOAT(letype) &&
-       (p2 = powof2 ((unsigned long)floatFromVal(right->operand.valOperand)))) 
-       ic = newiCode(LEFT_OP, left,operandFromLit(p2)); /* left shift */
-    else {
-       ic = newiCode('*',left,right);  /* normal multiplication */
-       /* if the size left or right > 1 then support routine */
-       if (getSize(ltype) > 1 || getSize(rtype) > 1)
-           ic->supportRtn = 1;
-
-    }
-    IC_RESULT(ic) = newiTempOperand(resType,1);
-    
-    ADDTOCHAIN(ic);
-    return IC_RESULT(ic) ;
+operand *
+geniCodeMultiply (operand * left, operand * right,int resultIsInt)
+{
+  iCode *ic;
+  int p2 = 0;
+  sym_link *resType;
+  LRTYPE;
+
+  /* if they are both literal then we know the result */
+  if (IS_LITERAL (letype) && IS_LITERAL (retype))
+    return operandFromValue (valMult (left->operand.valOperand,
+                                     right->operand.valOperand));
+
+  if (IS_LITERAL(retype)) {
+    p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
+  }
+
+  resType = usualBinaryConversions (&left, &right);
+#if 1
+  rtype = operandType (right);
+  retype = getSpec (rtype);
+  ltype = operandType (left);
+  letype = getSpec (ltype);
+#endif
+  if (resultIsInt)
+    {
+      SPEC_NOUN(getSpec(resType))=V_INT;
+    }
+
+  /* if the right is a literal & power of 2 */
+  /* then make it a left shift              */
+  /* 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 */
+    }
+  else
+    {
+      ic = newiCode ('*', left, right);                /* normal multiplication */
+      /* if the size left or right > 1 then support routine */
+      if (getSize (ltype) > 1 || getSize (rtype) > 1)
+       ic->supportRtn = 1;
+
+    }
+  IC_RESULT (ic) = newiTempOperand (resType, 1);
+
+  ADDTOCHAIN (ic);
+  return IC_RESULT (ic);
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeDivision - gen intermediate code for division           */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeDivision - gen intermediate code for division           */
 /*-----------------------------------------------------------------*/
-operand *geniCodeDivision (operand *left, operand *right)
-{ 
-    iCode *ic ;
-    int p2 = 0;
-    sym_link *resType;
-    sym_link *rtype = operandType(right);
-    sym_link *retype= getSpec(rtype);
-    sym_link *ltype = operandType(left);
-    sym_link *letype= getSpec(ltype);
-    
-    resType = usualBinaryConversions(&left, &right);
-    
-    /* if the right is a literal & power of 2 */
-    /* then make it a right shift             */
-    if (IS_LITERAL(retype) && 
-       !IS_FLOAT(letype)  &&
-       (p2 = powof2 ((unsigned long) 
-                     floatFromVal(right->operand.valOperand)))) 
-       ic = newiCode(RIGHT_OP, left,operandFromLit(p2)); /* right shift */
-    else {
-       ic = newiCode('/',left,right);  /* normal division */
-       /* if the size left or right > 1 then support routine */
-       if (getSize(ltype) > 1 || getSize(rtype) > 1)
-           ic->supportRtn = 1;
-    }
-    IC_RESULT(ic) = newiTempOperand(resType,0);
-    
-    ADDTOCHAIN(ic);
-    return IC_RESULT(ic) ;
+operand *
+geniCodeDivision (operand * left, operand * right)
+{
+  iCode *ic;
+  int p2 = 0;
+  sym_link *resType;
+  sym_link *rtype = operandType (right);
+  sym_link *retype = getSpec (rtype);
+  sym_link *ltype = operandType (left);
+  sym_link *letype = getSpec (ltype);
+
+  resType = usualBinaryConversions (&left, &right);
+
+  /* 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 */
+  }
+  else
+    {
+      ic = newiCode ('/', left, right);                /* normal division */
+      /* if the size left or right > 1 then support routine */
+      if (getSize (ltype) > 1 || getSize (rtype) > 1)
+       ic->supportRtn = 1;
+    }
+  IC_RESULT (ic) = newiTempOperand (resType, 0);
+
+  ADDTOCHAIN (ic);
+  return IC_RESULT (ic);
 }
 /*-----------------------------------------------------------------*/
 /* geniCodeModulus  - gen intermediate code for modulus            */
 /*-----------------------------------------------------------------*/
 }
 /*-----------------------------------------------------------------*/
 /* geniCodeModulus  - gen intermediate code for modulus            */
 /*-----------------------------------------------------------------*/
-operand *geniCodeModulus (operand *left, operand *right)
-{ 
-    iCode *ic ;
-    sym_link *resType;
-    LRTYPE ;
-    
-    /* if they are both literal then we know the result */
-    if (IS_LITERAL(letype) && IS_LITERAL(retype)) 
-       return operandFromValue (valMod(left->operand.valOperand,
-                                       right->operand.valOperand));
-    
-    resType = usualBinaryConversions(&left, &right);
-    
-    /* now they are the same size */
-    ic = newiCode('%',left,right);
+operand *
+geniCodeModulus (operand * left, operand * right)
+{
+  iCode *ic;
+  sym_link *resType;
+  LRTYPE;
 
 
-    /* if the size left or right > 1 then support routine */
-    if (getSize(ltype) > 1 || getSize(rtype) > 1)
-       ic->supportRtn = 1;
-    IC_RESULT(ic) = newiTempOperand(resType,0);
-    
-    ADDTOCHAIN(ic);
-    return IC_RESULT(ic) ;
+  /* if they are both literal then we know the result */
+  if (IS_LITERAL (letype) && IS_LITERAL (retype))
+    return operandFromValue (valMod (left->operand.valOperand,
+                                    right->operand.valOperand));
+
+  resType = usualBinaryConversions (&left, &right);
+
+  /* now they are the same size */
+  ic = newiCode ('%', left, right);
+
+  /* if the size left or right > 1 then support routine */
+  if (getSize (ltype) > 1 || getSize (rtype) > 1)
+    ic->supportRtn = 1;
+  IC_RESULT (ic) = newiTempOperand (resType, 0);
+
+  ADDTOCHAIN (ic);
+  return IC_RESULT (ic);
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodePtrPtrSubtract - subtracts pointer from pointer         */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodePtrPtrSubtract - subtracts pointer from pointer         */
 /*-----------------------------------------------------------------*/
-operand *geniCodePtrPtrSubtract (operand *left, operand *right)
+operand *
+geniCodePtrPtrSubtract (operand * left, operand * right)
 {
 {
-    iCode *ic ;
-    operand *result;
-    LRTYPE ;
-    
-    /* if they are both literals then */
-    if (IS_LITERAL(letype) && IS_LITERAL(retype)) {
-       result = operandFromValue (valMinus(left->operand.valOperand,
-                                           right->operand.valOperand));
-       goto subtractExit;
+  iCode *ic;
+  operand *result;
+  LRTYPE;
+
+  /* if they are both literals then */
+  if (IS_LITERAL (letype) && IS_LITERAL (retype))
+    {
+      result = operandFromValue (valMinus (left->operand.valOperand,
+                                          right->operand.valOperand));
+      goto subtractExit;
     }
     }
-    
-    ic = newiCode('-',left,right);
-    
-    IC_RESULT(ic) = result = newiTempOperand(newIntLink(),1);
-    ADDTOCHAIN(ic);
-    
- subtractExit:
-    return geniCodeDivision (result,
-                            operandFromLit(getSize(ltype->next)));   
+
+  ic = newiCode ('-', left, right);
+
+  IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
+  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)));
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeSubtract - generates code for subtraction               */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeSubtract - generates code for subtraction               */
 /*-----------------------------------------------------------------*/
-operand *geniCodeSubtract (operand *left, operand *right)
+operand *
+geniCodeSubtract (operand * left, operand * right)
 {
 {
-    iCode *ic ;
-    int isarray= 0;
-    sym_link *resType;
-    LRTYPE ;
-    
-    /* if they both pointers then */
-    if ((IS_PTR(ltype) || IS_ARRAY(ltype)) &&
-       (IS_PTR(rtype) || IS_ARRAY(rtype)))
-       return geniCodePtrPtrSubtract (left,right);
-    
-    /* if they are both literal then we know the result */
-    if (IS_LITERAL(letype) && IS_LITERAL(retype)
-       && left->isLiteral && right->isLiteral) 
-       return operandFromValue (valMinus(left->operand.valOperand,
-                                         right->operand.valOperand));
-    
-    /* if left is an array or pointer */
-    if ( IS_PTR(ltype) || IS_ARRAY(ltype) ) {    
-       isarray = left->isaddr ;    
-       right = geniCodeMultiply (right,
-                                 operandFromLit(getSize(ltype->next)));
-       resType = copyLinkChain(IS_ARRAY(ltype) ? ltype->next : ltype);
+  iCode *ic;
+  int isarray = 0;
+  sym_link *resType;
+  LRTYPE;
+
+  /* if they both pointers then */
+  if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
+      (IS_PTR (rtype) || IS_ARRAY (rtype)))
+    return geniCodePtrPtrSubtract (left, right);
+
+  /* if they are both literal then we know the result */
+  if (IS_LITERAL (letype) && IS_LITERAL (retype)
+      && left->isLiteral && right->isLiteral)
+    return operandFromValue (valMinus (left->operand.valOperand,
+                                      right->operand.valOperand));
+
+  /* if left is an array or pointer */
+  if (IS_PTR (ltype) || IS_ARRAY (ltype))
+    {
+      isarray = left->isaddr;
+      right = geniCodeMultiply (right,
+                               operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
+      resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
     }
     }
-    else { /* make them the same size */
-        resType = usualBinaryConversions(&left, &right);
+  else
+    {                          /* make them the same size */
+      resType = usualBinaryConversions (&left, &right);
     }
     }
-    
-    ic = newiCode('-',left,right);
-    
-    IC_RESULT(ic)= newiTempOperand(resType,1);
-    IC_RESULT(ic)->isaddr = (isarray ? 1 : 0);
 
 
-    /* if left or right is a float */
-    if (IS_FLOAT(ltype) || IS_FLOAT(rtype))
-       ic->supportRtn = 1;
+  ic = newiCode ('-', left, right);
 
 
-    ADDTOCHAIN(ic);
-    return IC_RESULT(ic) ;
+  IC_RESULT (ic) = newiTempOperand (resType, 1);
+  IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
+
+  /* if left or right is a float */
+  if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
+    ic->supportRtn = 1;
+
+  ADDTOCHAIN (ic);
+  return IC_RESULT (ic);
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeAdd - generates iCode for addition                      */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeAdd - generates iCode for addition                      */
 /*-----------------------------------------------------------------*/
-operand *geniCodeAdd (operand *left, operand *right )
+operand *
+geniCodeAdd (operand * left, operand * right, int lvl)
 {
 {
-    iCode *ic ;
-    sym_link *resType ;
-    operand *size ;
-    int isarray = 0;
-    LRTYPE ;
+  iCode *ic;
+  sym_link *resType;
+  operand *size;
+  int isarray = 0;
+  LRTYPE;
 
 
-    /* if left is an array then array access */
-    if (IS_ARRAY(ltype)) 
-       return geniCodeArray (left,right);           
-    
-    /* if the right side is LITERAL zero */
-    /* return the left side              */
-    if (IS_LITERAL(retype) && right->isLiteral && !floatFromVal(valFromType(retype)))
-       return left;
-    
-    /* if left is literal zero return 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)) {    
-       
-       isarray = left->isaddr;
-       size = 
-           operandFromLit(getSize(ltype->next));
-       if (getSize(ltype) > 1 && (getSize(rtype) < INTSIZE)) 
-       {
-           right = geniCodeCast(INTTYPE,right,TRUE);       
-       }
-       right = geniCodeMultiply (right ,size);
+#if 0
+  /* if left is an array then array access */
+  if (IS_ARRAY (ltype))
+    return geniCodeArray (left, right,lvl);
+#endif
+
+  /* if the right side is LITERAL zero */
+  /* return the left side              */
+  if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
+    return left;
+
+  /* if left is literal zero return right */
+  if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
+    return right;
 
 
-       resType = copyLinkChain(ltype);
+  /* if left is a pointer then size */
+  if (IS_PTR (ltype) || IS_ARRAY(ltype))
+    {
+      isarray = left->isaddr;
+      // 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 */
-        resType = usualBinaryConversions(&left, &right);
+  else
+    { // make them the same size
+      resType = usualBinaryConversions (&left, &right);
     }
     }
-    
-    /* if they are both literals then we know */
-    if (IS_LITERAL(letype) && IS_LITERAL(retype)
-       && left->isLiteral && right->isLiteral)
-       return operandFromValue (valPlus(valFromType(letype),
-                                        valFromType(retype)));
-    
-    ic = newiCode('+',left,right);
-    
-    IC_RESULT(ic) = newiTempOperand(resType,1);
-    IC_RESULT(ic)->isaddr = ( isarray ? 1 : 0);
 
 
-    /* if left or right is a float then support
-       routine */
-    if (IS_FLOAT(ltype) || IS_FLOAT(rtype))
-       ic->supportRtn = 1;
+  /* if they are both literals then we know */
+  if (IS_LITERAL (letype) && IS_LITERAL (retype)
+      && left->isLiteral && right->isLiteral)
+    return operandFromValue (valPlus (valFromType (letype),
+                                     valFromType (retype)));
+
+  ic = newiCode ('+', left, right);
+
+  IC_RESULT (ic) = newiTempOperand (resType, 1);
+  IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
+
+  /* if left or right is a float then support
+     routine */
+  if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
+    ic->supportRtn = 1;
+
+  ADDTOCHAIN (ic);
+
+  return IC_RESULT (ic);
 
 
-    ADDTOCHAIN(ic);
-    
-    return IC_RESULT(ic) ;
-    
 }
 
 /*-----------------------------------------------------------------*/
 /* aggrToPtr - changes an aggregate to pointer to an aggregate     */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* aggrToPtr - changes an aggregate to pointer to an aggregate     */
 /*-----------------------------------------------------------------*/
-sym_link *aggrToPtr ( sym_link *type, bool force)
+sym_link *
+aggrToPtr (sym_link * type, bool force)
 {
 {
-    sym_link *etype ;
-    sym_link *ptype ;
+  sym_link *etype;
+  sym_link *ptype;
 
 
-    
-    if (IS_PTR(type) && !force)
-       return type;
 
 
-    etype = getSpec(type);
-    ptype = newLink();
+  if (IS_PTR (type) && !force)
+    return type;
+
+  etype = getSpec (type);
+  ptype = newLink ();
 
 
-    ptype->next = type;
-    /* if the output class is generic */
-    if ((DCL_TYPE(ptype) = PTR_TYPE(SPEC_OCLS(etype))) == CPOINTER)
-       DCL_PTR_CONST(ptype) = port->mem.code_ro;
+  ptype->next = type;
+  /* if the output class is generic */
+  if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
+    DCL_PTR_CONST (ptype) = port->mem.code_ro;
 
 
-    /* if the variable was declared a constant */
-    /* then the pointer points to a constant */
-    if (IS_CONSTANT(etype) )
-       DCL_PTR_CONST(ptype) = 1;
+  /* if the variable was declared a constant */
+  /* then the pointer points to a constant */
+  if (IS_CONSTANT (etype))
+    DCL_PTR_CONST (ptype) = 1;
 
 
-    /* the variable was volatile then pointer to volatile */
-    if (IS_VOLATILE(etype))
-       DCL_PTR_VOLATILE(ptype) = 1;
-    return ptype; 
+  /* the variable was volatile then pointer to volatile */
+  if (IS_VOLATILE (etype))
+    DCL_PTR_VOLATILE (ptype) = 1;
+  return ptype;
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeArray2Ptr - array to pointer                            */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeArray2Ptr - array to pointer                            */
 /*-----------------------------------------------------------------*/
-operand *geniCodeArray2Ptr (operand *op)
+operand *
+geniCodeArray2Ptr (operand * op)
 {
 {
-    sym_link *optype = operandType(op);
-    sym_link *opetype = getSpec(optype);
+  sym_link *optype = operandType (op);
+  sym_link *opetype = getSpec (optype);
 
 
-    /* set the pointer depending on the storage class */    
-    if ((DCL_TYPE(optype) = PTR_TYPE(SPEC_OCLS(opetype))) == CPOINTER)
-       DCL_PTR_CONST(optype) = port->mem.code_ro;
+  /* set the pointer depending on the storage class */
+  if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
+    DCL_PTR_CONST (optype) = port->mem.code_ro;
 
 
-    
-    /* if the variable was declared a constant */
-    /* then the pointer points to a constant */
-    if (IS_CONSTANT(opetype) )
-       DCL_PTR_CONST(optype) = 1;
-
-    /* the variable was volatile then pointer to volatile */
-    if (IS_VOLATILE(opetype))
-       DCL_PTR_VOLATILE(optype) = 1;
-    op->isaddr = 0;
-    return op;
+
+  /* if the variable was declared a constant */
+  /* then the pointer points to a constant */
+  if (IS_CONSTANT (opetype))
+    DCL_PTR_CONST (optype) = 1;
+
+  /* the variable was volatile then pointer to volatile */
+  if (IS_VOLATILE (opetype))
+    DCL_PTR_VOLATILE (optype) = 1;
+  op->isaddr = 0;
+  return op;
 }
 
 
 /*-----------------------------------------------------------------*/
 /* geniCodeArray - array access                                    */
 /*-----------------------------------------------------------------*/
 }
 
 
 /*-----------------------------------------------------------------*/
 /* geniCodeArray - array access                                    */
 /*-----------------------------------------------------------------*/
-operand *geniCodeArray (operand *left,operand *right)
+operand *
+geniCodeArray (operand * left, operand * right,int lvl)
 {
 {
-    iCode *ic;
-    sym_link *ltype = operandType(left);
-    
-    if (IS_PTR(ltype)) {
-       if (IS_PTR(ltype->next) && left->isaddr)
+  iCode *ic;
+  sym_link *ltype = operandType (left);
+
+  if (IS_PTR (ltype))
+    {
+      if (IS_PTR (ltype->next) && left->isaddr)
        {
        {
-           left = geniCodeRValue(left,FALSE);
+         left = geniCodeRValue (left, FALSE);
        }
        }
-       return geniCodeDerefPtr(geniCodeAdd(left,right));
+      return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
     }
 
     }
 
-    /* array access */
-    right = usualUnaryConversions(right);
-    right = geniCodeMultiply(right,
-                            operandFromLit(getSize(ltype->next)));
+  right = geniCodeMultiply (right,
+                           operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
 
 
-    /* we can check for limits here */
-    if (isOperandLiteral(right) &&
-       IS_ARRAY(ltype)         &&
-       DCL_ELEM(ltype)         &&
-       (operandLitValue(right)/getSize(ltype->next)) >= DCL_ELEM(ltype)) {
-       werror(E_ARRAY_BOUND);
-       right = operandFromLit(0);
+  /* we can check for limits here */
+  if (isOperandLiteral (right) &&
+      IS_ARRAY (ltype) &&
+      DCL_ELEM (ltype) &&
+      (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
+    {
+      werror (E_ARRAY_BOUND);
+      right = operandFromLit (0);
     }
 
     }
 
-    ic = newiCode('+',left,right);    
+  ic = newiCode ('+', left, right);
 
 
-    IC_RESULT(ic) = newiTempOperand(((IS_PTR(ltype) && 
-                                     !IS_AGGREGATE(ltype->next) &&
-                                     !IS_PTR(ltype->next))
-                                    ? ltype : ltype->next),0);
+  IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
+                                     !IS_AGGREGATE (ltype->next) &&
+                                     !IS_PTR (ltype->next))
+                                    ? ltype : ltype->next), 0);
 
 
-    IC_RESULT(ic)->isaddr = (!IS_AGGREGATE(ltype->next));
-    ADDTOCHAIN(ic);
-    return IC_RESULT(ic) ;
+  IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
+  ADDTOCHAIN (ic);
+  return IC_RESULT (ic);
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeStruct - generates intermediate code for structres      */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeStruct - generates intermediate code for structres      */
 /*-----------------------------------------------------------------*/
-operand *geniCodeStruct (operand *left, operand *right, bool islval)
+operand *
+geniCodeStruct (operand * left, operand * right, bool islval)
 {
 {
-    iCode *ic ;
-    sym_link *type = operandType(left);
-    sym_link *etype = getSpec(type);
-    sym_link *retype ;
-    symbol *element = getStructElement(SPEC_STRUCT(etype), 
-                                      right->operand.symOperand);
-    
-    /* add the offset */
-    ic = newiCode('+',left,operandFromLit(element->offset));
+  iCode *ic;
+  sym_link *type = operandType (left);
+  sym_link *etype = getSpec (type);
+  sym_link *retype;
+  symbol *element = getStructElement (SPEC_STRUCT (etype),
+                                     right->operand.symOperand);
+
+  wassert(IS_SYMOP(right));
     
     
-    IC_RESULT(ic) = newiTempOperand(element->type,0);
+  /* add the offset */
+  ic = newiCode ('+', left, operandFromLit (element->offset));
 
 
-    /* preserve the storage & output class of the struct */
-    /* as well as the volatile attribute */
-    retype = getSpec(operandType(IC_RESULT(ic)));
-    SPEC_SCLS(retype) = SPEC_SCLS(etype);
-    SPEC_OCLS(retype) = SPEC_OCLS(etype);
-    SPEC_VOLATILE(retype) |= SPEC_VOLATILE(etype);    
+  IC_RESULT (ic) = newiTempOperand (element->type, 0);
 
 
-    if (IS_PTR(element->type)) 
-       setOperandType(IC_RESULT(ic),aggrToPtr(operandType(IC_RESULT(ic)),TRUE));
-    
-    IC_RESULT(ic)->isaddr = (!IS_AGGREGATE(element->type));
+  /* preserve the storage & output class of the struct */
+  /* as well as the volatile attribute */
+  retype = getSpec (operandType (IC_RESULT (ic)));
+  SPEC_SCLS (retype) = SPEC_SCLS (etype);
+  SPEC_OCLS (retype) = SPEC_OCLS (etype);
+  SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
 
 
-    
-    ADDTOCHAIN(ic);
-    return (islval ? IC_RESULT(ic) : geniCodeRValue(IC_RESULT(ic),TRUE));
+  if (IS_PTR (element->type))
+    setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
+
+  IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
+
+
+  ADDTOCHAIN (ic);
+  return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodePostInc - generate int code for Post increment          */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodePostInc - generate int code for Post increment          */
 /*-----------------------------------------------------------------*/
-operand *geniCodePostInc (operand *op)
-{
-    iCode *ic ;
-    operand *rOp ;
-    sym_link *optype = operandType(op);
-    operand *result ;
-    operand *rv = (IS_ITEMP(op) ? 
-                  geniCodeRValue(op,(IS_PTR(optype) ? TRUE : FALSE)) :
-                  op);            
-    sym_link *rvtype = operandType(rv);    
-    int size = 0;
-    
-    /* if this is not an address we have trouble */
-    if ( ! op->isaddr ) {
-       werror (E_LVALUE_REQUIRED,"++");
-       return op ;
+operand *
+geniCodePostInc (operand * op)
+{
+  iCode *ic;
+  operand *rOp;
+  sym_link *optype = operandType (op);
+  operand *result;
+  operand *rv = (IS_ITEMP (op) ?
+                geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
+                op);
+  sym_link *rvtype = operandType (rv);
+  int size = 0;
+
+  /* if this is not an address we have trouble */
+  if (!op->isaddr)
+    {
+      werror (E_LVALUE_REQUIRED, "++");
+      return op;
     }
     }
-    
-    rOp = newiTempOperand(rvtype,0);
-    rOp->noSpilLoc = 1;
 
 
-    if (IS_ITEMP(rv))
-       rv->noSpilLoc = 1;
+  rOp = newiTempOperand (rvtype, 0);
+  OP_SYMBOL(rOp)->noSpilLoc = 1;
 
 
-    geniCodeAssign(rOp,rv,0);
-   
-    size = (IS_PTR(rvtype) ? getSize(rvtype->next) : 1);
-    ic = newiCode('+',rv,operandFromLit(size));          
-    IC_RESULT(ic) = result =newiTempOperand(rvtype,0);
-    ADDTOCHAIN(ic);
+  if (IS_ITEMP (rv))
+    OP_SYMBOL(rv)->noSpilLoc = 1;
+
+  geniCodeAssign (rOp, rv, 0);
+
+  size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
+  if (IS_FLOAT (rvtype))
+    ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
+  else
+    ic = newiCode ('+', rv, operandFromLit (size));
+
+  IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
+  ADDTOCHAIN (ic);
+
+  geniCodeAssign (op, result, 0);
+
+  return rOp;
 
 
-    geniCodeAssign(op,result,0);
-    
-    return rOp;
-    
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodePreInc - generate code for preIncrement                 */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodePreInc - generate code for preIncrement                 */
 /*-----------------------------------------------------------------*/
-operand *geniCodePreInc (operand *op)
+operand *
+geniCodePreInc (operand * op)
 {
 {
-    iCode *ic ;
-    sym_link *optype = operandType(op);    
-    operand *rop = (IS_ITEMP(op) ? 
-                   geniCodeRValue (op,(IS_PTR(optype) ? TRUE : FALSE)) :
-                   op);
-    sym_link *roptype = operandType(rop);
-    operand *result;
-    int size = 0;
-    
-    if ( ! op->isaddr ) {
-       werror(E_LVALUE_REQUIRED,"++");
-       return op ;
+  iCode *ic;
+  sym_link *optype = operandType (op);
+  operand *rop = (IS_ITEMP (op) ?
+                 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
+                 op);
+  sym_link *roptype = operandType (rop);
+  operand *result;
+  int size = 0;
+
+  if (!op->isaddr)
+    {
+      werror (E_LVALUE_REQUIRED, "++");
+      return op;
     }
 
 
     }
 
 
-    size = (IS_PTR(roptype) ? getSize(roptype->next) : 1);
-    ic = newiCode('+',rop,operandFromLit(size));
-    IC_RESULT(ic) = result = newiTempOperand(roptype,0) ;
-    ADDTOCHAIN(ic);
+  size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
+  if (IS_FLOAT (roptype))
+    ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
+  else
+    ic = newiCode ('+', rop, operandFromLit (size));
+  IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
+  ADDTOCHAIN (ic);
 
 
-    
-    return geniCodeAssign(op,result,0) ;
+
+  return geniCodeAssign (op, result, 0);
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodePostDec - generates code for Post decrement             */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodePostDec - generates code for Post decrement             */
 /*-----------------------------------------------------------------*/
-operand *geniCodePostDec (operand *op)
-{
-    iCode *ic ;
-    operand *rOp ;
-    sym_link *optype = operandType(op);
-    operand *result ;
-    operand *rv = (IS_ITEMP(op) ? 
-                  geniCodeRValue(op,(IS_PTR(optype) ? TRUE : FALSE)) :
-                  op);            
-    sym_link *rvtype = operandType(rv);    
-    int size = 0;
-    
-    /* if this is not an address we have trouble */
-    if ( ! op->isaddr ) {
-       werror (E_LVALUE_REQUIRED,"++");
-       return op ;
+operand *
+geniCodePostDec (operand * op)
+{
+  iCode *ic;
+  operand *rOp;
+  sym_link *optype = operandType (op);
+  operand *result;
+  operand *rv = (IS_ITEMP (op) ?
+                geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
+                op);
+  sym_link *rvtype = operandType (rv);
+  int size = 0;
+
+  /* if this is not an address we have trouble */
+  if (!op->isaddr)
+    {
+      werror (E_LVALUE_REQUIRED, "--");
+      return op;
     }
     }
-    
-    rOp = newiTempOperand(rvtype,0);
-    rOp->noSpilLoc = 1;
 
 
-    if (IS_ITEMP(rv))
-       rv->noSpilLoc = 1;
+  rOp = newiTempOperand (rvtype, 0);
+  OP_SYMBOL(rOp)->noSpilLoc = 1;
 
 
-    geniCodeAssign(rOp,rv,0);
-   
-    size = (IS_PTR(rvtype) ? getSize(rvtype->next) : 1);
-    ic = newiCode('-',rv,operandFromLit(size));          
-    IC_RESULT(ic) = result =newiTempOperand(rvtype,0);
-    ADDTOCHAIN(ic);
+  if (IS_ITEMP (rv))
+    OP_SYMBOL(rv)->noSpilLoc = 1;
+
+  geniCodeAssign (rOp, rv, 0);
+
+  size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
+  if (IS_FLOAT (rvtype))
+    ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
+  else
+    ic = newiCode ('-', rv, operandFromLit (size));
+
+  IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
+  ADDTOCHAIN (ic);
+
+  geniCodeAssign (op, result, 0);
+
+  return rOp;
 
 
-    geniCodeAssign(op,result,0);
-    
-    return rOp;
-    
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodePreDec - generate code for pre  decrement               */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodePreDec - generate code for pre  decrement               */
 /*-----------------------------------------------------------------*/
-operand *geniCodePreDec (operand *op)
-{  
-    iCode *ic ;
-    sym_link *optype = operandType(op);    
-    operand *rop = (IS_ITEMP(op) ? 
-                   geniCodeRValue (op,(IS_PTR(optype) ? TRUE : FALSE)) :
-                   op);
-    sym_link *roptype = operandType(rop);
-    operand *result;
-    int size = 0;
-    
-    if ( ! op->isaddr ) {
-       werror(E_LVALUE_REQUIRED,"++");
-       return op ;
+operand *
+geniCodePreDec (operand * op)
+{
+  iCode *ic;
+  sym_link *optype = operandType (op);
+  operand *rop = (IS_ITEMP (op) ?
+                 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
+                 op);
+  sym_link *roptype = operandType (rop);
+  operand *result;
+  int size = 0;
+
+  if (!op->isaddr)
+    {
+      werror (E_LVALUE_REQUIRED, "--");
+      return op;
     }
 
 
     }
 
 
-    size = (IS_PTR(roptype) ? getSize(roptype->next) : 1);
-    ic = newiCode('-',rop,operandFromLit(size));
-    IC_RESULT(ic) = result = newiTempOperand(roptype,0) ;
-    ADDTOCHAIN(ic);
+  size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
+  if (IS_FLOAT (roptype))
+    ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
+  else
+    ic = newiCode ('-', rop, operandFromLit (size));
+  IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
+  ADDTOCHAIN (ic);
 
 
-    
-    return geniCodeAssign(op,result,0) ;
+
+  return geniCodeAssign (op, result, 0);
 }
 
 
 /*-----------------------------------------------------------------*/
 /* geniCodeBitwise - gen int code for bitWise  operators           */
 /*-----------------------------------------------------------------*/
 }
 
 
 /*-----------------------------------------------------------------*/
 /* geniCodeBitwise - gen int code for bitWise  operators           */
 /*-----------------------------------------------------------------*/
-operand *geniCodeBitwise (operand *left, operand *right, 
-                         int oper, sym_link *resType)
+operand *
+geniCodeBitwise (operand * left, operand * right,
+                int oper, sym_link * resType)
 {
 {
-    iCode *ic;   
-    
-    left = geniCodeCast(resType,left,TRUE);
-    right= geniCodeCast(resType,right,TRUE);
-    
-    ic = newiCode(oper,left,right);
-    IC_RESULT(ic) = newiTempOperand(resType,0);
-    
-    ADDTOCHAIN(ic);
-    return IC_RESULT(ic) ;
+  iCode *ic;
+
+  left = geniCodeCast (resType, left, TRUE);
+  right = geniCodeCast (resType, right, TRUE);
+
+  ic = newiCode (oper, left, right);
+  IC_RESULT (ic) = newiTempOperand (resType, 0);
+
+  ADDTOCHAIN (ic);
+  return IC_RESULT (ic);
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeAddressOf - gens icode for '&' address of operator      */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeAddressOf - gens icode for '&' address of operator      */
 /*-----------------------------------------------------------------*/
-operand *geniCodeAddressOf (operand *op) 
+operand *
+geniCodeAddressOf (operand * op)
 {
 {
-    iCode *ic;
-    sym_link *p ;
-    sym_link *optype = operandType(op);
-    sym_link *opetype= getSpec(optype);
-    
-    /* lvalue check already done in decorateType */
-    /* this must be a lvalue */
+  iCode *ic;
+  sym_link *p;
+  sym_link *optype = operandType (op);
+  sym_link *opetype = getSpec (optype);
+
+  /* lvalue check already done in decorateType */
+  /* this must be a lvalue */
 /*     if (!op->isaddr && !IS_AGGREGATE(optype)) { */
 /*     if (!op->isaddr && !IS_AGGREGATE(optype)) { */
-/*     werror (E_LVALUE_REQUIRED,"&"); */
-/*     return op; */
+/*  werror (E_LVALUE_REQUIRED,"&"); */
+/*  return op; */
 /*     } */
 /*     } */
-    
-    p = newLink();
-    p->class = DECLARATOR ;
-    
-    /* set the pointer depending on the storage class */
-    if ((DCL_TYPE(p) = PTR_TYPE(SPEC_OCLS(opetype))) == CPOINTER)
-       DCL_PTR_CONST(p) = port->mem.code_ro;
 
 
-    /* make sure we preserve the const & volatile */
-    if (IS_CONSTANT(opetype)) 
-       DCL_PTR_CONST(p) = 1;
+  p = newLink ();
+  p->class = DECLARATOR;
 
 
-    if (IS_VOLATILE(opetype))
-       DCL_PTR_VOLATILE(p) = 1;
-    
-    p->next = copyLinkChain(optype);
-    
-    /* if already a temp */
-    if (IS_ITEMP(op)) {
-       setOperandType (op,p);     
-       op->isaddr= 0;
-       return op;
+  /* set the pointer depending on the storage class */
+  if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
+    DCL_PTR_CONST (p) = port->mem.code_ro;
+
+  /* make sure we preserve the const & volatile */
+  if (IS_CONSTANT (opetype))
+    DCL_PTR_CONST (p) = 1;
+
+  if (IS_VOLATILE (opetype))
+    DCL_PTR_VOLATILE (p) = 1;
+
+  p->next = copyLinkChain (optype);
+
+  /* if already a temp */
+  if (IS_ITEMP (op))
+    {
+      setOperandType (op, p);
+      op->isaddr = 0;
+      return op;
     }
     }
-    
-    /* other wise make this of the type coming in */
-    ic = newiCode(ADDRESS_OF,op,NULL);
-    IC_RESULT(ic) = newiTempOperand(p,1);
-    IC_RESULT(ic)->isaddr = 0;
-    ADDTOCHAIN(ic);
-    return IC_RESULT(ic);
+
+  /* other wise make this of the type coming in */
+  ic = newiCode (ADDRESS_OF, op, NULL);
+  IC_RESULT (ic) = newiTempOperand (p, 1);
+  IC_RESULT (ic)->isaddr = 0;
+  ADDTOCHAIN (ic);
+  return IC_RESULT (ic);
 }
 /*-----------------------------------------------------------------*/
 /* setOClass - sets the output class depending on the pointer type */
 /*-----------------------------------------------------------------*/
 }
 /*-----------------------------------------------------------------*/
 /* setOClass - sets the output class depending on the pointer type */
 /*-----------------------------------------------------------------*/
-void setOClass (sym_link *ptr, sym_link *spec)
+void 
+setOClass (sym_link * ptr, sym_link * spec)
 {
 {
-    switch (DCL_TYPE(ptr)) {
+  switch (DCL_TYPE (ptr))
+    {
     case POINTER:
     case POINTER:
-       SPEC_OCLS(spec) = data ;
-       break ;
-       
+      SPEC_OCLS (spec) = data;
+      break;
+
     case GPOINTER:
     case GPOINTER:
-       SPEC_OCLS(spec) = generic;
-       break;
-       
+      SPEC_OCLS (spec) = generic;
+      break;
+
     case FPOINTER:
     case FPOINTER:
-       SPEC_OCLS(spec) = xdata ;
-       break ;
-       
+      SPEC_OCLS (spec) = xdata;
+      break;
+
     case CPOINTER:
     case CPOINTER:
-       SPEC_OCLS(spec) = code ;
-       break ;  
-       
+      SPEC_OCLS (spec) = code;
+      break;
+
     case IPOINTER:
     case IPOINTER:
-       SPEC_OCLS(spec) = idata;
-       break;
+      SPEC_OCLS (spec) = idata;
+      break;
 
     case PPOINTER:
 
     case PPOINTER:
-       SPEC_OCLS(spec) = xstack;
-       break;
+      SPEC_OCLS (spec) = xstack;
+      break;
 
     case EEPPOINTER:
 
     case EEPPOINTER:
-       SPEC_OCLS(spec) = eeprom;
-       break;
+      SPEC_OCLS (spec) = eeprom;
+      break;
 
     default:
 
     default:
-       break;
+      break;
 
     }
 }
 
     }
 }
@@ -2167,1078 +2524,1265 @@ void setOClass (sym_link *ptr, sym_link *spec)
 /*-----------------------------------------------------------------*/
 /* geniCodeDerefPtr - dereference pointer with '*'                 */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* geniCodeDerefPtr - dereference pointer with '*'                 */
 /*-----------------------------------------------------------------*/
-operand *geniCodeDerefPtr (operand *op)
-{    
-    sym_link *rtype , *retype ;
-    sym_link *optype = operandType(op);  
-
-    /* if this is a pointer then generate the rvalue */
-    if (IS_PTR(optype)) {
-       if (IS_TRUE_SYMOP(op)) {
-           op->isaddr = 1;
-           op = geniCodeRValue(op,TRUE);
+operand *
+geniCodeDerefPtr (operand * op,int lvl)
+{
+  sym_link *rtype, *retype;
+  sym_link *optype = operandType (op);
+
+  /* if this is a pointer then generate the rvalue */
+  if (IS_PTR (optype))
+    {
+      if (IS_TRUE_SYMOP (op))
+       {
+         op->isaddr = 1;
+         op = geniCodeRValue (op, TRUE);
        }
        }
-       else    
-           op = geniCodeRValue(op,TRUE);       
+      else
+       op = geniCodeRValue (op, TRUE);
     }
     }
-    
-    /* now get rid of the pointer part */
-    if (lvaluereq && IS_ITEMP(op) )
+
+  /* now get rid of the pointer part */
+  if (isLvaluereq(lvl) && IS_ITEMP (op))
     {
     {
-       retype = getSpec(rtype = copyLinkChain(optype)) ;
+      retype = getSpec (rtype = copyLinkChain (optype));
     }
     }
-    else
+  else
     {
     {
-       retype = getSpec(rtype = copyLinkChain(optype->next)) ;
+      retype = getSpec (rtype = copyLinkChain (optype->next));
     }
     }
-    
-    /* if this is a pointer then outputclass needs 2b updated */
-    if (IS_PTR(optype)) 
-       setOClass(optype,retype);    
-        
-    op->isGptr = IS_GENPTR(optype);
-
-    /* if the pointer was declared as a constant */
-    /* then we cannot allow assignment to the derefed */
-    if (IS_PTR_CONST(optype))
-       SPEC_CONST(retype) = 1;
-    
-    op->isaddr = (IS_PTR(rtype)    ||
-                 IS_STRUCT(rtype) || 
-                 IS_INT(rtype)    ||
-                 IS_CHAR(rtype)   ||
-                 IS_FLOAT(rtype) );
 
 
-    if (!lvaluereq)
-       op = geniCodeRValue(op,TRUE);
+  /* if this is a pointer then outputclass needs 2b updated */
+  if (IS_PTR (optype))
+    setOClass (optype, retype);
 
 
-    setOperandType(op,rtype);
-    
-    return op;    
+  op->isGptr = IS_GENPTR (optype);
+
+  /* if the pointer was declared as a constant */
+  /* then we cannot allow assignment to the derefed */
+  if (IS_PTR_CONST (optype))
+    SPEC_CONST (retype) = 1;
+
+  op->isaddr = (IS_PTR (rtype) ||
+               IS_STRUCT (rtype) ||
+               IS_INT (rtype) ||
+               IS_CHAR (rtype) ||
+               IS_FLOAT (rtype));
+
+  if (!isLvaluereq(lvl))
+    op = geniCodeRValue (op, TRUE);
+
+  setOperandType (op, rtype);
+
+  return op;
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeUnaryMinus - does a unary minus of the operand          */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeUnaryMinus - does a unary minus of the operand          */
 /*-----------------------------------------------------------------*/
-operand *geniCodeUnaryMinus (operand *op)
+operand *
+geniCodeUnaryMinus (operand * op)
 {
 {
-    iCode *ic ;
-    sym_link *optype = operandType(op);
-    
-    if (IS_LITERAL(optype))
-       return operandFromLit(- floatFromVal(op->operand.valOperand));
-    
-    ic = newiCode(UNARYMINUS,op,NULL);
-    IC_RESULT(ic) = newiTempOperand(optype,0);
-    ADDTOCHAIN(ic);
-    return IC_RESULT(ic);
+  iCode *ic;
+  sym_link *optype = operandType (op);
+
+  if (IS_LITERAL (optype))
+    return operandFromLit (-floatFromVal (op->operand.valOperand));
+
+  ic = newiCode (UNARYMINUS, op, NULL);
+  IC_RESULT (ic) = newiTempOperand (optype, 0);
+  ADDTOCHAIN (ic);
+  return IC_RESULT (ic);
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeLeftShift - gen i code for left shift                   */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeLeftShift - gen i code for left shift                   */
 /*-----------------------------------------------------------------*/
-operand *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.
-     */
-    right = usualUnaryConversions(right);
-    left = usualUnaryConversions(left);
+operand *
+geniCodeLeftShift (operand * left, operand * right)
+{
+  iCode *ic;
 
 
-    ic = newiCode(LEFT_OP,left,right);
-    IC_RESULT(ic) = newiTempOperand(operandType(left),0);
-    ADDTOCHAIN(ic);
-    return IC_RESULT(ic) ;  
+  ic = newiCode (LEFT_OP, left, right);
+  IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
+  ADDTOCHAIN (ic);
+  return IC_RESULT (ic);
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeRightShift - gen i code for right shift                 */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeRightShift - gen i code for right shift                 */
 /*-----------------------------------------------------------------*/
-operand *geniCodeRightShift (operand *left, operand *right)
-{ 
-    iCode *ic;
+operand *
+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.
-     */
-    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) ;  
+  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                                       */
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 /* geniCodeLogic- logic code                                       */
 /*-----------------------------------------------------------------*/
-operand *geniCodeLogic (operand *left, operand *right, int op )
+operand *
+geniCodeLogic (operand * left, operand * right, int op)
 {
 {
-    iCode *ic ;
-    sym_link *ctype; 
-    sym_link *rtype = operandType(right);
-    sym_link *ltype = operandType(left);
-    
-    /* left is integral type and right is literal then
-       check if the literal value is within bounds */
-    if (IS_INTEGRAL(ltype) && IS_LITERAL(rtype)) {
-       int nbits = bitsForType(ltype);
-       long v = operandLitValue(right);
+  iCode *ic;
+  sym_link *ctype;
+  sym_link *rtype = operandType (right);
+  sym_link *ltype = operandType (left);
 
 
-       if (v > ((LONG_LONG) 1 << nbits) && v > 0)
-           werror(W_CONST_RANGE," compare operation ");
+  /* left is integral type and right is literal then
+     check if the literal value is within bounds */
+  if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
+    {
+      checkConstantRange(ltype, 
+                        OP_VALUE(right), "compare operation", 1);
     }
 
     }
 
-    ctype = usualBinaryConversions(&left, &right);
+  ctype = usualBinaryConversions (&left, &right);
 
 
-    ic = newiCode(op,left,right);
-    IC_RESULT(ic) = newiTempOperand (newCharLink(),1);
+  ic = newiCode (op, left, right);
+  IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
 
 
-    /* if comparing anything greater than one byte
-       and not a '==' || '!=' || '&&' || '||' (these
-       will be inlined */
-    if (getSize(ctype) > 1 && 
-       op != EQ_OP        && 
-       op != NE_OP        &&
-       op != AND_OP       &&
-       op != OR_OP        )
-       ic->supportRtn = 1;
+  /* if comparing float
+     and not a '==' || '!=' || '&&' || '||' (these
+     will be inlined */
+  if (IS_FLOAT(ctype) &&
+      op != EQ_OP &&
+      op != NE_OP &&
+      op != AND_OP &&
+      op != OR_OP)
+    ic->supportRtn = 1;
 
 
-    ADDTOCHAIN(ic);
-    return IC_RESULT(ic);
+  ADDTOCHAIN (ic);
+  return IC_RESULT (ic);
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeUnary - for a a generic unary operation                 */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeUnary - for a a generic unary operation                 */
 /*-----------------------------------------------------------------*/
-operand *geniCodeUnary (operand *op, int oper )
+operand *
+geniCodeUnary (operand * op, int oper)
 {
 {
-    iCode *ic = newiCode (oper,op,NULL);
-    
-    IC_RESULT(ic)= newiTempOperand(operandType(op),0);
-    ADDTOCHAIN(ic);
-    return IC_RESULT(ic) ;
+  iCode *ic = newiCode (oper, op, NULL);
+
+  IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
+  ADDTOCHAIN (ic);
+  return IC_RESULT (ic);
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeConditional - geniCode for '?' ':' operation            */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeConditional - geniCode for '?' ':' operation            */
 /*-----------------------------------------------------------------*/
-operand *geniCodeConditional (ast *tree)
+operand *
+geniCodeConditional (ast * tree,int lvl)
 {
 {
-    iCode *ic ;
-    symbol *falseLabel = newiTempLabel(NULL);
-    symbol *exitLabel  = newiTempLabel(NULL);
-    operand *cond = ast2iCode(tree->left);
-    operand *true, *false , *result;
-    
-    ic = newiCodeCondition(geniCodeRValue(cond,FALSE),
-                          NULL,falseLabel);
-    ADDTOCHAIN(ic);
-    
-    true = ast2iCode(tree->right->left);
-    
-    /* move the value to a new Operand */
-    result = newiTempOperand(operandType(true),0);
-    geniCodeAssign(result,geniCodeRValue(true,FALSE),0);
-    
-    /* generate an unconditional goto */
-    geniCodeGoto(exitLabel);
-    
-    /* now for the right side */
-    geniCodeLabel(falseLabel);
-    
-    false = ast2iCode(tree->right->right);
-    geniCodeAssign(result,geniCodeRValue(false,FALSE),0);
-    
-    /* create the exit label */
-    geniCodeLabel(exitLabel);
-    
-    return result ;
+  iCode *ic;
+  symbol *falseLabel = newiTempLabel (NULL);
+  symbol *exitLabel = newiTempLabel (NULL);
+  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,lvl+1);
+
+  /* move the value to a new Operand */
+  result = newiTempOperand (tree->right->ftype, 0);
+  geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
+
+  /* generate an unconditional goto */
+  geniCodeGoto (exitLabel);
+
+  /* now for the right side */
+  geniCodeLabel (falseLabel);
+
+  false = ast2iCode (tree->right->right,lvl+1);
+  geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
+
+  /* create the exit label */
+  geniCodeLabel (exitLabel);
+
+  return result;
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeAssign - generate code for assignment                   */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeAssign - generate code for assignment                   */
 /*-----------------------------------------------------------------*/
-operand *geniCodeAssign (operand *left, operand *right, int nosupdate)
+operand *
+geniCodeAssign (operand * left, operand * right, int nosupdate)
 {
 {
-    iCode *ic ;
-    sym_link *ltype = operandType(left);
-    sym_link *rtype = operandType(right);
-    
-    if (!left->isaddr && !IS_ITEMP(left)) {
-       werror(E_LVALUE_REQUIRED,"assignment");
-       return left;
+  iCode *ic;
+  sym_link *ltype = operandType (left);
+  sym_link *rtype = operandType (right);
+
+  if (!left->isaddr && !IS_ITEMP (left))
+    {
+      werror (E_LVALUE_REQUIRED, "assignment");
+      return left;
     }
     }
-       
-    /* left is integral type and right is literal then
-       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");
-    }
-
-    /* if the left & right type don't exactly match */
-    /* if pointer set then make sure the check is
-       done with the type & not the pointer */
-    /* then cast rights type to left */   
-
-    /* first check the type for pointer assignement */
-    if (left->isaddr && IS_PTR(ltype) && IS_ITEMP(left) &&
-       checkType(ltype,rtype)<0) {
-       if (checkType(ltype->next,rtype) < 0)
-           right = geniCodeCast(ltype->next,right,TRUE);
-    } else
-       if (checkType(ltype,rtype) < 0 )
-           right = geniCodeCast(ltype,right,TRUE);
-
-    /* if left is a true symbol & ! volatile 
-       create an assignment to temporary for
-       the right & then assign this temporary
-       to the symbol this is SSA . isn't it simple
-       and folks have published mountains of paper on it */
-    if (IS_TRUE_SYMOP(left) && 
-       !isOperandVolatile(left,FALSE) &&
-       isOperandGlobal(left)) {
-       symbol *sym = NULL;
-
-       if (IS_TRUE_SYMOP(right))
-           sym = OP_SYMBOL(right);
-       ic = newiCode('=',NULL,right);
-       IC_RESULT(ic) = right = newiTempOperand(ltype,0);       
-       SPIL_LOC(right)  = sym ;
-       ADDTOCHAIN(ic);
+
+  /* left is integral type and right is literal then
+     check if the literal value is within bounds */
+  if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
+    {
+      checkConstantRange(ltype, 
+                        OP_VALUE(right), "= operation", 0);
     }
     }
-    
-    ic = newiCode('=',NULL,right);
-    IC_RESULT(ic) = left;
-    ADDTOCHAIN(ic);    
 
 
-    /* if left isgptr flag is set then support
-       routine will be required */
-    if (left->isGptr)
-       ic->supportRtn = 1;
+  /* if the left & right type don't exactly match */
+  /* if pointer set then make sure the check is
+     done with the type & not the pointer */
+  /* then cast rights type to left */
 
 
-    ic->nosupdate = nosupdate;
-    return left;
+  /* first check the type for pointer assignement */
+  if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
+      compareType (ltype, rtype) <= 0)
+    {
+      if (compareType (ltype->next, rtype) < 0)
+       right = geniCodeCast (ltype->next, right, TRUE);
+    }
+  else if (compareType (ltype, rtype) < 0)
+    right = geniCodeCast (ltype, right, TRUE);
+
+  /* if left is a true symbol & ! volatile
+     create an assignment to temporary for
+     the right & then assign this temporary
+     to the symbol this is SSA . isn't it simple
+     and folks have published mountains of paper on it */
+  if (IS_TRUE_SYMOP (left) &&
+      !isOperandVolatile (left, FALSE) &&
+      isOperandGlobal (left))
+    {
+      symbol *sym = NULL;
+
+      if (IS_TRUE_SYMOP (right))
+       sym = OP_SYMBOL (right);
+      ic = newiCode ('=', NULL, right);
+      IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
+      SPIL_LOC (right) = sym;
+      ADDTOCHAIN (ic);
+    }
+
+  ic = newiCode ('=', NULL, right);
+  IC_RESULT (ic) = left;
+  ADDTOCHAIN (ic);
+
+  /* if left isgptr flag is set then support
+     routine will be required */
+  if (left->isGptr)
+    ic->supportRtn = 1;
+
+  ic->nosupdate = nosupdate;
+  return left;
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeSEParms - generate code for side effecting fcalls       */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeSEParms - generate code for side effecting fcalls       */
 /*-----------------------------------------------------------------*/
-static void geniCodeSEParms (ast *parms)
+static void 
+geniCodeSEParms (ast * parms,int lvl)
 {
 {
-    if (!parms)
-       return ;
+  if (!parms)
+    return;
 
 
-    if (parms->type == EX_OP && parms->opval.op == PARAM) {
-       geniCodeSEParms (parms->left) ;
-       geniCodeSEParms (parms->right);
-       return ;
+  if (parms->type == EX_OP && parms->opval.op == PARAM)
+    {
+      geniCodeSEParms (parms->left,lvl);
+      geniCodeSEParms (parms->right,lvl);
+      return;
     }
 
     }
 
-    /* hack don't like this but too lazy to think of
-       something better */
-    if (IS_ADDRESS_OF_OP(parms))
-       parms->left->lvalue = 1;
-    
-    if (IS_CAST_OP(parms) && 
-       IS_PTR(parms->ftype) && 
-       IS_ADDRESS_OF_OP(parms->right))
-       parms->right->left->lvalue = 1;
+  /* hack don't like this but too lazy to think of
+     something better */
+  if (IS_ADDRESS_OF_OP (parms))
+    parms->left->lvalue = 1;
 
 
-    parms->opval.oprnd = 
-       geniCodeRValue(ast2iCode (parms),FALSE);
-   
-    parms->type = EX_OPERAND ;
+  if (IS_CAST_OP (parms) &&
+      IS_PTR (parms->ftype) &&
+      IS_ADDRESS_OF_OP (parms->right))
+    parms->right->left->lvalue = 1;
+
+  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                            */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* 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 ;
-    
-    /* 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 ;
+  iCode *ic;
+  operand *pval;
+
+  if (!parms)
+    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)
+    {
+      argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
+      argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
+      return argVals;
     }
     }
-    
-    /* get the parameter value */
-    if (parms->type == EX_OPERAND)
-       pval = parms->opval.oprnd ;
-    else {
-       /* maybe this else should go away ?? */
-       /* hack don't like this but too lazy to think of
-          something better */
-       if (IS_ADDRESS_OF_OP(parms))
-           parms->left->lvalue = 1;
-    
-       if (IS_CAST_OP(parms) && 
-           IS_PTR(parms->ftype) && 
-           IS_ADDRESS_OF_OP(parms->right))
-           parms->right->left->lvalue = 1;
 
 
-       pval = geniCodeRValue(ast2iCode (parms),FALSE); 
+  /* get the parameter value */
+  if (parms->type == EX_OPERAND)
+    pval = parms->opval.oprnd;
+  else
+    {
+      /* maybe this else should go away ?? */
+      /* hack don't like this but too lazy to think of
+         something better */
+      if (IS_ADDRESS_OF_OP (parms))
+       parms->left->lvalue = 1;
+
+      if (IS_CAST_OP (parms) &&
+         IS_PTR (parms->ftype) &&
+         IS_ADDRESS_OF_OP (parms->right))
+       parms->right->left->lvalue = 1;
+
+      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 ) {
-       ic = newiCode(SEND,pval,NULL);
-       ADDTOCHAIN(ic);
-    } else {
-       /* now decide whether to push or assign */
-       if (!(options.stackAuto || IS_RENT(fetype))) { 
-           
-           /* assign */
-           operand *top = operandFromSymbol(parms->argSym);
-           geniCodeAssign(top,pval,1);
+  /* if register parm then make it a send */
+  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 || IFFUNC_ISREENT (func->type)))
+       {
+
+         /* assign */
+         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 { 
-           sym_link *p = operandType(pval);
-           /* push */
-           ic = newiCode(IPUSH,pval,NULL);
-           ic->parmPush = 1;
-           /* update the stack adjustment */
-           *stack += getSize(IS_AGGREGATE(p)? aggrToPtr(p,FALSE):p);
-           ADDTOCHAIN(ic);
+      else
+       {
+         sym_link *p = operandType (pval);
+         /* push */
+         ic = newiCode (IPUSH, pval, NULL);
+         ic->parmPush = 1;
+         /* update the stack adjustment */
+         *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
+         ADDTOCHAIN (ic);
        }
     }
        }
     }
-    
+
+  argVals=argVals->next;
+  return argVals;
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeCall - generates temp code for calling                  */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeCall - generates temp code for calling                  */
 /*-----------------------------------------------------------------*/
-operand *geniCodeCall (operand *left, ast *parms)
-{ 
-    iCode *ic ;
-    operand *result ;
-    sym_link *type, *etype;
-    int stack = 0 ;
-    
-    /* take care of parameters with side-effecting
-       function calls in them, this is required to take care 
-       of overlaying function parameters */
-    geniCodeSEParms ( parms );
+operand *
+geniCodeCall (operand * left, ast * parms,int lvl)
+{
+  iCode *ic;
+  operand *result;
+  sym_link *type, *etype;
+  int stack = 0;
 
 
-    /* first the parameters */
-    geniCodeParms ( parms , &stack , getSpec(operandType(left)), OP_SYMBOL(left));
-    
-    /* now call : if symbol then pcall */
-    if (IS_ITEMP(left)) 
-       ic = newiCode(PCALL,left,NULL);
-    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;
-    IC_RESULT(ic) = result = newiTempOperand(type,1);
-    
-    ADDTOCHAIN(ic);
-    
-    /* stack adjustment after call */
-    left->parmBytes = stack;
+  if (!IS_FUNC(OP_SYMBOL(left)->type) && 
+      !IS_CODEPTR(OP_SYMBOL(left)->type)) {
+    werror (E_FUNCTION_EXPECTED);
+    return NULL;
+  }
 
 
-    return result;
+  /* take care of parameters with side-effecting
+     function calls in them, this is required to take care
+     of overlaying function parameters */
+  geniCodeSEParms (parms,lvl);
+
+  /* first the parameters */
+  geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
+
+  /* now call : if symbol then pcall */
+  if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
+    ic = newiCode (PCALL, left, NULL);
+  } else {
+    ic = newiCode (CALL, left, NULL);
+  }
+
+  type = copyLinkChain (operandType (left)->next);
+  etype = getSpec (type);
+  SPEC_EXTR (etype) = 0;
+  IC_RESULT (ic) = result = newiTempOperand (type, 1);
+
+  ADDTOCHAIN (ic);
+
+  /* stack adjustment after call */
+  ic->parmBytes = stack;
+
+  return result;
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeReceive - generate intermediate code for "receive"      */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeReceive - generate intermediate code for "receive"      */
 /*-----------------------------------------------------------------*/
-static void geniCodeReceive (value *args)
-{   
-    /* for all arguments that are passed in registers */
-    while (args) {
-
-       if (IS_REGPARM(args->etype)) {
-           operand *opr = operandFromValue(args);
-           operand *opl ;
-           symbol *sym  = OP_SYMBOL(opr);
-           iCode *ic ;
-
-           /* we will use it after all optimizations
-              and before liveRange calculation */          
-           if (!sym->addrtaken && !IS_VOLATILE(sym->etype)) {
-
-               if (IN_FARSPACE(SPEC_OCLS(sym->etype)) &&
-                  options.stackAuto == 0 &&
-                  !IS_DS390_PORT) {
-               } else {
-                   opl = newiTempOperand(args->type,0);
-                   sym->reqv = opl ;       
-                   sym->reqv->key = sym->key ;
-                   OP_SYMBOL(sym->reqv)->key = sym->key;
-                   OP_SYMBOL(sym->reqv)->isreqv = 1;
-                   OP_SYMBOL(sym->reqv)->islocal= 0;
-                   SPIL_LOC(sym->reqv) =  sym;
+static void 
+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);
+         operand *opl;
+         symbol *sym = OP_SYMBOL (opr);
+         iCode *ic;
+
+         /* we will use it after all optimizations
+            and before liveRange calculation */
+         if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
+           {
+
+             if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
+                 options.stackAuto == 0 &&
+                 (!(options.model == MODEL_FLAT24)) )
+               {
+               }
+             else
+               {
+                 opl = newiTempOperand (args->type, 0);
+                 sym->reqv = opl;
+                 sym->reqv->key = sym->key;
+                 OP_SYMBOL (sym->reqv)->key = sym->key;
+                 OP_SYMBOL (sym->reqv)->isreqv = 1;
+                 OP_SYMBOL (sym->reqv)->islocal = 0;
+                 SPIL_LOC (sym->reqv) = sym;
                }
            }
 
                }
            }
 
-           ic = newiCode(RECEIVE,NULL,NULL);
-           currFunc->recvSize = getSize(sym->etype);
-           IC_RESULT(ic) = opr;
-           ADDTOCHAIN(ic);
+         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);
        }
        }
-       
-       args = args->next;
+
+      args = args->next;
     }
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeFunctionBody - create the function body                 */
 /*-----------------------------------------------------------------*/
     }
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeFunctionBody - create the function body                 */
 /*-----------------------------------------------------------------*/
-void geniCodeFunctionBody (ast *tree)
+void 
+geniCodeFunctionBody (ast * tree,int lvl)
 {
 {
-    iCode *ic ;
-    operand *func ;
-    sym_link *fetype  ;
-    int savelineno ;
-    
-    /* reset the auto generation */
-    /* numbers */
-    iTempNum = 0 ;
-    iTempLblNum = 0;   
-    operandKey = 0 ;
-    iCodeKey = 0 ;
-    func  = ast2iCode(tree->left);
-    fetype = getSpec(operandType(func));
-    
-    savelineno = lineno;
-    lineno = OP_SYMBOL(func)->lineDef;
-    /* create an entry label */
-    geniCodeLabel(entryLabel);    
-    lineno = savelineno;
-
-    /* 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;
-
-    ADDTOCHAIN(ic);   
-    
-    /* for all parameters that are passed
-       on registers add a "receive" */
-    geniCodeReceive( tree->values.args );
+  iCode *ic;
+  operand *func;
+  sym_link *fetype;
+  int savelineno;
 
 
-    /* generate code for the body */
-    ast2iCode(tree->right);
-    
-    /* create a label for return */
-    geniCodeLabel(returnLabel);
-    
-    /* now generate the end proc */
-    ic = newiCode(ENDFUNCTION,func,NULL);
-    ADDTOCHAIN(ic);
-    return ;
+  /* reset the auto generation */
+  /* numbers */
+  iTempNum = 0;
+  iTempLblNum = 0;
+  operandKey = 0;
+  iCodeKey = 0;
+  func = ast2iCode (tree->left,lvl+1);
+  fetype = getSpec (operandType (func));
+
+  savelineno = lineno;
+  lineno = OP_SYMBOL (func)->lineDef;
+  /* create an entry label */
+  geniCodeLabel (entryLabel);
+  lineno = savelineno;
+
+  /* create a proc icode */
+  ic = newiCode (FUNCTION, func, NULL);
+  lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
+
+  ADDTOCHAIN (ic);
+
+  /* for all parameters that are passed
+     on registers add a "receive" */
+  geniCodeReceive (tree->values.args);
+
+  /* generate code for the body */
+  ast2iCode (tree->right,lvl+1);
+
+  /* create a label for return */
+  geniCodeLabel (returnLabel);
+
+  /* now generate the end proc */
+  ic = newiCode (ENDFUNCTION, func, NULL);
+  ADDTOCHAIN (ic);
+  return;
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeReturn - gen icode for 'return' statement               */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeReturn - gen icode for 'return' statement               */
 /*-----------------------------------------------------------------*/
-void geniCodeReturn (operand *op)
+void 
+geniCodeReturn (operand * op)
 {
 {
-    iCode *ic;
-    
-    /* if the operand is present force an rvalue */
-    if (op) 
-       op = geniCodeRValue(op,FALSE);    
-    
-    ic = newiCode(RETURN,op,NULL);
-    ADDTOCHAIN(ic);
+  iCode *ic;
+
+  /* if the operand is present force an rvalue */
+  if (op)
+    op = geniCodeRValue (op, FALSE);
+
+  ic = newiCode (RETURN, op, NULL);
+  ADDTOCHAIN (ic);
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeIfx - generates code for extended if statement          */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeIfx - generates code for extended if statement          */
 /*-----------------------------------------------------------------*/
-void geniCodeIfx (ast *tree)
+void 
+geniCodeIfx (ast * tree,int lvl)
 {
 {
-    iCode *ic;
-    operand *condition = ast2iCode(tree->left);
-    sym_link *cetype; 
-    
-    /* if condition is null then exit */
-    if (!condition)
-       goto exit ;
-    else
-       condition = geniCodeRValue(condition,FALSE);
-    
-    cetype = getSpec(operandType(condition));
-    /* if the condition is a literal */
-    if (IS_LITERAL(cetype)) {
-       if (floatFromVal(condition->operand.valOperand)) {
-           if (tree->trueLabel)
-               geniCodeGoto(tree->trueLabel);
-           else
-               assert(1);
+  iCode *ic;
+  operand *condition = ast2iCode (tree->left,lvl+1);
+  sym_link *cetype;
+
+  /* if condition is null then exit */
+  if (!condition)
+    goto exit;
+  else
+    condition = geniCodeRValue (condition, FALSE);
+
+  cetype = getSpec (operandType (condition));
+  /* if the condition is a literal */
+  if (IS_LITERAL (cetype))
+    {
+      if (floatFromVal (condition->operand.valOperand))
+       {
+         if (tree->trueLabel)
+           geniCodeGoto (tree->trueLabel);
+         else
+           assert (0);
        }
        }
-       else {
-           if (tree->falseLabel)
-               geniCodeGoto (tree->falseLabel);
-           else
-               assert(1);
+      else
+       {
+         if (tree->falseLabel)
+           geniCodeGoto (tree->falseLabel);
+         else
+           assert (0);
        }
        }
-       goto exit;
+      goto exit;
     }
     }
-    
-    if ( tree->trueLabel ) {
-       ic = newiCodeCondition(condition,
-                              tree->trueLabel,
-                              NULL );
-       ADDTOCHAIN(ic);
-       
-       if ( tree->falseLabel) 
-           geniCodeGoto(tree->falseLabel);     
+
+  if (tree->trueLabel)
+    {
+      ic = newiCodeCondition (condition,
+                             tree->trueLabel,
+                             NULL);
+      ADDTOCHAIN (ic);
+
+      if (tree->falseLabel)
+       geniCodeGoto (tree->falseLabel);
     }
     }
-    else {
-       ic = newiCodeCondition (condition,
-                               NULL,
-                               tree->falseLabel);
-       ADDTOCHAIN(ic);
+  else
+    {
+      ic = newiCodeCondition (condition,
+                             NULL,
+                             tree->falseLabel);
+      ADDTOCHAIN (ic);
     }
     }
-    
- exit:
-    ast2iCode(tree->right);
+
+exit:
+  ast2iCode (tree->right,lvl+1);
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeJumpTable - tries to create a jump table for switch     */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeJumpTable - tries to create a jump table for switch     */
 /*-----------------------------------------------------------------*/
-int geniCodeJumpTable (operand *cond, value *caseVals, ast *tree)
+int 
+geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
 {
 {
-    int min = 0 ,max = 0, t, cnt = 0;
-    value *vch;
-    iCode *ic;
-    operand *boundary;
-    symbol *falseLabel;
-    set *labels = NULL ;
+  int min = 0, max = 0, t, cnt = 0;
+  value *vch;
+  iCode *ic;
+  operand *boundary;
+  symbol *falseLabel;
+  set *labels = NULL;
 
 
-    if (!tree || !caseVals)
-       return 0;
+  if (!tree || !caseVals)
+    return 0;
 
 
-    /* the criteria for creating a jump table is */
-    /* 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",
-           tree->values.switchVals.swNum,
-           min);
-    addSet(&labels,newiTempLabel(buffer));
-
-    /* if there is only one case value then no need */
-    if (!(vch = vch->next ))
+  /* the criteria for creating a jump table is */
+  /* all integer numbers between the maximum & minimum must */
+  /* be present , the maximum value should not exceed 255 */
+  min = max = (int) floatFromVal (vch = caseVals);
+  SNPRINTF (buffer, sizeof(buffer), 
+           "_case_%d_%d",
+          tree->values.switchVals.swNum,
+          min);
+  addSet (&labels, newiTempLabel (buffer));
+
+  /* if there is only one case value then no need */
+  if (!(vch = vch->next))
+    return 0;
+
+  while (vch)
+    {
+      if (((t = (int) floatFromVal (vch)) - max) != 1)
        return 0;
        return 0;
+      SNPRINTF (buffer, sizeof(buffer), 
+               "_case_%d_%d",
+              tree->values.switchVals.swNum,
+              t);
+      addSet (&labels, newiTempLabel (buffer));
+      max = t;
+      cnt++;
+      vch = vch->next;
+    }
+
+  /* if the number of case statements <= 2 then */
+  /* it is not economical to create the jump table */
+  /* since two compares are needed for boundary conditions */
+  if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
+    return 0;
 
 
-    while (vch) {
-       if (((t = (int)floatFromVal(vch)) - max) != 1)
-           return 0;
-       sprintf(buffer,"_case_%d_%d",
-               tree->values.switchVals.swNum,
-               t);
-       addSet(&labels,newiTempLabel(buffer));
-       max = t;
-       cnt++ ;
-       vch = vch->next ;
+  if (tree->values.switchVals.swDefault)
+    {
+       SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
+    }
+  else
+    {
+       SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
     }
     
     }
     
-    /* if the number of case statements <= 2 then */
-    /* it is not economical to create the jump table */
-    /* since two compares are needed for boundary conditions */
-    if ((! optimize.noJTabBoundary  && cnt <= 2) || max > (255/3))
-       return 0;
-    
-    if ( tree->values.switchVals.swDefault )
-       sprintf (buffer,"_default_%d",tree->values.switchVals.swNum);
-    else
-       sprintf (buffer,"_swBrk_%d",tree->values.switchVals.swNum  );
-    
-    falseLabel = newiTempLabel (buffer);
-
-    /* so we can create a jumptable */
-    /* first we rule out the boundary conditions */
-    /* if only optimization says so */
-    if ( ! optimize.noJTabBoundary ) {
-       sym_link *cetype = getSpec(operandType(cond));
-       /* no need to check the lower bound if
-          the condition is unsigned & minimum value is zero */
-       if (!( min == 0  && SPEC_USIGN(cetype))) {
-           boundary = geniCodeLogic (cond,operandFromLit(min),'<');
-           ic = newiCodeCondition (boundary,falseLabel,NULL);
-           ADDTOCHAIN(ic);
+
+  falseLabel = newiTempLabel (buffer);
+
+  /* so we can create a jumptable */
+  /* first we rule out the boundary conditions */
+  /* if only optimization says so */
+  if (!optimize.noJTabBoundary)
+    {
+      sym_link *cetype = getSpec (operandType (cond));
+      /* no need to check the lower bound if
+         the condition is unsigned & minimum value is zero */
+      if (!(min == 0 && SPEC_USIGN (cetype)))
+       {
+         boundary = geniCodeLogic (cond, operandFromLit (min), '<');
+         ic = newiCodeCondition (boundary, falseLabel, NULL);
+         ADDTOCHAIN (ic);
        }
 
        }
 
-       /* now for upper bounds */
-       boundary = geniCodeLogic(cond,operandFromLit(max),'>');
-       ic = newiCodeCondition (boundary,falseLabel,NULL);
-       ADDTOCHAIN(ic);
+      /* now for upper bounds */
+      boundary = geniCodeLogic (cond, operandFromLit (max), '>');
+      ic = newiCodeCondition (boundary, falseLabel, NULL);
+      ADDTOCHAIN (ic);
     }
 
     }
 
-    /* if the min is not zero then we no make it zero */
-    if (min) {
-       cond = geniCodeSubtract(cond,operandFromLit(min));
-       setOperandType(cond, UCHARTYPE);
+  /* if the min is not zero then we no make it zero */
+  if (min)
+    {
+      cond = geniCodeSubtract (cond, operandFromLit (min));
+      setOperandType (cond, UCHARTYPE);
     }
 
     }
 
-    /* now create the jumptable */
-    ic = newiCode(JUMPTABLE,NULL,NULL);
-    IC_JTCOND(ic) = cond;
-    IC_JTLABELS(ic) = labels;
-    ADDTOCHAIN(ic);
-    return 1;       
+  /* now create the jumptable */
+  ic = newiCode (JUMPTABLE, NULL, NULL);
+  IC_JTCOND (ic) = cond;
+  IC_JTLABELS (ic) = labels;
+  ADDTOCHAIN (ic);
+  return 1;
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeSwitch - changes a switch to a if statement             */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* geniCodeSwitch - changes a switch to a if statement             */
 /*-----------------------------------------------------------------*/
-void geniCodeSwitch (ast *tree)
+void 
+geniCodeSwitch (ast * tree,int lvl)
 {
 {
-    iCode *ic ;
-    operand *cond = geniCodeRValue(ast2iCode (tree->left),FALSE);
-    value *caseVals = tree->values.switchVals.swVals ;
-    symbol *trueLabel , *falseLabel;
-    
-    /* if we can make this a jump table */
-    if ( geniCodeJumpTable (cond,caseVals,tree) )
-       goto jumpTable ; /* no need for the comparison */
+  iCode *ic;
+  operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
+  value *caseVals = tree->values.switchVals.swVals;
+  symbol *trueLabel, *falseLabel;
 
 
-    /* for the cases defined do */
-    while (caseVals) {
-       
-       operand *compare = geniCodeLogic (cond,
-                                         operandFromValue(caseVals),
-                                         EQ_OP);
-       
-       sprintf(buffer,"_case_%d_%d",
-               tree->values.switchVals.swNum,
-               (int) floatFromVal(caseVals));
-       trueLabel = newiTempLabel(buffer);
-       
-       ic = newiCodeCondition(compare,trueLabel,NULL);
-       ADDTOCHAIN(ic);
-       caseVals = caseVals->next;
+  /* if we can make this a jump table */
+  if (geniCodeJumpTable (cond, caseVals, tree))
+    goto jumpTable;            /* no need for the comparison */
+
+  /* for the cases defined do */
+  while (caseVals)
+    {
+
+      operand *compare = geniCodeLogic (cond,
+                                       operandFromValue (caseVals),
+                                       EQ_OP);
+
+      SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
+              tree->values.switchVals.swNum,
+              (int) floatFromVal (caseVals));
+      trueLabel = newiTempLabel (buffer);
+
+      ic = newiCodeCondition (compare, trueLabel, NULL);
+      ADDTOCHAIN (ic);
+      caseVals = caseVals->next;
     }
 
 
     }
 
 
-    
-    /* if default is present then goto break else break */
-    if ( tree->values.switchVals.swDefault )
-       sprintf (buffer,"_default_%d",tree->values.switchVals.swNum);
-    else
-       sprintf (buffer,"_swBrk_%d",tree->values.switchVals.swNum  );
-    
-    falseLabel = newiTempLabel (buffer);
-    geniCodeGoto(falseLabel);
- jumpTable:   
-    ast2iCode(tree->right);
-} 
+
+  /* if default is present then goto break else break */
+  if (tree->values.switchVals.swDefault)
+    {
+       SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
+    }
+  else
+    {
+       SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
+    }
+
+  falseLabel = newiTempLabel (buffer);
+  geniCodeGoto (falseLabel);
+
+jumpTable:
+  ast2iCode (tree->right,lvl+1);
+}
 
 /*-----------------------------------------------------------------*/
 /* geniCodeInline - intermediate code for inline assembler         */
 /*-----------------------------------------------------------------*/
 
 /*-----------------------------------------------------------------*/
 /* geniCodeInline - intermediate code for inline assembler         */
 /*-----------------------------------------------------------------*/
-static void geniCodeInline (ast *tree)
+static void 
+geniCodeInline (ast * tree)
 {
 {
-    iCode *ic;
+  iCode *ic;
 
 
-    ic = newiCode(INLINEASM,NULL,NULL);
-    IC_INLINE(ic) = tree->values.inlineasm;
-    ADDTOCHAIN(ic);
+  ic = newiCode (INLINEASM, NULL, NULL);
+  IC_INLINE (ic) = tree->values.inlineasm;
+  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                    */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* ast2iCode - creates an icodeList from an ast                    */
 /*-----------------------------------------------------------------*/
-operand *ast2iCode (ast *tree)
+operand *
+ast2iCode (ast * tree,int lvl)
 {
 {
-    operand *left = NULL;
-    operand *right= NULL;
-    
-    if (!tree)
-       return NULL ;
-    
-    /* set the global variables for filename & line number */
-    if ( tree->filename )
-       filename =  tree->filename ;
-    if ( tree->lineno)
-       lineno   = tree->lineno ;
-    if (tree->block)
-       block = tree->block ;
-    if (tree->level)
-       scopeLevel = tree->level;
-    
-    if (tree->type == EX_VALUE )
-       return operandFromValue(tree->opval.val);
-    
-    if (tree->type == EX_LINK )
-       return operandFromLink (tree->opval.lnk);
-    
-    /* if we find a nullop */
-    if (tree->type == EX_OP && 
-       ( tree->opval.op == NULLOP || 
-         tree->opval.op == BLOCK )) {
-       ast2iCode (tree->left);
-       ast2iCode (tree->right);
-       return NULL ;
-    }
-    
-    /* special cases for not evaluating */
-    if ( tree->opval.op != ':'   && 
-        tree->opval.op != '?'   &&
-        tree->opval.op != CALL  && 
-        tree->opval.op != IFX   &&
-        tree->opval.op != LABEL &&
-        tree->opval.op != GOTO  &&     
-        tree->opval.op != SWITCH &&
-        tree->opval.op != FUNCTION &&
-        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);
-       }
-    }
-    
-    /* now depending on the type of operand */
-    /* this will be a biggy                 */
-    switch (tree->opval.op) {
-       
-    case '[' :    /* array operation */
-       {
-           sym_link *ltype = operandType(left);
-           left= geniCodeRValue (left,IS_PTR(ltype->next) ? TRUE : FALSE);
-           right=geniCodeRValue (right,TRUE);             
+  operand *left = NULL;
+  operand *right = NULL;
+  if (!tree)
+    return NULL;
+
+  /* set the global variables for filename & line number */
+  if (tree->filename)
+    filename = tree->filename;
+  if (tree->lineno)
+    lineno = tree->lineno;
+  if (tree->block)
+    block = tree->block;
+  if (tree->level)
+    scopeLevel = tree->level;
+
+  if (tree->type == EX_VALUE)
+    return operandFromValue (tree->opval.val);
+
+  if (tree->type == EX_LINK)
+    return operandFromLink (tree->opval.lnk);
+
+  /* if we find a nullop */
+  if (tree->type == EX_OP &&
+     (tree->opval.op == NULLOP ||
+     tree->opval.op == BLOCK))
+    {
+      ast2iCode (tree->left,lvl+1);
+      ast2iCode (tree->right,lvl+1);
+      return NULL;
+    }
+
+  /* special cases for not evaluating */
+  if (tree->opval.op != ':' &&
+      tree->opval.op != '?' &&
+      tree->opval.op != CALL &&
+      tree->opval.op != IFX &&
+      tree->opval.op != LABEL &&
+      tree->opval.op != GOTO &&
+      tree->opval.op != SWITCH &&
+      tree->opval.op != FUNCTION &&
+      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)
+          {
+            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                 */
+  switch (tree->opval.op)
+    {
+
+    case '[':                  /* array operation */
+      {
+       //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,lvl);
+
+    case '.':                  /* structure dereference */
+      if (IS_PTR (operandType (left)))
+       left = geniCodeRValue (left, TRUE);
+      else
+       left = geniCodeRValue (left, FALSE);
+
+      return geniCodeStruct (left, right, tree->lvalue);
+
+    case PTR_OP:               /* structure pointer dereference */
+      {
+       sym_link *pType;
+       pType = operandType (left);
+       left = geniCodeRValue (left, TRUE);
+
+       setOClass (pType, getSpec (operandType (left)));
+      }
+
+      return geniCodeStruct (left, right, tree->lvalue);
+
+    case INC_OP:               /* increment operator */
+      if (left)
+       return geniCodePostInc (left);
+      else
+       return geniCodePreInc (right);
+
+    case DEC_OP:               /* decrement operator */
+      if (left)
+       return geniCodePostDec (left);
+      else
+       return geniCodePreDec (right);
+
+    case '&':                  /* bitwise and or address of operator */
+      if (right)
+       {                       /* this is a bitwise operator   */
+         left = geniCodeRValue (left, FALSE);
+         right = geniCodeRValue (right, FALSE);
+         return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
        }
        }
-       
-       return geniCodeArray (left,right);
-       
-    case '.' :   /* structure dereference */
-       if (IS_PTR(operandType(left)))
-           left = geniCodeRValue(left,TRUE);
-       else
-           left = geniCodeRValue(left,FALSE);            
-       
-       return geniCodeStruct (left,right,tree->lvalue);
-       
-    case PTR_OP: /* structure pointer dereference */
-       {
-           sym_link *pType;
-           pType = operandType(left);
-           left = geniCodeRValue(left,TRUE);
-           
-           setOClass (pType,getSpec(operandType(left)));
-       }              
-       
-       return geniCodeStruct (left, right,tree->lvalue);
-       
-    case INC_OP: /* increment operator */
-       if ( left )
-           return geniCodePostInc (left);
-       else
-           return geniCodePreInc (right);
-       
-    case DEC_OP: /* decrement operator */
-       if ( left )
-           return geniCodePostDec (left);
-       else
-           return geniCodePreDec (right);
-       
-    case '&' : /* bitwise and or address of operator */
-       if ( right ) { /* this is a bitwise operator   */
-           left= geniCodeRValue(left,FALSE);
-           right= geniCodeRValue(right,FALSE);     
-           return geniCodeBitwise (left,right,BITWISEAND,tree->ftype);
-       } else
-           return geniCodeAddressOf (left);
-       
-    case '|': /* bitwise or & xor */
+      else
+       return geniCodeAddressOf (left);
+
+    case '|':                  /* bitwise or & xor */
     case '^':
     case '^':
-       return geniCodeBitwise (geniCodeRValue(left,FALSE),
-                               geniCodeRValue(right,FALSE),
-                               tree->opval.op,
-                               tree->ftype);
-       
+      return geniCodeBitwise (geniCodeRValue (left, FALSE),
+                             geniCodeRValue (right, FALSE),
+                             tree->opval.op,
+                             tree->ftype);
+
     case '/':
     case '/':
-       return geniCodeDivision (geniCodeRValue(left,FALSE),
-                                geniCodeRValue(right,FALSE));
-       
-    case '%' :
-       return geniCodeModulus (geniCodeRValue(left,FALSE),
-                               geniCodeRValue(right,FALSE));
+      return geniCodeDivision (geniCodeRValue (left, FALSE),
+                              geniCodeRValue (right, FALSE));
+
+    case '%':
+      return geniCodeModulus (geniCodeRValue (left, FALSE),
+                             geniCodeRValue (right, FALSE));
     case '*':
     case '*':
-       if ( right ) 
-           return geniCodeMultiply (geniCodeRValue(left,FALSE),
-                                    geniCodeRValue(right,FALSE));
-       else        
-           return geniCodeDerefPtr (geniCodeRValue(left,FALSE));
-       
-    case '-' :
-       if ( right ) 
-           return geniCodeSubtract (geniCodeRValue(left,FALSE),
-                                    geniCodeRValue(right,FALSE));
-       else
-           return geniCodeUnaryMinus (geniCodeRValue(left,FALSE));
-       
-    case '+' :
-       if ( right ) 
-           return geniCodeAdd (geniCodeRValue(left,FALSE),
-                               geniCodeRValue(right,FALSE));
-       else
-           return geniCodeRValue(left,FALSE) ; /* unary '+' has no meaning */
-       
+      if (right)
+       return geniCodeMultiply (geniCodeRValue (left, FALSE),
+                                geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
+      else
+       return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
+
+    case '-':
+      if (right)
+       return geniCodeSubtract (geniCodeRValue (left, FALSE),
+                                geniCodeRValue (right, FALSE));
+      else
+       return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
+
+    case '+':
+      if (right)
+       return geniCodeAdd (geniCodeRValue (left, FALSE),
+                           geniCodeRValue (right, FALSE),lvl);
+      else
+       return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
+
     case LEFT_OP:
     case LEFT_OP:
-       return geniCodeLeftShift (geniCodeRValue(left,FALSE),
-                                 geniCodeRValue(right,FALSE));
-       
+      return geniCodeLeftShift (geniCodeRValue (left, FALSE),
+                               geniCodeRValue (right, FALSE));
+
     case RIGHT_OP:
     case RIGHT_OP:
-       return geniCodeRightShift (geniCodeRValue(left,FALSE),
-                                  geniCodeRValue(right,FALSE));
+      return geniCodeRightShift (geniCodeRValue (left, FALSE),
+                                geniCodeRValue (right, FALSE));
     case CAST:
     case CAST:
-       return geniCodeCast (operandType(left),
-                            geniCodeRValue(right,FALSE),FALSE);
-       
-    case '~' :
-    case '!' :
+      return geniCodeCast (operandType (left),
+                          geniCodeRValue (right, FALSE), FALSE);
+
+    case '~':
+    case '!':
     case RRC:
     case RRC:
-    case RLC:  
-       return geniCodeUnary (geniCodeRValue(left,FALSE),tree->opval.op);
-       
+    case RLC:
+      return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
+
     case GETHBIT:
     case GETHBIT:
-       {
-           operand *op = geniCodeUnary (geniCodeRValue(left,FALSE),tree->opval.op);
-           setOperandType(op, UCHARTYPE);
-           return op;
-       }
-    case '>' :
-    case '<' :
+      {
+       operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
+       setOperandType (op, UCHARTYPE);
+       return op;
+      }
+    case '>':
+    case '<':
     case LE_OP:
     case GE_OP:
     case EQ_OP:
     case NE_OP:
     case AND_OP:
     case OR_OP:
     case LE_OP:
     case GE_OP:
     case EQ_OP:
     case NE_OP:
     case AND_OP:
     case OR_OP:
-       return geniCodeLogic (geniCodeRValue(left,FALSE),
-                             geniCodeRValue(right,FALSE),
-                             tree->opval.op);
-    case '?' : 
-       return geniCodeConditional (tree); 
-       
+      return geniCodeLogic (geniCodeRValue (left, FALSE),
+                           geniCodeRValue (right, FALSE),
+                           tree->opval.op);
+    case '?':
+      return geniCodeConditional (tree,lvl);
+
     case SIZEOF:
     case SIZEOF:
-       return operandFromLit(getSize(tree->right->ftype));
-       
-    case '='        :
-       {
-           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 =  geniCodeRValue(right,TRUE);
-           else
-               right = geniCodeRValue(right,FALSE);
-
-           geniCodeAssign (left,right,0);
-           return right ;
-       }              
+      return operandFromLit (getSize (tree->right->ftype));
+
+    case '=':
+      {
+       sym_link *rtype = operandType (right);
+       sym_link *ltype = operandType (left);
+       if (IS_PTR (rtype) && IS_ITEMP (right)
+           && right->isaddr && compareType (rtype->next, ltype) == 1)
+         right = geniCodeRValue (right, TRUE);
+       else
+         right = geniCodeRValue (right, FALSE);
+
+       geniCodeAssign (left, right, 0);
+       return right;
+      }
     case MUL_ASSIGN:
     case MUL_ASSIGN:
-       return 
-           geniCodeAssign(left,
-                          geniCodeMultiply(geniCodeRValue (operandFromOperand(left),
-                                                           FALSE),
-                                           geniCodeRValue(right,FALSE)),0);
-                                               
+      return
+       geniCodeAssign (left,
+               geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
+                                                 FALSE),
+                                 geniCodeRValue (right, FALSE),FALSE), 0);
+
     case DIV_ASSIGN:
     case DIV_ASSIGN:
-       return 
-           geniCodeAssign(left,
-                          geniCodeDivision(geniCodeRValue(operandFromOperand(left),
-                                                          FALSE),
-                                           geniCodeRValue(right,FALSE)),0);
+      return
+       geniCodeAssign (left,
+               geniCodeDivision (geniCodeRValue (operandFromOperand (left),
+                                                 FALSE),
+                                 geniCodeRValue (right, FALSE)), 0);
     case MOD_ASSIGN:
     case MOD_ASSIGN:
-       return 
-           geniCodeAssign(left,
-                          geniCodeModulus(geniCodeRValue(operandFromOperand(left),
-                                                         FALSE),
-                                          geniCodeRValue(right,FALSE)),0);
-    case ADD_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 =  geniCodeRValue(right,TRUE);
-           else
-               right = geniCodeRValue(right,FALSE);
-
-          
-           return geniCodeAssign(left,
-                                 geniCodeAdd (geniCodeRValue(operandFromOperand(left),
-                                                             FALSE),
-                                              right),0);
-       }
+      return
+       geniCodeAssign (left,
+                geniCodeModulus (geniCodeRValue (operandFromOperand (left),
+                                                 FALSE),
+                                 geniCodeRValue (right, FALSE)), 0);
+    case ADD_ASSIGN:
+      {
+       sym_link *rtype = operandType (right);
+       sym_link *ltype = operandType (left);
+       if (IS_PTR (rtype) && IS_ITEMP (right)
+           && right->isaddr && compareType (rtype->next, ltype) == 1)
+         right = geniCodeRValue (right, TRUE);
+       else
+         right = geniCodeRValue (right, FALSE);
+
+
+       return geniCodeAssign (left,
+                    geniCodeAdd (geniCodeRValue (operandFromOperand (left),
+                                                 FALSE),
+                                 right,lvl), 0);
+      }
     case SUB_ASSIGN:
     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 =  geniCodeRValue(right,TRUE);
-           }
-           else {
-               right = geniCodeRValue(right,FALSE);
-           }
-           return 
-               geniCodeAssign (left,
-                               geniCodeSubtract(geniCodeRValue(operandFromOperand(left),
-                                                               FALSE),
-                                                right),0);
-       }
+      {
+       sym_link *rtype = operandType (right);
+       sym_link *ltype = operandType (left);
+       if (IS_PTR (rtype) && IS_ITEMP (right)
+           && right->isaddr && compareType (rtype->next, ltype) == 1)
+         {
+           right = geniCodeRValue (right, TRUE);
+         }
+       else
+         {
+           right = geniCodeRValue (right, FALSE);
+         }
+       return
+         geniCodeAssign (left,
+               geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
+                                                 FALSE),
+                                 right), 0);
+      }
     case LEFT_ASSIGN:
     case LEFT_ASSIGN:
-       return 
-           geniCodeAssign (left,
-                           geniCodeLeftShift(geniCodeRValue(operandFromOperand(left)
-                                                            ,FALSE),
-                                             geniCodeRValue(right,FALSE)),0);
+      return
+       geniCodeAssign (left,
+               geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
+                                                  ,FALSE),
+                                  geniCodeRValue (right, FALSE)), 0);
     case RIGHT_ASSIGN:
     case RIGHT_ASSIGN:
-       return 
-           geniCodeAssign(left,
-                          geniCodeRightShift(geniCodeRValue(operandFromOperand(left)
-                                                            ,FALSE),
-                                             geniCodeRValue(right,FALSE)),0);
+      return
+       geniCodeAssign (left,
+              geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
+                                                  ,FALSE),
+                                  geniCodeRValue (right, FALSE)), 0);
     case AND_ASSIGN:
     case AND_ASSIGN:
-       return 
-           geniCodeAssign (left,
-                           geniCodeBitwise(geniCodeRValue(operandFromOperand(left),
-                                                          FALSE),
-                                           geniCodeRValue(right,FALSE),
-                                           BITWISEAND,
-                                           operandType(left)),0);
+      return
+       geniCodeAssign (left,
+                geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
+                                                 FALSE),
+                                 geniCodeRValue (right, FALSE),
+                                 BITWISEAND,
+                                 operandType (left)), 0);
     case XOR_ASSIGN:
     case XOR_ASSIGN:
-       return 
-           geniCodeAssign (left,
-                           geniCodeBitwise (geniCodeRValue(operandFromOperand(left),
-                                                           FALSE),
-                                            geniCodeRValue(right,FALSE),
-                                            '^',
-                                            operandType(left)),0);
+      return
+       geniCodeAssign (left,
+                geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
+                                                 FALSE),
+                                 geniCodeRValue (right, FALSE),
+                                 '^',
+                                 operandType (left)), 0);
     case OR_ASSIGN:
     case OR_ASSIGN:
-       return 
-           geniCodeAssign (left,
-                           geniCodeBitwise (geniCodeRValue(operandFromOperand(left)
-                                                           ,FALSE),
-                                            geniCodeRValue(right,FALSE),
-                                            '|',
-                                            operandType(left)),0);
-    case ',' :
-       return geniCodeRValue(right,FALSE);
-       
+      return
+       geniCodeAssign (left,
+                 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
+                                                  ,FALSE),
+                                  geniCodeRValue (right, FALSE),
+                                  '|',
+                                  operandType (left)), 0);
+    case ',':
+      return geniCodeRValue (right, FALSE);
+
     case CALL:
     case CALL:
-       return geniCodeCall (ast2iCode(tree->left),
-                            tree->right);
+      return geniCodeCall (ast2iCode (tree->left,lvl+1),
+                          tree->right,lvl);
     case LABEL:
     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:
     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:
     case FUNCTION:
-       geniCodeFunctionBody ( tree );
-       return NULL ;
-       
+      geniCodeFunctionBody (tree,lvl);
+      return NULL;
+
     case RETURN:
     case RETURN:
-       geniCodeReturn (right);
-       return NULL ;
-       
+      geniCodeReturn (right);
+      return NULL;
+
     case IFX:
     case IFX:
-       geniCodeIfx (tree);
-       return NULL ;
-       
+      geniCodeIfx (tree,lvl);
+      return NULL;
+
     case SWITCH:
     case SWITCH:
-       geniCodeSwitch (tree);
-       return NULL;
+      geniCodeSwitch (tree,lvl);
+      return NULL;
 
     case INLINEASM:
 
     case INLINEASM:
-       geniCodeInline (tree);
-       return NULL ;
+      geniCodeInline (tree);
+      return NULL;
+       
+    case ARRAYINIT:
+       geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
+       return NULL;
     }
     }
-    
-    return NULL;
+
+  return NULL;
 }
 
 /*-----------------------------------------------------------------*/
 /* reverseICChain - gets from the list and creates a linkedlist    */
 /*-----------------------------------------------------------------*/
 }
 
 /*-----------------------------------------------------------------*/
 /* reverseICChain - gets from the list and creates a linkedlist    */
 /*-----------------------------------------------------------------*/
-iCode *reverseiCChain ()
+iCode *
+reverseiCChain ()
 {
 {
-    iCode *loop = NULL ;
-    iCode *prev = NULL ;
-    
-    while ((loop = getSet(&iCodeChain))) {
-       loop->next = prev ;
-       if ( prev )
-           prev->prev = loop; 
-       prev = loop ;
+  iCode *loop = NULL;
+  iCode *prev = NULL;
+
+  while ((loop = getSet (&iCodeChain)))
+    {
+      loop->next = prev;
+      if (prev)
+       prev->prev = loop;
+      prev = loop;
     }
     }
-    
-    return prev;
+
+  return prev;
 }
 
 
 /*-----------------------------------------------------------------*/
 /* iCodeFromAst - given an ast will convert it to iCode            */
 /*-----------------------------------------------------------------*/
 }
 
 
 /*-----------------------------------------------------------------*/
 /* iCodeFromAst - given an ast will convert it to iCode            */
 /*-----------------------------------------------------------------*/
-iCode *iCodeFromAst ( ast *tree )
+iCode *
+iCodeFromAst (ast * tree)
 {
 {
-    returnLabel = newiTempLabel("_return");
-    entryLabel  = newiTempLabel("_entry") ;
-    ast2iCode (tree);
-    return reverseiCChain ();
+  returnLabel = newiTempLabel ("_return");
+  entryLabel = newiTempLabel ("_entry");
+  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.
+}