Buffer overflow hunt: removing strcpy, strcat, sprintf
[fw/sdcc] / src / ds390 / gen.c
index 1aa6a2fe9f401337467462bd97e9bb3c3b51e569..1cf40126b348e97bf7c6490a1f18184af97ec885 100644 (file)
@@ -30,7 +30,7 @@
 #include <string.h>
 #include <ctype.h>
 
-#include <common.h>
+#include "common.h"
 #include "ralloc.h"
 #include "gen.h"
 #include "SDCCglobl.h"
@@ -93,6 +93,8 @@ static struct
     short inLine;
     short debugLine;
     short nRegsSaved;
+    short dptrInUse;
+    short dptr1InUse;
     set *sendSet;
   }
 _G;
@@ -157,33 +159,47 @@ static unsigned char SRMask[] =
 static void
 emitcode (char *inst, char *fmt,...)
 {
-  va_list ap;
-  char lb[INITIAL_INLINEASM];
-  char *lbp = lb;
-
-  va_start (ap, fmt);
-
-  if (inst && *inst)
+    va_list ap;
+    char lb[INITIAL_INLINEASM];
+    char *lbp = lb;
+    
+    va_start (ap, fmt);
+    
+    if (inst && *inst)
     {
-      if (fmt && *fmt)
-       sprintf (lb, "%s\t", inst);
-      else
-       sprintf (lb, "%s", inst);
-      tvsprintf (lb + (strlen (lb)), fmt, ap);
+       if (fmt && *fmt)
+       {
+           SNPRINTF (lb, sizeof(lb), "%s\t", inst);
+       }
+       else
+       {
+           SNPRINTF (lb, sizeof(lb), "%s", inst);
+       }
+       
+       tvsprintf (lb + strlen(lb), sizeof(lb) - strlen(lb), 
+                  fmt, ap);
     }
-  else
-    tvsprintf (lb, fmt, ap);
+    else
+    {
+       tvsprintf (lb, sizeof(lb), fmt, ap);
+    }
+    
 
-  while (isspace (*lbp))
-    lbp++;
+    while (isspace (*lbp))
+    {
+       lbp++;
+    }
 
-  if (lbp && *lbp)
-    lineCurr = (lineCurr ?
-               connectLine (lineCurr, newLineNode (lb)) :
-               (lineHead = newLineNode (lb)));
-  lineCurr->isInline = _G.inLine;
-  lineCurr->isDebug = _G.debugLine;
-  va_end (ap);
+    if (lbp && *lbp)
+    {
+       lineCurr = (lineCurr ?
+                   connectLine (lineCurr, newLineNode (lb)) :
+                   (lineHead = newLineNode (lb)));
+    }
+    
+    lineCurr->isInline = _G.inLine;
+    lineCurr->isDebug = _G.debugLine;
+    va_end (ap);
 }
 
 /*-----------------------------------------------------------------*/
@@ -483,9 +499,18 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2)
        short stack_val = -((sym->stack < 0) ?
                            ((short) (sym->stack - _G.nRegsSaved)) :
                            ((short) sym->stack)) ;
+       if (useDP2 && _G.dptr1InUse) {
+           emitcode ("push","dpl1");
+           emitcode ("push","dph1");
+           emitcode ("push","dpx1");
+       } else if (_G.dptrInUse ) {
+           emitcode ("push","dpl");
+           emitcode ("push","dph");
+           emitcode ("push","dpx");
+       }
       /* It's on the 10 bit stack, which is located in
        * far data space.
-       */
+       */          
        if (stack_val < 0 && stack_val > -5) { /* between -5 & -1 */
            if (useDP2) {
                if (options.model == MODEL_FLAT24)
@@ -641,10 +666,10 @@ aopForRemat (symbol * sym)
   aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (buffer) + 1);
   strcpy (aop->aopu.aop_immd.aop_immd1, buffer);
   /* set immd2 field if required */
-  if (aop->aopu.aop_immd.from_cast_remat) {
-         tsprintf(buffer,"#!constbyte",ptr_type);
-         aop->aopu.aop_immd.aop_immd2 = Safe_calloc (1, strlen (buffer) + 1);
-         strcpy (aop->aopu.aop_immd.aop_immd2, buffer);
+  if (aop->aopu.aop_immd.from_cast_remat) 
+  {
+      tsprintf(buffer, sizeof(buffer), "#!constbyte",ptr_type);
+      aop->aopu.aop_immd.aop_immd2 = Safe_strdup(buffer);  
   }
 
   return aop;
@@ -1010,8 +1035,21 @@ freeAsmop (operand * op, asmop * aaop, iCode * ic, bool pop)
            _G.r1Pushed--;
          }
       }
+    case AOP_DPTR2:
+       if (_G.dptr1InUse) {
+           emitcode ("pop","dpx1");
+           emitcode ("pop","dph1");
+           emitcode ("pop","dpl1");
+       }
+       break;
+    case AOP_DPTR:
+       if (_G.dptrInUse) {
+           emitcode ("pop","dpx");
+           emitcode ("pop","dph");
+           emitcode ("pop","dpl");
+       }
+       break;
     }
-
 dealloc:
   /* all other cases just dealloc */
   if (op)
@@ -1042,8 +1080,8 @@ aopGet (asmop * aop,
        bool dname,
        bool canClobberACC)
 {
-  char *s = buffer;
-  char *rs;
+  //char *s = buffer;
+  //char *rs;
 
   /* offset is greater than
      size then zero */
@@ -1076,10 +1114,8 @@ aopGet (asmop * aop,
          emitcode ("movx", "a,@%s", aop->aopu.aop_ptr->name);
          return (dname ? "acc" : "a");
        }
-      sprintf (s, "@%s", aop->aopu.aop_ptr->name);
-      rs = Safe_calloc (1, strlen (s) + 1);
-      strcpy (rs, s);
-      return rs;
+      SNPRINTF (buffer, sizeof(buffer), "@%s", aop->aopu.aop_ptr->name);
+      return Safe_strdup(buffer);      
 
     case AOP_DPTRn:
        assert(offset <= 3);
@@ -1136,44 +1172,60 @@ aopGet (asmop * aop,
       return (dname ? "acc" : "a");
 
     case AOP_IMMD:
-      if (aop->aopu.aop_immd.from_cast_remat && (offset == (aop->size-1))) {
-             sprintf(s,"%s",aop->aopu.aop_immd.aop_immd2);
-      } else if (bit16)
-       sprintf (s, "#%s", aop->aopu.aop_immd.aop_immd1);
-      else if (offset) {
+      if (aop->aopu.aop_immd.from_cast_remat && (offset == (aop->size-1))) 
+      {
+         SNPRINTF(buffer, sizeof(buffer), 
+                  "%s",aop->aopu.aop_immd.aop_immd2);
+      } 
+      else if (bit16)
+      {
+        SNPRINTF(buffer, sizeof(buffer), 
+                 "#%s", aop->aopu.aop_immd.aop_immd1);
+      }
+      else if (offset) 
+      {
          switch (offset) {
          case 1:
-             tsprintf(s,"#!his",aop->aopu.aop_immd.aop_immd1);
+             tsprintf(buffer, sizeof(buffer),
+                      "#!his",aop->aopu.aop_immd.aop_immd1);
              break;
          case 2:
-             tsprintf(s,"#!hihis",aop->aopu.aop_immd.aop_immd1);
+             tsprintf(buffer, sizeof(buffer), 
+                      "#!hihis",aop->aopu.aop_immd.aop_immd1);
              break;
          case 3:
-             tsprintf(s,"#!hihihis",aop->aopu.aop_immd.aop_immd1);
+             tsprintf(buffer, sizeof(buffer),
+                      "#!hihihis",aop->aopu.aop_immd.aop_immd1);
              break;
          default: /* should not need this (just in case) */
-             sprintf (s, "#(%s >> %d)",
+             SNPRINTF (buffer, sizeof(buffer), 
+                       "#(%s >> %d)",
                       aop->aopu.aop_immd.aop_immd1,
                       offset * 8);
          }
       }
       else
-       sprintf (s, "#%s",
-                aop->aopu.aop_immd.aop_immd1);
-      rs = Safe_calloc (1, strlen (s) + 1);
-      strcpy (rs, s);
-      return rs;
+      {
+       SNPRINTF (buffer, sizeof(buffer), 
+                 "#%s", aop->aopu.aop_immd.aop_immd1);
+      }
+      return Safe_strdup(buffer);      
 
     case AOP_DIR:
       if (offset)
-       sprintf (s, "(%s + %d)",
+      {
+       SNPRINTF (buffer, sizeof(buffer),
+                 "(%s + %d)",
                 aop->aopu.aop_dir,
                 offset);
+      }
       else
-       sprintf (s, "%s", aop->aopu.aop_dir);
-      rs = Safe_calloc (1, strlen (s) + 1);
-      strcpy (rs, s);
-      return rs;
+      {
+       SNPRINTF(buffer, sizeof(buffer), 
+                "%s", aop->aopu.aop_dir);
+      }
+
+      return Safe_strdup(buffer);
 
     case AOP_REG:
       if (dname)
@@ -1385,11 +1437,8 @@ aopPut (asmop * aop, char *s, int offset)
                  MOVA (s);
                }
              {
-               symbol *lbl = newiTempLabel (NULL);
-               emitcode ("clr", "c");
-               emitcode ("jz", "!tlabel", lbl->key + 100);
-               emitcode ("cpl", "c");
-               emitcode ("", "!tlabeldef", lbl->key + 100);
+               /* set C, if a >= 1 */
+               emitcode ("add", "a,#!constbyte",0xff);
                emitcode ("mov", "%s,c", aop->aopu.aop_dir);
              }
            }
@@ -2118,7 +2167,7 @@ genIpush (iCode * ic)
     {
 
       /* and the item is spilt then do nothing */
-      if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
+      if (OP_SYMBOL (IC_LEFT (ic))->isspilt || OP_SYMBOL(IC_LEFT(ic))->dptr)
        return;
 
       aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
@@ -2190,7 +2239,7 @@ genIpop (iCode * ic)
 
 
   /* if the temp was not pushed then */
-  if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
+  if (OP_SYMBOL (IC_LEFT (ic))->isspilt || OP_SYMBOL (IC_LEFT (ic))->dptr)
     return;
 
   aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
@@ -3514,6 +3563,23 @@ genPlusIncr (iCode * ic)
       return TRUE;
     }
 
+  if (AOP_TYPE(IC_RESULT(ic))==AOP_STR && IS_ITEMP(IC_RESULT(ic)) &&
+      !AOP_USESDPTR(IC_LEFT(ic)) && icount <= 5 && size <= 3 && 
+      options.model == MODEL_FLAT24 ) {
+
+      switch (size) {
+      case 3:
+         emitcode ("mov","dpx,%s",aopGet(AOP (IC_LEFT (ic)), 2, FALSE, FALSE, FALSE));
+      case 2:
+         emitcode ("mov","dph,%s",aopGet(AOP (IC_LEFT (ic)), 1, FALSE, FALSE, FALSE));
+      case 1:
+         emitcode ("mov","dpl,%s",aopGet(AOP (IC_LEFT (ic)), 0, FALSE, FALSE, FALSE));
+         break;
+      }
+      while (icount--) emitcode ("inc","dptr");      
+      return TRUE;
+  }
+
   if (AOP_INDPTRn(IC_LEFT(ic)) && AOP_INDPTRn(IC_RESULT(ic)) &&
       AOP(IC_LEFT(ic))->aopu.dptr == AOP(IC_RESULT(ic))->aopu.dptr &&
       icount <= 5 ) {
@@ -3642,6 +3708,7 @@ adjustArithmeticResult (iCode * ic)
     }
 }
 
+#ifdef KEVIN_SCREWED_UP
 // Macro to aopOp all three operands of an ic. If this cannot be done, 
 // the IC_LEFT and IC_RIGHT operands will be aopOp'd, and the rc parameter
 // will be set TRUE. The caller must then handle the case specially, noting
@@ -3675,6 +3742,88 @@ adjustArithmeticResult (iCode * ic)
     aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \
     aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR));
 
+#else // Kevin didn't screw up...
+
+#define AOP_IS_STR(x) (IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
+
+// The guts of AOP_OP_3_NOFATAL. Generates the left & right opcodes of an IC,
+// generates the result if possible. If result is generated, returns TRUE; otherwise
+// returns false and caller must deal with fact that result isn't aopOp'd.
+bool aopOp3(iCode * ic)
+{
+    bool dp1InUse, dp2InUse;
+    
+    // First, generate the right opcode. DPTR may be used if neither left nor result are
+    // of type AOP_STR.
+    
+//    D(emitcode(";", "aopOp3: AOP_IS_STR left: %s right: %s result: %s",
+//            AOP_IS_STR(IC_LEFT(ic)) ? "true" : "false",
+//            AOP_IS_STR(IC_RIGHT(ic)) ? "true" : "false",
+//            AOP_IS_STR(IC_RESULT(ic)) ? "true" : "false");
+//      );
+    
+    aopOp (IC_RIGHT(ic),ic,FALSE, AOP_IS_STR(IC_LEFT(ic)) || AOP_IS_STR(IC_RESULT(ic)));
+    
+    // Now, the left opcode. This can use DPTR if the right didn't AND the result is not
+    // AOP_STR (however, if the result is the same operand as the left, then DPTR may be used).
+    aopOp (IC_LEFT(ic),ic,FALSE, AOP_USESDPTR(IC_RIGHT(ic)) ||
+                                  (AOP_IS_STR(IC_RESULT(ic)) && !isOperandEqual(IC_LEFT(ic),IC_RESULT(ic))));
+    
+    // We've op'd the left. So, if left & result are the same operand, we know aopOp
+    // will succeed, and we can just do it & bail.
+    if (isOperandEqual(IC_LEFT(ic),IC_RESULT(ic)))
+    {
+//     D(emitcode(";", "aopOp3: left & result equal"););
+       aopOp(IC_RESULT(ic),ic,TRUE, FALSE);
+       return TRUE;
+    }
+    
+    // Note which dptrs are currently in use.
+    dp1InUse = (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR) || (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) ||
+               AOP_IS_STR(IC_RIGHT(ic)) || AOP_IS_STR(IC_LEFT(ic));
+    dp2InUse = (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR2) || (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2);
+    
+    // OK, now if either left or right uses DPTR and the result is an AOP_STR, we cannot generate it.
+    if (dp1InUse && AOP_IS_STR(IC_RESULT(ic)))
+    {
+       return FALSE;
+    }
+    
+    // or, if both dp1 & dp2 are in use and the result needs a dptr, we're out of luck    
+    if (dp1InUse && dp2InUse && isOperandInFarSpace(IC_RESULT(ic)))
+    {
+       return FALSE;
+    }
+
+    aopOp (IC_RESULT(ic),ic,TRUE, dp1InUse);
+
+    // SOme sanity checking...
+    if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2 &&
+       AOP_TYPE(IC_RESULT(ic)) == AOP_DPTR2)
+    {
+       fprintf(stderr,
+               "Ack: got unexpected DP2! (%s:%d %s:%d)\n",
+               __FILE__, __LINE__, ic->filename, ic->lineno);  
+    }
+       
+    return TRUE;
+}
+
+// Macro to aopOp all three operands of an ic. If this cannot be done, 
+// the IC_LEFT and IC_RIGHT operands will be aopOp'd, and the rc parameter
+// will be set TRUE. The caller must then handle the case specially, noting
+// that the IC_RESULT operand is not aopOp'd.
+// 
+#define AOP_OP_3_NOFATAL(ic, rc) \
+           do { rc = !aopOp3(ic); } while (0)
+
+// aopOp the left & right operands of an ic.
+#define AOP_OP_2(ic) \
+    aopOp (IC_RIGHT(ic),ic,FALSE, AOP_IS_STR(IC_LEFT(ic))); \
+    aopOp (IC_LEFT(ic),ic,FALSE, AOP_USESDPTR(IC_RIGHT(ic)));
+
+#endif
+
 // convienience macro.
 #define AOP_SET_LOCALS(ic) \
     left = IC_LEFT(ic); \
@@ -4118,7 +4267,8 @@ genMinus (iCode * ic)
   aopOp (IC_RIGHT (ic), ic, FALSE, 
         (AOP_INDPTRn(IC_LEFT(ic)) ? FALSE : (AOP_USESDPTR(IC_LEFT(ic)) ? TRUE : FALSE)));
   if ((AOP_TYPE (IC_LEFT (ic)) == AOP_DPTR) &&
-      (AOP_TYPE (IC_RIGHT (ic)) == AOP_DPTR2))
+      ((AOP_TYPE (IC_RIGHT (ic)) == AOP_DPTR2)
+       || OP_SYMBOL(IC_RESULT(ic))->ruonly))
     {
       pushResult = TRUE;
     }
@@ -8446,11 +8596,11 @@ genRightShiftLiteral (operand * left,
        default:
          break;
        }
-
-      freeAsmop (left, NULL, ic, TRUE);
-      freeAsmop (result, NULL, ic, TRUE);
     }
-    return TRUE;
+  freeAsmop (left, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
+  
+  return TRUE;
 }
 #endif
 
@@ -9194,10 +9344,10 @@ genFarPointerGet (operand * left,
 }
 
 /*-----------------------------------------------------------------*/
-/* emitcodePointerGet - gget value from code space                  */
+/* genCodePointerGet - get value from code space                  */
 /*-----------------------------------------------------------------*/
 static void
-emitcodePointerGet (operand * left,
+genCodePointerGet (operand * left,
                    operand * result, iCode * ic, iCode *pi)
 {
   int size, offset, dopi=1;
@@ -9343,6 +9493,8 @@ genGenPointerGet (operand * left,
       else
        {                       /* we need to get it byte by byte */
          _startLazyDPSEvaluation ();
+#if 0  // I see no point at all to this code.
+       // So I yanked it. Kill at some future date if no bugs rear their heads.
          if (AOP(left)->type==AOP_DPTR2) {
            char *l;
            l=aopGet(AOP(left),0,FALSE,FALSE,TRUE);
@@ -9362,7 +9514,10 @@ genGenPointerGet (operand * left,
            } else {
              emitcode ("mov", "b,%s", aopGet (AOP(left),2,FALSE,FALSE,TRUE));
            }
-         } else {
+         } 
+         else 
+#endif         
+         {
            emitcode ("mov", "dpl,%s", aopGet (AOP(left),0,FALSE,FALSE,TRUE));
            emitcode ("mov", "dph,%s", aopGet (AOP(left),1,FALSE,FALSE,TRUE));
            if (options.model == MODEL_FLAT24) {
@@ -9375,23 +9530,48 @@ genGenPointerGet (operand * left,
          _endLazyDPSEvaluation ();
        }
     }
-  /* so dptr know contains the address */
+
+  /* so dptr-b now contains the address */
+  _G.bInUse++;
   aopOp (result, ic, FALSE, TRUE);
+  _G.bInUse--;
 
   /* if bit then unpack */
   if (IS_BITVAR (retype) || IS_BITVAR (letype))
+  {
     genUnpackBits (result, "dptr", GPOINTER);
+  }
   else
     {
-      size = AOP_SIZE (result);
-      offset = 0;
+       size = AOP_SIZE (result);
+       offset = 0;
 
-      while (size--)
+       while (size--)
        {
-         emitcode ("lcall", "__gptrget");
-         aopPut (AOP (result), "a", offset++);
-         if (size || (pi && AOP_TYPE (left) != AOP_IMMD))
-           emitcode ("inc", "dptr");
+           if (size)
+           {
+               // Get two bytes at a time, results in _AP & A.
+               // dptr will be incremented ONCE by __gptrgetWord.
+               //
+               // Note: any change here must be coordinated
+               // with the implementation of __gptrgetWord
+               // in device/lib/_gptrget.c
+               emitcode ("lcall", "__gptrgetWord");
+               aopPut (AOP (result), DP2_RESULT_REG, offset++);
+               aopPut (AOP (result), "a", offset++);
+               size--;
+           }
+           else
+           {
+               // Only one byte to get.
+               emitcode ("lcall", "__gptrget");
+               aopPut (AOP (result), "a", offset++);
+           }
+           
+           if (size || (pi && AOP_TYPE (left) != AOP_IMMD))
+           {
+               emitcode ("inc", "dptr");
+           }
        }
     }
 
@@ -9446,7 +9626,7 @@ genPointerGet (iCode * ic, iCode *pi)
   if (p_type == GPOINTER && OP_SYMBOL(left)->remat &&
       IS_CAST_ICODE(OP_SYMBOL(left)->rematiCode)) {
          left = IC_RIGHT(OP_SYMBOL(left)->rematiCode);
-         type =   type = operandType (left);
+         type = operandType (left);
          p_type = DCL_TYPE (type);
   }
   /* now that we have the pointer type we assign
@@ -9468,7 +9648,7 @@ genPointerGet (iCode * ic, iCode *pi)
       break;
 
     case CPOINTER:
-      emitcodePointerGet (left, result, ic, pi);
+      genCodePointerGet (left, result, ic, pi);
       break;
 
     case GPOINTER:
@@ -10115,7 +10295,7 @@ genPointerSet (iCode * ic, iCode *pi)
   if (p_type == GPOINTER && OP_SYMBOL(result)->remat &&
       IS_CAST_ICODE(OP_SYMBOL(result)->rematiCode)) {
          result = IC_RIGHT(OP_SYMBOL(result)->rematiCode);
-         type =   type = operandType (result);
+         type = operandType (result);
          p_type = DCL_TYPE (type);
   }
 
@@ -10140,6 +10320,10 @@ genPointerSet (iCode * ic, iCode *pi)
     case GPOINTER:
       genGenPointerSet (right, result, ic, pi);
       break;
+
+    default:
+      werror (E_INTERNAL_ERROR, __FILE__, __LINE__, 
+             "genPointerSet: illegal pointer type");
     }
 
 }
@@ -10203,16 +10387,17 @@ genAddrOf (iCode * ic)
       /* if 10 bit stack */
       if (options.stack10bit) {
          char buff[10];
-         tsprintf(buff,"#!constbyte",(options.stack_loc >> 16) & 0xff);
+         tsprintf(buff, sizeof(buff), 
+                  "#!constbyte",(options.stack_loc >> 16) & 0xff);
          /* if it has an offset then we need to compute it */
-         emitcode ("subb", "a,#!constbyte",
-                   -((sym->stack < 0) ?
-                     ((short) (sym->stack - _G.nRegsSaved)) :
-                     ((short) sym->stack)) & 0xff);
-         emitcode ("mov","b,a");
-         emitcode ("mov","a,#!constbyte",(-((sym->stack < 0) ?
-                                        ((short) (sym->stack - _G.nRegsSaved)) :
-                                        ((short) sym->stack)) >> 8) & 0xff);
+/*       emitcode ("subb", "a,#!constbyte", */
+/*                 -((sym->stack < 0) ? */
+/*                   ((short) (sym->stack - _G.nRegsSaved)) : */
+/*                   ((short) sym->stack)) & 0xff); */
+/*       emitcode ("mov","b,a"); */
+/*       emitcode ("mov","a,#!constbyte",(-((sym->stack < 0) ? */
+/*                                      ((short) (sym->stack - _G.nRegsSaved)) : */
+/*                                      ((short) sym->stack)) >> 8) & 0xff); */
          if (sym->stack) {
              emitcode ("mov", "a,_bpx");
              emitcode ("add", "a,#!constbyte", ((sym->stack < 0) ? 
@@ -10269,16 +10454,16 @@ genAddrOf (iCode * ic)
       if (offset) {
          switch (offset) {
          case 1:
-             tsprintf(s,"!his",sym->rname);
+             tsprintf(s, sizeof(s), "!his",sym->rname);
              break;
          case 2:
-             tsprintf(s,"!hihis",sym->rname);
+             tsprintf(s, sizeof(s), "!hihis",sym->rname);
              break;
          case 3:
-             tsprintf(s,"!hihihis",sym->rname);
+             tsprintf(s, sizeof(s), "!hihihis",sym->rname);
              break;
          default: /* should not need this (just in case) */
-             sprintf (s, "#(%s >> %d)",
+             SNPRINTF (s, sizeof(s), "#(%s >> %d)",
                       sym->rname,
                       offset * 8);
          }
@@ -10739,8 +10924,6 @@ genCast (iCode * ic)
       /* pointer to generic pointer */
       if (IS_GENPTR (ctype))
        {
-         char *l = zero;
-
          if (IS_PTR (type))
            {
              p_type = DCL_TYPE (type);
@@ -10800,29 +10983,19 @@ genCast (iCode * ic)
          _endLazyDPSEvaluation ();
 
          /* the last byte depending on type */
-         switch (p_type)
            {
-           case IPOINTER:
-           case POINTER:
-             l = zero;
-             break;
-           case FPOINTER:
-             l = one;
-             break;
-           case CPOINTER:
-             l = "#0x02";
-             break;
-           case PPOINTER:
-             l = "#0x03";
-             break;
-
-           default:
-             /* this should never happen */
-             werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
-                     "got unknown pointer type");
-             exit (1);
+               int gpVal = pointerTypeToGPByte(p_type, NULL, NULL);
+               char gpValStr[10];
+           
+               if (gpVal == -1)
+               {
+                   // pointerTypeToGPByte will have bitched.
+                   exit(1);
+               }
+           
+               sprintf(gpValStr, "#0x%d", gpVal);
+               aopPut (AOP (result), gpValStr, GPTRSIZE - 1);
            }
-         aopPut (AOP (result), l, GPTRSIZE - 1);
          goto release;
        }
 
@@ -11092,32 +11265,27 @@ static void genMemcpyX2X( iCode *ic, int nparms, operand **parms, int fromc)
        }
     }
     freeAsmop (to, NULL, ic, FALSE);
-
+    _G.dptrInUse = _G.dptr1InUse = 1;
     aopOp (count, ic->next->next, FALSE,FALSE);
     lbl =newiTempLabel(NULL);
 
     /* now for the actual copy */
     if (AOP_TYPE(count) == AOP_LIT && 
        (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) {
-       emitcode (";","OH  JOY auto increment with djnz (very fast)");
-       emitcode ("mov", "dps,#!constbyte",0x21);       /* Select DPTR2 & auto-toggle. */
        emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,FALSE));
-       emitcode ("","!tlabeldef",lbl->key+100);
        if (fromc) {
-           emitcode ("clr","a");
-           emitcode ("movc", "a,@a+dptr");
-       } else 
-           emitcode ("movx", "a,@dptr");
-       emitcode ("movx", "@dptr,a");
-       emitcode ("inc", "dptr");
-       emitcode ("inc", "dptr");
-       emitcode ("djnz","b,!tlabel",lbl->key+100);
+           emitcode ("lcall","__bi_memcpyc2x_s");
+       } else {
+           emitcode ("lcall","__bi_memcpyx2x_s");
+       }
+       freeAsmop (count, NULL, ic, FALSE);
     } else {
        symbol *lbl1 = newiTempLabel(NULL);
        
        emitcode (";"," Auto increment but no djnz");
        emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, TRUE));
        emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, TRUE));
+       freeAsmop (count, NULL, ic, FALSE);
        emitcode ("mov", "dps,#!constbyte",0x21);       /* Select DPTR2 & auto-toggle. */
        emitcode ("","!tlabeldef",lbl->key+100);
        if (fromc) {
@@ -11141,7 +11309,7 @@ static void genMemcpyX2X( iCode *ic, int nparms, operand **parms, int fromc)
        emitcode ("","!tlabeldef",lbl1->key+100);
     }
     emitcode ("mov", "dps,#0"); 
-    freeAsmop (count, NULL, ic, FALSE);
+    _G.dptrInUse = _G.dptr1InUse = 0;
     unsavermask(rsave);
 
 }
@@ -11212,39 +11380,31 @@ static void genMemcmpX2X( iCode *ic, int nparms, operand **parms, int fromc)
        }
     }
     freeAsmop (to, NULL, ic, FALSE);
-
+    _G.dptrInUse = _G.dptr1InUse = 1;
     aopOp (count, ic->next->next, FALSE,FALSE);
     lbl =newiTempLabel(NULL);
     lbl2 =newiTempLabel(NULL);
 
     /* now for the actual compare */
-    emitcode("push","ar0");
     if (AOP_TYPE(count) == AOP_LIT && 
        (int)floatFromVal (AOP(count)->aopu.aop_lit) <= 256) {
-       emitcode (";","OH  JOY auto increment with djnz (very fast)");
-       emitcode ("mov", "dps,#!constbyte",0x21);       /* Select DPTR2 & auto-toggle. */
        emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,FALSE));
-       emitcode ("","!tlabeldef",lbl->key+100);
-       if (fromc) {
-           emitcode ("clr","a");
-           emitcode ("movc", "a,@a+dptr");
-       } else 
-           emitcode ("movx", "a,@dptr");
-       emitcode ("mov","r0,a");
-       emitcode ("movx", "a,@dptr");
-       emitcode ("clr","c");
-       emitcode ("subb","a,r0");
-       emitcode ("jnz","!tlabel",lbl2->key+100);
-       emitcode ("inc", "dptr");
-       emitcode ("inc", "dptr");
-       emitcode ("djnz","b,!tlabel",lbl->key+100);
-       emitcode ("clr","a");   
+       if (fromc)
+           emitcode("lcall","__bi_memcmpc2x_s");
+       else
+           emitcode("lcall","__bi_memcmpx2x_s");
+       freeAsmop (count, NULL, ic, FALSE);
+       aopOp (IC_RESULT(ic), ic, FALSE,FALSE);
+       aopPut(AOP(IC_RESULT(ic)),"a",0);
+       freeAsmop (IC_RESULT(ic), NULL, ic, FALSE);
     } else {
        symbol *lbl1 = newiTempLabel(NULL);
-       
+
+       emitcode("push","ar0");         
        emitcode (";"," Auto increment but no djnz");
        emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, TRUE));
        emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, TRUE));
+       freeAsmop (count, NULL, ic, FALSE);
        emitcode ("mov", "dps,#!constbyte",0x21);       /* Select DPTR2 & auto-toggle. */
        emitcode ("","!tlabeldef",lbl->key+100);
        if (fromc) {
@@ -11271,15 +11431,14 @@ static void genMemcmpX2X( iCode *ic, int nparms, operand **parms, int fromc)
        emitcode ("sjmp","!tlabel",lbl->key+100);
        emitcode ("","!tlabeldef",lbl1->key+100);
        emitcode ("clr","a");
+       emitcode ("","!tlabeldef",lbl2->key+100);
+       aopOp (IC_RESULT(ic), ic, FALSE,FALSE);
+       aopPut(AOP(IC_RESULT(ic)),"a",0);
+       freeAsmop (IC_RESULT(ic), NULL, ic, FALSE);
+       emitcode("pop","ar0");
+       emitcode ("mov", "dps,#0");      
     }
-    freeAsmop (count, NULL, ic, FALSE);
-    emitcode ("","!tlabeldef",lbl2->key+100);
-    aopOp (IC_RESULT(ic), ic, FALSE,FALSE);
-    aopPut(AOP(IC_RESULT(ic)),"a",0);
-    freeAsmop (IC_RESULT(ic), NULL, ic, FALSE);
-    emitcode("pop","ar0");
-    emitcode ("mov", "dps,#0"); 
-    
+    _G.dptrInUse = _G.dptr1InUse = 0;
     unsavermask(rsave);
 
 }
@@ -11353,6 +11512,7 @@ static void genInp( iCode *ic, int nparms, operand **parms)
     }
     freeAsmop (to, NULL, ic, FALSE);
 
+    _G.dptrInUse = _G.dptr1InUse = 1;
     aopOp (count, ic->next->next, FALSE,FALSE);
     lbl =newiTempLabel(NULL);
 
@@ -11362,6 +11522,7 @@ static void genInp( iCode *ic, int nparms, operand **parms)
        emitcode (";","OH  JOY auto increment with djnz (very fast)");
        emitcode ("mov", "dps,#!constbyte",0x1);        /* Select DPTR2 */
        emitcode ("mov", "b,%s",aopGet(AOP(count),0,FALSE,FALSE,FALSE));
+       freeAsmop (count, NULL, ic, FALSE);
        emitcode ("","!tlabeldef",lbl->key+100);
        emitcode ("movx", "a,@dptr");   /* read data from port */
        emitcode ("dec","dps");         /* switch to DPTR */
@@ -11375,6 +11536,7 @@ static void genInp( iCode *ic, int nparms, operand **parms)
        emitcode (";"," Auto increment but no djnz");
        emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, TRUE));
        emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, TRUE));
+       freeAsmop (count, NULL, ic, FALSE);
        emitcode ("mov", "dps,#!constbyte",0x1);        /* Select DPTR2 */
        emitcode ("","!tlabeldef",lbl->key+100);
        emitcode ("movx", "a,@dptr");
@@ -11397,7 +11559,7 @@ static void genInp( iCode *ic, int nparms, operand **parms)
        emitcode ("","!tlabeldef",lbl1->key+100);
     }
     emitcode ("mov", "dps,#0"); 
-    freeAsmop (count, NULL, ic, FALSE);
+    _G.dptrInUse = _G.dptr1InUse = 0;
     unsavermask(rsave);
 
 }
@@ -11471,6 +11633,7 @@ static void genOutp( iCode *ic, int nparms, operand **parms)
     }
     freeAsmop (to, NULL, ic, FALSE);
 
+    _G.dptrInUse = _G.dptr1InUse = 1;
     aopOp (count, ic->next->next, FALSE,FALSE);
     lbl =newiTempLabel(NULL);
 
@@ -11487,23 +11650,21 @@ static void genOutp( iCode *ic, int nparms, operand **parms)
        emitcode ("inc", "dptr");       /* point to next area */
        emitcode ("dec","dps");         /* switch to DPTR */
        emitcode ("djnz","b,!tlabel",lbl->key+100);
+       freeAsmop (count, NULL, ic, FALSE);
     } else {
        symbol *lbl1 = newiTempLabel(NULL);
        
        emitcode (";"," Auto increment but no djnz");
        emitcode ("mov","_ap,%s",aopGet (AOP (count), 0, FALSE, TRUE, TRUE));
        emitcode ("mov","b,%s",aopGet (AOP (count), 1, FALSE, TRUE, TRUE));
+       freeAsmop (count, NULL, ic, FALSE);
        emitcode ("mov", "dps,#!constbyte",0x0);        /* Select DPTR */
        emitcode ("","!tlabeldef",lbl->key+100);
-/*     emitcode ("push","acc"); */
        emitcode ("movx", "a,@dptr");
        emitcode ("inc", "dptr");
        emitcode ("inc","dps");         /* switch to DPTR2 */
        emitcode ("movx", "@dptr,a");
        emitcode ("dec","dps");         /* switch to DPTR */
-/*     emitcode ("pop","acc"); */
-/*     emitcode ("djnz","acc,!tlabel",lbl->key+100); */
-/*     emitcode ("djnz","b,!tlabel",lbl->key+100); */
        emitcode ("mov","a,b");
        emitcode ("orl","a,_ap");
        emitcode ("jz","!tlabel",lbl1->key+100);
@@ -11517,7 +11678,7 @@ static void genOutp( iCode *ic, int nparms, operand **parms)
        emitcode ("","!tlabeldef",lbl1->key+100);
     }
     emitcode ("mov", "dps,#0"); 
-    freeAsmop (count, NULL, ic, FALSE);
+    _G.dptrInUse = _G.dptr1InUse = 0;
     unsavermask(rsave);
 
 }
@@ -12411,10 +12572,15 @@ gen390Code (iCode * lic)
                        ic->level, ic->block);
              _G.debugLine = 0;
            }
-         emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
-                   printCLine(ic->filename, ic->lineno));
+         if (!options.noCcodeInAsm) {
+           emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, 
+                     printCLine(ic->filename, ic->lineno));
+         }
          cln = ic->lineno;
        }
+      if (options.iCodeInAsm) {
+       emitcode("", ";ic:%d: %s", ic->key, printILine(ic));
+      }
       /* if the result is marked as
          spilt and rematerializable or code for
          this has already been generated then