From 116a1bfc169e441ed10267f1b0fe8a2336b6dc78 Mon Sep 17 00:00:00 2001 From: maartenbrock Date: Sat, 3 Sep 2005 10:35:46 +0000 Subject: [PATCH] * .version: changed to version 2.5.3 * doc/sdccman.lyx: changed version to 2.5.3, documented --codeseg and --constseg and pragma codeseg and constseg, documented bit parameters (reentrant) and bit returning * src/SDCCicode.c (geniCodeReceive): fixed (possible) bug generating currFunc->recvSize, but is this ok for all ports? (ast2iCode): result of ~ on unsigned char must be cast to int for bool to work * src/SDCCmem.c (allocGlobal, allocLocal): don't put bit returning function pointers in bit space * src/SDCCsymt.c (checkSClass): allow bit returning function pointers, (processFuncArgs): call port.reg_parm() with reentrancy info * src/port.h, * src/avr/main.c, * src/ds390/main.c, * src/hc08/main.c, * src/pic/main.c, * src/pic16/main.c, * src/xa51/main.c, * src/z80/main.c: port.reg_parm prototype extended with "bool reentrant" parameter * src/mcs51/main.c (_mcs51_regparm): use parameter reentrant instead of options.stackAuto for allocating bit register parameters * src/mcs51/gen.c (genNot): optimized complementing direct bit, (genSend): set BitBankUsed if it is, (selectRegBank): factored out of genCall for use in genPcall, (genCall): removed redundant dtype assignmen, use selectRegBank, (genPcall): handle returning in Carry properly, save in F0 if needed, (genReceive): handle bit register parameters * src/mcs51/ralloc.c (updateRegUsage): update BitBankUsed along the way, (mcs51_assignRegisters): enable bit registers for all reentrant functions and don't set BitBankUsed unconditionally * src/mcs51/peeph.def (177.d): fixed bug if %2==%3 * support/regression/tests/bitvars.c: enable tests for SDCC_STACK_AUTO * support/regression/tests/funptrs.c: added tests for BOOL and for return git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3885 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- .version | 2 +- ChangeLog | 38 ++++++++ doc/sdccman.lyx | 106 ++++++++++++++++++++-- src/SDCCicode.c | 15 +++- src/SDCCmem.c | 12 +-- src/SDCCsymt.c | 3 +- src/avr/main.c | 2 +- src/ds390/main.c | 2 +- src/hc08/main.c | 2 +- src/mcs51/gen.c | 138 ++++++++++++++++++++--------- src/mcs51/main.c | 4 +- src/mcs51/peeph.def | 2 +- src/mcs51/ralloc.c | 4 +- src/pic/main.c | 2 +- src/pic16/main.c | 2 +- src/port.h | 30 +++---- src/xa51/main.c | 2 +- src/z80/main.c | 2 +- support/regression/tests/bitvars.c | 2 +- support/regression/tests/funptrs.c | 33 ++++++- 20 files changed, 311 insertions(+), 92 deletions(-) diff --git a/.version b/.version index f225a78a..aedc15bb 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -2.5.2 +2.5.3 diff --git a/ChangeLog b/ChangeLog index 40c1ba3c..b0a32031 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,41 @@ +2005-09-03 Maarten Brock + + * .version: changed to version 2.5.3 + * doc/sdccman.lyx: changed version to 2.5.3, + documented --codeseg and --constseg and pragma codeseg and constseg, + documented bit parameters (reentrant) and bit returning + * src/SDCCicode.c (geniCodeReceive): fixed (possible) bug generating + currFunc->recvSize, but is this ok for all ports? + (ast2iCode): result of ~ on unsigned char must be cast to int for + bool to work + * src/SDCCmem.c (allocGlobal, allocLocal): don't put bit returning + function pointers in bit space + * src/SDCCsymt.c (checkSClass): allow bit returning function pointers, + (processFuncArgs): call port.reg_parm() with reentrancy info + * src/port.h, + * src/avr/main.c, + * src/ds390/main.c, + * src/hc08/main.c, + * src/pic/main.c, + * src/pic16/main.c, + * src/xa51/main.c, + * src/z80/main.c: port.reg_parm prototype extended with + "bool reentrant" parameter + * src/mcs51/main.c (_mcs51_regparm): use parameter reentrant instead of + options.stackAuto for allocating bit register parameters + * src/mcs51/gen.c (genNot): optimized complementing direct bit, + (genSend): set BitBankUsed if it is, + (selectRegBank): factored out of genCall for use in genPcall, + (genCall): removed redundant dtype assignmen, use selectRegBank, + (genPcall): handle returning in Carry properly, save in F0 if needed, + (genReceive): handle bit register parameters + * src/mcs51/ralloc.c (updateRegUsage): update BitBankUsed along the way, + (mcs51_assignRegisters): enable bit registers for all reentrant + functions and don't set BitBankUsed unconditionally + * src/mcs51/peeph.def (177.d): fixed bug if %2==%3 + * support/regression/tests/bitvars.c: enable tests for SDCC_STACK_AUTO + * support/regression/tests/funptrs.c: added tests for BOOL and for return + 2005-08-27 Borut Razem * device/lib/Makefile.in: cp on sparc-solaris (SunOS) and on diff --git a/doc/sdccman.lyx b/doc/sdccman.lyx index 6b0c34f6..31ab8d0d 100644 --- a/doc/sdccman.lyx +++ b/doc/sdccman.lyx @@ -82,7 +82,7 @@ SDCC Compiler User Guide \size normal -SDCC 2.5.2 +SDCC 2.5.3 \size footnotesize \newline @@ -557,8 +557,8 @@ char KernelFunction3(char p) at 0x340; \family typewriter -code banking -\begin_inset LatexCommand \index{code banking (not supported)} +better code banking +\begin_inset LatexCommand \index{code banking (limited support)} \end_inset @@ -3268,8 +3268,10 @@ bin before running SDCC. \newline WARNING: Visual studio is very picky with line terminations; it expects the 0x0d, 0x0a DOS style line endings, not the 0x0a Unix style line endings. - If you are getting a message such as "This makefile was not generated by - Developer Studio etc. + When using the CVS repository it's easiest to configure the cvs client + to convert automatically for you. + If however you are getting a message such as "This makefile was not generated + by Developer Studio etc. etc. \begin_inset Quotes srd \end_inset @@ -6065,6 +6067,7 @@ status Collapsed details. If this option is used all source files in the project have to be compiled with this option. + It must also be used when invoking the linker. \layout List \labelwidthstring 00.00.0000 @@ -7796,6 +7799,74 @@ status Collapsed \labelwidthstring 00.00.0000 +\series bold +- +\begin_inset ERT +status Collapsed + +\layout Standard + +\backslash +/ +\end_inset + +-codeseg +\series default + +\begin_inset LatexCommand \index{-\/-codeseg } + +\end_inset + +\SpecialChar ~ + The name to be used for the code +\begin_inset LatexCommand \index{code} + +\end_inset + + segment, default CSEG. + This is useful if you need to tell the compiler to put the code in a special + segment so you can later on tell the linker to put this segment in a special + place in memory. + Can be used for instance when using bank switching to put the code in a + bank. +\layout List +\labelwidthstring 00.00.0000 + + +\series bold +- +\begin_inset ERT +status Collapsed + +\layout Standard + +\backslash +/ +\end_inset + +-constseg +\series default + +\begin_inset LatexCommand \index{-\/-constseg } + +\end_inset + +\SpecialChar ~ + The name to be used for the const +\begin_inset LatexCommand \index{code} + +\end_inset + + segment, default CONST. + This is useful if you need to tell the compiler to put the const data in + a special segment so you can later on tell the linker to put this segment + in a special place in memory. + Can be used for instance when using bank switching to put the const data + in a bank. +\layout List +\labelwidthstring 00.00.0000 + + \series bold more-pedantic \series default @@ -10331,6 +10402,13 @@ Parameters , (storage classes for parameters will be ignored), their allocation is governed by the memory model in use, and the reentrancy options. +\layout Standard + +It is however allowed to use bit parameters in reentrant functions and also + non-static local bit variables are supported. + Efficient use is limited to 8 semi-bitregisters in bit space. + They are pushed and popped to stack as a single byte just like the normal + registers. \layout Section Overlaying @@ -15217,6 +15295,24 @@ std_c99 - Follow the C99 standard and disable SDCC features that conflict with the standard (incomplete support). +\layout Itemize + +codeseg +\begin_inset LatexCommand \index{\#pragma codeseg} + +\end_inset + +- Use this name (max. + 8 characters) for the code segment. +\layout Itemize + +constseg +\begin_inset LatexCommand \index{\#pragma constseg} + +\end_inset + +- Use this name (max. + 8 characters) for the const segment. \layout Standard SDCPP supports the following #pragma directives: diff --git a/src/SDCCicode.c b/src/SDCCicode.c index 26dbaab3..ee4783cd 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -3110,7 +3110,7 @@ geniCodeLogicAndOr (ast *tree, int lvl) } /*-----------------------------------------------------------------*/ -/* geniCodeUnary - for a a generic unary operation */ +/* geniCodeUnary - for a generic unary operation */ /*-----------------------------------------------------------------*/ operand * geniCodeUnary (operand * op, int oper) @@ -3426,7 +3426,6 @@ geniCodeReceive (value * args, operand * func) /* for all arguments that are passed in registers */ while (args) { - int first = 1; if (IS_REGPARM (args->etype)) { operand *opr = operandFromValue (args); @@ -3458,9 +3457,8 @@ geniCodeReceive (value * args, operand * func) ic = newiCode (RECEIVE, func, NULL); ic->argreg = SPEC_ARGREG(args->etype); - if (first) { + if (ic->argreg == 1) { currFunc->recvSize = getSize (sym->type); - first = 0; } IC_RESULT (ic) = opr; @@ -4222,6 +4220,15 @@ ast2iCode (ast * tree,int lvl) #endif case '~': + { + sym_link *ltype = operandType (left); + operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op); + if ((SPEC_NOUN(ltype) == V_CHAR) && IS_UNSIGNED(ltype)) + { + setOperandType (op, INTTYPE); + } + return op; + } case RRC: case RLC: case SWAP: diff --git a/src/SDCCmem.c b/src/SDCCmem.c index ddf5ce66..35b0d9e1 100644 --- a/src/SDCCmem.c +++ b/src/SDCCmem.c @@ -416,10 +416,10 @@ allocGlobal (symbol * sym) } /* if this is a bit variable and no storage class */ - if (SPEC_NOUN (sym->etype) == V_BIT - /*&& SPEC_SCLS (sym->etype) == S_BIT*/) + if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT) + /*&& SPEC_SCLS (sym->etype) == S_BIT*/ { - SPEC_OCLS (sym->etype) = bit; + SPEC_OCLS (sym->type) = bit; allocIntoSeg (sym); return; } @@ -663,10 +663,10 @@ allocLocal (symbol * sym) } /* if this is a bit variable and no storage class */ - if (SPEC_NOUN (sym->etype) == V_BIT) + if (IS_SPEC(sym->type) && SPEC_NOUN (sym->type) == V_BIT) { - SPEC_SCLS (sym->etype) = S_BIT; - SPEC_OCLS (sym->etype) = bit; + SPEC_SCLS (sym->type) = S_BIT; + SPEC_OCLS (sym->type) = bit; allocIntoSeg (sym); return; } diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index c1bdae25..a34b6bb7 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -1521,6 +1521,7 @@ checkSClass (symbol * sym, int isProto) /* arrays & pointers cannot be defined for bits */ /* SBITS or SFRs or BIT */ if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) && + !IS_FUNCPTR (sym->type) && (SPEC_NOUN (sym->etype) == V_BIT || SPEC_NOUN (sym->etype) == V_SBIT || SPEC_NOUN (sym->etype) == V_BITFIELD || @@ -2587,7 +2588,7 @@ processFuncArgs (symbol * func) the function does not have VA_ARG and as port dictates */ if (!IFFUNC_HASVARARGS(funcType) && - (argreg = (*port->reg_parm) (val->type))) + (argreg = (*port->reg_parm) (val->type, FUNC_ISREENT(funcType)))) { SPEC_REGPARM (val->etype) = 1; SPEC_ARGREG(val->etype) = argreg; diff --git a/src/avr/main.c b/src/avr/main.c index aa9a9d3e..828c3c03 100644 --- a/src/avr/main.c +++ b/src/avr/main.c @@ -48,7 +48,7 @@ _avr_reset_regparm (void) } static int -_avr_regparm (sym_link * l) +_avr_regparm (sym_link * l, bool reentrant) { /* the first eight bytes will be passed in registers r16-r23. but we won't split variables diff --git a/src/ds390/main.c b/src/ds390/main.c index 639ab5df..a2e54083 100644 --- a/src/ds390/main.c +++ b/src/ds390/main.c @@ -76,7 +76,7 @@ _ds390_reset_regparm (void) } static int -_ds390_regparm (sym_link * l) +_ds390_regparm (sym_link * l, bool reentrant) { if (IS_SPEC(l) && (SPEC_NOUN(l) == V_BIT)) return 0; diff --git a/src/hc08/main.c b/src/hc08/main.c index 1e15fd5b..a86d3a12 100644 --- a/src/hc08/main.c +++ b/src/hc08/main.c @@ -68,7 +68,7 @@ _hc08_reset_regparm (void) } static int -_hc08_regparm (sym_link * l) +_hc08_regparm (sym_link * l, bool reentrant) { int size = getSize(l); diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index 6f9f7252..2ac72db6 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -1745,14 +1745,23 @@ genNot (iCode * ic) /* if in bit space then a special case */ if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY) { - emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir); - emitcode ("cpl", "c"); - outBitC (IC_RESULT (ic)); + /* if left==result then cpl bit */ + if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic)))) + { + emitcode ("cpl", "%s", IC_LEFT (ic)->aop->aopu.aop_dir); + } + else + { + emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir); + emitcode ("cpl", "c"); + outBitC (IC_RESULT (ic)); + } goto release; } toBoolean (IC_LEFT (ic)); + /* set C, if a == 0 */ tlbl = newiTempLabel (NULL); emitcode ("cjne", "a,#0x01,%05d$", tlbl->key + 100); emitcode ("", "%05d$:", tlbl->key + 100); @@ -2530,6 +2539,7 @@ static void genSend(set *sendSet) emitcode ("mov", "b[%d],c", bit); } bit_count++; + BitBankUsed = 1; } freeAsmop (IC_LEFT (sic), NULL, sic, TRUE); } @@ -2571,6 +2581,25 @@ static void genSend(set *sendSet) } } +/*-----------------------------------------------------------------*/ +/* selectRegBank - emit code to select the register bank */ +/*-----------------------------------------------------------------*/ +static void +selectRegBank (short bank, bool keepFlags) +{ + /* if f.e. result is in carry */ + if (keepFlags) + { + emitcode ("anl", "psw,#0xE7"); + if (bank) + emitcode ("orl", "psw,#0x%02x", (bank << 3) & 0xff); + } + else + { + emitcode ("mov", "psw,#0x%02x", (bank << 3) & 0xff); + } +} + /*-----------------------------------------------------------------*/ /* genCall - generates a call statement */ /*-----------------------------------------------------------------*/ @@ -2578,6 +2607,7 @@ static void genCall (iCode * ic) { sym_link *dtype; + sym_link *etype; // bool restoreBank = FALSE; bool swapBanks = FALSE; bool accuse = FALSE; @@ -2587,6 +2617,7 @@ genCall (iCode * ic) D(emitcode("; genCall","")); dtype = operandType (IC_LEFT (ic)); + etype = getSpec(dtype); /* if send set is not empty then assign */ if (_G.sendSet) { @@ -2602,7 +2633,6 @@ genCall (iCode * ic) /* if we are calling a not _naked function that is not using the same register bank then we need to save the destination registers on the stack */ - dtype = operandType (IC_LEFT (ic)); if (currFunc && dtype && !IFFUNC_ISNAKED(dtype) && (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) && !IFFUNC_ISISR (dtype)) @@ -2647,20 +2677,8 @@ genCall (iCode * ic) } if (swapBanks) - { - /* if result is in carry */ - if (IS_BIT (OP_SYM_ETYPE (IC_LEFT (ic)))) - { - emitcode ("anl", "psw,#0xE7"); - if (FUNC_REGBANK(currFunc->type)) - emitcode ("orl", "psw,#0x%02x", - ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff); - } - else - { - emitcode ("mov", "psw,#0x%02x", - ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff); - } + { + selectRegBank (FUNC_REGBANK(currFunc->type), IS_BIT (etype)); } /* if we need assign a result value */ @@ -2757,9 +2775,12 @@ genPcall (iCode * ic) symbol *rlbl = newiTempLabel (NULL); // bool restoreBank=FALSE; bool swapBanks = FALSE; + bool resultInF0 = FALSE; D(emitcode("; genPCall","")); + dtype = operandType (IC_LEFT (ic))->next; + etype = getSpec(dtype); /* if caller saves & we have not saved then */ if (!ic->regsSaved) saveRegisters (ic); @@ -2767,18 +2788,16 @@ genPcall (iCode * ic) /* if we are calling a not _naked function that is not using the same register bank then we need to save the destination registers on the stack */ - dtype = operandType (IC_LEFT (ic))->next; if (currFunc && dtype && !IFFUNC_ISNAKED(dtype) && (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) && !IFFUNC_ISISR (dtype)) - { + { // saveRBank (FUNC_REGBANK (dtype), ic, TRUE); // restoreBank=TRUE; swapBanks = TRUE; // need caution message to user here - } + } - etype = getSpec(dtype); if (IS_LITERAL(etype)) { /* if send set is not empty then assign */ @@ -2894,13 +2913,13 @@ genPcall (iCode * ic) } } if (swapBanks) - { - emitcode ("mov", "psw,#0x%02x", - ((FUNC_REGBANK(currFunc->type)) << 3) & 0xff); - } + { + selectRegBank (FUNC_REGBANK(currFunc->type), IS_BIT (etype)); + } /* if we need assign a result value */ if ((IS_ITEMP (IC_RESULT (ic)) && + !IS_BIT (OP_SYM_ETYPE (IC_RESULT (ic))) && (OP_SYMBOL (IC_RESULT (ic))->nRegs || OP_SYMBOL (IC_RESULT (ic))->spildir)) || IS_TRUE_SYMOP (IC_RESULT (ic))) @@ -2915,13 +2934,19 @@ genPcall (iCode * ic) freeAsmop (IC_RESULT (ic), NULL, ic, TRUE); } - /* adjust the stack for parameters if - required */ + /* adjust the stack for parameters if required */ if (ic->parmBytes) { int i; if (ic->parmBytes > 3) { + if (IS_BIT (OP_SYM_ETYPE (IC_LEFT (ic))) && + IS_BIT (OP_SYM_ETYPE (IC_RESULT (ic)))) + { + emitcode ("mov", "F0,c"); + resultInF0 = TRUE; + } + emitcode ("mov", "a,%s", spname); emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff); emitcode ("mov", "%s,a", spname); @@ -2936,10 +2961,19 @@ genPcall (iCode * ic) // if (restoreBank) // unsaveRBank (FUNC_REGBANK (dtype), ic, TRUE); - /* if we hade saved some registers then - unsave them */ + /* if we had saved some registers then unsave them */ if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype)) unsaveRegisters (ic); + + if (IS_BIT (OP_SYM_ETYPE (IC_RESULT (ic)))) + { + if (resultInF0) + emitcode ("mov", "c,F0"); + + aopOp (IC_RESULT (ic), ic, FALSE); + assignResultValue (IC_RESULT (ic), IC_LEFT (ic)); + freeAsmop (IC_RESULT (ic), NULL, ic, TRUE); + } } /*-----------------------------------------------------------------*/ @@ -10670,11 +10704,12 @@ genReceive (iCode * ic) D(emitcode ("; genReceive","")); - if (ic->argreg == 1) { /* first parameter */ + if (ic->argreg == 1) + { /* first parameter */ if (isOperandInFarSpace (IC_RESULT (ic)) && (OP_SYMBOL (IC_RESULT (ic))->isspilt || - IS_TRUE_SYMOP (IC_RESULT (ic)))) { - + IS_TRUE_SYMOP (IC_RESULT (ic)))) + { regs *tempRegs[4]; int receivingA = 0; int roffset = 0; @@ -10716,33 +10751,48 @@ genReceive (iCode * ic) } offset = fReturnSizeMCS51 - size; - while (size--) { + while (size--) + { emitcode ("push", "%s", (strcmp (fReturn[fReturnSizeMCS51 - offset - 1], "a") ? fReturn[fReturnSizeMCS51 - offset - 1] : "acc")); offset++; - } + } aopOp (IC_RESULT (ic), ic, FALSE); size = AOP_SIZE (IC_RESULT (ic)); offset = 0; - while (size--) { + while (size--) + { emitcode ("pop", "acc"); aopPut (IC_RESULT (ic), "a", offset++, isOperandVolatile (IC_RESULT (ic), FALSE)); - } - - } else { + } + } + else + { _G.accInUse++; aopOp (IC_RESULT (ic), ic, FALSE); _G.accInUse--; assignResultValue (IC_RESULT (ic), NULL); - } - } else { /* second receive onwards */ + } + } + else if (ic->argreg > 12) + { /* bit parameters */ + if (OP_SYMBOL (IC_RESULT (ic))->regs[0]->rIdx != ic->argreg-5) + { + aopOp (IC_RESULT (ic), ic, FALSE); + emitcode ("mov", "c,%s", rb1regs[ic->argreg-5]); + outBitC(IC_RESULT (ic)); + } + } + else + { /* other parameters */ int rb1off ; aopOp (IC_RESULT (ic), ic, FALSE); rb1off = ic->argreg; - while (size--) { + while (size--) + { aopPut (IC_RESULT (ic), rb1regs[rb1off++ -5], offset++, isOperandVolatile (IC_RESULT (ic), FALSE)); - } - } + } + } release: freeAsmop (IC_RESULT (ic), NULL, ic, TRUE); diff --git a/src/mcs51/main.c b/src/mcs51/main.c index a8854a78..e3788b23 100644 --- a/src/mcs51/main.c +++ b/src/mcs51/main.c @@ -69,11 +69,11 @@ _mcs51_reset_regparm (void) } static int -_mcs51_regparm (sym_link * l) +_mcs51_regparm (sym_link * l, bool reentrant) { if (IS_SPEC(l) && (SPEC_NOUN(l) == V_BIT)) { /* bit parameters go to b0 thru b7 */ - if (options.stackAuto && (regBitParmFlg < 8)) { + if (reentrant && (regBitParmFlg < 8)) { regBitParmFlg++; return 12 + regBitParmFlg; } diff --git a/src/mcs51/peeph.def b/src/mcs51/peeph.def index f6b05b3b..d4eea55e 100644 --- a/src/mcs51/peeph.def +++ b/src/mcs51/peeph.def @@ -1284,7 +1284,7 @@ replace restart { mov %1,%2 mov %3,%4 ; Peephole 177.d removed redundant move -} if notVolatile(%1 %2),operandsNotRelated(%1 %3) +} if notVolatile(%1 %2),operandsNotRelated(%1 %2 %3) // applies to f.e. bug-607243.c // also check notVolatile %3, as it will return FALSE if it's @r%1 diff --git a/src/mcs51/ralloc.c b/src/mcs51/ralloc.c index 9251cd32..e983d48a 100644 --- a/src/mcs51/ralloc.c +++ b/src/mcs51/ralloc.c @@ -984,6 +984,7 @@ updateRegUsage (iCode * ic) else { ic->riu |= (1<= 8); } } } @@ -3232,10 +3233,9 @@ mcs51_assignRegisters (ebbIndex * ebbi) setToNull ((void *) &_G.regAssigned); setToNull ((void *) &_G.totRegAssigned); mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; - if (options.stackAuto) + if ((currFunc && IFFUNC_ISREENT (currFunc->type)) || options.stackAuto) { mcs51_nRegs = 16; - BitBankUsed = 1; } else { diff --git a/src/pic/main.c b/src/pic/main.c index c646ae65..7ff31656 100644 --- a/src/pic/main.c +++ b/src/pic/main.c @@ -71,7 +71,7 @@ _pic14_reset_regparm (void) } static int -_pic14_regparm (sym_link * l) +_pic14_regparm (sym_link * l, bool reentrant) { /* for this processor it is simple can pass only the first parameter in a register */ diff --git a/src/pic16/main.c b/src/pic16/main.c index 4eb914b6..67c85790 100644 --- a/src/pic16/main.c +++ b/src/pic16/main.c @@ -116,7 +116,7 @@ _pic16_reset_regparm (void) } static int -_pic16_regparm (sym_link * l) +_pic16_regparm (sym_link * l, bool reentrant) { /* force all parameters via SEND/RECEIVE */ if(0 /*pic16_options.ip_stack*/) { diff --git a/src/port.h b/src/port.h index e44e610b..fa127a4e 100644 --- a/src/port.h +++ b/src/port.h @@ -92,7 +92,7 @@ typedef struct /* assembler file extension */ const char *file_ext; /** If non-null will be used to execute the assembler. */ - void (*do_assemble) (set *); + void (*do_assemble) (set *); } assembler; @@ -107,7 +107,7 @@ typedef struct void (*do_link) (void); /** Extension for object files (.rel, .obj, ...) */ const char *rel_ext; - /** 1 if port needs the .lnk file, 0 otherwise */ + /** 1 if port needs the .lnk file, 0 otherwise */ const int needLinkerScript; } linker; @@ -169,7 +169,7 @@ typedef struct void (*genExtraAreaLinkOptions)(FILE *); } extraAreas; - + /* stack related information */ struct { @@ -191,8 +191,8 @@ typedef struct struct { - /** One more than the smallest - mul/div operation the processor can do nativley + /** One more than the smallest + mul/div operation the processor can do nativley Eg if the processor has an 8 bit mul, nativebelow is 2 */ unsigned muldiv; unsigned shift; @@ -227,7 +227,7 @@ typedef struct int sizeofDispatch; } jumptableCost; - + /** Prefix to add to a C function (eg "_") */ const char *fun_prefix; @@ -261,30 +261,30 @@ typedef struct /* Write any port specific assembler output. */ void (*genAssemblerPreamble) (FILE * of); - /* invoked at end assembler file */ + /* invoked at end assembler file */ void (*genAssemblerEnd) (FILE * of); /* Write the port specific IVT. If genIVT is NULL or if * it returns zero, default (8051) IVT generation code - * will be used. + * will be used. */ int (*genIVT) (FILE * of, symbol ** intTable, int intCount); void (*genXINIT) (FILE * of); - + /* Write port specific startup code */ void (*genInitStartup) (FILE * of); /* parameter passing in register related functions */ void (*reset_regparms) (void); /* reset the register count */ - int (*reg_parm) (struct sym_link *); /* will return 1 if can be passed in register */ + int (*reg_parm) (struct sym_link *, bool reentrant); /* will return 1 if can be passed in register */ /** Process the pragma string 'sz'. Returns 0 if recognised and processed, 1 otherwise. May be NULL. */ int (*process_pragma) (const char *sz); - /** Mangles a support function name to reflect the calling model. + /** Mangles a support function name to reflect the calling model. */ char *(*getMangledFunctionName) (char *szOrginial); @@ -297,12 +297,12 @@ typedef struct manipulation iCodes (RRC, RLC, SWAP, GETHBIT) */ bool (*hasExtBitOp) (int op, int size); - + /** Returns the relative expense of accessing a particular output storage class. Larger values indicate higher expense. */ int (*oclsExpense) (struct memmap *oclass); - + /** If TRUE, then tprintf and !dw will be used for some initalisers */ bool use_dw_for_init; @@ -320,10 +320,10 @@ typedef struct bool ne_neq; /* transform a != b --> ! (a == b) */ bool eq_nne; /* transform a == b --> ! (a != b) */ - bool arrayInitializerSuppported; + bool arrayInitializerSuppported; bool (*cseOk) (iCode *ic, iCode *pdic); builtins *builtintable; /* table of builtin functions */ - int unqualified_pointer; /* unqualified pointers type is */ + int unqualified_pointer; /* unqualified pointers type is */ int reset_labelKey ; /* reset Label no 1 at the start of a function */ int globals_allowed ; /* global & static locals not allowed ? 0 ONLY TININative*/ #define PORT_MAGIC 0xAC32 diff --git a/src/xa51/main.c b/src/xa51/main.c index 8030dbdd..a9b329cb 100755 --- a/src/xa51/main.c +++ b/src/xa51/main.c @@ -70,7 +70,7 @@ _xa51_reset_regparm (void) } static int -_xa51_regparm (sym_link * l) +_xa51_regparm (sym_link * l, bool reentrant) { return 0; // for now /* for this processor it is simple diff --git a/src/z80/main.c b/src/z80/main.c index 33f5bbd4..248e31b5 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -119,7 +119,7 @@ _reset_regparm (void) } static int -_reg_parm (sym_link * l) +_reg_parm (sym_link * l, bool reentrant) { if (options.noRegParams) { diff --git a/support/regression/tests/bitvars.c b/support/regression/tests/bitvars.c index 6fbee3b9..abe33473 100644 --- a/support/regression/tests/bitvars.c +++ b/support/regression/tests/bitvars.c @@ -10,7 +10,7 @@ #pragma disable_warning 180 //no warning about using complement on bit/unsigned char #endif -#if defined (SDCC_STACK_AUTO) || defined (SDCC_hc08) || defined (SDCC_z80) +#if defined (SDCC_hc08) || defined (SDCC_z80) #define NO_BITS #endif diff --git a/support/regression/tests/funptrs.c b/support/regression/tests/funptrs.c index ad5248b8..546eb6b5 100644 --- a/support/regression/tests/funptrs.c +++ b/support/regression/tests/funptrs.c @@ -1,8 +1,15 @@ /** Function pointer tests. - type: char, int, long + type: BOOL, char, int, long */ #include +#include + +#ifndef BOOL +#define BOOL bool +#endif + +#define TYPE_{type} /* Must use a typedef as there is no way of adding the code modifier on the z80. @@ -10,9 +17,11 @@ typedef void (*NOARGFUNPTR)(void); typedef void (*ONEARGFUNPTR)({type}) REENTRANT; typedef long int (*FOURARGFUNPTR)(char, char, long int, long int) REENTRANT; +typedef {type} (*TYPEFUNPTR)({type}, {type}) REENTRANT; int count; FOURARGFUNPTR fafp; +TYPEFUNPTR tfp; void incCount(void) @@ -75,6 +84,13 @@ callViaPtr3Ansi(void (*fptr)(void)) fptr(); } +{type} f_ret({type} arg1, {type} arg2) REENTRANT +{ + {type} local; + local = !arg1; + return (local & arg2); +} + void @@ -86,7 +102,7 @@ testFunPtr(void) callViaPtr(incCount); ASSERT(count == 1); callViaPtr2(incBy, 7); - ASSERT(count == 8); + ASSERT(count == 8 || count == 2); ASSERT((*fafp)(0, 0x55, 0x12345678, 0x9abcdef0) == 0); ASSERT((*fafp)(1, 0x55, 0x12345678, 0x9abcdef0) == 0x55); @@ -103,7 +119,7 @@ testFunPtrAnsi(void) callViaPtrAnsi(incCount); ASSERT(count == 1); callViaPtr2Ansi(incBy, 7); - ASSERT(count == 8); + ASSERT(count == 8 || count == 2); ASSERT(fafp(0, 0x55, 0x12345678, 0x9abcdef0) == 0); ASSERT(fafp(1, 0x55, 0x12345678, 0x9abcdef0) == 0x55); @@ -111,3 +127,14 @@ testFunPtrAnsi(void) ASSERT(fafp(3, 0x55, 0x12345678, 0x9abcdef0) == 0x9abcdef0); } +void +testFunPtrReturn(void) +{ + tfp = f_ret; + + ASSERT(tfp(0, 0) == 0); + ASSERT(tfp(0, 1) == 1); + ASSERT(tfp(1, 0) == 0); + ASSERT(tfp(1, 1) == 0); +} + -- 2.30.2