*** empty log message ***
[fw/sdcc] / src / xa51 / gen.c
index 74f0947db8789e2193907fd299c81439e7fe1dc3..2ce675329ec7837f960900daa215d9692ad2c4c1 100755 (executable)
@@ -76,6 +76,7 @@ static struct
     short debugLine;
     short stackExtend;
     short nRegsSaved;
+    short parmsPushed;
     set *sendSet;
   }
 _G;
@@ -142,9 +143,7 @@ static void emitcode (char *inst, char *fmt,...) {
 
 char *getStackOffset(int stack) {
   static char gsoBuf[1024];
-  sprintf (gsoBuf, "r7+(%d%+d%+d%+d)", stack,
-          FUNC_ISISR(currFunc->type) ? 
-            port->stack.isr_overhead : port->stack.call_overhead,
+  sprintf (gsoBuf, "r7+(%d%+d%+d)", stack,
           currFunc->stack, _G.nRegsSaved);
   return gsoBuf;
 }
@@ -265,27 +264,28 @@ static asmop *aopForSym(symbol *sym,
        {
        case 1:
          emitcode (MOV, "r0,#%s", sym->rname);
-         emitcode (MOVC, "r0l,[r0]");
+         emitcode (MOVC, "r0l,[r0+]");
          sprintf (aop->name[0], "r0l");
          return aop;
        case 2:
          emitcode (MOV, "r0,#%s", sym->rname);
-         emitcode (MOVC, "r0,[r0]");
+         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");
+         emitcode (MOVC, "r0,[r0+]");
+         sprintf (aop->name[1], "r0");
+         emitcode (MOV, "r1l,[r0+]");
+         sprintf (aop->name[0], "r1l");
          return aop;
        case 4:
          emitcode (MOV, "r0,#%s", sym->rname);
-         emitcode (MOVC, "r1,[r0+2]");
-         sprintf (aop->name[1], "r1");
-         emitcode (MOVC, "r0,[r0]");
+         emitcode (MOVC, "r1,[r0+]");
+         emitcode (MOVC, "r0,[r0+]");
+         emitcode ("xch", "r0,r1");
          sprintf (aop->name[0], "r0");
+         sprintf (aop->name[1], "r1");
          return aop;
        }
       
@@ -333,7 +333,7 @@ static asmop *aopForSym(symbol *sym,
        }
     } else {
       aop->type=AOP_FAR;
-      emitcode ("mov", "r0,#%s ; aopForSym:far", sym->rname);
+      emitcode ("mov.w", "r0,#%s ; aopForSym:far", sym->rname);
       sprintf (aop->name[0], "[r0]");
       if (size>2) {
        sprintf (aop->name[1], "[r0+2]");
@@ -559,7 +559,7 @@ char * printOp (operand *op) {
   } else if (IS_VALOP(op)) {
     opRegName(op, 0, line, 1);
   } else if (IS_TYPOP(op)) {
-    sprintf (line, "[");
+    sprintf (line, "(");
     if (isPtr) {
       if (DCL_TYPE(optype)==FPOINTER)
        strcat (line, "far * ");
@@ -576,14 +576,15 @@ 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");
   }
   return line;
 }
 
-void printIc (char *op, iCode * ic, bool result, bool left, bool right) {
+void printIc (bool printToStderr, 
+             char *op, iCode * ic, bool result, bool left, bool right) {
   char line[132];
 
   sprintf (line, "%s(%d)", op, ic->lineno);
@@ -600,6 +601,9 @@ void printIc (char *op, iCode * ic, bool result, bool left, bool right) {
     strcat (line, printOp (IC_RIGHT(ic)));
   }
   emitcode (";", line);
+  if (printToStderr) {
+    fprintf (stderr, "%s\n", line);
+  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -680,21 +684,21 @@ static int resultRemat (iCode * ic) {
 /* genNot - generate code for ! operation                          */
 /*-----------------------------------------------------------------*/
 static void genNot (iCode * ic) {
-  printIc("genNot:", ic, 1,1,0);
+  printIc (0, "genNot:", ic, 1,1,0);
 }
 
 /*-----------------------------------------------------------------*/
 /* genCpl - generate code for complement                           */
 /*-----------------------------------------------------------------*/
 static void genCpl (iCode * ic) {
-  printIc("genCpl", ic, 1,1,0);
+  printIc (0, "genCpl", ic, 1,1,0);
 }
 
 /*-----------------------------------------------------------------*/
 /* genUminus - unary minus code generation                         */
 /*-----------------------------------------------------------------*/
 static void genUminus (iCode * ic) {
-  printIc("genUminus", ic, 1,1,0);
+  printIc (0, "genUminus", ic, 1,1,0);
 }
 
 /*-----------------------------------------------------------------*/
@@ -703,37 +707,45 @@ static void genUminus (iCode * ic) {
 static void genIpush (iCode * ic) {
   operand *left=IC_LEFT(ic);
 
-  printIc ("genIpush", ic, 0,1,0);
+  printIc (0, "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++;
   }
 }
 
@@ -741,7 +753,7 @@ static void genIpush (iCode * ic) {
 /* genIpop - recover the registers: can happen only for spilling   */
 /*-----------------------------------------------------------------*/
 static void genIpop (iCode * ic) {
-  printIc ("genIpop", ic, 0,1,0);
+  printIc (0, "genIpop", ic, 0,1,0);
 }
 
 /*-----------------------------------------------------------------*/
@@ -755,6 +767,12 @@ static void genCall (iCode * ic) {
            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) {
@@ -824,7 +842,7 @@ genEndFunction (iCode * ic)
 {
   symbol *sym = OP_SYMBOL (IC_LEFT (ic));
 
-  printIc ("genEndFunction", ic, 0,0,0);
+  printIc (0, "genEndFunction", ic, 0,0,0);
 
   if (IFFUNC_ISNAKED(sym->type)) {
       emitcode(";", "naked function: no epilogue.");
@@ -848,27 +866,32 @@ genEndFunction (iCode * ic)
 /*-----------------------------------------------------------------*/
 static void genRet (iCode * ic) {
 
-  printIc ("genRet", ic, 0,1,0);
-
-  aopOp(IC_LEFT(ic), TRUE, TRUE);
+  if (!IC_LEFT(ic)) {
+    printIc (0, "genRet", ic, 0, 0, 0);
+  } else {
+    printIc (0, "genRet", ic, 0, 1, 0);
+    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]);
+       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]);
+       break;
+      case 1:
+       emitcode ("mov", "r0l,%s", AOP_NAME(IC_LEFT(ic))[0]);
+       break;
+      default:
+       bailOut("genRet");
+      }
+  }
 
-  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;
-    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;
-    case 1:
-      emitcode ("mov", "r0l,%s", AOP_NAME(IC_LEFT(ic))[0]);
-      return;
-    }
-  bailOut("genRet");
+  emitcode ("jmp", "%05d$", returnLabel->key+100);
 }
 
 /*-----------------------------------------------------------------*/
@@ -879,7 +902,7 @@ 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));
 }
 
@@ -887,7 +910,7 @@ static void genLabel (iCode * ic) {
 /* genGoto - generates a jmp                                      */
 /*-----------------------------------------------------------------*/
 static void genGoto (iCode * ic) {
-  emitcode (";", "genGoto %s", IC_LABEL(ic)->name);
+  emitcode (";", "genGoto(%d) %s", ic->lineno, IC_LABEL(ic)->name);
   emitcode ("jmp", "%05d$", (IC_LABEL (ic)->key + 100));
 }
 
@@ -899,7 +922,7 @@ static void genPlus (iCode * ic) {
   int size;
   char *instr;
 
-  printIc ("genPlus", ic, 1,1,1);
+  printIc (0, "genPlus", ic, 1,1,1);
 
   size=aopOp(result, TRUE, TRUE);
 
@@ -926,6 +949,27 @@ static void genPlus (iCode * ic) {
   aopOp(left, !aopIsPtr(result), !aopIsDir(result));
   aopOp(right, !aopIsPtr(result), !aopIsDir(result));
 
+  // special case for * = * + char, needs a closer look
+  // heck, this shouldn't have come here but bug-223113 does
+  if (size==3 && AOP_SIZE(right)==1) {
+    emitcode ("mov", "r1l,%s", AOP_NAME(right)[0]);
+    emitcode ("mov", "r1h,#0"); // ptr arith unsigned????????????
+    emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+    emitcode ("add.w", "%s,r1", AOP_NAME(result)[0]);
+    emitcode ("mov", "%s,%s", AOP_NAME(result)[1], AOP_NAME(left)[1]);
+    return;
+  }
+
+  // special case for (whatever)* = (whatever)** + char, needs a closer look
+  // heck, this shouldn't have come here but bug-441448 does
+  if (size==2 && AOP_SIZE(right)==1) {
+    emitcode ("mov", "r1l,%s", AOP_NAME(right)[0]);
+    emitcode ("mov", "r1h,#0"); // ptr arith unsigned????????????
+    emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+    emitcode ("add.w", "%s,r1", AOP_NAME(result)[0]);
+    return;
+  }
+
   if (size>1) {
     instr="add.w";
   } else {
@@ -952,7 +996,7 @@ static void genPlus (iCode * ic) {
 /* genMinus - generates code for subtraction                       */
 /*-----------------------------------------------------------------*/
 static void genMinus (iCode * ic) {
-  printIc ("genMinus", ic, 1,1,1);
+  printIc (0, "genMinus", ic, 1,1,1);
 }
 
 
@@ -960,58 +1004,21 @@ static void genMinus (iCode * ic) {
 /* genMult - generates code for multiplication                     */
 /*-----------------------------------------------------------------*/
 static void genMult (iCode * ic) {
-  printIc ("genMult", ic, 1,1,1);
+  printIc (0, "genMult", ic, 1,1,1);
 }
 
 /*-----------------------------------------------------------------*/
 /* genDiv - generates code for division                            */
 /*-----------------------------------------------------------------*/
 static void genDiv (iCode * ic) {
-  printIc ("genDiv", ic, 1,1,1);
+  printIc (0, "genDiv", ic, 1,1,1);
 }
 
 /*-----------------------------------------------------------------*/
 /* genMod - generates code for division                            */
 /*-----------------------------------------------------------------*/
 static void genMod (iCode * ic) {
-  printIc ("genMod", ic, 1,1,1);
-}
-
-/*-----------------------------------------------------------------*/
-/* genCmpGt :- greater than comparison                             */
-/*-----------------------------------------------------------------*/
-static void genCmpGt (iCode * ic) {
-  printIc ("genCmpGt", ic, 1,1,1);
-}
-/*-----------------------------------------------------------------*/
-/* genCmpGt :- greater than comparison                             */
-/*-----------------------------------------------------------------*/
-static void genCmpLe (iCode * ic) {
-  printIc ("genCmpLe", ic, 1,1,1);
-}
-/*-----------------------------------------------------------------*/
-/* genCmpGt :- greater than comparison                             */
-/*-----------------------------------------------------------------*/
-static void genCmpGe (iCode * ic) {
-  printIc ("genCmpGe", ic, 1,1,1);
-}
-/*-----------------------------------------------------------------*/
-/* genCmpGt :- greater than comparison                             */
-/*-----------------------------------------------------------------*/
-static void genCmpNe (iCode * ic) {
-  printIc ("genCmpNe", ic, 1,1,1);
-}
-/*-----------------------------------------------------------------*/
-/* genCmpLt - less than comparisons                                */
-/*-----------------------------------------------------------------*/
-static void genCmpLt (iCode * ic) {
-  printIc ("genCmpLt", ic, 1,1,1);
-}
-/*-----------------------------------------------------------------*/
-/* genCmpEq - generates code for equal to                          */
-/*-----------------------------------------------------------------*/
-static void genCmpEq (iCode * ic) {
-  printIc ("genCmpEq", ic, 1,1,1);
+  printIc (0, "genMod", ic, 1,1,1);
 }
 
 /*-----------------------------------------------------------------*/
@@ -1034,6 +1041,80 @@ static iCode *ifxForOp (operand * op, iCode * ic) {
   return NULL;
 }
 
+/*-----------------------------------------------------------------*/
+/* genCmp - compares whatever                                      */
+/*-----------------------------------------------------------------*/
+static void genCmp (iCode * ic, char *trueInstr, char *falseInstr) {
+  iCode *ifx=ifxForOp(IC_RESULT(ic),ic);
+  operand *left=IC_LEFT(ic), *right=IC_RIGHT(ic);
+  int size;
+  bool isTrue;
+  char *instr;
+  int jlbl;
+
+  if (!ifx) {
+    bailOut("genCmp: no ifx");
+  } else {
+    ifx->generated=1;
+  }
+
+  size=aopOp(left, TRUE, TRUE);
+  aopOp(right, !aopIsPtr(left), TRUE);
+
+  if (IC_TRUE(ifx)) {
+    isTrue=TRUE;
+    jlbl=IC_TRUE(ifx)->key+100;
+  } else {
+    isTrue=FALSE;
+    jlbl=IC_FALSE(ifx)->key+100;
+  }
+
+  if (size==1) {
+    instr="cmp.b";
+  } else {
+    instr="cmp.w";
+  }
+  emitcode(instr, "%s,%s", AOP_NAME(left)[0], AOP_NAME(right)[0]);
+  emitcode(isTrue ? trueInstr : falseInstr, "%05d$", jlbl);
+  if (size>2) {
+    bailOut("genCmp: size > 2");
+  }
+}
+
+/*-----------------------------------------------------------------*/
+/* genCmpEq :- generates code for equal to                         */
+/*-----------------------------------------------------------------*/
+static void genCmpEq (iCode * ic) {
+  printIc (0, "genCmpEq", ic, 0,1,1);
+  genCmp(ic, "beq", "bne"); // no sign
+}
+
+/*-----------------------------------------------------------------*/
+/* genCmpGt :- greater than comparison                             */
+/*-----------------------------------------------------------------*/
+static void genCmpGt (iCode * ic) {
+  printIc (0, "genCmpGt", ic, 0,1,1);
+  if (SPEC_USIGN(operandType(IC_LEFT(ic))) ||
+      SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
+    genCmp(ic, "bg", "bl"); // unsigned
+  } else {
+    genCmp(ic, "bgt", "ble"); // signed
+  }
+}
+
+/*-----------------------------------------------------------------*/
+/* genCmpLt - less than comparisons                                */
+/*-----------------------------------------------------------------*/
+static void genCmpLt (iCode * ic) {
+  printIc (0, "genCmpLt", ic, 0,1,1);
+  if (SPEC_USIGN(operandType(IC_LEFT(ic))) ||
+      SPEC_USIGN(operandType(IC_RIGHT(ic)))) {
+    genCmp(ic, "bcs", "bcc"); // unsigned
+  } else {
+    genCmp(ic, "blt", "bge"); // signed
+  }
+}
+
 /*-----------------------------------------------------------------*/
 /* hasInc - operand is incremented before any other use            */
 /*-----------------------------------------------------------------*/
@@ -1076,21 +1157,21 @@ static iCode *hasInc (operand *op, iCode *ic, int osize) {
 /* genAndOp - for && operation                                     */
 /*-----------------------------------------------------------------*/
 static void genAndOp (iCode * ic) {
-  printIc ("genAndOp(&&)", ic, 1,1,1);
+  printIc (0, "genAndOp(&&)", ic, 1,1,1);
 }
 
 /*-----------------------------------------------------------------*/
 /* genOrOp - for || operation                                      */
 /*-----------------------------------------------------------------*/
 static void genOrOp (iCode * ic) {
-  printIc ("genOrOp(||)", ic, 1,1,1);
+  printIc (0, "genOrOp(||)", ic, 1,1,1);
 }
 
 /*-----------------------------------------------------------------*/
 /* genAnd  - code for and                                            */
 /*-----------------------------------------------------------------*/
 static void genAnd (iCode * ic, iCode * ifx) {
-  printIc ("genAnd", ic, 1,1,1);
+  printIc (0, "genAnd", ic, 1,1,1);
 }
 
 /*-----------------------------------------------------------------*/
@@ -1101,7 +1182,7 @@ static void genOr (iCode * ic, iCode * ifx) {
   int size;
   char *instr;
 
-  printIc ("genOr", ic, 1,1,1);
+  printIc (0, "genOr", ic, 1,1,1);
 
   size=aopOp(result, TRUE, TRUE);
 
@@ -1149,7 +1230,7 @@ static void genOr (iCode * ic, iCode * ifx) {
 /* genXor - code for xclusive or                                   */
 /*-----------------------------------------------------------------*/
 static void genXor (iCode * ic, iCode * ifx) {
-  printIc ("genXor", ic, 1,1,1);
+  printIc (0, "genXor", ic, 1,1,1);
 }
 
 /*-----------------------------------------------------------------*/
@@ -1157,7 +1238,7 @@ static void genXor (iCode * ic, iCode * ifx) {
 /*-----------------------------------------------------------------*/
 static void genInline (iCode * ic) {
 
-  printIc ("genInline", ic, 0,0,0);
+  printIc (0, "genInline", ic, 0,0,0);
   
   emitcode ("", IC_INLINE(ic));
 }
@@ -1166,35 +1247,35 @@ static void genInline (iCode * ic) {
 /* genRRC - rotate right with carry                                */
 /*-----------------------------------------------------------------*/
 static void genRRC (iCode * ic) {
-  printIc ("genRRC", ic, 1,1,0);
+  printIc (0, "genRRC", ic, 1,1,0);
 }
 
 /*-----------------------------------------------------------------*/
 /* genRLC - generate code for rotate left with carry               */
 /*-----------------------------------------------------------------*/
 static void genRLC (iCode * ic) {
-  printIc ("genRLC", ic, 1,1,0);
+  printIc (0, "genRLC", ic, 1,1,0);
 }
 
 /*-----------------------------------------------------------------*/
 /* genGetHbit - generates code get highest order bit               */
 /*-----------------------------------------------------------------*/
 static void genGetHbit (iCode * ic) {
-  printIc ("genGetHbit", ic, 1,1,0);
+  printIc (0, "genGetHbit", ic, 1,1,0);
 }
 
 /*-----------------------------------------------------------------*/
 /* genLeftShift - generates code for left shifting                 */
 /*-----------------------------------------------------------------*/
 static void genLeftShift (iCode * ic) {
-  printIc ("genLeftShift", ic, 1,1,1);
+  printIc (0, "genLeftShift", ic, 1,1,1);
 }
 
 /*-----------------------------------------------------------------*/
 /* genRightShift - generate code for right shifting                */
 /*-----------------------------------------------------------------*/
 static void genRightShift (iCode * ic) {
-  printIc ("genRightShift", ic, 1,1,1);
+  printIc (0, "genRightShift", ic, 1,1,1);
 }
 
 /*-----------------------------------------------------------------*/
@@ -1206,7 +1287,11 @@ static void genPointerGet (iCode * ic, iCode *pi) {
   bool codePointer=IS_CODEPTR(operandType(left));
   int size;
 
-  printIc ("genPointerGet", ic, 1,1,0);
+  if (pi) {
+    printIc (0, "genPointerGet pi", ic, 1,1,0);
+  } else {
+    printIc (0, "genPointerGet", ic, 1,1,0);
+  }
 
   if (!IS_PTR(operandType(left))) {
     bailOut ("genPointerGet: pointer required");
@@ -1219,7 +1304,7 @@ static void genPointerGet (iCode * ic, iCode *pi) {
     symbol *tlbl1=newiTempLabel(NULL);
     symbol *tlbl2=newiTempLabel(NULL);
     emitcode ("cmp", "%s,#0x%02x", AOP_NAME(left)[1], CPOINTER);
-    emitcode ("bne", "%05d$", tlbl1->key+100);
+    emitcode ("beq", "%05d$", tlbl1->key+100);
     // far/near pointer
     if (pi) {
       emitcode ("mov", "%s,[%s+]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
@@ -1257,6 +1342,10 @@ static void genPointerGet (iCode * ic, iCode *pi) {
 
   switch (AOP_TYPE(left)) 
     {
+    case AOP_LIT:
+      emitcode("mov","r1,%s", AOP_NAME(left)[0]);
+      sprintf (AOP_NAME(left)[0], "r1");
+      // fall through
     case AOP_REG:
       if (size>1) {
        if (codePointer) {
@@ -1330,7 +1419,7 @@ static void genPointerSet (iCode * ic, iCode *pi) {
   operand *result=IC_RESULT(ic), *right=IC_RIGHT(ic);
   int size;
 
-  printIc ("genPointerSet", ic, 1,0,1);
+  printIc (0, "genPointerSet", ic, 1,0,1);
 
   if (!IS_PTR(operandType(result))) {
     bailOut ("genPointerSet: pointer required");
@@ -1385,11 +1474,11 @@ static void genIfx (iCode * ic, iCode * popIc) {
   int size;
   char *instr;
   bool trueOrFalse;
-  symbol *jlbl, *tlbl;
+  symbol *jlbl, *tlbl=newiTempLabel(NULL);
   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");
 
@@ -1406,14 +1495,15 @@ static void genIfx (iCode * ic, iCode * popIc) {
   switch (AOP_TYPE(cond) )
     {
     case AOP_BIT:
-      emitcode (trueOrFalse ? "jb" : "jbc", "%s,%05d$", 
-               AOP_NAME(cond)[0], jlbl->key+100);
+      emitcode (trueOrFalse ? "jnb" : "jb", "%s,%05d$", 
+               AOP_NAME(cond)[0], tlbl->key+100);
+      emitcode ("jmp", "%05d$", jlbl->key+100);
+      emitcode ("", "%05d$:", tlbl->key+100);
       return;
     case AOP_REG:
     case AOP_DIR:
     case AOP_FAR:
     case AOP_STK:
-      tlbl=newiTempLabel(NULL);
       if (size>1) {
        instr="cmp.w";
       } else {
@@ -1443,7 +1533,7 @@ static void genAddrOf (iCode * ic) {
   int size;
   operand *left=IC_LEFT(ic);
 
-  printIc ("genAddrOf", ic, 1,1,0);
+  printIc (0, "genAddrOf", ic, 1,1,0);
 
   size=aopOp (IC_RESULT(ic), FALSE, TRUE);
 
@@ -1452,7 +1542,7 @@ static void genAddrOf (iCode * ic) {
              getStackOffset(OP_SYMBOL(left)->stack));
     if (size > 2) {
       // this must be a generic pointer
-      emitcode ("mov", "%s,#0x%02x", AOP_NAME(IC_RESULT(ic))[1], FPOINTER);
+      emitcode ("mov.b", "%s,#0x%02x", AOP_NAME(IC_RESULT(ic))[1], FPOINTER);
     }
     return;
   }
@@ -1486,7 +1576,7 @@ static void genAssign (iCode * ic) {
   int size;
   char *instr;
 
-  printIc ("genAssign", ic, 1,0,1);
+  printIc (0, "genAssign", ic, 1,0,1);
   
   if (!IS_SYMOP(result)) {
     bailOut("genAssign: result is not a symbol");
@@ -1518,6 +1608,7 @@ static void genAssign (iCode * ic) {
     return;
   }
 
+  // TODO: if (-8 >= right==lit <= 7) instr=MOVS
   /* general case */
   if (size>1) {
     instr=MOVW;
@@ -1540,16 +1631,163 @@ static void genAssign (iCode * ic) {
 /* genJumpTab - genrates code for jump table                       */
 /*-----------------------------------------------------------------*/
 static void genJumpTab (iCode * ic) {
-  printIc ("genJumpTab", ic, 0,0,0);
+  printIc (0, "genJumpTab", ic, 0,0,0);
 }
 
 /*-----------------------------------------------------------------*/
 /* genCast - gen code for casting                                  */
 /*-----------------------------------------------------------------*/
 static void genCast (iCode * ic) {
-  printIc ("genCast", ic, 1,1,1);
+  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 (0, "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)) {
+         ptrType=0; // hush the compiler
+         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.b", "%s,#0x00", AOP_NAME(result)[1]);
+         break;
+       case FPOINTER:
+         emitcode ("mov.b", "%s,#0x01", AOP_NAME(result)[1]);
+         break;
+       case CPOINTER:
+         emitcode ("mov.b", "%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 0x42:
+      emitcode("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+      if (signedness) {
+       emitcode("sext", "%s", AOP_NAME(result)[1]);
+      } else {
+       emitcode("mov", "%s,#0", AOP_NAME(result)[1]);
+      }
+      return;
+    case 0x41:
+    case 0x21:
+      emitcode("mov", "r1l,%s", AOP_NAME(right)[0]);
+      if (signedness) {
+       emitcode("sext", "r1h");
+      } else {
+       emitcode("mov", "r1h,#0");
+      }
+      emitcode("mov", "%s,r1", AOP_NAME(result)[0]);
+      if (size==2)
+       return;
+      // fall through: case 0x41
+      if (signedness) {
+       emitcode("sext", "r1");
+      } else {
+       emitcode("mov", "r1,#0");
+      }
+      emitcode("mov", "%s,r1", AOP_NAME(result)[1]);
+      return;
+    case 0x14:
+    case 0x12:
+      emitcode("mov", "r1,%s", AOP_NAME(right)[0]);
+      emitcode("mov", "%s,r1l", AOP_NAME(result)[0]);
+      return;
+    }
+  fprintf(stderr, "genCast: unknown size: %d:%d\n",
+         AOP_SIZE(result), AOP_SIZE(right));
+  bailOut("genCast: unknown size");
 }
 
+
 /*-----------------------------------------------------------------*/
 /* genDjnz - generate decrement & jump if not zero instrucion      */
 /*-----------------------------------------------------------------*/
@@ -1578,7 +1816,7 @@ static bool genDjnz (iCode * ic, iCode * ifx) {
   if (getSize (operandType (IC_RESULT (ic))) > 2)
     return 0;
 
-  printIc ("genDjnz", ic, 1,1,1);
+  printIc (0, "genDjnz", ic, 1,1,1);
 
   /* otherwise we can save BIG */
   lbl = newiTempLabel (NULL);
@@ -1603,7 +1841,7 @@ static bool genDjnz (iCode * ic, iCode * ifx) {
 /* genReceive - generate code for a receive iCode                  */
 /*-----------------------------------------------------------------*/
 static void genReceive (iCode * ic) {
-  printIc ("genReceive", ic, 1,0,0);
+  printIc (0, "genReceive", ic, 1,0,0);
 }
 
 /*-----------------------------------------------------------------*/
@@ -1739,15 +1977,13 @@ void genXA51Code (iCode * lic) {
        break;
        
       case LE_OP:
-       genCmpLe (ic);
-       break;
-
       case GE_OP:
-       genCmpGe (ic);
-       break;
-
       case NE_OP:
-       genCmpNe (ic);
+
+       /* note these two are xlated by algebraic equivalence
+          during parsing SDCC.y */
+       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+               "got '>=' or '<=' shouldn't have come here");
        break;
 
       case EQ_OP: