* src/SDCCicode.c (operandOperation): really fixed problem with bitops
[fw/sdcc] / src / z80 / gen.c
index 03e5a780d397b86f6b64282228ca52958e5656c9..7231edf2b9ef1cf9894c46ede6d6745f1fbb0149 100644 (file)
 #include <string.h>
 #include <ctype.h>
 
-#ifdef HAVE_SYS_ISA_DEFS_H
-#include <sys/isa_defs.h>
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+#define STRCASECMP stricmp
+#else
+#define STRCASECMP strcasecmp
 #endif
 
 #include "z80.h"
@@ -396,7 +398,7 @@ _vemit2 (const char *szFormat, va_list ap)
 {
   char buffer[256];
 
-  tvsprintf (buffer, szFormat, ap);
+  tvsprintf (buffer, sizeof(buffer), szFormat, ap);
 
   _tidyUp (buffer);
   _G.lines.current = (_G.lines.current ?
@@ -424,11 +426,11 @@ emitDebug (const char *szFormat,...)
   if (!DISABLE_DEBUG)
     {
       va_list ap;
-      
+
       va_start (ap, szFormat);
-      
+
       _vemit2 (szFormat, ap);
-      
+
       va_end (ap);
     }
 }
@@ -469,7 +471,7 @@ _emit2 (const char *inst, const char *fmt,...)
 static void
 _emitMove(const char *to, const char *from)
 {
-  if (strcasecmp(to, from) != 0) 
+  if (STRCASECMP(to, from) != 0) 
     {
       emit2("ld %s,%s", to, from);
     }
@@ -491,6 +493,7 @@ aopDump(const char *plabel, asmop *aop)
       break;
     default:
       /* No information. */
+      break;
     }
 }
 
@@ -1072,8 +1075,6 @@ isLitWord (asmop * aop)
 char *
 aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
 {
-  char *s = buffer;
-
   /* depending on type */
   switch (aop->type)
     {
@@ -1083,17 +1084,20 @@ aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
       /* PENDING: for re-target */
       if (with_hash)
         {
-          tsprintf (s, "!hashedstr + %d", aop->aopu.aop_immd, offset);
+          tsprintf (buffer, sizeof(buffer), 
+                   "!hashedstr + %d", aop->aopu.aop_immd, offset);
         }
       else if (offset == 0)
         {
-          tsprintf (s, "%s", aop->aopu.aop_immd);
+          tsprintf (buffer, sizeof(buffer),
+                   "%s", aop->aopu.aop_immd);
         }
       else
         {
-          tsprintf (s, "%s + %d", aop->aopu.aop_immd, offset);
+          tsprintf (buffer, sizeof(buffer), 
+                   "%s + %d", aop->aopu.aop_immd, offset);
         }
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     case AOP_LIT:
       {
@@ -1118,9 +1122,9 @@ aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
               }
 
            if (with_hash)
-             tsprintf (buffer, "!immedword", v);
+             tsprintf (buffer, sizeof(buffer), "!immedword", v);
            else
-             tsprintf (buffer, "!constword", v);
+             tsprintf (buffer, sizeof(buffer), "!constword", v);
 
             return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
          }
@@ -1136,15 +1140,15 @@ aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
             /* it is type float */
             fl.f = (float) floatFromVal (val);
 
-#ifdef _BIG_ENDIAN
+#ifdef WORDS_BIGENDIAN
             i = fl.c[3-offset] | (fl.c[3-offset-1]<<8);
 #else
             i = fl.c[offset] | (fl.c[offset+1]<<8);
 #endif
            if (with_hash)
-             tsprintf (buffer, "!immedword", i);
+             tsprintf (buffer, sizeof(buffer), "!immedword", i);
            else
-             tsprintf (buffer, "!constword", i);
+             tsprintf (buffer, sizeof(buffer), "!constword", i);
 
             return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
          }
@@ -1469,15 +1473,15 @@ emitLabel (int key)
 static const char *
 aopGet (asmop * aop, int offset, bool bit16)
 {
-  char *s = buffer;
+  // char *s = buffer;
 
   /* offset is greater than size then zero */
   /* PENDING: this seems a bit screwed in some pointer cases. */
   if (offset > (aop->size - 1) &&
       aop->type != AOP_LIT) 
     {
-      tsprintf (s, "!zero");
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      tsprintf (buffer, sizeof(buffer), "!zero");
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
     }
 
   /* depending on type */
@@ -1486,38 +1490,38 @@ aopGet (asmop * aop, int offset, bool bit16)
     case AOP_IMMD:
       /* PENDING: re-target */
       if (bit16)
-       tsprintf (s, "!immedwords", aop->aopu.aop_immd);
+       tsprintf (buffer, sizeof(buffer), "!immedwords", aop->aopu.aop_immd);
       else
        switch (offset)
          {
          case 2:
-           tsprintf (s, "!bankimmeds", aop->aopu.aop_immd);
+           tsprintf (buffer, sizeof(buffer), "!bankimmeds", aop->aopu.aop_immd);
            break;
          case 1:
-           tsprintf (s, "!msbimmeds", aop->aopu.aop_immd);
+           tsprintf (buffer, sizeof(buffer), "!msbimmeds", aop->aopu.aop_immd);
            break;
          case 0:
-           tsprintf (s, "!lsbimmeds", aop->aopu.aop_immd);
+           tsprintf (buffer, sizeof(buffer), "!lsbimmeds", aop->aopu.aop_immd);
            break;
          default:
            wassertl (0, "Fetching from beyond the limits of an immediate value.");
          }
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     case AOP_DIR:
       wassert (IS_GB);
       emit2 ("ld a,(%s+%d)", aop->aopu.aop_dir, offset);
-      sprintf (s, "a");
+      SNPRINTF (buffer, sizeof(buffer), "a");
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     case AOP_SFR:
       wassert (IS_GB);
       emit2 ("ldh a,(%s+%d)", aop->aopu.aop_dir, offset);
-      sprintf (s, "a");
+      SNPRINTF (buffer, sizeof(buffer), "a");
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     case AOP_REG:
       return aop->aopu.aop_reg[offset]->name;
@@ -1525,38 +1529,39 @@ aopGet (asmop * aop, int offset, bool bit16)
     case AOP_HL:
       wassert (IS_GB);
       setupPair (PAIR_HL, aop, offset);
-      tsprintf (s, "!*hl");
+      tsprintf (buffer, sizeof(buffer), "!*hl");
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup (s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup (buffer));
 
     case AOP_IY:
       wassert (IS_Z80);
       setupPair (PAIR_IY, aop, offset);
-      tsprintf (s, "!*iyx", offset);
+      tsprintf (buffer, sizeof(buffer), "!*iyx", offset);
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     case AOP_EXSTK:
       wassert (IS_Z80);
       setupPair (PAIR_IY, aop, offset);
-      tsprintf (s, "!*iyx", offset, offset);
+      tsprintf (buffer, sizeof(buffer), "!*iyx", offset, offset);
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     case AOP_STK:
       if (IS_GB)
        {
          setupPair (PAIR_HL, aop, offset);
-         tsprintf (s, "!*hl");
+         tsprintf (buffer, sizeof(buffer), "!*hl");
        }
       else
        {
          if (aop->aopu.aop_stk >= 0)
            offset += _G.stack.param_offset;
-         tsprintf (s, "!*ixx", aop->aopu.aop_stk + offset);
+         tsprintf (buffer, sizeof(buffer),
+                   "!*ixx", aop->aopu.aop_stk + offset);
        }
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     case AOP_CRY:
       wassertl (0, "Tried to fetch from a bit variable");
@@ -1568,8 +1573,8 @@ aopGet (asmop * aop, int offset, bool bit16)
        }
       else
         {
-          tsprintf(s, "!zero");
-          return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+          tsprintf(buffer, sizeof(buffer), "!zero");
+          return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
         }
 
     case AOP_HLREG:
@@ -1584,9 +1589,10 @@ aopGet (asmop * aop, int offset, bool bit16)
         unsigned long v = aop->aopu.aop_simplelit;
         
         v >>= (offset * 8);
-        tsprintf (s, "!immedbyte", (unsigned int) v & 0xff);
+        tsprintf (buffer, sizeof(buffer), 
+                 "!immedbyte", (unsigned int) v & 0xff);
         
-        return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+        return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
       }
     case AOP_STR:
       aop->coff = offset;
@@ -1594,9 +1600,10 @@ aopGet (asmop * aop, int offset, bool bit16)
 
     case AOP_PAIRPTR:
       setupPair (aop->aopu.aop_pairId, aop, offset);
-      sprintf (s, "(%s)", _pairs[aop->aopu.aop_pairId].name);
+      SNPRINTF (buffer, sizeof(buffer), 
+               "(%s)", _pairs[aop->aopu.aop_pairId].name);
 
-      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+      return traceAlloc(&_G.trace.aops, Safe_strdup(buffer));
 
     default:
       break;
@@ -1652,7 +1659,7 @@ aopPut (asmop * aop, const char *s, int offset)
     }
 
   // PENDING
-  tsprintf(buffer2, s);
+  tsprintf(buffer2, sizeof(buffer2), s);
   s = buffer2;
 
   /* will assign value to value */
@@ -5883,9 +5890,19 @@ genRightShiftLiteral (operand * left,
       wassert (0);
     }
 
-  else if (shCount >= (size * 8))
+  else if (shCount >= (size * 8)) {
+    const char *s;
+    if (!SPEC_USIGN(getSpec(operandType(left)))) {
+      _moveA(aopGet (AOP (left), 0, FALSE));
+      emit2 ("rlc a");
+      emit2 ("sbc a,a");
+      s=ACC_NAME;
+    } else {
+      s="!zero";
+    }
     while (size--)
-      aopPut (AOP (result), "!zero", size);
+      aopPut (AOP (result), s, size);
+  }
   else
     {
       switch (size)
@@ -5948,13 +5965,16 @@ genRightShift (iCode * ic)
       return;
     }
 
+  emit2 ("ld a,%s", aopGet (AOP (right), 0, FALSE));
+  emit2 ("inc a");
+  freeAsmop (right, NULL, ic);
+
   aopOp (left, ic, FALSE, FALSE);
   aopOp (result, ic, FALSE, FALSE);
 
   /* now move the left to the result if they are not the
      same */
-  if (!sameRegs (AOP (left), AOP (result)) &&
-      AOP_SIZE (result) > 1)
+  if (!sameRegs (AOP (left), AOP (result)))
     {
 
       size = AOP_SIZE (result);
@@ -5967,10 +5987,6 @@ genRightShift (iCode * ic)
        }
     }
 
-  emit2 ("ld a,%s", aopGet (AOP (right), 0, FALSE));
-  emit2 ("inc a");
-  freeAsmop (right, NULL, ic);
-
   tlbl = newiTempLabel (NULL);
   tlbl1 = newiTempLabel (NULL);
   size = AOP_SIZE (result);
@@ -6023,7 +6039,8 @@ genGenPointerGet (operand * left,
       /* Just do it */
       if (isPtrPair (AOP (left)))
        {
-         tsprintf (buffer, "!*pair", getPairName (AOP (left)));
+         tsprintf (buffer, sizeof(buffer), 
+                   "!*pair", getPairName (AOP (left)));
          aopPut (AOP (result), buffer, 0);
        }
       else
@@ -6042,7 +6059,7 @@ genGenPointerGet (operand * left,
       while (size--) 
         {
           char at[20];
-          tsprintf (at, "!*iyx", offset);
+          tsprintf (at, sizeof(at), "!*iyx", offset);
           aopPut (AOP (result), at, offset);
           offset++;
         }
@@ -6689,6 +6706,17 @@ genReceive (iCode * ic)
   freeAsmop (IC_RESULT (ic), NULL, ic);
 }
 
+/*-----------------------------------------------------------------*/
+/* genDummyRead - generate code for dummy read of volatiles        */
+/*-----------------------------------------------------------------*/
+static void
+genDummyRead (iCode * ic)
+{
+  emit2 ("; genDummyRead not implemented");
+
+  ic = ic;
+}
+
 enum
   {
     /** Maximum number of bytes to emit per line. */
@@ -7231,9 +7259,15 @@ genZ80Code (iCode * lic)
 
       if (cln != ic->lineno)
        {
-         emit2 ("; %s %d", ic->filename, ic->lineno);
+         if (!options.noCcodeInAsm) {
+           emit2 (";%s:%d: %s", ic->filename, ic->lineno,
+                  printCLine(ic->filename, ic->lineno));
+         }
          cln = ic->lineno;
        }
+      if (options.iCodeInAsm) {
+       emit2 (";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
@@ -7486,7 +7520,11 @@ genZ80Code (iCode * lic)
          emitDebug ("; genArrayInit");
           genArrayInit(ic);
           break;
-           
+
+       case DUMMY_READ_VOLATILE:
+         genDummyRead (ic);
+         break;
+
        default:
          ic = ic;
        }
@@ -7554,7 +7592,7 @@ fetchLitSpecial (asmop * aop, bool negate, bool xor)
     v = 0-v;
   v &= 0xFFFF;
 
-  tsprintf (buffer, "!immedword", v);
+  tsprintf (buffer, sizeof(buffer), "!immedword", v);
   return traceAlloc(&_G.trace.aops, Safe_strdup (buffer));
 }