* sim/ucsim/cmd.src/cmdutil.cc: NUL device is detected as CG_FILE type
[fw/sdcc] / src / xa51 / gen.c
index 14190ca02e30dcf424a51dafe316d173493a20ca..bf86fa619ca685b20ae43a15d41d15e273f5019b 100755 (executable)
 #include "SDCCglobl.h"
 #include "newalloc.h"
 
-#ifdef HAVE_SYS_ISA_DEFS_H
-#include <sys/isa_defs.h>
-#else
-#ifdef HAVE_MACHINE_ENDIAN_H
-#include <machine/endian.h>
-#else
-#ifdef HAVE_ENDIAN_H
-#include <endian.h>
-#else
-#if !defined(__BORLANDC__) && !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__CYGWIN__)
-#warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
-#warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
-#endif
-#endif
-#endif
-#endif
-
 #include "common.h"
 #include "SDCCpeeph.h"
 #include "ralloc.h"
 #include "gen.h"
 
-#if defined(__BORLANDC__) || defined(_MSC_VER)
-#define STRCASECMP stricmp
-#else
-#define STRCASECMP strcasecmp
-#endif
-
 extern int allocInfo;
 
 /* this is the down and dirty file with all kinds of
@@ -83,7 +60,7 @@ _G;
 
 extern int xa51_ptrRegReq;
 extern int xa51_nRegs;
-extern FILE *codeOutFile;
+extern struct dbuf_s *codeOutBuf;
 
 static lineNode *lineHead = NULL;
 static lineNode *lineCurr = NULL;
@@ -129,7 +106,7 @@ static void emitcode (char *inst, char *fmt,...) {
   else
     vsprintf (lb, fmt, ap);
 
-  while (isspace ((int)*lbp))
+  while (isspace (*lbp))
     lbp++;
 
   if (lbp && *lbp)
@@ -141,6 +118,19 @@ static void emitcode (char *inst, char *fmt,...) {
   va_end (ap);
 }
 
+/*-----------------------------------------------------------------*/
+/* xa51_emitDebuggerSymbol - associate the current code location  */
+/*   with a debugger symbol                                        */
+/*-----------------------------------------------------------------*/
+void
+xa51_emitDebuggerSymbol (char * debugSym)
+{
+  _G.debugLine = 1;
+  emitcode ("", "%s ==.", debugSym);
+  _G.debugLine = 0;
+}
+
+
 char *getStackOffset(int stack) {
   static char gsoBuf[1024];
   sprintf (gsoBuf, "r7+(%d%+d%+d)", stack,
@@ -205,23 +195,23 @@ static asmop *aopForSym(symbol *sym,
       switch (size) 
        {
        case 1:
-         emitcode ("mov.b", "r0l,[%s]", getStackOffset(sym->stack));
+         emitcode ("mov.b", "r0l,[%s] ;aopForSym:stack:1", getStackOffset(sym->stack));
          sprintf (aop->name[0], "r0l");
          return aop;
        case 2:
-         emitcode ("mov.w", "r0,[%s]", getStackOffset(sym->stack));
+         emitcode ("mov.w", "r0,[%s] ;aopForSym:stack:2", getStackOffset(sym->stack));
          sprintf (aop->name[0], "r0");
          return aop;
        case 3:
-         emitcode ("mov.w", "r0,[%s]", getStackOffset(sym->stack));
+         emitcode ("mov.w", "r0,[%s] ;aopForSym:stack:3.w", getStackOffset(sym->stack));
          sprintf (aop->name[0], "r0");
-         emitcode ("mov.b", "r1l,[%s]", getStackOffset(sym->stack+2));
+         emitcode ("mov.b", "r1l,[%s] ;aopForSym:stack:3.b", getStackOffset(sym->stack+2));
          sprintf (aop->name[1], "r1l");
          return aop;
        case 4:
-         emitcode ("mov.w", "r0,[%s]", getStackOffset(sym->stack));
+         emitcode ("mov.w", "r0,[%s] ;aopForSym:stack:4", getStackOffset(sym->stack));
          sprintf (aop->name[0], "r0");
-         emitcode ("mov.w", "r1,[%s]", getStackOffset(sym->stack+2));
+         emitcode ("mov.w", "r1,[%s] ;aopForSym:stack:4", getStackOffset(sym->stack+2));
          sprintf (aop->name[1], "r1");
          return aop;
        }
@@ -264,27 +254,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;
        }
       
@@ -373,9 +364,9 @@ static asmop *aopForVal(operand *op) {
        sprintf (aop->name[1], "#0");
        break;
       case 4:
-       sprintf (aop->name[0], "#0x%04lx",
+       sprintf (aop->name[0], "#0x%04x",
                 SPEC_CVAL(operandType(op)).v_ulong & 0xffff);
-       sprintf (aop->name[1], "#0x%04lx", 
+       sprintf (aop->name[1], "#0x%04x", 
                 SPEC_CVAL(operandType(op)).v_ulong >> 16);
        break;
       default:
@@ -475,7 +466,7 @@ char *opRegName(operand *op, int offset, char *opName, bool decorate) {
       break;
     case V_INT:
       if (SPEC_LONG(OP_VALUE(op)->type)) {
-       sprintf (opName, "#%s0x%02lx", decorate?"(long)":"",
+       sprintf (opName, "#%s0x%02x", decorate?"(long)":"",
                 SPEC_CVAL(OP_VALUE(op)->type).v_long);
       } else {
        sprintf (opName, "#%s0x%02x", decorate?"(int)":"",
@@ -582,7 +573,8 @@ char * printOp (operand *op) {
   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);
@@ -599,6 +591,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);
+  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -679,21 +674,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);
 }
 
 /*-----------------------------------------------------------------*/
@@ -702,7 +697,7 @@ 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);
 
 
@@ -748,7 +743,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);
 }
 
 /*-----------------------------------------------------------------*/
@@ -813,7 +808,7 @@ static void genFunction (iCode * ic) {
   emitcode (";", "genFunction %s", sym->rname);
 
   /* print the allocation information */
-  printAllocInfo (currFunc, codeOutFile);
+  printAllocInfo (currFunc, codeOutBuf);
 
   emitcode ("", "%s:", sym->rname);
 
@@ -837,10 +832,12 @@ 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.");
+      if (options.debug && currFunc)
+       debugFile->writeEndFunction (currFunc, ic, 0);
       return;
   }
 
@@ -849,6 +846,10 @@ genEndFunction (iCode * ic)
     emitcode ("add", "r7,#%d\t; release stack space for locals", sym->stack);
   }
 
+  if (options.debug && currFunc) {
+    debugFile->writeEndFunction (currFunc, ic, 1);
+  }
+
   if (IFFUNC_ISISR(sym->type)) {
     emitcode ("reti", "");
   } else {
@@ -861,28 +862,31 @@ 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]);
-      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");
-    }
   emitcode ("jmp", "%05d$", returnLabel->key+100);
 }
 
@@ -914,7 +918,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);
 
@@ -941,6 +945,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 "xdata * = xdata * + 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 {
@@ -967,66 +992,82 @@ static void genPlus (iCode * ic) {
 /* genMinus - generates code for subtraction                       */
 /*-----------------------------------------------------------------*/
 static void genMinus (iCode * ic) {
-  printIc ("genMinus", ic, 1,1,1);
-}
+  operand *result=IC_RESULT(ic), *left=IC_LEFT(ic), *right=IC_RIGHT(ic);
+  int size;
+  char *instr;
+
+  printIc (0, "genMinus", 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 ("clr", 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");
+  }
+  
+  if (isOperandEqual(result,left)) {
+    left->aop=result->aop;
+  } else {
+    aopOp(left, !aopIsPtr(result), !aopIsDir(result));
+  }
+  aopOp(right, !aopIsPtr(result), !aopIsDir(result));
+
+  if (size>1) {
+    instr="sub.w";
+  } else {
+    instr="sub.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 ("subb.w", "%s,%s", AOP_NAME(result)[1], AOP_NAME(right)[1]);
+    }
+  }
+  return;
+}
 
 /*-----------------------------------------------------------------*/
 /* 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);
 }
 
 /*-----------------------------------------------------------------*/
@@ -1049,6 +1090,89 @@ 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;
+
+
+  size=aopOp(left, TRUE, TRUE);
+  aopOp(right, !aopIsPtr(left), TRUE);
+
+  if (size==1) {
+    instr="cmp.b";
+  } else {
+    instr="cmp.w";
+  }
+
+  if (IC_TRUE(ifx)) {
+    isTrue=TRUE;
+    jlbl=IC_TRUE(ifx)->key+100;
+  } else {
+    isTrue=FALSE;
+    jlbl=IC_FALSE(ifx)->key+100;
+  }
+  
+  if (!ifx) {
+    aopOp(IC_RESULT(ic), !aopIsPtr(left), TRUE);
+    jlbl=newiTempLabel(NULL)->key+100;
+    emitcode("mov", "%s,#-1", AOP_NAME(IC_RESULT(ic))[0]);
+    emitcode(instr, "%s,%s", AOP_NAME(left)[0], AOP_NAME(right)[0]);
+    emitcode(isTrue ? trueInstr : falseInstr, "%05d$", jlbl);
+    emitcode("cpl", "%s", AOP_NAME(IC_RESULT(ic))[0]);
+    emitcode("", "%05d$:", jlbl);
+  } else {
+    emitcode(instr, "%s,%s", AOP_NAME(left)[0], AOP_NAME(right)[0]);
+    emitcode(isTrue ? trueInstr : falseInstr, "%05d$", jlbl);
+    ifx->generated=1;
+  }
+
+  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            */
 /*-----------------------------------------------------------------*/
@@ -1077,7 +1201,7 @@ static iCode *hasInc (operand *op, iCode *ic, int osize) {
       }
     }
     /* if the operand used or deffed */
-    if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) {
+    if (bitVectBitValue(OP_USES(op),lic->key) || lic->defKey == op->key) {
       return NULL;
     }
     /* if GOTO or IFX */
@@ -1091,21 +1215,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);
 }
 
 /*-----------------------------------------------------------------*/
@@ -1116,7 +1240,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);
 
@@ -1164,7 +1288,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);
 }
 
 /*-----------------------------------------------------------------*/
@@ -1172,7 +1296,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));
 }
@@ -1181,35 +1305,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);
 }
 
 /*-----------------------------------------------------------------*/
@@ -1222,9 +1346,9 @@ static void genPointerGet (iCode * ic, iCode *pi) {
   int size;
 
   if (pi) {
-    printIc ("genPointerGet pi", ic, 1,1,0);
+    printIc (0, "genPointerGet pi", ic, 1,1,0);
   } else {
-    printIc ("genPointerGet", ic, 1,1,0);
+    printIc (0, "genPointerGet", ic, 1,1,0);
   }
 
   if (!IS_PTR(operandType(left))) {
@@ -1276,6 +1400,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) {
@@ -1349,7 +1477,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");
@@ -1463,7 +1591,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);
 
@@ -1472,7 +1600,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;
   }
@@ -1506,7 +1634,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");
@@ -1538,6 +1666,7 @@ static void genAssign (iCode * ic) {
     return;
   }
 
+  // TODO: if (-8 >= right==lit <= 7) instr=MOVS
   /* general case */
   if (size>1) {
     instr=MOVW;
@@ -1560,7 +1689,7 @@ 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);
 }
 
 /*-----------------------------------------------------------------*/
@@ -1575,7 +1704,7 @@ static void genCast (iCode * ic) {
   sym_link *etype=getSpec(rtype);
   short ptrType, signedness;
 
-  printIc ("genCast", ic, 1,1,1);
+  printIc (0, "genCast", ic, 1,1,1);
 
   aopOp(result, TRUE, TRUE);
   aopOp(right, !aopIsPtr(result), AOP_TYPE(result)!=AOP_DIR);
@@ -1648,13 +1777,13 @@ static void genCast (iCode * ic) {
       switch (ptrType)
        {
        case POINTER:
-         emitcode ("mov", "%s,#0x00", AOP_NAME(result)[1]);
+         emitcode ("mov.b", "%s,#0x00", AOP_NAME(result)[1]);
          break;
        case FPOINTER:
-         emitcode ("mov", "%s,#0x01", AOP_NAME(result)[1]);
+         emitcode ("mov.b", "%s,#0x01", AOP_NAME(result)[1]);
          break;
        case CPOINTER:
-         emitcode ("mov", "%s,#0x02", AOP_NAME(result)[1]);
+         emitcode ("mov.b", "%s,#0x02", AOP_NAME(result)[1]);
          break;
        default:
          bailOut("genCast: got unknown storage class");
@@ -1698,7 +1827,12 @@ static void genCast (iCode * ic) {
       if (size==2)
        return;
       // fall through: case 0x41
-      emitcode("sext", AOP_NAME(result)[1]);
+      if (signedness) {
+       emitcode("sext", "r1");
+      } else {
+       emitcode("mov", "r1,#0");
+      }
+      emitcode("mov", "%s,r1", AOP_NAME(result)[1]);
       return;
     case 0x14:
     case 0x12:
@@ -1740,7 +1874,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);
@@ -1765,7 +1899,18 @@ 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);
+}
+
+/*-----------------------------------------------------------------*/
+/* genDummyRead - generate code for dummy read of volatiles        */
+/*-----------------------------------------------------------------*/
+static void
+genDummyRead (iCode * ic)
+{
+  emitcode (";     genDummyRead","");
+
+  ic = ic;
 }
 
 /*-----------------------------------------------------------------*/
@@ -1774,52 +1919,50 @@ static void genReceive (iCode * ic) {
 void genXA51Code (iCode * lic) {
   iCode *ic;
   int cln = 0;
-  
+
   lineHead = lineCurr = NULL;
-  
+
   /* if debug information required */
   if (options.debug && currFunc)
     {
-      cdbSymbol (currFunc, cdbFile, FALSE, TRUE);
-      _G.debugLine = 1;
-      if (IS_STATIC (currFunc->etype))
-       emitcode ("", "F%s$%s$0$0 ==.", moduleName, currFunc->name);
-      else
-       emitcode ("", "G$%s$0$0 ==.", currFunc->name);
-      _G.debugLine = 0;
+      debugFile->writeFunction (currFunc, lic);
     }
-  
+
   for (ic = lic; ic; ic = ic->next) {
     if (ic->lineno && cln != ic->lineno) {
       if (options.debug) {
-       _G.debugLine = 1;
-       emitcode ("", "C$%s$%d$%d$%d ==.",
-                 FileBaseName (ic->filename), ic->lineno,
-                 ic->level, ic->block);
-       _G.debugLine = 0;
+       debugFile->writeCLine (ic);
+      }
+      if (!options.noCcodeInAsm) {
+       emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno,
+                 printCLine(ic->filename, ic->lineno));
       }
-      emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
-               printCLine(ic->filename, ic->lineno));
       cln = ic->lineno;
     }
+    if (options.iCodeInAsm) {
+      char *iLine = printILine(ic);
+      emitcode("", ";ic:%d: %s", ic->key, iLine);
+      dbuf_free(iLine);
+    }
+
     /* if the result is marked as
        spilt and rematerializable or code for
        this has already been generated then
        do nothing */
     if (resultRemat (ic) || ic->generated)
       continue;
-    
+
     /* depending on the operation */
     switch (ic->op)
       {
       case '!':
        genNot (ic);
        break;
-       
+
       case '~':
        genCpl (ic);
        break;
-       
+
       case UNARYMINUS:
        genUminus (ic);
        break;
@@ -1901,15 +2044,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:
@@ -1947,7 +2088,7 @@ void genXA51Code (iCode * lic) {
       case RLC:
        genRLC (ic);
        break;
-       
+
       case GETHBIT:
        genGetHbit (ic);
        break;
@@ -1990,23 +2131,27 @@ void genXA51Code (iCode * lic) {
       case RECEIVE:
        genReceive (ic);
        break;
-       
+
       case SEND:
        addSet (&_G.sendSet, ic);
        break;
-       
+
+      case DUMMY_READ_VOLATILE:
+       genDummyRead (ic);
+       break;
+
       default:
        ic = ic;
       }
   }
-  
-  
+
+
   /* now we are ready to call the
      peep hole optimizer */
   if (!options.nopeep)
     peepHole (&lineHead);
-  
+
   /* now do the actual printing */
-  printLine (lineHead, codeOutFile);
+  printLine (lineHead, codeOutBuf);
   return;
 }