* src/ds390/gen.c (pushSide, genPcall),
authorMaartenBrock <MaartenBrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 8 Mar 2008 17:34:50 +0000 (17:34 +0000)
committerMaartenBrock <MaartenBrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 8 Mar 2008 17:34:50 +0000 (17:34 +0000)
* src/hc08/gen.c (pushSide, genPcall): synchronized with mcs51
* src/mcs51/gen.c: cosmetic changes
* support/regression/fwk/include/testfwk.h: added macro reentrant
* support/regression/tests/bug1908493.c: new, added

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

ChangeLog
src/ds390/gen.c
src/hc08/gen.c
src/mcs51/gen.c
support/regression/fwk/include/testfwk.h
support/regression/tests/bug1908493.c [new file with mode: 0644]

index 1832021f2bc95b1535a75c26d865d7b7ff66df1b..96eb7c67270098c8350fce2bfe171d8b0105a8f4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,13 @@
+2008-03-08 Maarten Brock <sourceforge.brock AT dse.nl>
+
+       * src/ds390/gen.c (pushSide, genPcall),
+       * src/hc08/gen.c (pushSide, genPcall): synchronized with mcs51
+       * src/mcs51/gen.c: cosmetic changes
+       * support/regression/fwk/include/testfwk.h: added macro reentrant
+       * support/regression/tests/bug1908493.c: new, added
+
 2008-03-08 Jesus Calvino-Fraga <jesusc AT ece.ubc.ca>
+
        * src/SDCCdebug.c:, as/link/lkaomf51.c: Fixed bug 1909409: Pdata in OMF file
 
 2008-03-08 Maarten Brock <sourceforge.brock AT dse.nl>
index d8ff7c5134fda48e6110705b4d27511bc5de1802..f077ae71d96216fd92b764f593ae3703f5b45f61 100644 (file)
@@ -2455,12 +2455,32 @@ unsaveRegisters (iCode * ic)
 
 
 /*-----------------------------------------------------------------*/
-/* pushSide -                */
+/* pushSide -                                                      */
 /*-----------------------------------------------------------------*/
 static void
-pushSide (operand * oper, int size)
+pushSide (operand * oper, int size, iCode * ic)
 {
   int offset = 0;
+  int nPushed = _G.r0Pushed + _G.r1Pushed;
+
+  aopOp (oper, ic, FALSE);
+
+  if (nPushed != _G.r0Pushed + _G.r1Pushed)
+    {
+      while (offset < size)
+        {
+          char *l = aopGet (oper, offset, FALSE, TRUE, NULL);
+          emitcode ("mov", "%s,%s", fReturn[offset++], l);
+        }
+      freeAsmop (oper, NULL, ic, TRUE);
+      offset = 0;
+      while (offset < size)
+        {
+          emitcode ("push", "%s", fReturn[offset++]);
+        }
+      return;
+    }
+
   _startLazyDPSEvaluation ();
   while (size--)
     {
@@ -2478,6 +2498,7 @@ pushSide (operand * oper, int size)
         }
     }
   _endLazyDPSEvaluation ();
+  freeAsmop (oper, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -3235,14 +3256,10 @@ genPcall (iCode * ic)
       emitcode ("push", "acc");
     }
 
-  /* now push the calling address */
-  aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
-
-  pushSide (IC_LEFT (ic), FPTRSIZE);
-
-  freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+  /* now push the function address */
+  pushSide (IC_LEFT (ic), FPTRSIZE, ic);
 
-  /* if send set is not empty the assign */
+  /* if send set is not empty then assign */
   if (_G.sendSet)
     {
         genSend(reverseSet(_G.sendSet));
index 9ae9f8d24d55585ea7e555d48a7e403f4c177c60..a656eb5bf238c16ad47c5b619737a460edaadc46 100644 (file)
@@ -1709,7 +1709,7 @@ aopOp (operand * op, iCode * ic, bool result)
 
 //  printf("checking pre-existing\n");
   /* if already has a asmop then continue */
-  if (op->aop )
+  if (op->aop)
     {
       op->aop->op = op;
       op->aop->isaddr = op->isaddr;
@@ -1750,7 +1750,7 @@ aopOp (operand * op, iCode * ic, bool result)
     }
 
   /* this is a temporary : this has
-     only four choices :
+     only five choices :
      a) register
      b) spillocation
      c) rematerialize
@@ -1763,7 +1763,7 @@ aopOp (operand * op, iCode * ic, bool result)
   /* if the type is a conditional */
   if (sym->regType == REG_CND)
     {
-      aop = op->aop = sym->aop = newAsmop (AOP_CRY);
+      sym->aop = op->aop = aop = newAsmop (AOP_CRY);
       aop->size = 0;
       aop->op = op;
       aop->isaddr = op->isaddr;
@@ -1781,8 +1781,7 @@ aopOp (operand * op, iCode * ic, bool result)
       /* rematerialize it NOW */
       if (sym->remat)
         {
-          sym->aop = op->aop = aop =
-            aopForRemat (sym);
+          sym->aop = op->aop = aop = aopForRemat (sym);
           aop->size = getSize (sym->type);
           aop->op = op;
           aop->isaddr = op->isaddr;
@@ -1797,7 +1796,7 @@ aopOp (operand * op, iCode * ic, bool result)
 //      printf("checking accuse\n");
       if (sym->accuse)
         {
-          aop = op->aop = sym->aop = newAsmop (AOP_REG);
+          sym->aop = op->aop = aop = newAsmop (AOP_REG);
           aop->size = getSize (sym->type);
           switch (sym->accuse)
             {
@@ -1821,7 +1820,7 @@ aopOp (operand * op, iCode * ic, bool result)
         {
           unsigned i;
 
-          aop = op->aop = sym->aop = newAsmop (AOP_STR);
+          sym->aop = op->aop = aop = newAsmop (AOP_STR);
           aop->size = getSize (sym->type);
           for (i = 0; i < fReturnSizeHC08; i++)
             aop->aopu.aop_str[i] = fReturn2[i];
@@ -2523,17 +2522,22 @@ unsaveRegisters (iCode * ic)
 
 
 /*-----------------------------------------------------------------*/
-/* pushSide -                */
+/* pushSide -                                                      */
 /*-----------------------------------------------------------------*/
 static void
-pushSide (operand * oper, int size)
+pushSide (operand * oper, int size, iCode * ic)
 {
   int offset = 0;
+
+  aopOp (oper, ic, FALSE);
+
   while (size--)
     {
       loadRegFromAop (hc08_reg_a, AOP (oper), offset++);
       pushReg ( hc08_reg_a, TRUE);
     }
+
+  freeAsmop (oper, NULL, ic, TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -2752,7 +2756,7 @@ genPcall (iCode * ic)
 //  bool restoreBank=FALSE;
 //  bool swapBanks = FALSE;
 
-  D(emitcode(";     genPCall",""));
+  D (emitcode (";", "genPcall"));
 
   /* if caller saves & we have not saved then */
   if (!ic->regsSaved)
@@ -2763,19 +2767,17 @@ genPcall (iCode * ic)
      destination registers on the stack */
   dtype = operandType (IC_LEFT (ic))->next;
 
-  /* now push the calling address */
+  /* push the return address on to the stack */
   emitBranch ("bsr", tlbl);
   emitBranch ("bra", rlbl);
   emitLabel (tlbl);
   _G.stackPushes += 2; /* account for the bsr return address now on stack */
   updateCFA();
 
-  /* Push the function's address */
-  aopOp (IC_LEFT (ic), ic, FALSE);
-  pushSide (IC_LEFT (ic), FPTRSIZE);
-  freeAsmop (IC_LEFT (ic), NULL, ic, TRUE);
+  /* now push the function address */
+  pushSide (IC_LEFT (ic), FPTRSIZE, ic);
 
-  /* if send set is not empty the assign */
+  /* if send set is not empty then assign */
   if (_G.sendSet)
     {
         genSend(reverseSet(_G.sendSet));
index 68f8524cc0b5d1c7ddf5f5d951c501d324d32082..9db691c3917305b244b58a6d05f6645a4393de48 100644 (file)
@@ -1006,8 +1006,7 @@ aopOp (operand * op, iCode * ic, bool result)
               oldAsmOp = sym->usl.spillLoc->aop;
               sym->usl.spillLoc->aop = NULL;
             }
-          sym->aop = op->aop = aop =
-                     aopForSym (ic, sym->usl.spillLoc, result);
+          sym->aop = op->aop = aop = aopForSym (ic, sym->usl.spillLoc, result);
           if (getSize(sym->type) != getSize(sym->usl.spillLoc->type))
             {
               /* Don't reuse the new aop, go with the last one */
@@ -2442,7 +2441,7 @@ pushSide (operand * oper, int size, iCode * ic)
         }
       return;
     }
-    
+
   while (size--)
     {
       char *l = aopGet (oper, offset++, FALSE, TRUE);
@@ -3169,7 +3168,7 @@ genPcall (iCode * ic)
           emitcode ("mov", "a,#(%05d$ >> 8)", (rlbl->key + 100));
           emitcode ("push", "acc");
 
-          /* now push the calling address */
+          /* now push the function address */
           pushSide (IC_LEFT (ic), FPTRSIZE, ic);
 
           /* if send set is not empty then assign */
index 1e5d581baf069e08d89946524b8fa98c7dad73d0..4ded3748bebcde8fedc19b604607ed4b22512397 100644 (file)
@@ -27,6 +27,7 @@ void __printf(const char *szFormat, ...);
 # define near
 # define far
 # define at(x)
+# define reentrant
 #endif
 
 #if defined(SDCC_hc08)
diff --git a/support/regression/tests/bug1908493.c b/support/regression/tests/bug1908493.c
new file mode 100644 (file)
index 0000000..18795ce
--- /dev/null
@@ -0,0 +1,126 @@
+/* Bug 1908493
+ * Bug test contains code fragments from qpnano framework,
+ * Copyright (C) 2002-2007 Quantum Leaps, LLC. All rights reserved.
+ * and released under the GPL
+ * See www.quantum-leaps.com/downloads/index.htm#QPN
+ */
+
+#include <testfwk.h>
+
+#define Q_REENTRANT reentrant
+#define Q_ASSERT
+#define Q_SIG(me_) (((QFsm *)(me_))->evt.sig)
+#define int8_t char
+#define QEP_MAX_NEST_DEPTH 5
+
+#define QEP_EMPTY_SIG 0
+
+enum QReservedSignals {
+    Q_ENTRY_SIG = 1,                   /**< signal for coding entry actions */
+    Q_EXIT_SIG,                         /**< signal for coding exit actions */
+    Q_INIT_SIG,           /**< signal for coding nested initial transitions */
+    Q_TIMEOUT_SIG,                          /**< signal used by time events */
+    Q_USER_SIG      /**< first signal that can be used in user applications */
+};
+
+typedef int8_t QSignal;
+typedef struct QEventTag {
+    QSignal sig;
+} QEvent;
+
+struct QFsmTag;
+struct QHsmTag;
+
+typedef void (*QState)(struct QFsmTag *me);
+typedef QState (*QHsmState)(struct QHsmTag *me);
+
+typedef QState QSTATE;
+
+typedef struct QFsmTag {
+    QState state;
+    QEvent evt;
+} QFsm;
+
+typedef struct QHsmTag {
+    QHsmState state;
+    QEvent evt;
+} QHsm;
+
+typedef struct QHsmDerivedTag {
+    QHsm super;
+    char value;
+} QHsmDerived;
+
+QHsmDerived AO_derived;
+
+QSTATE state_1(QHsmDerived *me) Q_REENTRANT
+{
+    if (Q_SIG(me) == Q_INIT_SIG)
+        me->value = 3;
+
+    return (QSTATE)0;
+}
+
+QSTATE state_2(QHsmDerived *me) Q_REENTRANT
+{
+    if (Q_SIG(me) == Q_USER_SIG)
+        return (QSTATE)state_1;
+
+    return (QSTATE)0;
+}
+
+void QHsm_dispatch(QHsm *me) Q_REENTRANT
+{
+    QHsmState path[QEP_MAX_NEST_DEPTH];
+    QHsmState s;
+    QHsmState t = me->state;
+
+    path[1] = t;    /* save the current state in case a transition is taken */
+
+    do {                             /* process the event hierarchically... */
+        s = t;
+
+        /********************************************************************
+         *
+         *    The call which fails when s is copied from the stack frame
+         *
+         ********************************************************************/
+        t = (QHsmState)((*s)(me));                /* invoke state handler s */
+
+    } while (t != (QHsmState)0);
+
+    if (me->evt.sig == (QSignal)0) {                   /* transition taken? */
+        QHsmState src = s;                  /* the source of the transition */
+        int8_t ip = (int8_t)(-1);            /* transition entry path index */
+
+        path[0] = me->state;                          /* save the new state */
+        me->state = path[1];                   /* restore the current state */
+
+                      /* exit current state to the transition source src... */
+        for (s = path[1]; s != src; ) {
+            Q_SIG(me) = (QSignal)Q_EXIT_SIG;
+            t = (QHsmState)(*s)(me);                /* find superstate of s */
+            if (t != (QHsmState)0) {               /* exit action unhandled */
+                s = t;                            /* t points to superstate */
+            }
+            else {                                   /* exit action handled */
+                Q_SIG(me) = (QSignal)QEP_EMPTY_SIG;
+                s = (QHsmState)(*s)(me);            /* find superstate of s */
+            }
+        }
+
+        t = path[0];                            /* target of the transition */
+
+    }
+}
+
+void
+testBug (void)
+{
+    AO_derived.super.state = state_2;
+    AO_derived.super.evt.sig = 2;
+
+    QHsm_dispatch((QHsm *)&AO_derived);
+
+    ASSERT(1);      /*if we don't get here the regression test will timeout */
+}