Fix null pointer deref that caused build failures on Solaris
[fw/sdcc] / src / ds390 / gen.c
index dca1d9e0ebbff09cc1c6257eaac7274bdda18c51..d417b07fc9afe1de751f7ed6112b74f7b547de3f 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
-
 #define BETTER_LITERAL_SHIFT
 
 char *aopLiteral (value * val, int offset);
@@ -109,22 +92,9 @@ static void saveRBank (int, iCode *, bool);
                          (IC_RESULT(x) && IC_RESULT(x)->aop && \
                          IC_RESULT(x)->aop->type == AOP_STK )
 
-/* #define MOVA(x) if (strcmp(x,"a") && strcmp(x,"acc")) emitcode("mov","a,%s",x); */
-#define MOVA(x) { \
-                char *_mova_tmp = strdup(x); \
-                 if (strcmp(_mova_tmp,"a") && strcmp(_mova_tmp,"acc")) \
-                 { \
-                    emitcode("mov","a,%s",_mova_tmp); \
-                 } \
-                 free(_mova_tmp); \
-                }
-#define MOVB(x) { char *_movb_tmp = strdup(x); \
-                 if (strcmp(_movb_tmp,"b")) \
-                 { \
-                    emitcode("mov","b,%s",_movb_tmp); \
-                 } \
-                 free(_movb_tmp); \
-                }
+#define MOVA(x) _movA(x)
+#define MOVB(x) _movB(x)
+                
 #define CLRC    emitcode("clr","c")
 #define SETC    emitcode("setb","c")
 
@@ -210,6 +180,30 @@ emitcode (char *inst, char *fmt,...)
     va_end (ap);
 }
 
+//
+// Move the passed value into A unless it is already there.
+// 
+static void
+_movA(const char *s)
+{
+    if (strcmp(s,"a") && strcmp(s,"acc"))
+    { 
+       emitcode("mov","a,%s",s);
+    } 
+}
+
+//
+// Move the passed value into B unless it is already there.
+// 
+static void
+_movB(const char *s)
+{
+    if (strcmp(s,"b"))
+    { 
+       emitcode("mov","b,%s",s);
+    } 
+}
+
 /*-----------------------------------------------------------------*/
 /* getFreePtr - returns r0 or r1 whichever is free or can be pushed */
 /*-----------------------------------------------------------------*/
@@ -666,7 +660,7 @@ aopForRemat (symbol * sym)
                "(%s %c 0x%04x)",
                OP_SYMBOL (IC_LEFT (ic))->rname,
                val >= 0 ? '+' : '-',
-               abs (val) & 0xffff);
+               abs (val) & 0xffffff);
   }
   else 
   {
@@ -1150,11 +1144,11 @@ aopGet (asmop *aop,
       if (saveAcc)
        {
            TR_AP("#1");
-           if (aop->type != AOP_DPTR2)
-           {
-               if (saveAccWarn) { fprintf(stderr, "saveAcc for DPTR...\n"); }
-               emitcode(";", "spanky: saveAcc for DPTR");
-           }
+//         if (aop->type != AOP_DPTR2)
+//         {
+//             if (saveAccWarn) { fprintf(stderr, "saveAcc for DPTR...\n"); }
+//             emitcode(";", "spanky: saveAcc for DPTR");
+//         }
            
            emitcode ("xch", "a, %s", saveAcc);
        }
@@ -1193,10 +1187,10 @@ aopGet (asmop *aop,
        {
        TR_AP("#2");
              emitcode ("xch", "a, %s", saveAcc);
-             if (strcmp(saveAcc, "_ap"))
-             {
-                 emitcode(";", "spiffy: non _ap return from aopGet.");
-             }
+//           if (strcmp(saveAcc, "_ap"))
+//           {
+//               emitcode(";", "spiffy: non _ap return from aopGet.");
+//           }
                  
              return saveAcc;
        }
@@ -1609,7 +1603,6 @@ static void
 genNotFloat (operand * op, operand * res)
 {
   int size, offset;
-  char *l;
   symbol *tlbl;
 
   D (emitcode (";", "genNotFloat "););
@@ -1621,8 +1614,7 @@ genNotFloat (operand * op, operand * res)
   offset = 1;
 
   _startLazyDPSEvaluation ();
-  l = aopGet (op->aop, offset++, FALSE, FALSE, NULL);
-  MOVA (l);
+  MOVA(aopGet(op->aop, offset++, FALSE, FALSE, NULL));
 
   while (size--)
     {
@@ -1770,7 +1762,7 @@ toBoolean (operand * oper)
       else
        {
          emitcode ("orl", "a,%s",
-                   aopGet (AOP (oper), offset++, FALSE, FALSE, DP2_RESULT_REG));
+                   aopGet (AOP (oper), offset++, FALSE, FALSE, NULL));
        }
     }
   _endLazyDPSEvaluation ();
@@ -2042,11 +2034,14 @@ saveRegisters (iCode * lic)
 
   /* if the registers have been saved already then
      do nothing */
-  if (ic->regsSaved || IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT(ic)))) return ;
+  if (ic->regsSaved || 
+      (IS_SYMOP(IC_LEFT(ic)) && IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT(ic)))))
+    return ;
 
   /* special case if DPTR alive across a function call then must save it 
      even though callee saves */
-  if (IFFUNC_CALLEESAVES(OP_SYMBOL (IC_LEFT (ic))->type)) {
+  if (IS_SYMOP(IC_LEFT(ic)) &&
+      IFFUNC_CALLEESAVES(OP_SYMBOL (IC_LEFT (ic))->type)) {
       int i;
       rsave = newBitVect(ic->rMask->size);
       for (i = DPL_IDX ; i <= B_IDX ; i++ ) {
@@ -2151,7 +2146,24 @@ assignResultValue (operand * oper)
 {
   int offset = 0;
   int size = AOP_SIZE (oper);
+  bool pushedAcc = FALSE;
 
+  if (size == fReturnSizeDS390)
+  {
+      /* I don't think this case can ever happen... */
+      /* ACC is the last part of this. If writing the result
+       * uses AC, we must preserve it.
+       */
+      if (AOP_NEEDSACC(oper))
+      {
+         emitcode(";", "assignResultValue special case for ACC.");
+         emitcode("push", "acc");
+         pushedAcc = TRUE;
+         size--;
+      }
+  }
+    
+    
   _startLazyDPSEvaluation ();
   while (size--)
     {
@@ -2159,6 +2171,12 @@ assignResultValue (operand * oper)
       offset++;
     }
   _endLazyDPSEvaluation ();
+    
+  if (pushedAcc)
+    {
+       emitcode("pop", "acc");
+       aopPut(AOP(oper), "a", offset);
+    }
 }
 
 
@@ -3018,7 +3036,7 @@ genFunction (iCode * ic)
                     }
                }
            }
-           // jwk: this needs a closer look
+           // TODO: this needs a closer look
            SPEC_ISR_SAVED_BANKS(currFunc->etype) = banksToSave;
        }
     }
@@ -3241,7 +3259,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;
          
@@ -4052,10 +4069,10 @@ genPlus (iCode * ic)
          MOVA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE, FALSE, NULL));
          if (offset == 0)
            emitcode ("add", "a,%s",
-                aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, DP2_RESULT_REG));
+                aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, NULL));
          else
            emitcode ("addc", "a,%s",
-                aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, DP2_RESULT_REG));
+                aopGet (AOP (IC_RIGHT (ic)), offset, FALSE, FALSE, NULL));
        }
       else
        {
@@ -4200,7 +4217,7 @@ genMinusDec (iCode * ic)
          emitcode ("mov", "a,#!constbyte",0xff);
          emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
       }
-      l = aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, NULL, NULL);
+      l = aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, NULL);
       emitcode ("dec", "%s", l);
       if (size > 2)
        {
@@ -4219,7 +4236,7 @@ genMinusDec (iCode * ic)
                emitcode ("mov", "a,#!constbyte",0xff);
                emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
            }
-           l = aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, NULL, NULL);
+           l = aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, NULL);
            emitcode ("dec", "%s", l);
        }
       if (size > 3)
@@ -4239,7 +4256,7 @@ genMinusDec (iCode * ic)
                emitcode ("mov", "a,#!constbyte",0xff);
                emitcode ("cjne", "a,%s,!tlabel", l, tlbl->key + 100);
            }       
-           l = aopGet (AOP (IC_RESULT (ic)), MSB32, FALSE, NULL, NULL);
+           l = aopGet (AOP (IC_RESULT (ic)), MSB32, FALSE, FALSE, NULL);
            emitcode ("dec", "%s", l);
        }
       if (emitTlbl)
@@ -5371,7 +5388,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
     {
@@ -5597,7 +5614,7 @@ gencjneshort (operand * left, operand * right, symbol * lbl)
        {
          MOVA (aopGet (AOP (left), offset, FALSE, FALSE, NULL));
          emitcode ("cjne", "a,%s,!tlabel",
-                   aopGet (AOP (right), offset, FALSE, FALSE, DP2_RESULT_REG),
+                   aopGet (AOP (right), offset, FALSE, FALSE, NULL),
                    lbl->key + 100);
          offset++;
        }
@@ -6321,7 +6338,7 @@ genAnd (iCode * ic, iCode * ifx)
              else
                emitcode ("anl", "%s,%s",
                          aopGet (AOP (left), offset, FALSE, TRUE, NULL),
-                         aopGet (AOP (right), offset, FALSE, FALSE, DP2_RESULT_REG));
+                         aopGet (AOP (right), offset, FALSE, FALSE, NULL));
            }
          else
            {
@@ -9315,8 +9332,7 @@ genFarPointerGet (operand * left,
          else
            {
              /* We need to generate a load to DPTR indirect through DPTR. */
-             D (emitcode (";", "genFarPointerGet -- indirection special case.");
-               );
+             D (emitcode (";", "genFarPointerGet -- indirection special case."););
              emitcode ("push", "%s", aopGet (AOP (left), 0, FALSE, TRUE, NULL));
              emitcode ("push", "%s", aopGet (AOP (left), 1, FALSE, TRUE, NULL));
              if (options.model == MODEL_FLAT24)
@@ -9375,15 +9391,18 @@ genFarPointerGet (operand * left,
     }
   if (dopi && pi && AOP_TYPE (left) != AOP_IMMD) {
       if (!AOP_INDPTRn(left)) {
+         _startLazyDPSEvaluation ();
          aopPut ( AOP (left), "dpl", 0);
          aopPut ( AOP (left), "dph", 1);
          if (options.model == MODEL_FLAT24)
              aopPut ( AOP (left), "dpx", 2);
+         _endLazyDPSEvaluation ();
       }
     pi->generated = 1;
-  } else if ((OP_SYMBOL(left)->ruonly || AOP_INDPTRn(left)) && 
+  } else if ((AOP_IS_STR(left) || AOP_INDPTRn(left)) && 
             AOP_SIZE(result) > 1 &&
-            (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
+            IS_SYMOP(left) &&
+            (OP_SYMBOL(left)->liveTo > ic->seq || ic->depth)) {
       
       size = AOP_SIZE (result) - 1;
       if (AOP_INDPTRn(left)) {
@@ -9433,8 +9452,7 @@ genCodePointerGet (operand * left,
          else
            {
              /* We need to generate a load to DPTR indirect through DPTR. */
-             D (emitcode (";", "gencodePointerGet -- indirection special case.");
-               );
+             D (emitcode (";", "gencodePointerGet -- indirection special case."););
              emitcode ("push", "%s", aopGet (AOP (left), 0, FALSE, TRUE, NULL));
              emitcode ("push", "%s", aopGet (AOP (left), 1, FALSE, TRUE, NULL));
              if (options.model == MODEL_FLAT24)
@@ -9494,10 +9512,14 @@ genCodePointerGet (operand * left,
     }
   if (dopi && pi && AOP_TYPE (left) != AOP_IMMD) {
       if (!AOP_INDPTRn(left)) {
+         _startLazyDPSEvaluation ();
+         
          aopPut ( AOP (left), "dpl", 0);
          aopPut ( AOP (left), "dph", 1);
          if (options.model == MODEL_FLAT24)
              aopPut ( AOP (left), "dpx", 2);
+
+         _endLazyDPSEvaluation ();
       }
       pi->generated = 1;
   } else if ((OP_SYMBOL(left)->ruonly || AOP_INDPTRn(left)) && 
@@ -9610,12 +9632,17 @@ genGenPointerGet (operand * left,
     }
 
   if (pi && AOP_TYPE (left) != AOP_IMMD) {
+    _startLazyDPSEvaluation ();
+      
     aopPut ( AOP (left), "dpl", 0);
     aopPut ( AOP (left), "dph", 1);
     if (options.model == MODEL_FLAT24) {
        aopPut ( AOP (left), "dpx", 2);
        aopPut ( AOP (left), "b", 3);   
     } else  aopPut ( AOP (left), "b", 2);      
+    
+    _endLazyDPSEvaluation ();
+      
     pi->generated = 1;
   } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 &&
             (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) {
@@ -10186,10 +10213,14 @@ genFarPointerSet (operand * right,
   
   if (dopi && pi && AOP_TYPE (result) != AOP_IMMD) {
       if (!AOP_INDPTRn(result)) {
+         _startLazyDPSEvaluation ();
+         
          aopPut (AOP(result),"dpl",0);
          aopPut (AOP(result),"dph",1);
          if (options.model == MODEL_FLAT24)
              aopPut (AOP(result),"dpx",2);
+
+         _endLazyDPSEvaluation ();
       }
       pi->generated=1;
   } else if ((OP_SYMBOL(result)->ruonly || AOP_INDPTRn(result)) && 
@@ -10254,33 +10285,63 @@ genGenPointerSet (operand * right,
        }
       _endLazyDPSEvaluation ();
     }
-  /* so dptr know contains the address */
+  /* so dptr + b now contains the address */
+  _G.bInUse++;
   aopOp (right, ic, FALSE, TRUE);
+  _G.bInUse--;
+    
 
   /* if bit then unpack */
   if (IS_BITVAR (retype) || IS_BITVAR (letype))
-    genPackBits ((IS_BITVAR (retype) ? retype : letype), right, "dptr", GPOINTER);
+    {
+       genPackBits ((IS_BITVAR (retype) ? retype : letype), right, "dptr", GPOINTER);
+    }
   else
     {
-      size = AOP_SIZE (right);
-      offset = 0;
+       size = AOP_SIZE (right);
+       offset = 0;
 
-      _startLazyDPSEvaluation ();
-      while (size--)
+       _startLazyDPSEvaluation ();
+       while (size--)
        {
-         MOVA (aopGet (AOP (right), offset++, FALSE, FALSE, NULL));
-
-         genSetDPTR (0);
-         _flushLazyDPS ();
+           if (size)
+           {
+               // Set two bytes at a time, passed in _AP & A.
+               // dptr will be incremented ONCE by __gptrputWord.
+               //
+               // Note: any change here must be coordinated
+               // with the implementation of __gptrputWord
+               // in device/lib/_gptrput.c
+               emitcode("mov", "_ap, %s", 
+                        aopGet (AOP (right), offset++, FALSE, FALSE, NULL));
+               MOVA (aopGet (AOP (right), offset++, FALSE, FALSE, NULL));
+               
+               genSetDPTR (0);
+               _flushLazyDPS ();
+               emitcode ("lcall", "__gptrputWord");
+               size--;
+           }
+           else
+           {
+               // Only one byte to put.
+               MOVA (aopGet (AOP (right), offset++, FALSE, FALSE, NULL));
 
-         emitcode ("lcall", "__gptrput");
-         if (size || (pi && AOP_TYPE (result) != AOP_IMMD))
-           emitcode ("inc", "dptr");
+               genSetDPTR (0);
+               _flushLazyDPS ();               
+               emitcode ("lcall", "__gptrput");
+           }
+           
+           if (size || (pi && AOP_TYPE (result) != AOP_IMMD))
+           {
+               emitcode ("inc", "dptr");
+           }
        }
-      _endLazyDPSEvaluation ();
+       _endLazyDPSEvaluation ();
     }
 
   if (pi && AOP_TYPE (result) != AOP_IMMD) {
+      _startLazyDPSEvaluation ();
+      
       aopPut (AOP(result),"dpl",0);
       aopPut (AOP(result),"dph",1);
       if (options.model == MODEL_FLAT24) {
@@ -10289,6 +10350,8 @@ genGenPointerSet (operand * right,
       } else {
          aopPut (AOP(result),"b",2);
       }
+      _endLazyDPSEvaluation ();
+      
       pi->generated=1;
   } else if (OP_SYMBOL(result)->ruonly && AOP_SIZE(right) > 1 &&
             (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) {
@@ -10503,13 +10566,13 @@ genAddrOf (iCode * ic)
       if (offset) {
          switch (offset) {
          case 1:
-             tsprintf(s, sizeof(s), "!his",sym->rname);
+             tsprintf(s, sizeof(s), "#!his",sym->rname);
              break;
          case 2:
-             tsprintf(s, sizeof(s), "!hihis",sym->rname);
+             tsprintf(s, sizeof(s), "#!hihis",sym->rname);
              break;
          case 3:
-             tsprintf(s, sizeof(s), "!hihihis",sym->rname);
+             tsprintf(s, sizeof(s), "#!hihihis",sym->rname);
              break;
          default: /* should not need this (just in case) */
              SNPRINTF (s, sizeof(s), "#(%s >> %d)",
@@ -11201,53 +11264,55 @@ genDjnz (iCode * ic, iCode * ifx)
 static void
 genReceive (iCode * ic)
 {
-
     int size = getSize (operandType (IC_RESULT (ic)));
     int offset = 0;
     int rb1off ;
     
-    D (emitcode (";", "genReceive ");
-       );
+    D (emitcode (";", "genReceive "););
 
-  if (ic->argreg == 1) { /* first parameter */
-      if (isOperandInFarSpace (IC_RESULT (ic)) &&
-         (OP_SYMBOL (IC_RESULT (ic))->isspilt ||
-          IS_TRUE_SYMOP (IC_RESULT (ic))))
-         {
-             offset = fReturnSizeDS390 - size;
-             while (size--)
-                 {
-                     emitcode ("push", "%s", (strcmp (fReturn[fReturnSizeDS390 - offset - 1], "a") ?
-                                              fReturn[fReturnSizeDS390 - offset - 1] : "acc"));
-                     offset++;
-                 }
-             aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
-             size = AOP_SIZE (IC_RESULT (ic));
-             offset = 0;
-             while (size--)
-                 {
-                     emitcode ("pop", "acc");
-                     aopPut (AOP (IC_RESULT (ic)), "a", offset++);
-                 }
-             
-         } else {
-             _G.accInUse++;
-             aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
-             _G.accInUse--;
-             assignResultValue (IC_RESULT (ic));
-         }
-  } else { /* second receive onwards */
-      /* this gets a little tricky since unused recevies will be
+    if (ic->argreg == 1) 
+    {
+       /* first parameter */
+       if (AOP_IS_STR(IC_RESULT(ic)))
+       {
+           /* Nothing to do: it's already in the proper place. */
+           return;
+       }
+       else
+       {
+           bool useDp2;
+           
+           useDp2 = isOperandInFarSpace (IC_RESULT (ic)) &&
+               (OP_SYMBOL (IC_RESULT (ic))->isspilt ||
+                IS_TRUE_SYMOP (IC_RESULT (ic)));
+           
+           _G.accInUse++;
+           aopOp (IC_RESULT (ic), ic, FALSE, useDp2);
+           _G.accInUse--; 
+           
+           /* Sanity checking... */
+           if (AOP_USESDPTR(IC_RESULT(ic)))
+           {
+               werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                       "genReceive got unexpected DPTR.");
+           }
+           assignResultValue (IC_RESULT (ic));
+       }
+    } 
+    else 
+    { 
+       /* second receive onwards */
+       /* this gets a little tricky since unused recevies will be
         eliminated, we have saved the reg in the type field . and
         we use that to figure out which register to use */
-      aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
-      rb1off = ic->argreg;
-      while (size--) {
-         aopPut (AOP (IC_RESULT (ic)), rb1regs[rb1off++ -5], offset++);
-      }
-      
-  }
-  freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+       aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
+       rb1off = ic->argreg;
+       while (size--) 
+       {
+           aopPut (AOP (IC_RESULT (ic)), rb1regs[rb1off++ -5], offset++);
+       }
+    }
+    freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -12145,9 +12210,14 @@ static void genMMDeref (iCode *ic,int nparms, operand **parms)
                if (rsym->liveFrom != rsym->liveTo) {                   
                        aopOp (IC_RESULT(ic),ic,FALSE,FALSE);
                        if (AOP_TYPE(IC_RESULT(ic)) != AOP_STR) {
+                           _startLazyDPSEvaluation ();
+                           
                                aopPut(AOP(IC_RESULT(ic)),"dpl",0);
                                aopPut(AOP(IC_RESULT(ic)),"dph",1);
                                aopPut(AOP(IC_RESULT(ic)),"dpx",2);
+
+                           _endLazyDPSEvaluation ();
+                           
                        }
                }
        }
@@ -12627,13 +12697,13 @@ gen390Code (iCode * lic)
   }
 #if 1
   /* print the allocation information */
-  if (allocInfo)
+  if (allocInfo && currFunc)
     printAllocInfo (currFunc, codeOutFile);
 #endif
   /* 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);