* src/SDCCmain.c: Added --fommit-frame-pointer option and implemented in the z80...
authormichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 9 Oct 2001 02:28:32 +0000 (02:28 +0000)
committermichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 9 Oct 2001 02:28:32 +0000 (02:28 +0000)
* src/z80/gen.c (genPlus): Fixed to work with extended stack.  Also fixed genMinus, genCmp.  genUMinus is still left.

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1378 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/SDCCglobl.h
src/SDCCmain.c
src/z80/gen.c
src/z80/gen.h

index 76fbbf7e4c94a0afc7802ce8abc323a24a84be2b..07eec1dd9cccd15c003fb31daa1721d216c73c9a 100644 (file)
@@ -219,6 +219,8 @@ struct options
     int shortis8bits;           /* treat short like int or char */
     int lessPedantic;           /* disable some warnings */
     int profile;                /* Turn on extra profiling information */
+    int ommitFramePtr;         /* Turn off the frame pointer. */
+
     char *calleeSaves[128];    /* list of functions using callee save */
     char *excludeRegs[32];     /* registers excluded from saving */
 
index 60af6f82205f7b04086945b0d1a7aaaaadbc9e60..e7f5eea422791665b69493d3cbf3819d6e0a79d2 100644 (file)
@@ -203,7 +203,8 @@ optionsTable[] = {
     { 0,    "--verbose",            &options.verbose, "Trace calls to the preprocessor, assembler, and linker" },
     { 0,    OPTION_LESS_PEDANTIC,   NULL, "Disable some of the more pedantic warnings" },
     { 0,    OPTION_SHORT_IS_8BITS,   NULL, "Make short 8bits (for old times sake)" },
-    { 0,    "--profile",            &options.profile, "On supported ports, generate extra profiling information" }
+    { 0,    "--profile",            &options.profile, "On supported ports, generate extra profiling information" },
+    { 0,    "--fommit-frame-pointer", &options.ommitFramePtr, "Leave out the frame pointer." }
 };
 
 /** Table of all unsupported options and help text to display when one
index 7421f80070cf69ed65f888c99414c391aeecdd60..298ffcb47132dbf61ad4cf61fccf6231228d2a79 100644 (file)
 enum 
 {
   /* Set to enable debugging trace statements in the output assembly code. */
-  DISABLE_DEBUG = 0
+  DISABLE_DEBUG = 0,
 };
 
 static char *_z80_return[] =
@@ -539,7 +539,7 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool requires_a)
          Normally everything is AOP_STK, but for offsets of < -127 or
          > 128 on the Z80 an extended stack pointer is used.
       */
-      if (IS_Z80 && (sym->stack < -127 || sym->stack > (int)(128-getSize (sym->type))))
+      if (IS_Z80 && (options.ommitFramePtr || sym->stack < -127 || sym->stack > (int)(128-getSize (sym->type))))
         {
           emitDebug ("; AOP_EXSTK for %s", sym->rname);
           sym->aop = aop = newAsmop (AOP_EXSTK);
@@ -886,6 +886,11 @@ freeAsmop (operand * op, asmop * aaop, iCode * ic)
 
   aop->freed = 1;
 
+  if (aop->type == AOP_PAIRPTR && IS_Z80 && aop->aopu.aop_pairId == PAIR_DE)
+    {
+      _pop (aop->aopu.aop_pairId);
+    }
+
 dealloc:
   /* all other cases just dealloc */
   if (op)
@@ -899,6 +904,7 @@ dealloc:
            SPIL_LOC (op)->aop = NULL;
        }
     }
+
 }
 
 bool
@@ -1155,23 +1161,23 @@ fetchHL (asmop * aop)
 static void
 setupPair (PAIR_ID pairId, asmop * aop, int offset)
 {
-  assert (pairId == PAIR_HL || pairId == PAIR_IY);
-
   switch (aop->type)
     {
     case AOP_IY:
-      wassertl (pairId == PAIR_IY, "AOP_IY must be in IY");
+      wassertl (pairId == PAIR_IY || pairId == PAIR_HL, "AOP_IY must be in IY or HL");
       fetchLitPair (pairId, aop, 0);
       break;
 
     case AOP_HL:
+      wassertl (pairId == PAIR_HL, "AOP_HL must be in HL");
+      
       fetchLitPair (pairId, aop, offset);
       _G.pairs[pairId].offset = offset;
       break;
 
     case AOP_EXSTK:
       wassertl (IS_Z80, "Only the Z80 has an extended stack");
-      wassertl (pairId == PAIR_IY, "The Z80 extended stack must be in IY");
+      wassertl (pairId == PAIR_IY || pairId == PAIR_HL, "The Z80 extended stack must be in IY or HL");
 
       {
        int offset = aop->aopu.aop_stk + _G.stack.offset;
@@ -1185,8 +1191,8 @@ setupPair (PAIR_ID pairId, asmop * aop, int offset)
           {
             /* PENDING: Do this better. */
             sprintf (buffer, "%d", offset + _G.stack.pushed);
-            emit2 ("ld iy,!hashedstr", buffer);
-            emit2 ("add iy,sp");
+            emit2 ("ld %s,!hashedstr", _pairs[pairId].name, buffer);
+            emit2 ("add %s,sp", _pairs[pairId].name);
             _G.pairs[pairId].last_type = aop->type;
             _G.pairs[pairId].offset = offset;
           }
@@ -1214,6 +1220,11 @@ setupPair (PAIR_ID pairId, asmop * aop, int offset)
        _G.pairs[pairId].offset = abso;
        break;
       }
+
+    case AOP_PAIRPTR:
+      adjustPair (_pairs[pairId].name, &_G.pairs[pairId].offset, offset);
+      break;
+      
     default:
       wassert (0);
     }
@@ -1356,6 +1367,12 @@ aopGet (asmop * aop, int offset, bool bit16)
       aop->coff = offset;
       return aop->aopu.aop_str[offset];
 
+    case AOP_PAIRPTR:
+      setupPair (aop->aopu.aop_pairId, aop, offset);
+      sprintf (s, "(%s)", _pairs[aop->aopu.aop_pairId].name);
+
+      return traceAlloc(&_G.trace.aops, Safe_strdup(s));
+
     default:
       break;
     }
@@ -1557,6 +1574,11 @@ aopPut (asmop * aop, const char *s, int offset)
       emit2 ("ld %s,%s", aop->aopu.aop_str[offset], s);
       break;
 
+    case AOP_PAIRPTR:
+      setupPair (aop->aopu.aop_pairId, aop, offset);
+      emit2 ("ld (%s),%s", _pairs[aop->aopu.aop_pairId].name, s);
+      break;
+
     default:
       werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
              "aopPut got unsupported aop->type");
@@ -2824,6 +2846,86 @@ outBitAcc (operand * result)
     }
 }
 
+bool
+couldDestroyCarry (asmop *aop)
+{
+  if (aop)
+    {
+      if (aop->type == AOP_EXSTK || aop->type == AOP_IY)
+        {
+          return TRUE;
+        }
+    }
+  return FALSE;
+}
+
+static void
+shiftIntoPair (int idx, asmop *aop)
+{
+  PAIR_ID id;
+
+  wassertl (IS_Z80, "Only implemented for the Z80");
+  //  wassertl (aop->type == AOP_EXSTK, "Only implemented for EXSTK");
+
+  switch (idx) 
+    {
+    case 0:
+      id = PAIR_HL;
+      break;
+    case 1:
+      id = PAIR_DE;
+      _push (PAIR_DE);
+      break;
+    default:
+      wassertl (0, "Internal error - hit default case");
+    }
+
+  emitDebug ("; Shift into pair idx %u", idx);
+
+  if (id == PAIR_HL)
+    {
+      setupPair (PAIR_HL, aop, 0);
+    }
+  else
+    {
+      setupPair (PAIR_IY, aop, 0);
+      emit2 ("push iy");
+      emit2 ("pop %s", _pairs[id].name);
+    }
+
+  aop->type = AOP_PAIRPTR;
+  aop->aopu.aop_pairId = id;
+  _G.pairs[id].offset = 0;
+  _G.pairs[id].last_type = aop->type;
+}
+
+static void 
+setupToPreserveCarry (asmop *result, asmop *left, asmop *right)
+{
+  wassert (left && right);
+
+  if (IS_Z80)
+    {
+      if (couldDestroyCarry (right) && couldDestroyCarry (result))
+        {
+          shiftIntoPair (0, right);
+          shiftIntoPair (1, result);
+        }
+      else if (couldDestroyCarry (right))
+        {
+          shiftIntoPair (0, right);
+        }
+      else if (couldDestroyCarry (result))
+        {
+          shiftIntoPair (0, result);
+        }
+      else
+        {
+          /* Fine */
+        }
+    }
+}
+
 /*-----------------------------------------------------------------*/
 /* genPlus - generates code for addition                           */
 /*-----------------------------------------------------------------*/
@@ -2978,6 +3080,8 @@ genPlus (iCode * ic)
         }
     }
 
+  setupToPreserveCarry (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)), AOP (IC_RIGHT (ic)));
+
   while (size--)
     {
       if (AOP_TYPE (IC_LEFT (ic)) == AOP_ACC)
@@ -3171,6 +3275,8 @@ genMinus (iCode * ic)
         }
     }
 
+  setupToPreserveCarry (AOP (IC_RESULT (ic)), AOP (IC_LEFT (ic)), AOP (IC_RIGHT (ic)));
+
   /* if literal, add a,#-lit, else normal subb */
   while (size--)
     {
@@ -3399,6 +3505,43 @@ genCmp (operand * left, operand * right,
             }
           spillPair (PAIR_HL);
         }
+      else if (size == 4 && IS_Z80 && couldDestroyCarry(AOP(right)) && couldDestroyCarry(AOP(left)))
+        {
+          setupPair (PAIR_HL, AOP (left), 0);
+          aopGet (AOP(right), LSB, FALSE);
+
+          while (size--)
+            {
+              if (size == 0 && sign)
+                {
+                  // Highest byte when signed needs the bits flipped
+                  // Save the flags
+                  emit2 ("push af");
+                  emit2 ("ld a,(hl)");
+                  emit2 ("xor #0x80");
+                  emit2 ("ld l,a");
+                  emit2 ("ld a,%d(iy)", offset);
+                  emit2 ("xor #0x80");
+                  emit2 ("ld h,a");
+                  emit2 ("pop af");
+                  emit2 ("ld a,l");
+                  emit2 ("%s a,h", offset == 0 ? "sub" : "sbc");
+                }
+              else
+                {
+                  emit2 ("ld a,(hl)");
+                  emit2 ("%s a,%d(iy)", offset == 0 ? "sub" : "sbc", offset);
+                }
+              
+              if (size != 0)
+                {
+                  emit2 ("inc hl");
+                }
+              offset++;
+            }
+          spillPair (PAIR_HL);
+          spillPair (PAIR_IY);
+        }
       else
        {
          if (AOP_TYPE (right) == AOP_LIT)
@@ -3427,6 +3570,7 @@ genCmp (operand * left, operand * right,
                  goto release;
                }
            }
+          
          if (sign)
            {
              /* First setup h and l contaning the top most bytes XORed */
index 8751531ce8aa89299d916eae04de8a0891bcc9c6..20b5787716eaccf371854c5d95ccc74f242e4ed8 100644 (file)
@@ -55,7 +55,9 @@ typedef enum
     /* Simple literal. */
     AOP_SIMPLELIT,
     /* Is in the extended stack pointer (IY on the Z80) */
-    AOP_EXSTK
+    AOP_EXSTK,
+    /* Is referenced by a pointer in a register pair. */
+    AOP_PAIRPTR
   }
 AOP_TYPE;
 
@@ -67,9 +69,9 @@ typedef struct asmop
     AOP_TYPE type;
     short coff;                 /* current offset */
     short size;                 /* total size */
-    unsigned code:1;            /* is in Code space */
-    unsigned paged:1;           /* in paged memory  */
-    unsigned freed:1;           /* already freed    */
+    bool code;                  /* is in Code space */
+    bool paged;                 /* in paged memory  */
+    bool freed;                 /* already freed    */
     union
       {
         value *aop_lit;         /* if literal */
@@ -79,6 +81,7 @@ typedef struct asmop
         int aop_stk;            /* stack offset when AOP_STK */
         const char *aop_str[4]; /* just a string array containing the location */
         unsigned long aop_simplelit; /* Just the value. */
+        int aop_pairId;                /* The pair ID */
       }
     aopu;
   }