fixed bug #635354
[fw/sdcc] / src / mcs51 / gen.c
index 0daad8e21d17fdcabd22d9efc3be83d2f62380c6..529be381c2aeb3542a8c2f7e2680e27ca8104c27 100644 (file)
 #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"
@@ -247,17 +230,26 @@ getFreePtr (iCode * ic, asmop ** aopp, bool result)
       (*aopp)->type = AOP_R1;
       return mcs51_regWithIdx (R1_IDX);
     }
-
 endOfWorld:
-  /* I said end of world but not quite end of world yet */
-  /* if this is a result then we can push it on the stack */
-  if (result)
-    {
-      (*aopp)->type = AOP_STK;
-      return NULL;
+  /* I said end of world, but not quite end of world yet */
+  if (result) {
+    /* we can push it on the stack */
+    (*aopp)->type = AOP_STK;
+    return NULL;
+  } else {
+    /* in the case that result AND left AND right needs a pointer reg
+       we can safely use the result's */
+    if (bitVectBitValue (mcs51_rUmaskForOp(IC_RESULT(ic)), R0_IDX)) {
+      (*aopp)->type = AOP_R0;
+      return mcs51_regWithIdx (R0_IDX);
+    }
+    if (bitVectBitValue (mcs51_rUmaskForOp(IC_RESULT(ic)), R1_IDX)) {
+      (*aopp)->type = AOP_R1;
+      return mcs51_regWithIdx (R1_IDX);
     }
+  }
 
-  /* other wise this is true end of the world */
+  /* now this is REALLY the end of the world */
   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
          "getFreePtr should never reach here");
   exit (1);
@@ -1444,15 +1436,9 @@ genUminusFloat (operand * op, operand * result)
 
   D(emitcode (";     genUminusFloat",""));
 
-  /* for this we just need to flip the
-     first it then copy the rest in place */
-  size = AOP_SIZE (op) - 1;
-  l = aopGet (AOP (op), 3, FALSE, FALSE);
+  /* for this we just copy and then flip the bit */
 
-  MOVA (l);
-
-  emitcode ("cpl", "acc.7");
-  aopPut (AOP (result), "a", 3);
+  size = AOP_SIZE (op) - 1;
 
   while (size--)
     {
@@ -1461,6 +1447,13 @@ genUminusFloat (operand * op, operand * result)
              offset);
       offset++;
     }
+
+  l = aopGet (AOP (op), offset, FALSE, FALSE);
+
+  MOVA (l);
+
+  emitcode ("cpl", "acc.7");
+  aopPut (AOP (result), "a", offset);
 }
 
 /*-----------------------------------------------------------------*/
@@ -1564,10 +1557,13 @@ saveRegisters (iCode * lic)
 
   /* if the registers have been saved already or don't need to be then
      do nothing */
-  if (ic->regsSaved || IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type) ||
-      IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT (ic))))
+  if (ic->regsSaved)
     return;
-
+  if (IS_SYMOP(IC_LEFT(ic)) &&
+      (IFFUNC_CALLEESAVES(OP_SYMBOL(IC_LEFT(ic))->type) ||
+       IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT (ic)))))
+    return;
+  
   /* safe the registers in use at this time but skip the
      ones for the result */
   rsave = bitVectCplAnd (bitVectCopy (ic->rMask), 
@@ -2433,7 +2429,7 @@ genFunction (iCode * ic)
                     }
                }
            }
-           // jwk: this needs a closer look
+           // TODO: this needs a closer look
            SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave;
        }
     }
@@ -2658,7 +2654,6 @@ genEndFunction (iCode * ic)
             * Restore any register banks saved by genFunction
             * in reverse order.
             */
-         // jwk: this needs a closer look
            unsigned savedBanks = SPEC_ISR_SAVED_BANKS(currFunc->etype);
            int ix;
          
@@ -2888,8 +2883,8 @@ genPlusIncr (iCode * ic)
 
   D(emitcode (";     genPlusIncr",""));
 
-  /* if increment 16 bits in register */
-  if (AOP_TYPE(IC_LEFT(ic)) == AOP_REG &&
+  /* if increment >=16 bits in register or direct space */
+  if ((AOP_TYPE(IC_LEFT(ic)) == AOP_REG || AOP_TYPE(IC_LEFT(ic)) == AOP_DIR ) &&
       sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) && 
       (size > 1) &&
       (icount == 1))
@@ -3248,8 +3243,8 @@ genMinusDec (iCode * ic)
 
   D(emitcode (";     genMinusDec",""));
 
-  /* if decrement 16 bits in register */
-  if (AOP_TYPE(IC_LEFT(ic)) == AOP_REG &&
+  /* if decrement >=16 bits in register or direct space */
+  if ((AOP_TYPE(IC_LEFT(ic)) == AOP_REG || AOP_TYPE(IC_LEFT(ic)) == AOP_DIR) &&
       sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) &&
       (size > 1) &&
       (icount == 1))
@@ -3467,9 +3462,7 @@ genMinus (iCode * ic)
          if (aopGetUsesAcc(rightOp, offset)) {
            wassertl(!aopGetUsesAcc(leftOp, offset), "accumulator clash");
            MOVA (aopGet(rightOp, offset, FALSE, TRUE));
-           if (offset > 0) {
-             emitcode( "cpl", "c");
-           } else {
+           if (offset == 0) {
              emitcode( "setb", "c");
            }
            emitcode("subb", "a,%s", aopGet(leftOp, offset, FALSE, TRUE));
@@ -4022,7 +4015,7 @@ genCmp (operand * left, operand * right,
       AOP_TYPE (right) == AOP_CRY)
     {
       emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
-      emitcode ("anl", "c,/%s", AOP (left)->aopu.aop_dir);
+      emitcode ("anl", "c,%s", AOP (left)->aopu.aop_dir);
     }
   else
     {
@@ -6519,7 +6512,7 @@ genLeftShift (iCode * ic)
   char *l;
   symbol *tlbl, *tlbl1;
 
-  D(emitcode (";    genLeftShift",""));
+  D(emitcode (";     genLeftShift",""));
 
   right = IC_RIGHT (ic);
   left = IC_LEFT (ic);
@@ -6826,9 +6819,10 @@ genRightShiftLiteral (operand * left,
 
   else if (shCount >= (size * 8))
     {
-      if (sign)
+      if (sign) {
        /* get sign in acc.7 */
        MOVA (aopGet (AOP (left), size - 1, FALSE, FALSE));
+      }
       addSign (result, LSB, sign);
     }
   else
@@ -6849,10 +6843,9 @@ genRightShiftLiteral (operand * left,
        default:
          break;
        }
-
-      freeAsmop (left, NULL, ic, TRUE);
-      freeAsmop (result, NULL, ic, TRUE);
     }
+  freeAsmop (left, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -7541,11 +7534,19 @@ genCodePointerGet (operand * left,
 
       while (size--)
        {
-         emitcode ("clr", "a");
-         emitcode ("movc", "a,@a+dptr");
-         aopPut (AOP (result), "a", offset++);
-         if (size || pi)
-           emitcode ("inc", "dptr");
+         if (pi)
+           {
+             emitcode ("clr", "a");
+             emitcode ("movc", "a,@a+dptr");
+             aopPut (AOP (result), "a", offset++);
+             emitcode ("inc", "dptr");
+           }
+         else
+           { 
+             emitcode ("mov", "a,#0x%02x", offset);
+             emitcode ("movc", "a,@a+dptr");
+             aopPut (AOP (result), "a", offset++);
+           }
        }
     }
 
@@ -8449,8 +8450,9 @@ genAssign (iCode * ic)
   right = IC_RIGHT (ic);
 
   /* if they are the same */
-  if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic)))
+  if (operandsEqu (result, right)) {
     return;
+  }
 
   aopOp (right, ic, FALSE);
 
@@ -8886,12 +8888,12 @@ gen51Code (iCode * lic)
   lineHead = lineCurr = NULL;
 
   /* print the allocation information */
-  if (allocInfo)
+  if (allocInfo && currFunc)
     printAllocInfo (currFunc, codeOutFile);
   /* if debug information required */
   if (options.debug && currFunc)
     {
-      cdbSymbol (currFunc, cdbFile, FALSE, TRUE);
+      debugFile->writeFunction(currFunc);
       _G.debugLine = 1;
       if (IS_STATIC (currFunc->etype))
        emitcode ("", "F%s$%s$0$0 ==.", moduleName, currFunc->name);
@@ -8919,10 +8921,23 @@ gen51Code (iCode * lic)
                        ic->level, ic->block);
              _G.debugLine = 0;
            }
-         emitcode ("", "; %s:%d: %s", ic->filename, ic->lineno, 
-                   printCLine(ic->filename, ic->lineno));
+         if (!options.noCcodeInAsm) {
+           emitcode ("", ";%s:%d: %s", ic->filename, ic->lineno, 
+                     printCLine(ic->filename, ic->lineno));
+         }
          cln = ic->lineno;
        }
+      if (options.iCodeInAsm) {
+       char regsInUse[80];
+       int i;
+
+       for (i=0; i<8; i++) {
+         sprintf (&regsInUse[i],
+                  "%c", ic->riu & (1<<i) ? i+'0' : '-'); 
+       }
+       regsInUse[i]=0;
+       emitcode("", "; [%s] ic:%d: %s", regsInUse, ic->seq, printILine(ic));
+      }
       /* if the result is marked as
          spilt and rematerializable or code for
          this has already been generated then