work in progress
[fw/sdcc] / src / xa51 / gen.c
index 181c64e484d7bac534394fe0bbf547b3cac503f5..ec4e935630ec18396faf23eca82084672758172d 100755 (executable)
@@ -1,11 +1,3 @@
-/* The only ops for now are:
-   genAssign
-   genIfx
-   genAddrOf
-   genPointerSet
-   genPointerGet
-*/
-
 /*-------------------------------------------------------------------------
   SDCCgen51.c - source file for code generation for 8051
 
@@ -31,9 +23,6 @@
   You are forbidden to forbid anyone else to use, share and improve
   what you give them.   Help stamp out software-hoarding!
 
-  Notes:
-  000123 mlh  Moved aopLiteral to SDCCglue.c to help the split
-      Made everything static
 -------------------------------------------------------------------------*/
 
 //#define D(x)
@@ -85,7 +74,9 @@ static struct
   {
     short inLine;
     short debugLine;
+    short stackExtend;
     short nRegsSaved;
+    short parmsPushed;
     set *sendSet;
   }
 _G;
@@ -102,6 +93,16 @@ static lineNode *lineCurr = NULL;
 #define MSB24   2
 #define MSB32   3
 
+static char *MOV="mov";
+static char *MOVB="mov.b";
+static char *MOVW="mov.w";
+static char *MOVC="movc";
+static char *MOVCB="movc.b";
+static char *MOVCW="movc.w";
+
+static char *R1L="r1l";
+static char *R1="r1";
+
 void bailOut (char *mesg) {
   fprintf (stderr, "%s: bailing out\n", mesg);
   exit (1);
@@ -142,10 +143,8 @@ static void emitcode (char *inst, char *fmt,...) {
 
 char *getStackOffset(int stack) {
   static char gsoBuf[1024];
-  sprintf (gsoBuf, "r7%+d+0%+d%+d", stack,
-          FUNC_ISISR(currFunc->type) ? 
-            port->stack.isr_overhead : port->stack.call_overhead,
-          _G.nRegsSaved);
+  sprintf (gsoBuf, "r7+(%d%+d%+d)", stack,
+          currFunc->stack, _G.nRegsSaved);
   return gsoBuf;
 }
 
@@ -170,9 +169,10 @@ char *aopTypeName(asmop *aop) {
     case AOP_DIR: return "dir";
     case AOP_FAR: return "far";
     case AOP_CODE: return "code";
+    case AOP_GPTR: return "gptr";
     case AOP_STK: return "stack";
     case AOP_IMMD: return "imm";
-    case AOP_CRY: return "bit";
+    case AOP_BIT: return "bit";
     }
   return "unknown";
 }
@@ -180,7 +180,8 @@ char *aopTypeName(asmop *aop) {
 /*-----------------------------------------------------------------*/
 /* aopForSym - for a true symbol                                   */
 /*-----------------------------------------------------------------*/
-static asmop *aopForSym(symbol *sym, bool result) {
+static asmop *aopForSym(symbol *sym, 
+                       bool canUsePointer, bool canUseOffset) {
   int size;
   asmop *aop;
 
@@ -191,7 +192,7 @@ static asmop *aopForSym(symbol *sym, bool result) {
   if (sym->nRegs && sym->regs[0]) {
     aop->type=AOP_REG;
     sprintf (aop->name[0], sym->regs[0]->name);
-    if (size>2) {
+    if (size > 2) {
       sprintf (aop->name[1], sym->regs[1]->name);
     }
     return aop;
@@ -199,6 +200,32 @@ static asmop *aopForSym(symbol *sym, bool result) {
 
   // if it is on stack
   if (sym->onStack) {
+    if (!canUsePointer || !canUseOffset) {
+      aop->type=AOP_REG;
+      switch (size) 
+       {
+       case 1:
+         emitcode ("mov.b", "r0l,[%s]", getStackOffset(sym->stack));
+         sprintf (aop->name[0], "r0l");
+         return aop;
+       case 2:
+         emitcode ("mov.w", "r0,[%s]", getStackOffset(sym->stack));
+         sprintf (aop->name[0], "r0");
+         return aop;
+       case 3:
+         emitcode ("mov.w", "r0,[%s]", getStackOffset(sym->stack));
+         sprintf (aop->name[0], "r0");
+         emitcode ("mov.b", "r1l,[%s]", getStackOffset(sym->stack+2));
+         sprintf (aop->name[1], "r1l");
+         return aop;
+       case 4:
+         emitcode ("mov.w", "r0,[%s]", getStackOffset(sym->stack));
+         sprintf (aop->name[0], "r0");
+         emitcode ("mov.w", "r1,[%s]", getStackOffset(sym->stack+2));
+         sprintf (aop->name[1], "r1");
+         return aop;
+       }
+    }
     aop->type=AOP_STK;
     sprintf (aop->name[0], "[%s]", getStackOffset(sym->stack));
     if (size > 2) {
@@ -209,12 +236,12 @@ static asmop *aopForSym(symbol *sym, bool result) {
 
   // if it has a spillLoc
   if (sym->usl.spillLoc) {
-    return aopForSym (sym->usl.spillLoc, result);
+    return aopForSym (sym->usl.spillLoc, canUsePointer, canUseOffset);
   }
 
   // if in bit space
   if (IN_BITSPACE(SPEC_OCLS(sym->etype))) {
-    aop->type=AOP_CRY;
+    aop->type=AOP_BIT;
     sprintf (aop->name[0], sym->rname);
     return aop;
   }
@@ -224,36 +251,96 @@ static asmop *aopForSym(symbol *sym, bool result) {
     aop->type=AOP_DIR;
     sprintf (aop->name[0], sym->rname);
     if (size>2) {
-      sprintf (aop->name[0], "%s+2", sym->rname);
+      sprintf (aop->name[1], "%s+2", sym->rname);
     }
     return aop;
   }
 
   // if in code space
   if (IN_CODESPACE(SPEC_OCLS(sym->etype))) {
-    if (result) {
-      bailOut("aopForSym: result can not be in code space");
-    }
-    aop->type=AOP_CODE;
-    emitcode ("mov", "r0,#%s", sym->rname);
-    sprintf (aop->name[0], "[r0]");
-    if (size>2) {
-      sprintf (aop->name[1], "[r0+1]");
+    if (!canUsePointer) {
+      aop->type=AOP_REG;
+      switch (size) 
+       {
+       case 1:
+         emitcode (MOV, "r0,#%s", sym->rname);
+         emitcode (MOVC, "r0l,[r0]");
+         sprintf (aop->name[0], "r0l");
+         return aop;
+       case 2:
+         emitcode (MOV, "r0,#%s", sym->rname);
+         emitcode (MOVC, "r0,[r0]");
+         sprintf (aop->name[0], "r0");
+         return aop;
+       case 3:
+         emitcode (MOV, "r0,#%s", sym->rname);
+         emitcode (MOVC, "r1l,[r0+2]");
+         sprintf (aop->name[1], "r1l");
+         emitcode (MOV, "r0,[r0]");
+         sprintf (aop->name[0], "r0");
+         return aop;
+       case 4:
+         emitcode (MOV, "r0,#%s", sym->rname);
+         emitcode (MOVC, "r1,[r0+2]");
+         sprintf (aop->name[1], "r1");
+         emitcode (MOVC, "r0,[r0]");
+         sprintf (aop->name[0], "r0");
+         return aop;
+       }
+      
+    } else {
+      aop->type=AOP_CODE;
+      emitcode ("mov", "r0,#%s ; aopForSym:code", sym->rname);
+      sprintf (aop->name[0], "[r0]");
+      if (size>2) {
+       sprintf (aop->name[1], "[r0+2]");
+      }
     }
     return aop;
   }
 
   // if in far space
   if (IN_FARSPACE(SPEC_OCLS(sym->etype))) {
-    aop->type=AOP_FAR;
-    emitcode ("mov", "r0,#%s", sym->rname);
-    sprintf (aop->name[0], "[r0]");
-    if (size>2) {
-      sprintf (aop->name[1], "[r0+1]");
+    if (!canUsePointer) {
+      aop->type=AOP_REG;
+      switch (size) 
+       {
+       case 1:
+         emitcode (MOV, "r0,#%s", sym->rname);
+         emitcode (MOV, "r0l,[r0]");
+         sprintf (aop->name[0], "r0l");
+         return aop;
+       case 2:
+         emitcode (MOV, "r0,#%s", sym->rname);
+         emitcode (MOV, "r0,[r0]");
+         sprintf (aop->name[0], "r0");
+         return aop;
+       case 3:
+         emitcode (MOV, "r0,#%s", sym->rname);
+         emitcode (MOV, "r1l,[r0+2]");
+         sprintf (aop->name[1], "r1l");
+         emitcode (MOV, "r0,[r0]");
+         sprintf (aop->name[0], "r0");
+         return aop;
+       case 4:
+         emitcode (MOV, "r0,#%s", sym->rname);
+         emitcode (MOV, "r1,[r0+2]");
+         sprintf (aop->name[1], "r1");
+         emitcode (MOV, "r0,[r0]");
+         sprintf (aop->name[0], "r0");
+         return aop;
+       }
+    } else {
+      aop->type=AOP_FAR;
+      emitcode ("mov", "r0,#%s ; aopForSym:far", sym->rname);
+      sprintf (aop->name[0], "[r0]");
+      if (size>2) {
+       sprintf (aop->name[1], "[r0+2]");
+      }
+      return aop;
     }
-    return aop;
   }
-
+  
   bailOut("aopForSym");
   return NULL;
 }
@@ -263,21 +350,33 @@ static asmop *aopForSym(symbol *sym, bool result) {
 /*-----------------------------------------------------------------*/
 static asmop *aopForVal(operand *op) {
   asmop *aop;
-  long v=(long long)floatFromVal(OP_VALUE(op));
 
   if (IS_OP_LITERAL(op)) {
     op->aop = aop = newAsmop (AOP_LIT);
     switch ((aop->size=getSize(operandType(op))))
       {
       case 1:
-       sprintf (aop->name[0], "#0x%02lx", v);
+       sprintf (aop->name[0], "#0x%02x", 
+                SPEC_CVAL(operandType(op)).v_int & 0xff);
+       sprintf (aop->name[1], "#0");
        break;
       case 2:
-       sprintf (aop->name[0], "#0x%04lx", v);
+       sprintf (aop->name[0], "#0x%04x", 
+                SPEC_CVAL(operandType(op)).v_int & 0xffff);
+       sprintf (aop->name[1], "#0");
+       break;
+      case 3:
+       // must be a generic pointer, can only be zero
+       // ?? if (v!=0) fprintf (stderr, "invalid val op for gptr\n"); exit(1);
+       sprintf (aop->name[0], "#0x%04x", 
+                SPEC_CVAL(operandType(op)).v_uint & 0xffff);
+       sprintf (aop->name[1], "#0");
        break;
       case 4:
-       sprintf (aop->name[0], "#(0x%08lx >> 16)", v);
-       sprintf (aop->name[1], "#(0x%08lx & 0xffff)", v);
+       sprintf (aop->name[0], "#0x%04lx",
+                SPEC_CVAL(operandType(op)).v_ulong & 0xffff);
+       sprintf (aop->name[1], "#0x%04lx", 
+                SPEC_CVAL(operandType(op)).v_ulong >> 16);
        break;
       default:
        bailOut("aopForVal");
@@ -300,28 +399,53 @@ static asmop *aopForVal(operand *op) {
        return aop;
       }
   }
+
   bailOut ("aopForVal: unknown type");
   return NULL;
 }
 
-static void aopOp(operand *op, bool result) {
+static int aopOp(operand *op, 
+                 bool canUsePointer, bool canUseOffset) {
 
   if (IS_SYMOP(op)) {
-    op->aop=aopForSym (OP_SYMBOL(op), result);
-    return;
+    op->aop=aopForSym (OP_SYMBOL(op), canUsePointer, canUseOffset);
+    return AOP_SIZE(op);
   }
   if (IS_VALOP(op)) {
-    if (result) {
-      bailOut("aopOp: result can not be a value");
-    }
-    aopForVal (op);
-    return;
+    op->aop=aopForVal (op);
+    return AOP_SIZE(op);
   }
 
   bailOut("aopOp: unexpected operand");
+  return 0;
+}
+
+bool aopEqual(asmop *aop1, asmop *aop2, int offset) {
+  if (strcmp(aop1->name[offset], aop2->name[offset])) {
+    return FALSE;
+  }
+  return TRUE;
 }
 
-char *opRegName(operand *op, int offset, char *opName) {
+bool aopIsDir(operand *op) {
+  return AOP_TYPE(op)==AOP_DIR;
+}
+
+bool aopIsBit(operand *op) {
+  return AOP_TYPE(op)==AOP_BIT;
+}
+
+bool aopIsPtr(operand *op) {
+  if (AOP_TYPE(op)==AOP_STK ||
+      AOP_TYPE(op)==AOP_CODE ||
+      AOP_TYPE(op)==AOP_FAR) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+      
+char *opRegName(operand *op, int offset, char *opName, bool decorate) {
 
   if (IS_SYMOP(op)) {
     if (OP_SYMBOL(op)->onStack) {
@@ -346,17 +470,21 @@ char *opRegName(operand *op, int offset, char *opName) {
       }
       // fall through
     case V_CHAR:
-      sprintf (opName, "#0x%02x", SPEC_CVAL(OP_VALUE(op)->type).v_int);
+      sprintf (opName, "#%s0x%02x", decorate?"(char)":"", 
+              SPEC_CVAL(OP_VALUE(op)->type).v_int);
       break;
     case V_INT:
       if (SPEC_LONG(OP_VALUE(op)->type)) {
-       sprintf (opName, "#0x%02lx", SPEC_CVAL(OP_VALUE(op)->type).v_long);
+       sprintf (opName, "#%s0x%02lx", decorate?"(long)":"",
+                SPEC_CVAL(OP_VALUE(op)->type).v_long);
       } else {
-       sprintf (opName, "#0x%02x", SPEC_CVAL(OP_VALUE(op)->type).v_int);
+       sprintf (opName, "#%s0x%02x", decorate?"(int)":"",
+                SPEC_CVAL(OP_VALUE(op)->type).v_int);
       }
       break;
     case V_FLOAT:
-      sprintf (opName, "#%f", SPEC_CVAL(OP_VALUE(op)->type).v_float);
+      sprintf (opName, "#%s%f", decorate?"(float)":"",
+              SPEC_CVAL(OP_VALUE(op)->type).v_float);
       break;
     default: 
       bailOut("opRegName: unexpected noun");
@@ -409,6 +537,10 @@ char * printOp (operand *op) {
       sprintf (line+strlen(line), "stack%+d", sym->stack);
       return line;
     }
+    if (IN_CODESPACE(SPEC_OCLS(sym->etype))) {
+      strcat (line, "code");
+      return line;
+    }
     if (IN_FARSPACE(SPEC_OCLS(sym->etype))) {
       strcat (line, "far");
       return line;
@@ -424,9 +556,9 @@ char * printOp (operand *op) {
     strcat (line, "unknown");
     return line;
   } else if (IS_VALOP(op)) {
-    opRegName(op, 0, line);
+    opRegName(op, 0, line, 1);
   } else if (IS_TYPOP(op)) {
-    sprintf (line, "[");
+    sprintf (line, "(");
     if (isPtr) {
       if (DCL_TYPE(optype)==FPOINTER)
        strcat (line, "far * ");
@@ -443,7 +575,7 @@ char * printOp (operand *op) {
     if (SPEC_USIGN(operandType(op))) strcat (line, "unsigned ");
     if (SPEC_LONG(operandType(op))) strcat (line, "long ");
     strcat (line, nounName(operandType(op)));
-    strcat (line, "]");
+    strcat (line, ")");
   } else {
     bailOut("printOp: unexpected operand type");
   }
@@ -470,15 +602,20 @@ void printIc (char *op, iCode * ic, bool result, bool left, bool right) {
 }
 
 /*-----------------------------------------------------------------*/
-/* toBoolean - return bit for operand!=0                           */
+/* toBoolean - return carry for operand!=0                           */
 /*-----------------------------------------------------------------*/
 static char *toBoolean (operand * op) {
+  symbol *tlbl=newiTempLabel(NULL);
+
   switch (AOP_SIZE(op)) 
     {
     case 1:
     case 2:
-      emitcode ("cmp", "%s,#0", AOP_NAME(op));
-      return "z";
+      emitcode ("cjne", "%s,#1,%05d$; %s", AOP_NAME(op), tlbl->key+100,
+               "This needs a second thought");
+      
+      emitcode ("", "%05d$:", tlbl->key+100);
+      return "c";
     }
 
   bailOut("toBoolean: unknown size");
@@ -560,10 +697,51 @@ static void genUminus (iCode * ic) {
 }
 
 /*-----------------------------------------------------------------*/
-/* genIpush - genrate code for pushing this gets a little complex  */
+/* genIpush - generate code for pushing                            */
 /*-----------------------------------------------------------------*/
 static void genIpush (iCode * ic) {
+  operand *left=IC_LEFT(ic);
+
   printIc ("genIpush", ic, 0,1,0);
+  aopOp(left,FALSE,FALSE);
+
+
+  if (AOP_TYPE(left)==AOP_LIT) {
+    switch (AOP_SIZE(left)) 
+      {
+      case 1:
+       emitcode ("mov", "r1l,%s", AOP_NAME(left)[0]);
+       emitcode ("push", "r1l");
+       _G.parmsPushed++;
+       return;
+      case 2:
+       emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
+       emitcode ("push", "r1");
+       _G.parmsPushed++;
+       return;
+      case 3:
+       emitcode ("mov", "r1l,%s", AOP_NAME(left)[1]);
+       emitcode ("push", "r1l");
+       emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
+       emitcode ("push", "r1");
+       _G.parmsPushed += 2;
+       return;
+      case 4:
+       emitcode ("mov", "r1,%s", AOP_NAME(left)[1]);
+       emitcode ("push", "r1");
+       emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
+       emitcode ("push", "r1");
+       _G.parmsPushed += 2;
+       return;
+      }
+  } else {
+    if (AOP_SIZE(left)>2) {
+      emitcode ("push", "%s", AOP_NAME(left)[1]);
+      _G.parmsPushed++;
+    }
+    emitcode ("push", "%s", AOP_NAME(left)[0]);
+    _G.parmsPushed++;
+  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -577,8 +755,43 @@ static void genIpop (iCode * ic) {
 /* genCall - generates a call statement                            */
 /*-----------------------------------------------------------------*/
 static void genCall (iCode * ic) {
-  emitcode (";", "genCall %s result=%s", OP_SYMBOL(IC_LEFT(ic))->name,
+  operand *result=IC_RESULT(ic);
+
+  emitcode (";", "genCall(%d) %s result=%s", ic->lineno,
+           OP_SYMBOL(IC_LEFT(ic))->name,
            printOp (IC_RESULT(ic)));
+  emitcode ("call", "%s", OP_SYMBOL(IC_LEFT(ic))->rname);
+
+  /* readjust the stack if we have pushed some parms */
+  if (_G.parmsPushed) {
+    emitcode ("add", "r7,#0x%02x", _G.parmsPushed*2);
+    _G.parmsPushed=0;
+  }
+
+  /* if we need to assign a result value */
+  if (IS_ITEMP (IC_RESULT(ic)) &&
+      OP_SYMBOL (IC_RESULT (ic))->nRegs) {
+    aopOp(result,FALSE,FALSE);
+    switch (AOP_SIZE(result))
+      {
+      case 1:
+       emitcode ("mov", "%s,r0l", AOP_NAME(result)[0]);
+       return;
+      case 2:
+       emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
+       return;
+      case 3:
+       // generic pointer
+       emitcode ("mov", "%s,r1l", AOP_NAME(result)[1]);
+       emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
+       return;
+      case 4:
+       emitcode ("mov", "%s,r1", AOP_NAME(result)[1]);
+       emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
+       return;
+      }
+    bailOut("genCall");
+  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -597,10 +810,11 @@ static void genFunction (iCode * ic) {
   symbol *sym=OP_SYMBOL(IC_LEFT(ic));
   sym_link *type=sym->type;
 
-  emitcode (";", "-----------------------------------------");
-  emitcode (";", " function %s", sym->name);
-  emitcode (";", "-----------------------------------------");
-  
+  emitcode (";", "genFunction %s", sym->rname);
+
+  /* print the allocation information */
+  printAllocInfo (currFunc, codeOutFile);
+
   emitcode ("", "%s:", sym->rname);
 
   if (IFFUNC_ISNAKED(type))
@@ -609,10 +823,10 @@ static void genFunction (iCode * ic) {
       return;
   }
 
-  /* if critical function then turn interrupts off */
-  if (IFFUNC_ISCRITICAL (type))
-    emitcode ("clr", "ea");
-
+  /* adjust the stack for locals used in this function */
+  if (sym->stack) {
+    emitcode ("sub", "r7,#%d\t; create stack space for locals", sym->stack);
+  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -623,13 +837,23 @@ genEndFunction (iCode * ic)
 {
   symbol *sym = OP_SYMBOL (IC_LEFT (ic));
 
-  if (IFFUNC_ISNAKED(sym->type))
-  {
+  printIc ("genEndFunction", ic, 0,0,0);
+
+  if (IFFUNC_ISNAKED(sym->type)) {
       emitcode(";", "naked function: no epilogue.");
       return;
   }
 
-  printIc ("genEndFunction", ic, 0,0,0);
+  /* readjust the stock for locals used in this function */
+  if (sym->stack) {
+    emitcode ("add", "r7,#%d\t; release stack space for locals", sym->stack);
+  }
+
+  if (IFFUNC_ISISR(sym->type)) {
+    emitcode ("reti", "");
+  } else {
+    emitcode ("ret", "");
+  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -639,25 +863,27 @@ static void genRet (iCode * ic) {
 
   printIc ("genRet", ic, 0,1,0);
 
-  aopOp(IC_LEFT(ic),FALSE);
+  aopOp(IC_LEFT(ic), TRUE, TRUE);
 
   switch (AOP_SIZE(IC_LEFT(ic)))
     {
     case 4:
       emitcode ("mov", "r1,%s", AOP_NAME(IC_LEFT(ic))[1]);
       emitcode ("mov", "r0,%s", AOP_NAME(IC_LEFT(ic))[0]);
-      return;
+      break;
     case 3:
       emitcode ("mov", "r1l,%s", AOP_NAME(IC_LEFT(ic))[1]);
       // fall through
     case 2:
       emitcode ("mov", "r0,%s", AOP_NAME(IC_LEFT(ic))[0]);
-      return;
+      break;
     case 1:
       emitcode ("mov", "r0l,%s", AOP_NAME(IC_LEFT(ic))[0]);
-      return;
+      break;
+    default:
+      bailOut("genRet");
     }
-  bailOut("genRet");
+  emitcode ("jmp", "%05d$", returnLabel->key+100);
 }
 
 /*-----------------------------------------------------------------*/
@@ -668,23 +894,73 @@ static void genLabel (iCode * ic) {
   if (IC_LABEL (ic) == entryLabel)
     return;
 
-  emitcode (";", "genLabel %s", IC_LABEL(ic)->name);
+  emitcode (";", "genLabel(%d) %s", ic->lineno, IC_LABEL(ic)->name);
   emitcode ("", "%05d$:", (IC_LABEL (ic)->key + 100));
 }
 
 /*-----------------------------------------------------------------*/
-/* genGoto - generates a ljmp                                      */
+/* genGoto - generates a jmp                                      */
 /*-----------------------------------------------------------------*/
 static void genGoto (iCode * ic) {
-  emitcode (";", "genGoto %s", IC_LABEL(ic)->name);
-  emitcode ("ljmp", "%05d$", (IC_LABEL (ic)->key + 100));
+  emitcode (";", "genGoto(%d) %s", ic->lineno, IC_LABEL(ic)->name);
+  emitcode ("jmp", "%05d$", (IC_LABEL (ic)->key + 100));
 }
 
 /*-----------------------------------------------------------------*/
 /* genPlus - generates code for addition                           */
 /*-----------------------------------------------------------------*/
 static void genPlus (iCode * ic) {
+  operand *result=IC_RESULT(ic), *left=IC_LEFT(ic), *right=IC_RIGHT(ic);
+  int size;
+  char *instr;
+
   printIc ("genPlus", ic, 1,1,1);
+
+  size=aopOp(result, TRUE, TRUE);
+
+  /* if left is a literal, then exchange them */
+  if (IS_LITERAL(operandType(left))) {
+    operand *tmp = right;
+    right = left;
+    left = tmp;
+  }
+    
+  if (aopIsBit(result)) {
+    if (IS_LITERAL(operandType(right))) {
+      if (operandLitValue(right)) {
+       emitcode ("setb", AOP_NAME(result)[0]);
+       return;
+      }
+      aopOp(left, TRUE, TRUE);
+      emitcode ("mov", "%s,%s", AOP_NAME(result)[0], toBoolean(left));
+      return;
+    }
+    bailOut("genPlus: unfinished genPlus bit");
+  }
+  
+  aopOp(left, !aopIsPtr(result), !aopIsDir(result));
+  aopOp(right, !aopIsPtr(result), !aopIsDir(result));
+
+  if (size>1) {
+    instr="add.w";
+  } else {
+    instr="add.b";
+  }
+  if (!aopEqual(result->aop, left->aop, 0)) {
+    emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+  }
+  emitcode (instr, "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+  if (size>2) {
+    if (!aopEqual(result->aop, left->aop, 1)) {
+      emitcode ("mov", "%s,%s", AOP_NAME(result)[1], AOP_NAME(left)[1]);
+    }
+    if (size==3) {
+      // generic pointer
+    } else {
+      emitcode ("addc.w", "%s,%s", AOP_NAME(result)[1], AOP_NAME(right)[1]);
+    }
+  }
+  return;
 }
 
 /*-----------------------------------------------------------------*/
@@ -726,19 +1002,19 @@ static void genCmpGt (iCode * ic) {
 /* genCmpGt :- greater than comparison                             */
 /*-----------------------------------------------------------------*/
 static void genCmpLe (iCode * ic) {
-  printIc ("genCmpGt", ic, 1,1,1);
+  printIc ("genCmpLe", ic, 1,1,1);
 }
 /*-----------------------------------------------------------------*/
 /* genCmpGt :- greater than comparison                             */
 /*-----------------------------------------------------------------*/
 static void genCmpGe (iCode * ic) {
-  printIc ("genCmpGt", ic, 1,1,1);
+  printIc ("genCmpGe", ic, 1,1,1);
 }
 /*-----------------------------------------------------------------*/
 /* genCmpGt :- greater than comparison                             */
 /*-----------------------------------------------------------------*/
 static void genCmpNe (iCode * ic) {
-  printIc ("genCmpGt", ic, 1,1,1);
+  printIc ("genCmpNe", ic, 1,1,1);
 }
 /*-----------------------------------------------------------------*/
 /* genCmpLt - less than comparisons                                */
@@ -791,11 +1067,14 @@ static iCode *hasInc (operand *op, iCode *ic, int osize) {
 
   while (lic) {
     /* if operand of the form op = op + <sizeof *op> */
-    if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
-       isOperandEqual(IC_RESULT(lic),op) && 
-       isOperandLiteral(IC_RIGHT(lic)) &&
-       operandLitValue(IC_RIGHT(lic)) == isize) {
-      return lic;
+    if (lic->op == '+') {
+      if (isOperandEqual(IC_LEFT(lic),op) &&
+         //isOperandEqual(IC_RESULT(lic),op) && 
+         isOperandLiteral(IC_RIGHT(lic)) &&
+         operandLitValue(IC_RIGHT(lic)) == isize) {
+       emitcode (";", "Found hasInc");
+       return lic;
+      }
     }
     /* if the operand used or deffed */
     if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) {
@@ -833,7 +1112,52 @@ static void genAnd (iCode * ic, iCode * ifx) {
 /* genOr  - code for or                                            */
 /*-----------------------------------------------------------------*/
 static void genOr (iCode * ic, iCode * ifx) {
+  operand *result=IC_RESULT(ic), *left=IC_LEFT(ic), *right=IC_RIGHT(ic);
+  int size;
+  char *instr;
+
   printIc ("genOr", ic, 1,1,1);
+
+  size=aopOp(result, TRUE, TRUE);
+
+  /* if left is a literal, then exchange them */
+  if (IS_LITERAL(operandType(left))) {
+    operand *tmp = right;
+    right = left;
+    left = tmp;
+  }
+    
+  if (aopIsBit(result)) {
+    if (IS_LITERAL(operandType(right))) {
+      if (operandLitValue(right)) {
+       emitcode ("setb", AOP_NAME(result)[0]);
+       return;
+      }
+      aopOp(left, TRUE, TRUE);
+      emitcode ("mov", "%s,%s", AOP_NAME(result)[0], toBoolean(left));
+      return;
+    }
+  }
+  
+  aopOp(left, !aopIsPtr(result), !aopIsDir(result));
+  aopOp(right, !aopIsPtr(result), !aopIsDir(result));
+
+  if (size>1) {
+    instr="or.w";
+  } else {
+    instr="or.b";
+  }
+  if (!aopEqual(result->aop, left->aop, 0)) {
+    emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+  }
+  emitcode (instr, "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+  if (size>2) {
+    if (!aopEqual(result->aop, left->aop, 1)) {
+      emitcode ("mov", "%s,%s", AOP_NAME(result)[1], AOP_NAME(left)[1]);
+    }
+    emitcode (instr, "%s,%s", AOP_NAME(result)[1], AOP_NAME(right)[1]);
+  }
+  return;
 }
 
 /*-----------------------------------------------------------------*/
@@ -847,7 +1171,10 @@ static void genXor (iCode * ic, iCode * ifx) {
 /* genInline - write the inline code out                           */
 /*-----------------------------------------------------------------*/
 static void genInline (iCode * ic) {
+
   printIc ("genInline", ic, 0,0,0);
+  
+  emitcode ("", IC_INLINE(ic));
 }
 
 /*-----------------------------------------------------------------*/
@@ -889,9 +1216,10 @@ static void genRightShift (iCode * ic) {
 /* genPointerGet - generate code for pointer get                   */
 /*-----------------------------------------------------------------*/
 static void genPointerGet (iCode * ic, iCode *pi) {
-  char *instr="mov";
-
+  char *instr, *scratchReg;
   operand *result=IC_RESULT(ic), *left=IC_LEFT(ic);
+  bool codePointer=IS_CODEPTR(operandType(left));
+  int size;
 
   printIc ("genPointerGet", ic, 1,1,0);
 
@@ -899,56 +1227,123 @@ static void genPointerGet (iCode * ic, iCode *pi) {
     bailOut ("genPointerGet: pointer required");
   }
 
-  aopOp(left,FALSE);
-  aopOp(result,TRUE);
+  aopOp(left,FALSE,FALSE);
+  size=aopOp(result,TRUE,aopIsDir(left));
 
   if (IS_GENPTR(operandType(left))) {
-    emitcode ("INLINE", "_gptrget %s %s = [%s %s]", 
-             AOP_NAME(result)[0], AOP_NAME(result)[1],
-             AOP_NAME(left)[0], AOP_NAME(left)[1]);
+    symbol *tlbl1=newiTempLabel(NULL);
+    symbol *tlbl2=newiTempLabel(NULL);
+    emitcode ("cmp", "%s,#0x%02x", AOP_NAME(left)[1], CPOINTER);
+    emitcode ("bne", "%05d$", tlbl1->key+100);
+    // far/near pointer
+    if (pi) {
+      emitcode ("mov", "%s,[%s+]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+      pi->generated=1;
+    } else {
+      emitcode ("mov", "%s,[%s]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+    }
+    if (size>2) {
+      if (pi) {
+       emitcode ("mov", "%s,[%s+]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
+      } else {
+       emitcode ("mov", "%s,[%s+2]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
+      }
+    }
+    emitcode ("br", "%05d$", tlbl2->key+100);
+    emitcode ("", "%05d$:", tlbl1->key+100);
+    // code pointer
+    if (pi) {
+      emitcode ("movc", "%s,[%s+]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+      pi->generated=1;
+    } else {
+      emitcode ("mov", "r0,%s", AOP_NAME(left)[0]);
+      emitcode ("movc", "%s,[r0+]", AOP_NAME(result)[0]);
+    }
+    if (size>2) {
+      if (pi) {
+       emitcode ("movc", "%s,[%s+]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
+      } else {
+       emitcode ("movc", "%s,[r0+]", AOP_NAME(result)[1]);
+      }
+    }
+    emitcode ("", "%05d$:", tlbl2->key+100);
     return;
   }
 
   switch (AOP_TYPE(left)) 
     {
-    case AOP_CODE:
-      instr="movc";
-      // fall through
-    case AOP_FAR:
-      emitcode (instr, "%s,[%s]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
-      if (AOP_SIZE(result) > 2) {
-       emitcode (instr, "%s,[%s+2]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
-      }
-      return;
-    case AOP_DIR:
-      emitcode (instr, "%s,%s", AOP_NAME(result)[0], AOP_NAME(left)[0]);
-      if (AOP_SIZE(result) > 2) {
-       emitcode (instr, "%s,%s+2", AOP_NAME(result)[1], AOP_NAME(left)[0]);
-      }
-      return;
     case AOP_REG:
-      emitcode (instr, "%s,[%s]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
-      if (AOP_SIZE(result) > 2) {
-       emitcode (instr, "%s,[%s]", AOP_NAME(result)[1], AOP_NAME(left)[1]);
+      if (size>1) {
+       if (codePointer) {
+         instr=MOVCW;
+       } else {
+         instr=MOVW;
+       }
+       scratchReg=R1;
+      } else {
+       if (codePointer) {
+         instr=MOVCB;
+       } else {
+         instr=MOVB;
+       }
+       scratchReg=R1L;
       }
-      return;
-    case AOP_STK:
-      emitcode (instr, "%s,%s", AOP_NAME(result)[0], AOP_NAME(left)[0]);
-      if (AOP_SIZE(result) > 2) {
-       emitcode (instr, "%s,%s", AOP_NAME(result)[1], AOP_NAME(left)[1]);
+      if (AOP_TYPE(result)==AOP_STK) {
+       emitcode (MOV, "%s,[%s]", scratchReg, AOP_NAME(left)[0]);
+       emitcode (MOV, "%s,%s", AOP_NAME(result)[0], scratchReg);
+      } else {
+       if (pi) {
+         emitcode (instr, "%s,[%s+]", AOP_NAME(result)[0], 
+                   AOP_NAME(left)[0]);
+         pi->generated=1;
+       } else {
+         if (codePointer) {
+           emitcode (MOV, "r1,%s", AOP_NAME(left)[0]);
+           emitcode (instr, "%s,[r1+]", AOP_NAME(result)[0]);
+         } else {
+           emitcode (instr, "%s,[%s]", AOP_NAME(result)[0], 
+                     AOP_NAME(left)[0]);
+         }
+       }
+      }
+      if (size > 2) {
+       if (size==3) {
+         if (codePointer) {
+           instr=MOVCB;
+         } else {
+           instr=MOVB;
+         }
+         scratchReg=R1L;
+       }
+       if (AOP_TYPE(result)==AOP_STK) {
+         emitcode (MOV, "%s,[%s+2]", scratchReg, AOP_NAME(left)[0]);
+         emitcode (MOV, "%s,%s", AOP_NAME(result)[1], scratchReg);
+       } else {
+         if (pi) {
+           emitcode (instr, "%s,[%s+]", AOP_NAME(result)[1], 
+                     AOP_NAME(left)[0]);
+         } else {
+           if (codePointer) {
+             emitcode (instr, "%s,[r1]", AOP_NAME(result)[1]);
+           } else {
+             emitcode (instr, "%s,[%s+2]", AOP_NAME(result)[1], 
+                       AOP_NAME(left)[0]);
+           }
+         }
+       }
       }
       return;
     }
-  bailOut ("genPointerGet: unknown pointer");
+  bailOut ("genPointerGet");
 }
 
 /*-----------------------------------------------------------------*/
 /* genPointerSet - stores the value into a pointer location        */
 /*-----------------------------------------------------------------*/
 static void genPointerSet (iCode * ic, iCode *pi) {
-  char *instr="mov";
-
+  char *instr;
   operand *result=IC_RESULT(ic), *right=IC_RIGHT(ic);
+  int size;
 
   printIc ("genPointerSet", ic, 1,0,1);
 
@@ -956,49 +1351,64 @@ static void genPointerSet (iCode * ic, iCode *pi) {
     bailOut ("genPointerSet: pointer required");
   }
 
-  aopOp(right,FALSE);
-  aopOp(result,TRUE);
+  aopOp(result,FALSE,FALSE);
+  size=aopOp(right,FALSE, FALSE);
 
   if (IS_GENPTR(operandType(result))) {
-    emitcode ("INLINE", "_gptrset [%s %s]=  %s %s", 
+    emitcode (";", "INLINE\t_gptrset ; [%s %s] = %s %s", 
              AOP_NAME(result)[0], AOP_NAME(result)[1],
              AOP_NAME(right)[0], AOP_NAME(right)[1]);
     return;
   }
 
-  switch (AOP_TYPE(result)) 
+  switch (AOP_TYPE(right)) 
     {
-    case AOP_CODE:
-      instr="movc";
-      // fall through
+    case AOP_LIT:
     case AOP_REG:
-    case AOP_DIR:
-    case AOP_FAR:
-    case AOP_STK:
-      emitcode (instr, "[%s],%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
-      if (AOP_SIZE(result) > 2) {
-       emitcode (instr, "[%s],%s", AOP_NAME(result)[1], AOP_NAME(right)[1]);
+      if (size>1) {
+       instr=MOVW;
+      } else {
+       instr=MOVB;
+      }
+      if (pi) {
+       emitcode (instr, "[%s+],%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+       pi->generated=1;
+      } else {
+       emitcode (instr, "[%s],%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+      }
+      if (size > 2) {
+       if (size==3) {
+         instr=MOVB;
+       }
+       if (pi) {
+         emitcode (instr, "[%s+],%s", AOP_NAME(result)[0], 
+                   AOP_NAME(right)[1]);
+       } else {
+         emitcode (instr, "[%s+2],%s", AOP_NAME(result)[0], 
+                   AOP_NAME(right)[1]);
+       }
       }
       return;
-    case AOP_GPTR:
     }
-  bailOut ("genPointerSet: unknown pointer");
+  bailOut ("genPointerSet");
 }
 
 /*-----------------------------------------------------------------*/
 /* genIfx - generate code for Ifx statement                        */
 /*-----------------------------------------------------------------*/
 static void genIfx (iCode * ic, iCode * popIc) {
+  int size;
+  char *instr;
   bool trueOrFalse;
   symbol *jlbl, *tlbl;
   operand *cond=IC_COND(ic);
 
-  emitcode (";", "genIfx cond=%s trueLabel:%s falseLabel:%s", 
-           printOp(cond),
+  emitcode (";", "genIfx(%d) cond=%s trueLabel:%s falseLabel:%s", 
+           ic->lineno, printOp(cond),
            IC_TRUE(ic) ? IC_TRUE(ic)->name : "NULL",
            IC_FALSE(ic) ? IC_FALSE(ic)->name : "NULL");
 
-  aopOp(cond,FALSE);
+  size=aopOp(cond,TRUE,TRUE);
 
   if (IC_TRUE(ic)) {
     trueOrFalse=TRUE;
@@ -1010,8 +1420,8 @@ static void genIfx (iCode * ic, iCode * popIc) {
 
   switch (AOP_TYPE(cond) )
     {
-    case AOP_CRY:
-      emitcode (trueOrFalse ? "jb" : "jbc", "%s,%05d$", 
+    case AOP_BIT:
+      emitcode (trueOrFalse ? "jb" : "jnb", "%s,%05d$", 
                AOP_NAME(cond)[0], jlbl->key+100);
       return;
     case AOP_REG:
@@ -1019,11 +1429,20 @@ static void genIfx (iCode * ic, iCode * popIc) {
     case AOP_FAR:
     case AOP_STK:
       tlbl=newiTempLabel(NULL);
-      emitcode ("cmp", "%s,#0", AOP_NAME(cond)[0]);
+      if (size>1) {
+       instr="cmp.w";
+      } else {
+       instr="cmp.b";
+      }
+      emitcode (instr, "%s,#0", AOP_NAME(cond)[0]);
       emitcode (trueOrFalse ? "beq" : "bne", "%05d$", tlbl->key+100);
-      if (AOP_SIZE(cond) > 2) {
-       emitcode ("cmp", "%s,#0", AOP_NAME(cond)[1]);
-       emitcode (trueOrFalse ? "beq" : "bne", "%05d$", tlbl->key+100);
+      if (size > 2) {
+       if (size==3) {
+         // generic pointer, forget the generic part
+       } else {
+         emitcode (instr, "%s,#0", AOP_NAME(cond)[1]);
+         emitcode (trueOrFalse ? "beq" : "bne", "%05d$", tlbl->key+100);
+       }
       }
       emitcode ("jmp", "%05d$", jlbl->key+100);
       emitcode ("", "%05d$:", tlbl->key+100);
@@ -1036,19 +1455,19 @@ static void genIfx (iCode * ic, iCode * popIc) {
 /* genAddrOf - generates code for address of                       */
 /*-----------------------------------------------------------------*/
 static void genAddrOf (iCode * ic) {
+  int size;
   operand *left=IC_LEFT(ic);
 
   printIc ("genAddrOf", ic, 1,1,0);
 
-  aopOp (IC_RESULT(ic),TRUE);
+  size=aopOp (IC_RESULT(ic), FALSE, TRUE);
 
   if (isOperandOnStack(left)) {
-    aopOp (IC_LEFT(ic),FALSE);
     emitcode ("lea", "%s,%s", AOP_NAME(IC_RESULT(ic))[0],
-             AOP_NAME(IC_LEFT(ic))[0]);
-    if (AOP_SIZE(IC_RESULT(ic)) > 2) {
+             getStackOffset(OP_SYMBOL(left)->stack));
+    if (size > 2) {
       // this must be a generic pointer
-      emitcode ("mov", "%s,#0x01", AOP_NAME(IC_RESULT(ic))[1]);
+      emitcode ("mov", "%s,#0x%02x", AOP_NAME(IC_RESULT(ic))[1], FPOINTER);
     }
     return;
   }
@@ -1056,9 +1475,9 @@ static void genAddrOf (iCode * ic) {
   if (isOperandInDirSpace(left) ||
       isOperandInFarSpace(left) ||
       isOperandInCodeSpace(left)) {
-    emitcode ("mov", "%s,#%s", AOP_NAME(IC_RESULT(ic))[0],
-             OP_SYMBOL(left));
-    if (AOP_SIZE(IC_RESULT(ic)) > 2) {
+    emitcode ("mov.w", "%s,#%s", AOP_NAME(IC_RESULT(ic))[0],
+             OP_SYMBOL(left)->rname);
+    if (size > 2) {
       // this must be a generic pointer
       int space=0; // dir space
       if (isOperandInFarSpace(left)) {
@@ -1066,7 +1485,7 @@ static void genAddrOf (iCode * ic) {
       } else if (isOperandInCodeSpace(left)) {
        space=2;
       }
-      emitcode ("mov", "%s,#0x%02x", AOP_NAME(IC_RESULT(ic))[1], space);
+      emitcode ("mov.b", "%s,#0x%02x", AOP_NAME(IC_RESULT(ic))[1], space);
     }
     return;
   }
@@ -1079,6 +1498,8 @@ static void genAddrOf (iCode * ic) {
 /*-----------------------------------------------------------------*/
 static void genAssign (iCode * ic) {
   operand *result=IC_RESULT(ic), *right=IC_RIGHT(ic);
+  int size;
+  char *instr;
 
   printIc ("genAssign", ic, 1,0,1);
   
@@ -1086,26 +1507,12 @@ static void genAssign (iCode * ic) {
     bailOut("genAssign: result is not a symbol");
   }
   
-  aopOp(right, FALSE);
-  aopOp(result, TRUE);
-
-  if (result->aop->type==AOP_REG || 
-      right->aop->type==AOP_REG ||
-      right->aop->type==AOP_LIT ||
-      right->aop->type==AOP_STK ||
-      right->aop->type==AOP_IMMD) {
-    // everything will do
-  } else {
-    // they have to match
-    if (result->aop->type != right->aop->type) {
-      fprintf (stderr, "genAssign: types don't match (%s!=%s)\n",
-              aopTypeName(result->aop), aopTypeName(right->aop));
-      exit (1);
-    }
-  }
+  aopOp(result, TRUE, TRUE);
+  aopOp(right, !aopIsPtr(result), AOP_TYPE(result)!=AOP_DIR);
+  size=AOP_SIZE(result);
 
   /* if result is a bit */
-  if (AOP_TYPE(result) == AOP_CRY) {
+  if (AOP_TYPE(result) == AOP_BIT) {
     /* if right is literal, we know what the value is */
     if (AOP_TYPE(right) == AOP_LIT) {
       if (operandLitValue(right)) {
@@ -1116,24 +1523,32 @@ static void genAssign (iCode * ic) {
       return;
     }
     /* if right is also a bit */
-    if (AOP_TYPE(right) == AOP_CRY) {
+    if (AOP_TYPE(right) == AOP_BIT) {
       emitcode ("mov", "c,%s", AOP_NAME(right));
       emitcode ("mov", "%s,c", AOP_NAME(result));
       return;
     }
     /* we need to or */
-    emitcode ("mov", "%s,%s", AOP_NAME(result), toBoolean(right));
+    emitcode ("mov", "%s,%s; toBoolean", AOP_NAME(result), toBoolean(right));
     return;
   }
 
   /* general case */
-  emitcode ("mov", "%s,%s", 
-           result->aop->name[0], right->aop->name[0]);
-  if (AOP_SIZE(result) > 2) {
-    emitcode ("mov", "%s,%s",
-             result->aop->name[1], right->aop->name[1]);
+  if (size>1) {
+    instr=MOVW;
+  } else {
+    instr=MOVB;
+  }
+  emitcode (instr, "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+
+  if (size > 2) {
+    if (size==3) {
+      // generic pointer
+      instr=MOVB;
+    }
+    emitcode (instr, "%s,%s", AOP_NAME(result)[1], AOP_NAME(right)[1]);
+    return;
   }
-  
 }
 
 /*-----------------------------------------------------------------*/
@@ -1147,9 +1562,143 @@ static void genJumpTab (iCode * ic) {
 /* genCast - gen code for casting                                  */
 /*-----------------------------------------------------------------*/
 static void genCast (iCode * ic) {
+  int size;
+  operand *result=IC_RESULT(ic);
+  operand *right=IC_RIGHT(ic);
+  sym_link *ctype=operandType(IC_LEFT(ic));
+  sym_link *rtype=operandType(IC_RIGHT(ic));
+  sym_link *etype=getSpec(rtype);
+  short ptrType, signedness;
+
   printIc ("genCast", ic, 1,1,1);
+
+  aopOp(result, TRUE, TRUE);
+  aopOp(right, !aopIsPtr(result), AOP_TYPE(result)!=AOP_DIR);
+  size=AOP_SIZE(result);
+  
+  /* if result is a bit */
+  if (AOP_TYPE(result) == AOP_BIT) {
+    /* if right is literal, we know what the value is */
+    if (AOP_TYPE(right) == AOP_LIT) {
+      if (operandLitValue(right)) {
+       emitcode ("setb", AOP_NAME(result)[0]);
+      } else {
+       emitcode ("clr", AOP_NAME(result)[0]);
+      }
+      return;
+    }
+    /* if right is also a bit */
+    if (AOP_TYPE(right) == AOP_BIT) {
+      emitcode ("mov", "c,%s", AOP_NAME(right));
+      emitcode ("mov", "%s,c", AOP_NAME(result));
+      return;
+    }
+    /* we need to or */
+    emitcode ("mov", "%s,%s; toBoolean", AOP_NAME(result), toBoolean(right));
+    return;
+  }
+
+  /* if right is a bit */
+  if (AOP_TYPE(right)==AOP_BIT) {
+    emitcode ("mov", "c,%s", AOP_NAME(right));
+    emitcode ("mov", "%s,#0", AOP_NAME(result)[0]);
+    emitcode ("rlc", "%s,#1", AOP_NAME(result)[0]);
+    if (size>2) {
+      emitcode ("mov", "%s,#0", AOP_NAME(result)[1]);
+    }
+    return;
+  }
+
+  /* if the result is of type pointer */
+  if (IS_PTR (ctype)) {
+
+    if (AOP_SIZE(right)>1) {
+      emitcode ("mov", "%s,%s",  AOP_NAME(result)[0], AOP_NAME(right)[0]);
+    } else {
+      emitcode ("mov", "r1l,%s", AOP_NAME(right)[0]);
+      emitcode ("sext", "r1h");
+      emitcode ("mov", "%s,r1",  AOP_NAME(result)[0]);
+    }
+    
+    /* if pointer to generic pointer */
+    if (IS_GENPTR (ctype)) {
+            
+      if (IS_GENPTR (rtype)) {
+       bailOut("genCast: gptr -> gptr");
+      }
+
+      if (IS_PTR (rtype)) {
+       ptrType = DCL_TYPE (rtype);
+      } else {
+       /* we have to go by the storage class */
+       if (!SPEC_OCLS(etype)) {
+         bailOut("genCast: unknown storage class");
+       } else {
+         ptrType = PTR_TYPE (SPEC_OCLS (etype));
+       }
+      }
+      
+      /* the generic part depends on the type */
+      switch (ptrType)
+       {
+       case POINTER:
+         emitcode ("mov", "%s,#0x00", AOP_NAME(result)[1]);
+         break;
+       case FPOINTER:
+         emitcode ("mov", "%s,#0x01", AOP_NAME(result)[1]);
+         break;
+       case CPOINTER:
+         emitcode ("mov", "%s,#0x02", AOP_NAME(result)[1]);
+         break;
+       default:
+         bailOut("genCast: got unknown storage class");
+       }
+    }
+    return;
+  }
+
+  /* do we have to sign extend? */
+  signedness = SPEC_USIGN(rtype);
+
+  /* now depending on the size */
+  switch ((AOP_SIZE(result)<<4) + AOP_SIZE(right))
+    {
+    case 0x44:
+    case 0x33:
+      emitcode("mov", "%s,%s", AOP_NAME(result)[1], AOP_NAME(right)[1]);
+      // fall through
+    case 0x24:
+    case 0x22:
+    case 0x11:
+      emitcode("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+      return;
+    case 0x41:
+    case 0x21:
+      emitcode("mov", "r1l,%s", AOP_NAME(right)[0]);
+      if (signedness) {
+       emitcode("sext", "r1h");
+      } else {
+       emitcode("mov", "rlh,#0");
+      }
+      emitcode("mov", "%s,r1", AOP_NAME(result)[0]);
+      if (size==2)
+       return;
+      // fall through: case 0x41
+      emitcode("sext", AOP_NAME(result)[1]);
+      return;
+    case 14:
+    case 12:
+      emitcode("mov", "r1,%s", AOP_NAME(right)[0]);
+      emitcode("mov", "%s,r1l", AOP_NAME(result)[0]);
+      return;
+    case 24:
+      emitcode("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+      return;
+    }
+  bailOut("genCast: unknown size");
 }
 
+
 /*-----------------------------------------------------------------*/
 /* genDjnz - generate decrement & jump if not zero instrucion      */
 /*-----------------------------------------------------------------*/
@@ -1184,18 +1733,19 @@ static bool genDjnz (iCode * ic, iCode * ifx) {
   lbl = newiTempLabel (NULL);
   lbl1 = newiTempLabel (NULL);
 
-  aopOp (IC_RESULT (ic), TRUE);
+  aopOp (IC_RESULT (ic), FALSE, TRUE);
 
   if (AOP_TYPE(IC_RESULT(ic))==AOP_REG || AOP_TYPE(IC_RESULT(ic))==AOP_DIR) {
     emitcode ("djnz", "%s,%05d$", AOP_NAME(IC_RESULT(ic)), lbl->key+100);
-    emitcode ("bra", "%05d$", lbl1->key + 100);
+    emitcode ("br", "%05d$", lbl1->key + 100);
     emitcode ("", "%05d$:", lbl->key + 100);
     emitcode ("jmp", "%05d$", IC_TRUE (ifx)->key + 100);
     emitcode ("", "%05d$:", lbl1->key + 100);
     return TRUE;
   }
-    bailOut("genDjnz: aop type");
-    return FALSE;
+
+  bailOut("genDjnz: aop type");
+  return FALSE;
 }
 
 /*-----------------------------------------------------------------*/
@@ -1212,13 +1762,8 @@ void genXA51Code (iCode * lic) {
   iCode *ic;
   int cln = 0;
   
-  fprintf (stderr, "genXA51Code\n");
   lineHead = lineCurr = NULL;
   
-  /* print the allocation information */
-  if (allocInfo)
-    printAllocInfo (currFunc, codeOutFile);
-
   /* if debug information required */
   if (options.debug && currFunc)
     {
@@ -1232,7 +1777,7 @@ void genXA51Code (iCode * lic) {
     }
   
   for (ic = lic; ic; ic = ic->next) {
-    if (cln != ic->lineno) {
+    if (ic->lineno && cln != ic->lineno) {
       if (options.debug) {
        _G.debugLine = 1;
        emitcode ("", "C$%s$%d$%d$%d ==.",
@@ -1403,7 +1948,7 @@ void genXA51Code (iCode * lic) {
        break;
        
       case GET_VALUE_AT_ADDRESS:
-       genPointerGet (ic, hasInc(IC_LEFT(ic), ic, getSize(operandType(IC_LEFT(ic)))));
+       genPointerGet (ic, hasInc(IC_LEFT(ic), ic, getSize(operandType(IC_RESULT(ic)))));
        break;
        
       case '=':