+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>
/*-----------------------------------------------------------------*/
-/* 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--)
{
}
}
_endLazyDPSEvaluation ();
+ freeAsmop (oper, NULL, ic, TRUE);
}
/*-----------------------------------------------------------------*/
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));
// 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;
}
/* this is a temporary : this has
- only four choices :
+ only five choices :
a) register
b) spillocation
c) rematerialize
/* 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;
/* 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;
// 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)
{
{
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];
/*-----------------------------------------------------------------*/
-/* 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);
}
/*-----------------------------------------------------------------*/
// bool restoreBank=FALSE;
// bool swapBanks = FALSE;
- D(emitcode("; genPCall",""));
+ D (emitcode (";", "genPcall"));
/* if caller saves & we have not saved then */
if (!ic->regsSaved)
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));
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 */
}
return;
}
-
+
while (size--)
{
char *l = aopGet (oper, offset++, FALSE, TRUE);
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 */
# define near
# define far
# define at(x)
+# define reentrant
#endif
#if defined(SDCC_hc08)
--- /dev/null
+/* 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 */
+}