From 05e1b5ab697301a5fc525957cee1a9c7837f99c4 Mon Sep 17 00:00:00 2001 From: MaartenBrock Date: Sat, 8 Mar 2008 17:34:50 +0000 Subject: [PATCH] * 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 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@5077 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 9 ++ src/ds390/gen.c | 35 +++++-- src/hc08/gen.c | 34 +++--- src/mcs51/gen.c | 7 +- support/regression/fwk/include/testfwk.h | 1 + support/regression/tests/bug1908493.c | 126 +++++++++++++++++++++++ 6 files changed, 183 insertions(+), 29 deletions(-) create mode 100644 support/regression/tests/bug1908493.c diff --git a/ChangeLog b/ChangeLog index 1832021f..96eb7c67 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,13 @@ +2008-03-08 Maarten Brock + + * 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 + * src/SDCCdebug.c:, as/link/lkaomf51.c: Fixed bug 1909409: Pdata in OMF file 2008-03-08 Maarten Brock diff --git a/src/ds390/gen.c b/src/ds390/gen.c index d8ff7c51..f077ae71 100644 --- a/src/ds390/gen.c +++ b/src/ds390/gen.c @@ -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)); diff --git a/src/hc08/gen.c b/src/hc08/gen.c index 9ae9f8d2..a656eb5b 100644 --- a/src/hc08/gen.c +++ b/src/hc08/gen.c @@ -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)); diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index 68f8524c..9db691c3 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -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 */ diff --git a/support/regression/fwk/include/testfwk.h b/support/regression/fwk/include/testfwk.h index 1e5d581b..4ded3748 100644 --- a/support/regression/fwk/include/testfwk.h +++ b/support/regression/fwk/include/testfwk.h @@ -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 index 00000000..18795ceb --- /dev/null +++ b/support/regression/tests/bug1908493.c @@ -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 + +#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 */ +} -- 2.39.5