* as/hc08/lkaomf51.c (OutputName): made name unsigned char,
[fw/sdcc] / src / z80 / gen.c
index cd669c7c359f3741344515ea5947182b254badd1..72d5726683ebcc6742b85efb135b77742e0331a3 100644 (file)
@@ -442,6 +442,19 @@ emitDebug (const char *szFormat,...)
     }
 }
 
+/*-----------------------------------------------------------------*/
+/* z80_emitDebuggerSymbol - associate the current code location    */
+/*   with a debugger symbol                                        */
+/*-----------------------------------------------------------------*/
+void
+z80_emitDebuggerSymbol (char * debugSym)
+{
+  _G.lines.isDebug = 1;
+  emit2 ("%s !equ .", debugSym);
+  emit2 ("!global", debugSym);
+  _G.lines.isDebug = 0;
+}
+
 /*-----------------------------------------------------------------*/
 /* emit2 - writes the code into a file : for now it is simple    */
 /*-----------------------------------------------------------------*/
@@ -450,7 +463,7 @@ _emit2 (const char *inst, const char *fmt,...)
 {
   va_list ap;
   char lb[INITIAL_INLINEASM];
-  char *lbp = lb;
+  unsigned char *lbp = lb;
 
   va_start (ap, fmt);
 
@@ -934,10 +947,10 @@ operandsEqu (operand * op1, operand * op2)
   if (sym1 == sym2)
     return 1;
 
-  if (strcmp (sym1->rname, sym2->rname) == 0)
+  if (sym1->rname[0] && sym2->rname[0]
+      && strcmp (sym1->rname, sym2->rname) == 0)
     return 2;
 
-
   /* if left is a tmp & right is not */
   if (IS_ITEMP (op1) &&
       !IS_ITEMP (op2) &&
@@ -1866,48 +1879,46 @@ aopPut (asmop * aop, const char *s, int offset)
 
     case AOP_SFR:
       if( IS_GB )
-      {
-        //  wassert (IS_GB);
-        if (strcmp (s, "a"))
-          emit2 ("ld a,%s", s);
-        emit2 ("ldh (%s+%d),a", aop->aopu.aop_dir, offset);
-      }
+        {
+          //  wassert (IS_GB);
+          if (strcmp (s, "a"))
+            emit2 ("ld a,%s", s);
+          emit2 ("ldh (%s+%d),a", aop->aopu.aop_dir, offset);
+        }
       else
-      { /*.p.t.20030716 handling for i/o port read access for Z80 */
-        if( aop->paged )
-        { /* banked mode */
-          if( aop->bcInUse )  emit2( "push bc" );
-
-          emit2( "ld bc,#%s", aop->aopu.aop_dir );
-
-          if(( s[0] == '#'    ) /* immediate number */
-           ||( s[0] == '('    ) /* indirect register (ix or iy ??)*/
-           ||( isdigit( s[0] )))/* indirect register with offset (ix or iy ??)*/
-          {
-            emit2( "ld a,%s", s );
-            emit2( "out (c),a"  );
-          }
-          else
-          {
-            emit2( "out (c),%s", s );
-          }
+        { /*.p.t.20030716 handling for i/o port read access for Z80 */
+          if (aop->paged)
+            { /* banked mode */
+              if (aop->bcInUse)
+                emit2( "push bc" );
+
+              if (strlen(s) != 1
+                  || (s[0] != 'a' && s[0] != 'd' && s[0] != 'e'
+                      && s[0] != 'h' && s[0] != 'l'))
+                {
+                  emit2( "ld a,%s", s );
+                  s = "a";
+                }
+              
+              emit2( "ld bc,#%s", aop->aopu.aop_dir );
+              emit2( "out (c),%s", s );
         
-          if( aop->bcInUse )
-            emit2( "pop bc"    );
+              if( aop->bcInUse )
+                emit2( "pop bc"    );
+              else
+                spillPair (PAIR_BC);
+            }
+          else if( z80_opts.port_mode == 180 )
+            { /* z180 in0/out0 mode */
+              emit2( "ld a,%s", s );
+              emit2( "out0 (%s),a", aop->aopu.aop_dir );
+            }
           else
-            spillPair (PAIR_BC);
-        }
-        else if( z80_opts.port_mode == 180 )
-        { /* z180 in0/out0 mode */
-          emit2( "ld a,%s", s );
-          emit2( "out0 (%s),a", aop->aopu.aop_dir );
-        }
-        else
-        { /* 8 bit mode */
-          emit2( "ld a,%s", s );
-          emit2( "out (%s),a", aop->aopu.aop_dir );
+            { /* 8 bit mode */
+              emit2( "ld a,%s", s );
+              emit2( "out (%s),a", aop->aopu.aop_dir );
+            }
         }
-      }
       break;
 
     case AOP_REG:
@@ -2384,7 +2395,7 @@ genUminusFloat (operand * op, operand * result)
   emitDebug("; genUminusFloat");
 
   /* for this we just need to flip the
-     first it then copy the rest in place */
+     first bit then copy the rest in place */
   size = AOP_SIZE (op) - 1;
 
   _moveA(aopGet (AOP (op), MSB32, FALSE));
@@ -2903,7 +2914,7 @@ emitCall (iCode * ic, bool ispcall)
     }
   spillCached ();
 
-  /* Mark the regsiters as restored. */
+  /* Mark the registers as restored. */
   _G.saves.saved = FALSE;
 
   /* if we need assign a result value */
@@ -3089,8 +3100,11 @@ genFunction (iCode * ic)
   
   /* Create the function header */
   emit2 ("!functionheader", sym->name);
-  sprintf (buffer, "%s_start", sym->rname);
-  emit2 ("!labeldef", buffer);
+  if (!IS_STATIC(sym->etype))
+    {
+      sprintf (buffer, "%s_start", sym->rname);
+      emit2 ("!labeldef", buffer);
+    }
   emit2 ("!functionlabeldef", sym->rname);
 
   if (options.profile) 
@@ -3100,14 +3114,21 @@ genFunction (iCode * ic)
 
   ftype = operandType (IC_LEFT (ic));
 
-  /* if critical function then turn interrupts off */
-  if (IFFUNC_ISCRITICAL (ftype))
-    emit2 ("!di");
-
   /* if this is an interrupt service routine then save all potentially used registers. */
   if (IFFUNC_ISISR (sym->type))
     {
-      emit2 ("!pusha");
+      if (!FUNC_ISNAKED( sym->type ))
+        {
+          emit2 ("!pusha");
+       }
+    }
+  else
+    {
+      /* if critical function then turn interrupts off */
+      if (IFFUNC_ISCRITICAL (sym->type))
+        {
+          emit2 ("!di");
+       }
     }
 
   /* PENDING: callee-save etc */
@@ -3205,74 +3226,83 @@ genEndFunction (iCode * ic)
 {
   symbol *sym = OP_SYMBOL (IC_LEFT (ic));
 
-  if (IFFUNC_ISISR (sym->type))
+
+  /* PENDING: calleeSave */
+  if (IS_Z80 && _G.omitFramePtr)
     {
-      wassertl (0, "Tried to close an interrupt support function");
+      if (_G.stack.offset)
+        emit2 ("!ldaspsp", _G.stack.offset);
     }
-  else
+  else if (_G.stack.offset && IS_GB && _G.stack.offset > INT8MAX)
     {
-      if (IFFUNC_ISCRITICAL (sym->type))
-       emit2 ("!ei");
-
-      /* PENDING: calleeSave */
-
-      if (IS_Z80 && _G.omitFramePtr)
-        {
-          if (_G.stack.offset)
-            emit2 ("!ldaspsp", _G.stack.offset);
-        }
-      else if (_G.stack.offset && IS_GB && _G.stack.offset > INT8MAX)
-        {
-          emit2 ("!leavexl", _G.stack.offset);
-        }
-      else if (_G.stack.offset)
-        {
-          emit2 ("!leavex", _G.stack.offset);
-        }
-      else if( !FUNC_ISNAKED( sym->type )) /*.p.t.20030716 - now supporting Naked funcitons */
-        {
-          emit2 ("!leave");
-        }
+      emit2 ("!leavexl", _G.stack.offset);
+    }
+  else if (_G.stack.offset)
+    {
+      emit2 ("!leavex", _G.stack.offset);
+    }
+  else if( !FUNC_ISNAKED( sym->type )) /*.p.t.20030716 - now supporting Naked funcitons */
+    {
+      emit2 ("!leave");
+    }
+      
+  if (_G.calleeSaves.pushedDE) 
+    {
+      emit2 ("pop de");
+      _G.calleeSaves.pushedDE = FALSE;
+    }
 
-      if (_G.calleeSaves.pushedDE
-        {
-          emit2 ("pop de");
-          _G.calleeSaves.pushedDE = FALSE;
-        }
+  if (_G.calleeSaves.pushedBC
+    {
+      emit2 ("pop bc");
+      _G.calleeSaves.pushedBC = FALSE;
+    }
 
-      if (_G.calleeSaves.pushedBC) 
-        {
-          emit2 ("pop bc");
-          _G.calleeSaves.pushedBC = FALSE;
-        }
+  if (options.profile) 
+    {
+      emit2 ("!profileexit");
+    }
 
-      if (options.profile) 
+  /* if this is an interrupt service routine then restore all potentially used registers. */
+  if (IFFUNC_ISISR (sym->type))
+    {
+      if (!FUNC_ISNAKED( sym->type ))
         {
-          emit2 ("!profileexit");
+          emit2 ("!popa");
         }
+    }
+  else
+    {
+      /* if critical function then turn interrupts back on */
+      if (IFFUNC_ISCRITICAL (sym->type))
+        emit2 ("!ei");
+    }
 
-
-      if (options.debug && currFunc)
-       {
-         _G.lines.isDebug = 1;
-         sprintf (buffer, "C$%s$%d$%d$%d",
-                   FileBaseName (ic->filename), currFunc->lastLine,
-                   ic->level, ic->block);
-          emit2 ("!labeldef", buffer);
-         if (IS_STATIC (currFunc->etype))
-           sprintf (buffer, "XF%s$%s$0$0", moduleName, currFunc->name);
-         else
-           sprintf (buffer, "XG$%s$0$0", currFunc->name);
-          emit2 ("!labeldef", buffer);
-         _G.lines.isDebug = 0;
-       }
+  if (options.debug && currFunc)
+    {
+      debugFile->writeEndFunction (currFunc, ic, 1);
+    }
       
+  if (IFFUNC_ISISR (sym->type))
+    {
+      /* "critical interrupt" is used to imply NMI handler */
+      if (IS_Z80 && IFFUNC_ISCRITICAL (sym->type))
+        emit2 ("retn");
+      else
+        emit2 ("reti");
+    }
+  else
+    {
       /* Both banked and non-banked just ret */
       emit2 ("ret");
-
+    }
+      
+  if (!IS_STATIC(sym->etype))
+    {
       sprintf (buffer, "%s_end", sym->rname);
       emit2 ("!labeldef", buffer);
     }
+  
   _G.flushStatics = 1;
   _G.stack.pushed = 0;
   _G.stack.offset = 0;
@@ -4042,11 +4072,14 @@ genMult (iCode * ic)
   int count, i;
   /* If true then the final operation should be a subtract */
   bool active = FALSE;
+  bool byteResult;
 
   /* Shouldn't occur - all done through function calls */
   aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
   aopOp (IC_RIGHT (ic), ic, FALSE, FALSE);
   aopOp (IC_RESULT (ic), ic, TRUE, FALSE);
+  
+  byteResult =  (AOP_SIZE (IC_RESULT (ic)) == 1);
 
   if (AOP_SIZE (IC_LEFT (ic)) > 2 ||
       AOP_SIZE (IC_RIGHT (ic)) > 2 ||
@@ -4077,10 +4110,13 @@ genMult (iCode * ic)
   if ( AOP_SIZE (IC_LEFT (ic)) == 1 && !SPEC_USIGN (getSpec (operandType ( IC_LEFT (ic)))))
     {
       emit2 ("ld e,%s", aopGet (AOP (IC_LEFT (ic)), LSB, FALSE));
-      emit2 ("ld a,e");
-      emit2 ("rlc a");
-      emit2 ("sbc a,a");
-      emit2 ("ld d,a");
+      if (!byteResult)
+        {
+          emit2 ("ld a,e");
+          emit2 ("rlc a");
+          emit2 ("sbc a,a");
+          emit2 ("ld d,a");
+       }
     }
   else
     {
@@ -4102,7 +4138,8 @@ genMult (iCode * ic)
           if (active == FALSE)
             {
               emit2 ("ld l,e");
-              emit2 ("ld h,d");
+              if (!byteResult)
+               emit2 ("ld h,d");
             }
           else
             {
@@ -4121,7 +4158,10 @@ genMult (iCode * ic)
       _G.stack.pushedDE = FALSE;
     }
 
-  commitPair ( AOP (IC_RESULT (ic)), PAIR_HL);
+  if (byteResult)
+    aopPut (AOP (IC_RESULT (ic)), _pairs[PAIR_HL].l, 0);
+  else
+    commitPair ( AOP (IC_RESULT (ic)), PAIR_HL);
 
   freeAsmop (IC_LEFT (ic), NULL, ic);
   freeAsmop (IC_RIGHT (ic), NULL, ic);
@@ -6001,6 +6041,9 @@ genLeftShift (iCode * ic)
   aopOp (left, ic, FALSE, FALSE);
   aopOp (result, ic, FALSE, FALSE);
 
+  if (AOP_TYPE (left) != AOP_REG || AOP_TYPE (result) != AOP_REG)
+     _push (PAIR_AF);
+  
   /* now move the left to the result if they are not the
      same */
 
@@ -6022,6 +6065,9 @@ genLeftShift (iCode * ic)
   offset = 0;
   tlbl1 = newiTempLabel (NULL);
 
+  if (AOP_TYPE (left) != AOP_REG || AOP_TYPE (result) != AOP_REG)
+     _pop (PAIR_AF);
+  
   emit2 ("!shortjp !tlabel", tlbl1->key + 100);
   emitLabel (tlbl->key + 100);
   l = aopGet (AOP (result), offset, FALSE);
@@ -6275,6 +6321,9 @@ genRightShift (iCode * ic)
   aopOp (left, ic, FALSE, FALSE);
   aopOp (result, ic, FALSE, FALSE);
 
+  if (AOP_TYPE (left) != AOP_REG || AOP_TYPE (result) != AOP_REG)
+     _push (PAIR_AF);
+  
   /* now move the left to the result if they are not the
      same */
   if (!sameRegs (AOP (left), AOP (result)))
@@ -6294,6 +6343,9 @@ genRightShift (iCode * ic)
   tlbl1 = newiTempLabel (NULL);
   size = AOP_SIZE (result);
   offset = size - 1;
+  
+  if (AOP_TYPE (left) != AOP_REG || AOP_TYPE (result) != AOP_REG)
+     _pop (PAIR_AF);
 
   emit2 ("!shortjp !tlabel", tlbl1->key + 100);
   emitLabel (tlbl->key + 100);
@@ -6802,7 +6854,7 @@ genGenPointerSet (operand * right,
     {
       fetchPair (pairId, AOP (result));
     }
-  /* so hl know contains the address */
+  /* so hl now contains the address */
   freeAsmop (result, NULL, ic);
 
   /* if bit then unpack */
@@ -7395,7 +7447,7 @@ _rleCommit(RLECTX *self)
     chunks.
 */
 static void
-_rleAppend(RLECTX *self, int c)
+_rleAppend(RLECTX *self, unsigned c)
 {
   int i;
 
@@ -7478,13 +7530,27 @@ genArrayInit (iCode * ic)
     
   if (type && type->next)
     {
-      elementSize = getSize(type->next);
+      if (IS_SPEC(type->next) || IS_PTR(type->next))
+        {
+          elementSize = getSize(type->next);
+        }
+      else if (IS_ARRAY(type->next) && type->next->next)
+        {
+          elementSize = getSize(type->next->next);
+        }
+      else
+        {
+         printTypeChainRaw (type, NULL);
+          wassertl (0, "Can't determine element size in genArrayInit.");
+        }
     }
   else
     {
       wassertl (0, "Can't determine element size in genArrayInit.");
     }
 
+  wassertl ((elementSize > 0) && (elementSize <= 4), "Illegal element size in genArrayInit.");
+
   iLoop = IC_ARRAYILIST(ic);
   lastVal = (unsigned)-1;
 
@@ -7497,17 +7563,14 @@ genArrayInit (iCode * ic)
     {
       ix = iLoop->count;
 
-      if (ix != 0)
+      for (i = 0; i < ix; i++)
         {
-          for (i = 0; i < ix; i++)
+          for (eIndex = 0; eIndex < elementSize; eIndex++)
             {
-              for (eIndex = 0; eIndex < elementSize; eIndex++)
-                {
-                  val = (((int)iLoop->literalValue) >> (eIndex * 8)) & 0xff;
-                  _rleAppend(&rle, val);
-                }
+              val = (((int)iLoop->literalValue) >> (eIndex * 8)) & 0xff;
+              _rleAppend(&rle, val);
             }
-       }
+        }
        
       iLoop = iLoop->next;
     }
@@ -7825,14 +7888,7 @@ genZ80Code (iCode * lic)
   /* if debug information required */
   if (options.debug && currFunc)
     {
-      debugFile->writeFunction(currFunc);
-      _G.lines.isDebug = 1;
-      if (IS_STATIC (currFunc->etype))
-       sprintf (buffer, "F%s$%s$0$0", moduleName, currFunc->name);
-      else
-       sprintf (buffer, "G$%s$0$0", currFunc->name);
-      emit2 ("!labeldef", buffer);
-      _G.lines.isDebug = 0;
+      debugFile->writeFunction (currFunc, lic);
     }
 
   for (ic = lic; ic; ic = ic->next)
@@ -7843,13 +7899,7 @@ genZ80Code (iCode * lic)
        {
          if (options.debug)
            {
-             _G.lines.isDebug = 1;
-             sprintf (buffer, "C$%s$%d$%d$%d",
-                       FileBaseName (ic->filename), ic->lineno,
-                       ic->level, ic->block);
-              emit2 ("%s !equ .", buffer);
-              emit2 ("!global", buffer);
-             _G.lines.isDebug = 0;
+             debugFile->writeCLine (ic);
            }
          if (!options.noCcodeInAsm) {
            emit2 (";%s:%d: %s", ic->filename, ic->lineno,