From 6a370e6ab695babec796a8f30b7a03a6bc9dc77d Mon Sep 17 00:00:00 2001 From: maartenbrock Date: Thu, 18 Nov 2004 12:38:26 +0000 Subject: [PATCH] * .version: bumped version to 2.4.7 * device/lib/_gptrget.c (_gptrget): is now _naked * device/lib/_gptrgetc.c (_gptrgetc): is now _naked * device/lib/_gptrput.c (_gptrput): is now _naked * src/SDCCast.c (createBlock): removed ridiculous self-assignment, (createFunction): fixed xstack * src/SDCCglue.c (emitMaps): set allocation required for bit area * src/SDCCicode.c (geniCodeCast): don't change SPEC_OCLS for literal or bit either, (geniCodeCritical): store original interrupt state in an iTemp bit var unless stack-auto * src/SDCCicode.h: added CRITICAL and ENDCRITICAL to SKIP_IC2 * src/SDCCmain.c (setIncludePath): added include/target to search path * src/SDCCmem.c (allocParms): store bit vars in bit space, not overlay * src/SDCCsymt.c (checkFunction): don't check regbank for isr's against prototype, (processFuncArgs): put bit vars in bit area * src/mcs51/gen.c (saveRegisters, unsaveRegisters, genXpush, saveRBank, unsaveRBank): fixed xstack, (genFunction): bugfix: replaced (global!) reentrant with fReentrant, (genFunction, genEndFunction): fixed xstack, (genAssign): optimization don't walk backwards through mem * src/mcs51/main.c (_mcs51_regparm): don't pass bit params in registers * src/mcs51/ralloc.c (createStackSpil): spill bits to bit area * support/regression/Makefile: also make library (for stack-auto) when making "all" and added "test-mcs51-xstack-auto" * support/regression/fwk/lib/testfwk.c: added T2_isr prototype for mcs51 * support/regression/ports/mcs51/T2_isr.c: added this file as a stub * support/regression/ports/mcs51/fwk.lib: added to link T2_isr stub * support/regression/ports/mcs51/spec.mk: added rules for fwk.lib * support/regression/ports/mcs51-stack-auto/spec.mk: replaced make-library by MAKE_LIBRARY * support/regression/ports/mcs51-xstack-auto/spec.mk: file added to run regression tests for xstack * support/regression/tests/bitvars.c: test for bit vars (bug 938782) * support/regression/tests/critical.c: test for critical on mcs51 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3576 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- .version | 2 +- ChangeLog | 39 ++ device/lib/_gptrget.c | 4 +- device/lib/_gptrgetc.c | 7 +- device/lib/_gptrput.c | 4 +- src/SDCCast.c | 16 +- src/SDCCglue.c | 4 +- src/SDCCicode.c | 61 +- src/SDCCicode.h | 32 +- src/SDCCmain.c | 18 +- src/SDCCmem.c | 576 +++++++++--------- src/SDCCsymt.c | 19 +- src/mcs51/gen.c | 344 +++++++---- src/mcs51/main.c | 197 +++--- src/mcs51/ralloc.c | 51 +- support/regression/Makefile | 11 +- support/regression/fwk/lib/testfwk.c | 13 +- .../regression/ports/mcs51-stack-auto/spec.mk | 4 +- .../ports/mcs51-xstack-auto/spec.mk | 8 + support/regression/ports/mcs51/T2_isr.c | 6 + support/regression/ports/mcs51/fwk.lib | 1 + support/regression/ports/mcs51/spec.mk | 8 +- support/regression/tests/bitvars.c | 24 + support/regression/tests/critical.c | 69 +++ 24 files changed, 904 insertions(+), 614 deletions(-) create mode 100644 support/regression/ports/mcs51-xstack-auto/spec.mk create mode 100644 support/regression/ports/mcs51/T2_isr.c create mode 100644 support/regression/ports/mcs51/fwk.lib create mode 100644 support/regression/tests/bitvars.c create mode 100644 support/regression/tests/critical.c diff --git a/.version b/.version index 7bf4b6a8..e30309f7 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -2.4.6 +2.4.7 diff --git a/ChangeLog b/ChangeLog index 958159eb..b61e99b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,42 @@ +2004-11-18 Maarten Brock + + * .version: bumped version to 2.4.7 + * device/lib/_gptrget.c (_gptrget): is now _naked + * device/lib/_gptrgetc.c (_gptrgetc): is now _naked + * device/lib/_gptrput.c (_gptrput): is now _naked + * src/SDCCast.c (createBlock): removed ridiculous self-assignment, + (createFunction): fixed xstack + * src/SDCCglue.c (emitMaps): set allocation required for bit area + * src/SDCCicode.c (geniCodeCast): don't change SPEC_OCLS for literal + or bit either, + (geniCodeCritical): store original interrupt state in an iTemp bit + var unless stack-auto + * src/SDCCicode.h: added CRITICAL and ENDCRITICAL to SKIP_IC2 + * src/SDCCmain.c (setIncludePath): added include/target to search path + * src/SDCCmem.c (allocParms): store bit vars in bit space, not overlay + * src/SDCCsymt.c (checkFunction): don't check regbank for isr's against + prototype, + (processFuncArgs): put bit vars in bit area + * src/mcs51/gen.c (saveRegisters, unsaveRegisters, genXpush, saveRBank, + unsaveRBank): fixed xstack, + (genFunction): bugfix: replaced (global!) reentrant with fReentrant, + (genFunction, genEndFunction): fixed xstack, + (genAssign): optimization don't walk backwards through mem + * src/mcs51/main.c (_mcs51_regparm): don't pass bit params in registers + * src/mcs51/ralloc.c (createStackSpil): spill bits to bit area + * support/regression/Makefile: also make library (for stack-auto) when + making "all" and added "test-mcs51-xstack-auto" + * support/regression/fwk/lib/testfwk.c: added T2_isr prototype for mcs51 + * support/regression/ports/mcs51/T2_isr.c: added this file as a stub + * support/regression/ports/mcs51/fwk.lib: added to link T2_isr stub + * support/regression/ports/mcs51/spec.mk: added rules for fwk.lib + * support/regression/ports/mcs51-stack-auto/spec.mk: replaced + make-library by MAKE_LIBRARY + * support/regression/ports/mcs51-xstack-auto/spec.mk: file added to run + regression tests for xstack + * support/regression/tests/bitvars.c: test for bit vars (bug 938782) + * support/regression/tests/critical.c: test for critical on mcs51 + 2004-11-18 Erik Petrich * support/regression/ports/ucz80/spec.mk: use include and lib files from diff --git a/device/lib/_gptrget.c b/device/lib/_gptrget.c index 30f98297..e3e6d577 100644 --- a/device/lib/_gptrget.c +++ b/device/lib/_gptrget.c @@ -33,11 +33,12 @@ /* the return value is expected to be in acc, and not in the standard * location dpl. Therefore we choose return type void here: */ void -_gptrget (char *gptr) +_gptrget (char *gptr) _naked { gptr; /* hush the compiler */ _asm + ar0 = 0x00 ; save values passed ; ; depending on the pointer type acc. to SDCCsymt.h @@ -101,6 +102,7 @@ _gptrget (char *gptr) ; return ; 00005$: + ret _endasm ; } diff --git a/device/lib/_gptrgetc.c b/device/lib/_gptrgetc.c index 459562b9..45b79f31 100644 --- a/device/lib/_gptrgetc.c +++ b/device/lib/_gptrgetc.c @@ -27,7 +27,7 @@ /* the return value is expected to be in acc, and not in the standard * location dpl. Therefore we choose return type void here: */ void -_gptrgetc (char *gptr) +_gptrgetc (char *gptr) _naked { gptr; /* hush the compiler */ @@ -45,7 +45,7 @@ _gptrgetc (char *gptr) dec a jz 00003$ ; 2 code dec a - jz 00004$ + jz 00004$ ; 3 pdata dec a ; 4 skip generic pointer dec a jz 00001$ ; 5 idata @@ -81,7 +81,8 @@ _gptrgetc (char *gptr) 00005$: mov r0,a pop acc - xch a,r0 + xch a,r0 + ret _endasm ; } diff --git a/device/lib/_gptrput.c b/device/lib/_gptrput.c index f7aadc33..41d9a00e 100644 --- a/device/lib/_gptrput.c +++ b/device/lib/_gptrput.c @@ -31,11 +31,12 @@ #define USE_PDATA_PAGING_REGISTER 0 void -_gptrput (char *gptr, char c) +_gptrput (char *gptr, char c) _naked { gptr; c; /* hush the compiler */ _asm + ar0 = 0x00 push acc ; ; depending on the pointer type acc. to SDCCsymt.h @@ -85,6 +86,7 @@ _gptrput (char *gptr, char c) #endif 00005$: + ret _endasm; } diff --git a/src/SDCCast.c b/src/SDCCast.c index 1339b3ba..b3e14fe4 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -4431,7 +4431,6 @@ createBlock (symbol * decl, ast * body) ex = newNode (BLOCK, NULL, body); ex->values.sym = decl; - ex->right = ex->right;///????? ex->level++; ex->lineno = 0; return ex; @@ -5301,14 +5300,19 @@ createFunction (symbol * name, ast * body) currFunc = name; /* set the stack pointer */ - /* PENDING: check this for the mcs51 */ - stackPtr = -port->stack.direction * port->stack.call_overhead; + stackPtr = -port->stack.direction * port->stack.call_overhead; + xstackPtr = -port->stack.direction * port->stack.call_overhead; + if (IFFUNC_ISISR (name->type)) stackPtr -= port->stack.direction * port->stack.isr_overhead; - if (IFFUNC_ISREENT (name->type) || options.stackAuto) - stackPtr -= port->stack.direction * port->stack.reent_overhead; - xstackPtr = -port->stack.direction * port->stack.call_overhead; + if (IFFUNC_ISREENT (name->type) || options.stackAuto) + { + if (options.useXstack) + xstackPtr -= port->stack.direction * port->stack.reent_overhead; + else + stackPtr -= port->stack.direction * port->stack.reent_overhead; + } fetype = getSpec (name->type); /* get the specifier for the function */ /* if this is a reentrant function then */ diff --git a/src/SDCCglue.c b/src/SDCCglue.c index acb2d342..bf3c1ac4 100644 --- a/src/SDCCglue.c +++ b/src/SDCCglue.c @@ -1319,7 +1319,7 @@ emitMaps (void) data, idata & bit & xdata */ emitRegularMap (data, TRUE, TRUE); emitRegularMap (idata, TRUE, TRUE); - emitRegularMap (bit, TRUE, FALSE); + emitRegularMap (bit, TRUE, TRUE); emitRegularMap (pdata, TRUE, TRUE); emitRegularMap (xdata, TRUE, TRUE); if (port->genXINIT) { @@ -1595,7 +1595,7 @@ glue (void) cdbStructBlock (0); vFile = tempfile (); - /* PENDING: this isnt the best place but it will do */ + /* PENDING: this isn't the best place but it will do */ if (port->general.glue_up_main) { /* create the interrupt vector table */ diff --git a/src/SDCCicode.c b/src/SDCCicode.c index fb6c0224..6e7dcb26 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -660,7 +660,7 @@ newiTempLabel (char *s) { symbol *itmplbl; - /* check if this alredy exists */ + /* check if this already exists */ if (s && (itmplbl = findSym (LabelTab, NULL, s))) return itmplbl; @@ -2027,9 +2027,10 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) restype = getSpec (operandType (IC_RESULT (ic))); if (!IS_LITERAL(opetype) && !IS_BIT(opetype)) + { SPEC_SCLS (restype) = SPEC_SCLS (opetype); - SPEC_OCLS (restype) = SPEC_OCLS (opetype); - + SPEC_OCLS (restype) = SPEC_OCLS (opetype); + } ADDTOCHAIN (ic); return IC_RESULT (ic); } @@ -3237,12 +3238,12 @@ geniCodeParms (ast * parms, value *argVals, int *stack, /* hack don't like this but too lazy to think of something better */ if (IS_ADDRESS_OF_OP (parms)) - parms->left->lvalue = 1; + parms->left->lvalue = 1; if (IS_CAST_OP (parms) && - IS_PTR (parms->ftype) && - IS_ADDRESS_OF_OP (parms->right)) - parms->right->left->lvalue = 1; + IS_PTR (parms->ftype) && + IS_ADDRESS_OF_OP (parms->right)) + parms->right->left->lvalue = 1; pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE); } @@ -3260,24 +3261,24 @@ geniCodeParms (ast * parms, value *argVals, int *stack, { /* now decide whether to push or assign */ if (!(options.stackAuto || IFFUNC_ISREENT (ftype))) - { + { - /* assign */ - operand *top = operandFromSymbol (argVals->sym); - /* clear useDef and other bitVectors */ - OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL; - geniCodeAssign (top, pval, 1, 0); - } + /* assign */ + operand *top = operandFromSymbol (argVals->sym); + /* clear useDef and other bitVectors */ + OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL; + geniCodeAssign (top, pval, 1, 0); + } else - { - sym_link *p = operandType (pval); - /* push */ - ic = newiCode (IPUSH, pval, NULL); - ic->parmPush = 1; - /* update the stack adjustment */ - *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p); - ADDTOCHAIN (ic); - } + { + sym_link *p = operandType (pval); + /* push */ + ic = newiCode (IPUSH, pval, NULL); + ic->parmPush = 1; + /* update the stack adjustment */ + *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p); + ADDTOCHAIN (ic); + } } argVals=argVals->next; @@ -3817,11 +3818,23 @@ geniCodeCritical (ast *tree, int lvl) { iCode *ic; operand *op = NULL; + sym_link *type; + + if (!options.stackAuto) + { + type = newLink(SPECIFIER); + SPEC_VOLATILE(type) = 1; + SPEC_NOUN(type) = V_BIT; + SPEC_SCLS(type) = S_BIT; + SPEC_BLEN(type) = 1; + SPEC_BSTR(type) = 0; + op = newiTempOperand(type, 1); + } /* If op is NULL, the original interrupt state will saved on */ /* the stack. Otherwise, it will be saved in op. */ - /* Generate a save of the current interrupt state & disabled */ + /* Generate a save of the current interrupt state & disable */ ic = newiCode (CRITICAL, NULL, NULL); IC_RESULT (ic) = op; ADDTOCHAIN (ic); diff --git a/src/SDCCicode.h b/src/SDCCicode.h index 98469dba..2968911f 100644 --- a/src/SDCCicode.h +++ b/src/SDCCicode.h @@ -207,25 +207,27 @@ typedef struct icodeFuncTable iCodeTable; /* useful macros */ -#define SKIP_IC2(x) (x->op == GOTO || \ - x->op == LABEL || \ - x->op == FUNCTION || \ - x->op == INLINEASM || \ - x->op == ENDFUNCTION ) - -#define SKIP_IC1(x) (x->op == CALL || \ +#define SKIP_IC2(x) (x->op == GOTO || \ + x->op == LABEL || \ + x->op == FUNCTION || \ + x->op == INLINEASM || \ + x->op == ENDFUNCTION || \ + x->op == CRITICAL || \ + x->op == ENDCRITICAL ) + +#define SKIP_IC1(x) (x->op == CALL || \ SKIP_IC2(x) ) -#define SKIP_IC(x) (x->op == PCALL || \ - x->op == IPUSH || \ - x->op == IPOP || \ - x->op == JUMPTABLE || \ - x->op == RECEIVE || \ - x->op == ARRAYINIT || \ - SKIP_IC1(x)|| \ +#define SKIP_IC(x) (x->op == PCALL || \ + x->op == IPUSH || \ + x->op == IPOP || \ + x->op == JUMPTABLE || \ + x->op == RECEIVE || \ + x->op == ARRAYINIT || \ + SKIP_IC1(x) || \ x->op == SEND ) -#define SKIP_IC3(x) (SKIP_IC2(x) || \ +#define SKIP_IC3(x) (SKIP_IC2(x) || \ x->op == JUMPTABLE ) #define IS_CONDITIONAL(x) (x->op == EQ_OP || \ diff --git a/src/SDCCmain.c b/src/SDCCmain.c index 08215875..f8c454c2 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -2010,20 +2010,28 @@ static void setIncludePath(void) { char *p; + set *tempSet=NULL; /* * Search logic: * - * 1. - $SDCC_INCLUDE - * 2. - $SDCC_HOME/PREFIX2DATA_DIR/INCLUDE_DIR_SUFFIX - * 3. - path(argv[0])/BIN2DATA_DIR/INCLUDE_DIR_SUFFIX - * 4. - DATADIR/INCLUDE_DIR_SUFFIX (only on *nix) + * 1. - $SDCC_INCLUDE/target + * 2. - $SDCC_HOME/PREFIX2DATA_DIR/INCLUDE_DIR_SUFFIX/target + * 3. - path(argv[0])/BIN2DATA_DIR/INCLUDE_DIR_SUFFIX/target + * 4. - DATADIR/INCLUDE_DIR_SUFFIX/target (only on *nix) + * 5. - $SDCC_INCLUDE + * 6. - $SDCC_HOME/PREFIX2DATA_DIR/INCLUDE_DIR_SUFFIX + * 7. - path(argv[0])/BIN2DATA_DIR/INCLUDE_DIR_SUFFIX + * 8. - DATADIR/INCLUDE_DIR_SUFFIX (only on *nix) */ if (options.nostdinc) return; - includeDirsSet = appendStrSet(dataDirsSet, NULL, INCLUDE_DIR_SUFFIX); + tempSet = appendStrSet(dataDirsSet, NULL, INCLUDE_DIR_SUFFIX); + includeDirsSet = appendStrSet(tempSet, NULL, DIR_SEPARATOR_STRING); + includeDirsSet = appendStrSet(includeDirsSet, NULL, port->target); + mergeSets(&includeDirsSet, tempSet); if ((p = getenv(SDCC_INCLUDE_NAME)) != NULL) addSetHead(&includeDirsSet, p); diff --git a/src/SDCCmem.c b/src/SDCCmem.c index 1e062c54..cb092aa7 100644 --- a/src/SDCCmem.c +++ b/src/SDCCmem.c @@ -5,46 +5,46 @@ #include "common.h" /* memory segments */ -memmap *xstack = NULL; /* xternal stack data */ -memmap *istack = NULL; /* internal stack */ -memmap *code = NULL; /* code segment */ -memmap *data = NULL; /* internal data upto 128 */ -memmap *pdata = NULL; /* paged external data */ -memmap *xdata = NULL; /* external data */ +memmap *xstack = NULL; /* xternal stack data */ +memmap *istack = NULL; /* internal stack */ +memmap *code = NULL; /* code segment */ +memmap *data = NULL; /* internal data upto 128 */ +memmap *pdata = NULL; /* paged external data */ +memmap *xdata = NULL; /* external data */ memmap *xidata = NULL; /* the initialized xdata */ memmap *xinit = NULL; /* the initializers for xidata */ -memmap *idata = NULL; /* internal data upto 256 */ -memmap *bit = NULL; /* bit addressable space */ -memmap *statsg = NULL; /* the constant data segment */ -memmap *sfr = NULL; /* register space */ -memmap *reg = NULL; /* register space */ -memmap *sfrbit = NULL; /* sfr bit space */ -memmap *generic = NULL; /* is a generic pointer */ -memmap *overlay = NULL; /* overlay segment */ -memmap *eeprom = NULL; /* eeprom location */ -memmap *home = NULL; /* Unswitchable code bank */ +memmap *idata = NULL; /* internal data upto 256 */ +memmap *bit = NULL; /* bit addressable space */ +memmap *statsg = NULL; /* the constant data segment */ +memmap *sfr = NULL; /* register space */ +memmap *reg = NULL; /* register space */ +memmap *sfrbit = NULL; /* sfr bit space */ +memmap *generic = NULL; /* is a generic pointer */ +memmap *overlay = NULL; /* overlay segment */ +memmap *eeprom = NULL; /* eeprom location */ +memmap *home = NULL; /* Unswitchable code bank */ /* this is a set of sets each set containing symbols in a single overlay */ set *ovrSetSets = NULL; int maxRegBank = 0; -int fatalError = 0; /* fatal error flag */ +int fatalError = 0; /* fatal error flag */ /*-----------------------------------------------------------------*/ /* allocMap - allocates a memory map */ /*-----------------------------------------------------------------*/ memmap * -allocMap (char rspace, /* sfr space */ - char farmap, /* far or near segment */ - char paged, /* can this segment be paged */ - char direct, /* directly addressable */ - char bitaddr, /* bit addressable space */ - char codemap, /* this is code space */ - unsigned sloc, /* starting location */ - const char *name, /* 2 character name */ - char dbName, /* debug name */ - int ptrType /* pointer type for this space */ +allocMap (char rspace, /* sfr space */ + char farmap, /* far or near segment */ + char paged, /* can this segment be paged */ + char direct, /* directly addressable */ + char bitaddr, /* bit addressable space */ + char codemap, /* this is code space */ + unsigned sloc, /* starting location */ + const char *name, /* 2 character name */ + char dbName, /* debug name */ + int ptrType /* pointer type for this space */ ) { memmap *map; @@ -79,58 +79,58 @@ allocMap (char rspace, /* sfr space */ /*-----------------------------------------------------------------*/ /* initMem - allocates and initializes all the segments */ /*-----------------------------------------------------------------*/ -void +void initMem () { /* allocate all the segments */ - /* xternal stack segment ; + /* xternal stack segment ; SFRSPACE - NO FAR-SPACE - YES PAGED - YES DIRECT-ACCESS - NO BIT-ACCESS - NO - CODE-ACESS - NO + CODE-ACESS - NO DEBUG-NAME - 'A' POINTER-TYPE - FPOINTER */ xstack = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME, 'A', PPOINTER); - /* internal stack segment ; + /* internal stack segment ; SFRSPACE - NO FAR-SPACE - NO PAGED - NO DIRECT-ACCESS - NO BIT-ACCESS - NO - CODE-ACESS - NO + CODE-ACESS - NO DEBUG-NAME - 'B' POINTER-TYPE - POINTER */ if (ISTACK_NAME) { - istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc, - ISTACK_NAME, 'B', POINTER); + istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc, + ISTACK_NAME, 'B', POINTER); } else { istack=NULL; } - /* code segment ; + /* code segment ; SFRSPACE - NO FAR-SPACE - YES PAGED - NO DIRECT-ACCESS - NO BIT-ACCESS - NO - CODE-ACESS - YES + CODE-ACESS - YES DEBUG-NAME - 'C' POINTER-TYPE - CPOINTER */ code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER); - /* home segment ; + /* home segment ; SFRSPACE - NO FAR-SPACE - YES PAGED - NO DIRECT-ACCESS - NO BIT-ACCESS - NO - CODE-ACESS - YES + CODE-ACESS - YES DEBUG-NAME - 'C' POINTER-TYPE - CPOINTER */ @@ -142,7 +142,7 @@ initMem () PAGED - NO DIRECT-ACCESS - NO BIT-ACCESS - NO - CODE-ACESS - YES + CODE-ACESS - YES DEBUG-NAME - 'D' POINTER-TYPE - CPOINTER */ @@ -154,7 +154,7 @@ initMem () PAGED - NO DIRECT-ACCESS - YES BIT-ACCESS - NO - CODE-ACESS - NO + CODE-ACESS - NO DEBUG-NAME - 'E' POINTER-TYPE - POINTER */ @@ -166,7 +166,7 @@ initMem () PAGED - NO DIRECT-ACCESS - YES BIT-ACCESS - NO - CODE-ACESS - NO + CODE-ACESS - NO DEBUG-NAME - 'E' POINTER-TYPE - POINTER */ @@ -192,13 +192,13 @@ initMem () pdata = NULL; } - /* Xternal Data segment - + /* Xternal Data segment - SFRSPACE - NO FAR-SPACE - YES PAGED - NO DIRECT-ACCESS - NO BIT-ACCESS - NO - CODE-ACESS - NO + CODE-ACESS - NO DEBUG-NAME - 'F' POINTER-TYPE - FPOINTER */ @@ -212,15 +212,15 @@ initMem () PAGED - NO DIRECT-ACCESS - NO BIT-ACCESS - NO - CODE-ACESS - NO + CODE-ACESS - NO DEBUG-NAME - 'G' POINTER-TYPE - IPOINTER */ if (IDATA_NAME) { - idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc, - IDATA_NAME, 'G', IPOINTER); + idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc, + IDATA_NAME, 'G', IPOINTER); } else { - idata = NULL; + idata=NULL; } /* Static segment (code for variables ); @@ -229,7 +229,7 @@ initMem () PAGED - NO DIRECT-ACCESS - YES BIT-ACCESS - YES - CODE-ACESS - NO + CODE-ACESS - NO DEBUG-NAME - 'H' POINTER-TYPE - _NONE_ */ @@ -241,7 +241,7 @@ initMem () PAGED - NO DIRECT-ACCESS - YES BIT-ACCESS - NO - CODE-ACESS - NO + CODE-ACESS - NO DEBUG-NAME - 'I' POINTER-TYPE - _NONE_ */ @@ -253,31 +253,31 @@ initMem () PAGED - NO DIRECT-ACCESS - NO BIT-ACCESS - NO - CODE-ACESS - NO + CODE-ACESS - NO DEBUG-NAME - ' ' POINTER-TYPE - _NONE_ */ reg = allocMap (1, 0, 0, 0, 0, 0, 0, REG_NAME, ' ', 0); - /* SFR bit space + /* SFR bit space SFRSPACE - YES FAR-SPACE - NO PAGED - NO DIRECT-ACCESS - YES BIT-ACCESS - YES - CODE-ACESS - NO + CODE-ACESS - NO DEBUG-NAME - 'J' POINTER-TYPE - _NONE_ */ sfrbit = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, 'J', 0); - /* EEPROM bit space + /* EEPROM bit space SFRSPACE - NO FAR-SPACE - YES PAGED - NO DIRECT-ACCESS - NO BIT-ACCESS - NO - CODE-ACESS - NO + CODE-ACESS - NO DEBUG-NAME - 'K' POINTER-TYPE - EEPPOINTER */ @@ -291,7 +291,7 @@ initMem () /*-----------------------------------------------------------------*/ /* allocIntoSeg - puts a symbol into a memory segment */ /*-----------------------------------------------------------------*/ -void +void allocIntoSeg (symbol * sym) { memmap *segment = SPEC_OCLS (sym->etype); @@ -300,13 +300,13 @@ allocIntoSeg (symbol * sym) /*-----------------------------------------------------------------*/ /* deleteFromSeg - deletes a symbol from segment used when a var */ -/* firest declared as "extern" then no extern */ +/* first declared as "extern" then no extern */ /*-----------------------------------------------------------------*/ void deleteFromSeg(symbol *sym) { if (SPEC_OCLS(sym->etype)) { - memmap *segment = SPEC_OCLS (sym->etype); - deleteSetItem(&segment->syms,sym); + memmap *segment = SPEC_OCLS (sym->etype); + deleteSetItem(&segment->syms,sym); } } @@ -314,14 +314,14 @@ void deleteFromSeg(symbol *sym) /*-----------------------------------------------------------------*/ /* allocGlobal - assigns the output segment to a global var */ /*-----------------------------------------------------------------*/ -void +void allocGlobal (symbol * sym) { /* symbol name is internal name */ - if (!sym->level) /* local statics can come here */ - SNPRINTF (sym->rname, sizeof(sym->rname), - "%s%s", port->fun_prefix, sym->name); + if (!sym->level) /* local statics can come here */ + SNPRINTF (sym->rname, sizeof(sym->rname), + "%s%s", port->fun_prefix, sym->name); /* add it to the operandKey reset */ if (!isinSet (operKeyReset, sym)) { @@ -344,7 +344,7 @@ allocGlobal (symbol * sym) then put it in the interrupt service array */ if (FUNC_ISISR (sym->type) && !options.noiv && (FUNC_INTNO (sym->type) != INTNO_UNSPEC)) - { + { if (interrupts[FUNC_INTNO (sym->type)]) werror (E_INT_DEFINED, FUNC_INTNO (sym->type), @@ -355,7 +355,7 @@ allocGlobal (symbol * sym) /* automagically extend the maximum interrupts */ if (FUNC_INTNO (sym->type) >= maxInterrupts) maxInterrupts = FUNC_INTNO (sym->type) + 1; - } + } /* if it is not compiler defined */ if (!sym->cdef) allocIntoSeg (sym); @@ -369,7 +369,7 @@ allocGlobal (symbol * sym) { SPEC_OCLS (sym->etype) = - (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit); + (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit); allocIntoSeg (sym); return; @@ -394,8 +394,8 @@ allocGlobal (symbol * sym) if(!TARGET_IS_PIC16 || (TARGET_IS_PIC16 && sym->level)) /* register storage class ignored changed to FIXED */ - if (SPEC_SCLS (sym->etype) == S_REGISTER) - SPEC_SCLS (sym->etype) = S_FIXED; + if (SPEC_SCLS (sym->etype) == S_REGISTER) + SPEC_SCLS (sym->etype) = S_FIXED; /* if data specified then */ if (SPEC_SCLS (sym->etype) == S_DATA) @@ -434,7 +434,7 @@ allocGlobal (symbol * sym) { // should we move this to the initialized data segment? if (port->genXINIT && - sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) { + sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) { SPEC_OCLS(sym->etype)=xidata; } else { SPEC_OCLS (sym->etype) = xdata; @@ -472,7 +472,7 @@ allocGlobal (symbol * sym) /*-----------------------------------------------------------------*/ /* allocParms - parameters are always passed on stack */ /*-----------------------------------------------------------------*/ -void +void allocParms (value * val) { value *lval; @@ -502,69 +502,71 @@ allocParms (value * val) if (lval->sym) lval->sym->onStack = 1; - /* choose which stack 2 use */ - /* use xternal stack */ - if (options.useXstack) - { - /* PENDING: stack direction support */ - SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack; - SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack = - xstackPtr - getSize (lval->type); - xstackPtr -= getSize (lval->type); - } - else - { /* use internal stack */ - SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack; - if (port->stack.direction > 0) - { - SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack = - stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) - - getSize (lval->type) - - (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0); - stackPtr -= getSize (lval->type); - } - else - { - /* This looks like the wrong order but it turns out OK... */ - /* PENDING: isr, bank overhead, ... */ - SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack = - stackPtr + - ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) + - (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) + - 0; - stackPtr += getSize (lval->type); - } - } - allocIntoSeg (lval->sym); - } + /* choose which stack 2 use */ + /* use xternal stack */ + if (options.useXstack) + { + /* PENDING: stack direction support */ + SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack; + SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack = + xstackPtr - getSize (lval->type); + xstackPtr -= getSize (lval->type); + } + else + { /* use internal stack */ + SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack; + if (port->stack.direction > 0) + { + SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack = + stackPtr - (FUNC_REGBANK (currFunc->type) ? port->stack.bank_overhead : 0) - + getSize (lval->type) - + (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0); + stackPtr -= getSize (lval->type); + } + else + { + /* This looks like the wrong order but it turns out OK... */ + /* PENDING: isr, bank overhead, ... */ + SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack = + stackPtr + + ((IFFUNC_ISBANKEDCALL (currFunc->type) && !SPEC_STAT(getSpec(currFunc->etype)))? port->stack.banked_overhead : 0) + + (FUNC_ISISR (currFunc->type) ? port->stack.isr_overhead : 0) + + 0; + stackPtr += getSize (lval->type); + } + } + allocIntoSeg (lval->sym); + } else - { /* allocate them in the automatic space */ - /* generate a unique name */ - SNPRINTF (lval->sym->rname, sizeof(lval->sym->rname), - "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum); - strncpyz (lval->name, lval->sym->rname, sizeof(lval->name)); - - /* if declared in external storage */ - if (SPEC_SCLS (lval->etype) == S_XDATA) - SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata; - else - /* other wise depending on the memory model - note here that we put it into the overlay segment - first, we will remove it from the overlay segment - after the overlay determination has been done */ - if (options.model == MODEL_SMALL) - { - SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = - (options.noOverlay ? port->mem.default_local_map - : overlay); - } - else - { - SPEC_SCLS (lval->etype) = S_XDATA; - SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata; - } - allocIntoSeg (lval->sym); - } + { /* allocate them in the automatic space */ + /* generate a unique name */ + SNPRINTF (lval->sym->rname, sizeof(lval->sym->rname), + "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum); + strncpyz (lval->name, lval->sym->rname, sizeof(lval->name)); + + /* if declared in external storage */ + if (SPEC_SCLS (lval->etype) == S_XDATA) + SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata; + else if (SPEC_SCLS (lval->etype) == S_BIT) + SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = bit; + else + /* otherwise depending on the memory model + note here that we put it into the overlay segment + first, we will remove it from the overlay segment + after the overlay determination has been done */ + if (options.model == MODEL_SMALL) + { + SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = + (options.noOverlay ? port->mem.default_local_map + : overlay); + } + else + { + SPEC_SCLS (lval->etype) = S_XDATA; + SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata; + } + allocIntoSeg (lval->sym); + } } return; @@ -573,7 +575,7 @@ allocParms (value * val) /*-----------------------------------------------------------------*/ /* deallocParms - parameters are always passed on stack */ /*-----------------------------------------------------------------*/ -void +void deallocParms (value * val) { value *lval; @@ -588,30 +590,30 @@ deallocParms (value * val) deleteSym (SymbolTab, lval->sym, lval->sym->name); if (!lval->sym->isref) - { - lval->sym->allocreq = 0; - werror (W_NO_REFERENCE, - currFunc ? currFunc->name : "(unknown)", - "function argument", lval->sym->name); - } + { + lval->sym->allocreq = 0; + werror (W_NO_REFERENCE, + currFunc ? currFunc->name : "(unknown)", + "function argument", lval->sym->name); + } /* move the rname if any to the name for both val & sym */ /* and leave a copy of it in the symbol table */ if (lval->sym->rname[0]) - { - char buffer[SDCC_NAME_MAX]; - strncpyz (buffer, lval->sym->rname, sizeof(buffer)); - lval->sym = copySymbol (lval->sym); - strncpyz (lval->sym->rname, buffer, sizeof(lval->sym->rname)); - strncpyz (lval->sym->name, buffer, sizeof(lval->sym->name)); - strncpyz (lval->name, buffer, sizeof(lval->name)); - addSym (SymbolTab, lval->sym, lval->sym->name, - lval->sym->level, lval->sym->block, 1); - lval->sym->_isparm = 1; - if (!isinSet (operKeyReset, lval->sym)) { - addSet(&operKeyReset, lval->sym); - } - } + { + char buffer[SDCC_NAME_MAX]; + strncpyz (buffer, lval->sym->rname, sizeof(buffer)); + lval->sym = copySymbol (lval->sym); + strncpyz (lval->sym->rname, buffer, sizeof(lval->sym->rname)); + strncpyz (lval->sym->name, buffer, sizeof(lval->sym->name)); + strncpyz (lval->name, buffer, sizeof(lval->name)); + addSym (SymbolTab, lval->sym, lval->sym->name, + lval->sym->level, lval->sym->block, 1); + lval->sym->_isparm = 1; + if (!isinSet (operKeyReset, lval->sym)) { + addSet(&operKeyReset, lval->sym); + } + } } @@ -621,15 +623,15 @@ deallocParms (value * val) /*-----------------------------------------------------------------*/ /* allocLocal - allocate local variables */ /*-----------------------------------------------------------------*/ -void +void allocLocal (symbol * sym) { /* generate an unique name */ - SNPRINTF (sym->rname, sizeof(sym->rname), - "%s%s_%s_%d_%d", - port->fun_prefix, - currFunc->name, sym->name, sym->level, sym->block); + SNPRINTF (sym->rname, sizeof(sym->rname), + "%s%s_%s_%d_%d", + port->fun_prefix, + currFunc->name, sym->name, sym->level, sym->block); sym->islocal = 1; sym->localof = currFunc; @@ -659,17 +661,17 @@ allocLocal (symbol * sym) } else { SPEC_OCLS (sym->etype) = istack; if (port->stack.direction > 0) { - SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1); - stackPtr += getSize (sym->type); + SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1); + stackPtr += getSize (sym->type); } else { - stackPtr -= getSize (sym->type); - SPEC_STAK (sym->etype) = sym->stack = stackPtr; + stackPtr -= getSize (sym->type); + SPEC_STAK (sym->etype) = sym->stack = stackPtr; } } allocIntoSeg (sym); return; } - + /* else depending on the storage class specified */ if (SPEC_SCLS (sym->etype) == S_XDATA) { @@ -683,7 +685,7 @@ allocLocal (symbol * sym) allocIntoSeg (sym); return; } - + if (SPEC_SCLS (sym->etype) == S_IDATA) { SPEC_OCLS (sym->etype) = idata; @@ -704,7 +706,7 @@ allocLocal (symbol * sym) SPEC_SCLS (sym->etype) == S_SBIT) { SPEC_OCLS (sym->etype) = - (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit); + (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit); allocIntoSeg (sym); return; @@ -734,12 +736,12 @@ allocLocal (symbol * sym) } /* again note that we have put it into the overlay segment - will remove and put into the 'data' segment if required after + will remove and put into the 'data' segment if required after overlay analysis has been done */ if (options.model == MODEL_SMALL) { - SPEC_OCLS (sym->etype) = - (options.noOverlay ? port->mem.default_local_map - : overlay); + SPEC_OCLS (sym->etype) = + (options.noOverlay ? port->mem.default_local_map + : overlay); } else { SPEC_OCLS (sym->etype) = port->mem.default_local_map; } @@ -749,29 +751,29 @@ allocLocal (symbol * sym) /*-----------------------------------------------------------------*/ /* deallocLocal - deallocates the local variables */ /*-----------------------------------------------------------------*/ -void +void deallocLocal (symbol * csym) { symbol *sym; for (sym = csym; sym; sym = sym->next) { - if (sym->_isparm) - continue; + if (sym->_isparm) + continue; /* if it is on the stack */ if (sym->onStack) - { - if (options.useXstack) - xstackPtr -= getSize (sym->type); - else - stackPtr -= getSize (sym->type); - } + { + if (options.useXstack) + xstackPtr -= getSize (sym->type); + else + stackPtr -= getSize (sym->type); + } /* if not used give a warning */ if (!sym->isref && !IS_STATIC (sym->etype)) - werror (W_NO_REFERENCE, - currFunc ? currFunc->name : "(unknown)", - "local variable", sym->name); + werror (W_NO_REFERENCE, + currFunc ? currFunc->name : "(unknown)", + "local variable", sym->name); /* now delete it from the symbol table */ deleteSym (SymbolTab, sym, sym->name); } @@ -780,7 +782,7 @@ deallocLocal (symbol * csym) /*-----------------------------------------------------------------*/ /* overlay2data - moves declarations from the overlay seg to data */ /*-----------------------------------------------------------------*/ -void +void overlay2data () { symbol *sym; @@ -801,7 +803,7 @@ overlay2data () /* overlay2Set - will add all symbols from the overlay segment to */ /* the set of sets containing the overlable symbols */ /*-----------------------------------------------------------------*/ -void +void overlay2Set () { symbol *sym; @@ -822,7 +824,7 @@ overlay2Set () /*-----------------------------------------------------------------*/ /* allocVariables - creates decl & assign storage class for a v */ /*-----------------------------------------------------------------*/ -int +int allocVariables (symbol * symChain) { symbol *sym; @@ -837,20 +839,20 @@ allocVariables (symbol * symChain) /* if this is a typedef then add it */ /* to the typedef table */ if (IS_TYPEDEF (sym->etype)) - { - /* check if the typedef already exists */ - csym = findSym (TypedefTab, NULL, sym->name); - if (csym && csym->level == sym->level) - werror (E_DUPLICATE_TYPEDEF, sym->name); - - SPEC_EXTR (sym->etype) = 0; - addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0); - continue; /* go to the next one */ - } + { + /* check if the typedef already exists */ + csym = findSym (TypedefTab, NULL, sym->name); + if (csym && csym->level == sym->level) + werror (E_DUPLICATE_TYPEDEF, sym->name); + + SPEC_EXTR (sym->etype) = 0; + addSym (TypedefTab, sym, sym->name, sym->level, sym->block, 0); + continue; /* go to the next one */ + } /* make sure it already exist */ csym = findSymWithLevel (SymbolTab, sym); if (!csym || (csym && csym->level != sym->level)) - csym = sym; + csym = sym; /* check the declaration */ checkDecl (csym,0); @@ -871,29 +873,29 @@ allocVariables (symbol * symChain) /* if this is a extern variable then change the */ /* level to zero temporarily */ if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type)) - { - saveLevel = csym->level; - csym->level = 0; - } + { + saveLevel = csym->level; + csym->level = 0; + } /* if this is a literal then it is an enumerated */ /* type so need not allocate it space for it */ if (IS_LITERAL (sym->etype)) - continue; + continue; /* generate the actual declaration */ if (csym->level) - { - allocLocal (csym); - if (csym->onStack) - stack += getSize (csym->type); - } + { + allocLocal (csym); + if (csym->onStack) + stack += getSize (csym->type); + } else - allocGlobal (csym); + allocGlobal (csym); /* restore the level */ if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type)) - csym->level = saveLevel; + csym->level = saveLevel; } return stack; @@ -902,7 +904,7 @@ allocVariables (symbol * symChain) /*-----------------------------------------------------------------*/ /* redoStackOffsets :- will reassign the values for stack offsets */ /*-----------------------------------------------------------------*/ -void +void redoStackOffsets (void) { symbol *sym; @@ -921,42 +923,42 @@ redoStackOffsets (void) int size = getSize (sym->type); /* nothing to do with parameters so continue */ if ((sym->_isparm && !IS_REGPARM (sym->etype))) - continue; + continue; if (IS_AGGREGATE (sym->type)) - { - if (port->stack.direction > 0) - { - SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1); - sPtr += size; - } - else - { - sPtr -= size; - SPEC_STAK (sym->etype) = sym->stack = sPtr; - } - continue; - } + { + if (port->stack.direction > 0) + { + SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1); + sPtr += size; + } + else + { + sPtr -= size; + SPEC_STAK (sym->etype) = sym->stack = sPtr; + } + continue; + } /* if allocation not required then subtract size from overall stack size & continue */ if (!sym->allocreq) - { - currFunc->stack -= size; - SPEC_STAK (currFunc->etype) -= size; - continue; - } + { + currFunc->stack -= size; + SPEC_STAK (currFunc->etype) -= size; + continue; + } if (port->stack.direction > 0) - { - SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1); - sPtr += size; - } + { + SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1); + sPtr += size; + } else - { - sPtr -= size; - SPEC_STAK (sym->etype) = sym->stack = sPtr; - } + { + sPtr -= size; + SPEC_STAK (sym->etype) = sym->stack = sPtr; + } } /* do the same for the external stack */ @@ -968,23 +970,23 @@ redoStackOffsets (void) int size = getSize (sym->type); /* nothing to do with parameters so continue */ if ((sym->_isparm && !IS_REGPARM (sym->etype))) - continue; + continue; if (IS_AGGREGATE (sym->type)) - { - SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1); - xsPtr += size; - continue; - } + { + SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1); + xsPtr += size; + continue; + } /* if allocation not required then subtract size from overall stack size & continue */ if (!sym->allocreq) - { - currFunc->xstack -= size; - SPEC_STAK (currFunc->etype) -= size; - continue; - } + { + currFunc->xstack -= size; + SPEC_STAK (currFunc->etype) -= size; + continue; + } SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1); xsPtr += size; @@ -995,7 +997,7 @@ redoStackOffsets (void) /*-----------------------------------------------------------------*/ /* printAllocInfoSeg- print the allocation for a given section */ /*-----------------------------------------------------------------*/ -static void +static void printAllocInfoSeg (memmap * map, symbol * func, FILE * of) { symbol *sym; @@ -1004,44 +1006,44 @@ printAllocInfoSeg (memmap * map, symbol * func, FILE * of) return; if (!map->syms) return; - + for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) { if (sym->level == 0) - continue; + continue; if (sym->localof != func) - continue; - + continue; + fprintf (of, ";%-25s Allocated ", sym->name); /* if assigned to registers */ if (!sym->allocreq && sym->reqv) - { - int i; - - sym = OP_SYMBOL (sym->reqv); - if (!sym->isspilt || sym->remat) - { - fprintf (of, "to registers "); - for (i = 0; i < 4 && sym->regs[i]; i++) - fprintf (of, "%s ", port->getRegName (sym->regs[i])); - fprintf (of, "\n"); - continue; - } - else - { - sym = sym->usl.spillLoc; - } - } + { + int i; + + sym = OP_SYMBOL (sym->reqv); + if (!sym->isspilt || sym->remat) + { + fprintf (of, "to registers "); + for (i = 0; i < 4 && sym->regs[i]; i++) + fprintf (of, "%s ", port->getRegName (sym->regs[i])); + fprintf (of, "\n"); + continue; + } + else + { + sym = sym->usl.spillLoc; + } + } /* if on stack */ if (sym->onStack) - { - fprintf (of, "to stack - offset %d\n", sym->stack); - continue; - } + { + fprintf (of, "to stack - offset %d\n", sym->stack); + continue; + } /* otherwise give rname */ fprintf (of, "with name '%s'\n", sym->rname); @@ -1051,7 +1053,7 @@ printAllocInfoSeg (memmap * map, symbol * func, FILE * of) /*-----------------------------------------------------------------*/ /* canOverlayLocals - returns true if the local variables can overlayed */ /*-----------------------------------------------------------------*/ -static bool +static bool canOverlayLocals (eBBlock ** ebbs, int count) { int i; @@ -1062,7 +1064,7 @@ canOverlayLocals (eBBlock ** ebbs, int count) options.stackAuto || (currFunc && (IFFUNC_ISREENT (currFunc->type) || - FUNC_ISISR (currFunc->type))) || + FUNC_ISISR (currFunc->type))) || elementsInSet (overlay->syms) == 0) return FALSE; @@ -1077,13 +1079,13 @@ canOverlayLocals (eBBlock ** ebbs, int count) iCode *ic; for (ic = ebbs[i]->sch; ic; ic = ic->next) - if (ic) { - if (ic->op == CALL) { - sym_link *ftype = operandType(IC_LEFT(ic)); - /* builtins only can use overlays */ - if (!IFFUNC_ISBUILTIN(ftype)) return FALSE; - } else if (ic->op == PCALL) return FALSE; - } + if (ic) { + if (ic->op == CALL) { + sym_link *ftype = operandType(IC_LEFT(ic)); + /* builtins only can use overlays */ + if (!IFFUNC_ISBUILTIN(ftype)) return FALSE; + } else if (ic->op == PCALL) return FALSE; + } } /* no function calls found return TRUE */ @@ -1093,7 +1095,7 @@ canOverlayLocals (eBBlock ** ebbs, int count) /*-----------------------------------------------------------------*/ /* doOverlays - move the overlay segment to appropriate location */ /*-----------------------------------------------------------------*/ -void +void doOverlays (eBBlock ** ebbs, int count) { if (!overlay) { @@ -1118,12 +1120,12 @@ doOverlays (eBBlock ** ebbs, int count) /*-----------------------------------------------------------------*/ /* printAllocInfo - prints allocation information for a function */ /*-----------------------------------------------------------------*/ -void +void printAllocInfo (symbol * func, FILE * of) { if (!func) - return; - + return; + if (!of) of = stdout; @@ -1140,11 +1142,11 @@ printAllocInfo (symbol * func, FILE * of) printAllocInfoSeg (idata, func, of); printAllocInfoSeg (sfr, func, of); printAllocInfoSeg (sfrbit, func, of); - + { set *ovrset; set *tempOverlaySyms = overlay->syms; - + /* search the set of overlay sets for local variables/parameters */ for (ovrset = setFirstItem (ovrSetSets); ovrset; ovrset = setNextItem (ovrSetSets)) @@ -1154,6 +1156,6 @@ printAllocInfo (symbol * func, FILE * of) } overlay->syms = tempOverlaySyms; } - + fprintf (of, ";------------------------------------------------------------\n"); } diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index d4376dc1..668cf777 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -2333,7 +2333,10 @@ checkFunction (symbol * sym, symbol *csym) werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt"); } - if (FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type)) + /* I don't think this is necessary for interrupts. An isr is a */ + /* root in the calling tree. */ + if ((FUNC_REGBANK (csym->type) != FUNC_REGBANK (sym->type)) && + (!FUNC_ISISR (sym->type))) { werror (E_PREV_DEF_CONFLICT, csym->name, "using"); } @@ -2342,7 +2345,7 @@ checkFunction (symbol * sym, symbol *csym) { werror (E_PREV_DEF_CONFLICT, csym->name, "_naked"); } - + /* Really, reentrant should match regardless of argCnt, but */ /* this breaks some existing code (the fp lib functions). If */ /* the first argument is always passed the same way, this */ @@ -2528,7 +2531,10 @@ processFuncArgs (symbol * func) SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++); val->sym = newSymbol (val->name, 1); - SPEC_OCLS (val->etype) = port->mem.default_local_map; + if (SPEC_SCLS(val->etype) == S_BIT) + SPEC_OCLS (val->etype) = bit; + else + SPEC_OCLS (val->etype) = port->mem.default_local_map; val->sym->type = copyLinkChain (val->type); val->sym->etype = getSpec (val->sym->type); val->sym->_isparm = 1; @@ -2549,8 +2555,11 @@ processFuncArgs (symbol * func) SNPRINTF (val->name, sizeof(val->name), "_%s_PARM_%d", func->name, pNum++); strncpyz (val->sym->rname, val->name, sizeof(val->sym->rname)); val->sym->_isparm = 1; - SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) = - (options.model != MODEL_SMALL ? xdata : data); + if (SPEC_SCLS(val->etype) == S_BIT) + SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) = bit; + else + SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) = + (options.model != MODEL_SMALL ? xdata : data); #if 0 /* ?? static functions shouldn't imply static parameters - EEP */ diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index 4f0f8054..97218f07 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -1869,26 +1869,52 @@ saveRegisters (iCode * lic) ic->regsSaved = 1; if (options.useXstack) { - if (bitVectBitValue (rsave, R0_IDX)) + int count = bitVectnBitsOn (rsave); + + if (count == 1) { - emitcode ("mov", "a,r0"); - emitcode ("push", "%s", mcs51_regWithIdx (R0_IDX)->dname); + i = bitVectFirstBit (rsave); + emitcode ("mov", "a,%s", mcs51_regWithIdx (i)->name); + emitcode ("mov", "r0,%s", spname); + emitcode ("inc", "%s", spname);// allocate before use + emitcode ("movx", "@r0,a"); + if (bitVectBitValue (rsave, R0_IDX)) + emitcode ("mov", "r0,a"); } - emitcode ("mov", "r0,%s", spname); - for (i = 0; i < mcs51_nRegs; i++) + else if (count != 0) { - if (bitVectBitValue (rsave, i)) + if (bitVectBitValue (rsave, R0_IDX)) { - if (i != R0_IDX) - emitcode ("mov", "a,%s", mcs51_regWithIdx (i)->name); - emitcode ("movx", "@r0,a"); - emitcode ("inc", "r0"); + emitcode ("push", "%s", mcs51_regWithIdx (R0_IDX)->dname); + } + emitcode ("mov", "r0,%s", spname); + MOVA ("r0"); + emitcode ("add", "a,#%d", count); + emitcode ("mov", "%s,a", spname); + for (i = 0; i < mcs51_nRegs; i++) + { + if (bitVectBitValue (rsave, i)) + { + if (i == R0_IDX) + { + emitcode ("pop", "acc"); + emitcode ("push", "acc"); + } + else + { + emitcode ("mov", "a,%s", mcs51_regWithIdx (i)->name); + } + emitcode ("movx", "@r0,a"); + if (--count) + { + emitcode ("inc", "r0"); + } + } + } + if (bitVectBitValue (rsave, R0_IDX)) + { + emitcode ("pop", "%s", mcs51_regWithIdx (R0_IDX)->dname); } - } - emitcode ("mov", "%s,r0", spname); - if (bitVectBitValue (rsave, R0_IDX)) - { - emitcode ("pop", "%s", mcs51_regWithIdx (R0_IDX)->dname); } } else @@ -1915,22 +1941,35 @@ unsaveRegisters (iCode * ic) if (options.useXstack) { - emitcode ("mov", "r0,%s", spname); - for (i = mcs51_nRegs; i >= 0; i--) - { - if (bitVectBitValue (rsave, i)) - { - emitcode ("dec", "r0"); - emitcode ("movx", "a,@r0"); - if (i != R0_IDX) - emitcode ("mov", "%s,a", mcs51_regWithIdx (i)->name); - } + int count = bitVectnBitsOn (rsave); + if (count == 1) + { + emitcode ("mov", "r0,%s", spname); + emitcode ("dec", "r0"); + emitcode ("movx", "a,@r0"); + i = bitVectFirstBit (rsave); + emitcode ("mov", "%s,a", mcs51_regWithIdx (i)->name); + emitcode ("dec", "%s", spname); } - emitcode ("mov", "%s,r0", spname); - if (bitVectBitValue (rsave, R0_IDX)) + else { - emitcode ("mov", "r0,a"); + emitcode ("mov", "r0,%s", spname); + for (i = mcs51_nRegs; i >= 0; i--) + { + if (bitVectBitValue (rsave, i)) + { + emitcode ("dec", "r0"); + emitcode ("movx", "a,@r0"); + if (i != R0_IDX) + emitcode ("mov", "%s,a", mcs51_regWithIdx (i)->name); + } + } + emitcode ("mov", "%s,r0", spname); + if (bitVectBitValue (rsave, R0_IDX)) + { + emitcode ("mov", "r0,a"); + } } } else @@ -1939,7 +1978,6 @@ unsaveRegisters (iCode * ic) if (bitVectBitValue (rsave, i)) emitcode ("pop", "%s", mcs51_regWithIdx (i)->dname); } - } @@ -1996,23 +2034,30 @@ genXpush (iCode * ic) aopOp (IC_LEFT (ic), ic, FALSE); r = getFreePtr (ic, &aop, FALSE); - - emitcode ("mov", "%s,_spx", r->name); - size = AOP_SIZE (IC_LEFT (ic)); - while (size--) - { - char *l = aopGet (AOP (IC_LEFT (ic)), - offset++, FALSE, FALSE); - MOVA (l); + if (size == 1) + { + MOVA (aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE)); + emitcode ("mov", "%s,%s", r->name, spname); + emitcode ("inc", "%s", spname); // allocate space first emitcode ("movx", "@%s,a", r->name); - emitcode ("inc", "%s", r->name); - } + else + { + // allocate space first + emitcode ("mov", "%s,%s", r->name, spname); + MOVA (r->name); + emitcode ("add", "a,#%d", size); + emitcode ("mov", "%s,a", spname); - - emitcode ("mov", "_spx,%s", r->name); + while (size--) + { + MOVA (aopGet (AOP (IC_LEFT (ic)), offset++, FALSE, FALSE)); + emitcode ("movx", "@%s,a", r->name); + emitcode ("inc", "%s", r->name); + } + } freeAsmop (NULL, aop, ic, TRUE); freeAsmop (IC_LEFT (ic), NULL, ic, TRUE); @@ -2070,7 +2115,6 @@ genIpush (iCode * ic) /* then do the push */ aopOp (IC_LEFT (ic), ic, FALSE); - // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic))); size = AOP_SIZE (IC_LEFT (ic)); @@ -2086,7 +2130,7 @@ genIpush (iCode * ic) } else emitcode ("push", "%s", l); - } + } freeAsmop (IC_LEFT (ic), NULL, ic, TRUE); } @@ -2116,17 +2160,18 @@ genIpop (iCode * ic) } /*-----------------------------------------------------------------*/ -/* unsaveRBank - restores the resgister bank from stack */ +/* saveRBank - saves an entire register bank on the stack */ /*-----------------------------------------------------------------*/ static void -unsaveRBank (int bank, iCode * ic, bool popPsw) +saveRBank (int bank, iCode * ic, bool pushPsw) { int i; + int count = mcs51_nRegs + (pushPsw ? 1 : 0); asmop *aop = NULL; regs *r = NULL; if (options.useXstack) - { + { if (!ic) { /* Assume r0 is available for use. */ @@ -2137,54 +2182,60 @@ unsaveRBank (int bank, iCode * ic, bool popPsw) aop = newAsmop (0); r = getFreePtr (ic, &aop, FALSE); } - emitcode ("mov", "%s,_spx", r->name); - } + // allocate space first + emitcode ("mov", "%s,%s", r->name, spname); + MOVA (r->name); + emitcode ("add", "a,#%d", count); + emitcode ("mov", "%s,a", spname); + } - if (popPsw) + for (i = 0; i < mcs51_nRegs; i++) { if (options.useXstack) - { - emitcode ("movx", "a,@%s", r->name); - emitcode ("mov", "psw,a"); - emitcode ("dec", "%s", r->name); + { + emitcode ("mov", "a,(%s+%d)", + regs8051[i].base, 8 * bank + regs8051[i].offset); + emitcode ("movx", "@%s,a", r->name); + if (--count) + emitcode ("inc", "%s", r->name); } else - { - emitcode ("pop", "psw"); - } + emitcode ("push", "(%s+%d)", + regs8051[i].base, 8 * bank + regs8051[i].offset); } - for (i = (mcs51_nRegs - 1); i >= 0; i--) + if (pushPsw) { if (options.useXstack) { - emitcode ("movx", "a,@%s", r->name); - emitcode ("mov", "(%s+%d),a", - regs8051[i].base, 8 * bank + regs8051[i].offset); - emitcode ("dec", "%s", r->name); + emitcode ("mov", "a,psw"); + emitcode ("movx", "@%s,a", r->name); } else - emitcode ("pop", "(%s+%d)", - regs8051[i].base, 8 * bank + regs8051[i].offset); + { + emitcode ("push", "psw"); + } + + emitcode ("mov", "psw,#0x%02x", (bank << 3) & 0x00ff); } - if (options.useXstack) + if (aop) { - emitcode ("mov", "_spx,%s", r->name); + freeAsmop (NULL, aop, ic, TRUE); } - if (aop) + if (ic) { - freeAsmop (NULL, aop, ic, TRUE); + ic->bankSaved = 1; } } /*-----------------------------------------------------------------*/ -/* saveRBank - saves an entire register bank on the stack */ +/* unsaveRBank - restores the register bank from stack */ /*-----------------------------------------------------------------*/ static void -saveRBank (int bank, iCode * ic, bool pushPsw) +unsaveRBank (int bank, iCode * ic, bool popPsw) { int i; asmop *aop = NULL; @@ -2193,59 +2244,57 @@ saveRBank (int bank, iCode * ic, bool pushPsw) if (options.useXstack) { if (!ic) - { + { /* Assume r0 is available for use. */ r = mcs51_regWithIdx (R0_IDX);; - } + } else - { + { aop = newAsmop (0); r = getFreePtr (ic, &aop, FALSE); - } - emitcode ("mov", "%s,_spx", r->name); + } + emitcode ("mov", "%s,%s", r->name, spname); } - for (i = 0; i < mcs51_nRegs; i++) + if (popPsw) { if (options.useXstack) { - emitcode ("inc", "%s", r->name); - emitcode ("mov", "a,(%s+%d)", - regs8051[i].base, 8 * bank + regs8051[i].offset); - emitcode ("movx", "@%s,a", r->name); + emitcode ("dec", "%s", r->name); + emitcode ("movx", "a,@%s", r->name); + emitcode ("mov", "psw,a"); } else - emitcode ("push", "(%s+%d)", - regs8051[i].base, 8 * bank + regs8051[i].offset); + { + emitcode ("pop", "psw"); + } } - if (pushPsw) + for (i = (mcs51_nRegs - 1); i >= 0; i--) { if (options.useXstack) { - emitcode ("mov", "a,psw"); - emitcode ("movx", "@%s,a", r->name); - emitcode ("inc", "%s", r->name); - emitcode ("mov", "_spx,%s", r->name); - + emitcode ("dec", "%s", r->name); + emitcode ("movx", "a,@%s", r->name); + emitcode ("mov", "(%s+%d),a", + regs8051[i].base, 8 * bank + regs8051[i].offset); } else - { - emitcode ("push", "psw"); - } + { + emitcode ("pop", "(%s+%d)", + regs8051[i].base, 8 * bank + regs8051[i].offset); + } + } - emitcode ("mov", "psw,#0x%02x", (bank << 3) & 0x00ff); + if (options.useXstack) + { + emitcode ("mov", "%s,%s", spname, r->name); } if (aop) { freeAsmop (NULL, aop, ic, TRUE); } - - if (ic) - { - ic->bankSaved = 1; - } } /*-----------------------------------------------------------------*/ @@ -2543,13 +2592,14 @@ inExcludeList (char *s) static void genFunction (iCode * ic) { - symbol *sym = OP_SYMBOL (IC_LEFT (ic)); + symbol *sym = OP_SYMBOL (IC_LEFT (ic)); sym_link *ftype; - bool switchedPSW = FALSE; - int calleesaves_saved_register = -1; - int stackAdjust = sym->stack; - int accIsFree = sym->recvSize < 4; - iCode * ric = (ic->next && ic->next->op == RECEIVE) ? ic->next : NULL; + bool switchedPSW = FALSE; + int calleesaves_saved_register = -1; + int stackAdjust = sym->stack; + int accIsFree = sym->recvSize < 4; + iCode *ric = (ic->next && ic->next->op == RECEIVE) ? ic->next : NULL; + bool fReentrant = (IFFUNC_ISREENT (sym->type) || options.stackAuto); _G.nRegsSaved = 0; /* create the function header */ @@ -2770,16 +2820,17 @@ genFunction (iCode * ic) } - if (reentrant) + if (fReentrant) { if (options.useXstack) { - emitcode ("inc", "%s", spname); - emitcode ("mov", "r0,%s", spname); - emitcode ("xch", "a,_bp"); - emitcode ("movx", "@r0,a"); - emitcode ("mov", "a,r0"); - emitcode ("xch", "a,_bp"); + emitcode ("mov", "r0,%s", spname); + emitcode ("inc", "%s", spname); + emitcode ("xch", "a,_bp"); + emitcode ("movx", "@r0,a"); + emitcode ("inc", "r0"); + emitcode ("mov", "a,r0"); + emitcode ("xch", "a,_bp"); } else { @@ -2858,11 +2909,9 @@ genFunction (iCode * ic) if (i > 3 && accIsFree) { - emitcode ("mov", "a,sp"); emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff)); emitcode ("mov", "sp,a"); - } else if (i > 5) { @@ -2904,14 +2953,27 @@ genFunction (iCode * ic) if (sym->xstack) { + char i = ((char) sym->xstack & 0xff); - if (!accIsFree) - emitcode ("push", "acc"); - emitcode ("mov", "a,_spx"); - emitcode ("add", "a,#0x%02x", ((char) sym->xstack & 0xff)); - emitcode ("mov", "_spx,a"); - if (!accIsFree) - emitcode ("pop", "acc"); + if (i > 3 && accIsFree) + { + emitcode ("mov", "a,_spx"); + emitcode ("add", "a,#0x%02x", i); + emitcode ("mov", "_spx,a"); + } + else if (i > 5) + { + emitcode ("push", "acc"); + emitcode ("mov", "a,_spx"); + emitcode ("add", "a,#0x%02x", i); + emitcode ("mov", "_spx,a"); + emitcode ("pop", "acc"); + } + else + { + while (i--) + emitcode ("inc", "_spx"); + } } /* if critical function then turn interrupts off */ @@ -2955,7 +3017,7 @@ genEndFunction (iCode * ic) emitcode ("mov", "ea,c"); } - if (IFFUNC_ISREENT (sym->type) || options.stackAuto) + if ((IFFUNC_ISREENT (sym->type) || options.stackAuto) && !options.useXstack) { emitcode ("mov", "%s,_bp", spname); } @@ -2965,13 +3027,19 @@ genEndFunction (iCode * ic) local stack */ if (options.useXstack && sym->stack) { - if (!accIsFree) - emitcode ("push", "acc"); - emitcode ("mov", "a,sp"); - emitcode ("add", "a,#0x%02x", ((char) -sym->stack) & 0xff); - emitcode ("mov", "sp,a"); - if (!accIsFree) - emitcode ("pop", "acc"); + char count = sym->stack; + + if ((count>3) && accIsFree) + { + emitcode ("mov", "a,sp"); + emitcode ("add", "a,#0x%02x", ((char) -count) & 0xff); + emitcode ("mov", "sp,a"); + } + else + { + while (count--) + emitcode ("dec", "sp"); + } } if ((IFFUNC_ISREENT (sym->type) || options.stackAuto)) @@ -2979,10 +3047,11 @@ genEndFunction (iCode * ic) if (options.useXstack) { emitcode ("xch", "a,_bp"); - emitcode ("mov", "r0,%s", spname); + emitcode ("mov", "r0,a"); + emitcode ("dec", "r0"); emitcode ("movx", "a,@r0"); emitcode ("xch", "a,_bp"); - emitcode ("dec", "%s", spname); //read before freeing stack space (interrupts) + emitcode ("mov", "%s,r0", spname); //read before freeing stack space (interrupts) } else { @@ -9609,16 +9678,21 @@ genAssign (iCode * ic) !IS_FLOAT (operandType (right)) && (lit < 256L)) { + while ((size) && (lit)) + { + aopPut (AOP (result), + aopGet (AOP (right), offset, FALSE, FALSE), + offset, + isOperandVolatile (result, FALSE)); + lit >>= 8; + offset++; + size--; + } emitcode ("clr", "a"); while (size--) { - if ((unsigned int) ((lit >> (size * 8)) & 0x0FFL) == 0) - aopPut (AOP (result), "a", size, isOperandVolatile (result, FALSE)); - else - aopPut (AOP (result), - aopGet (AOP (right), size, FALSE, FALSE), - size, - isOperandVolatile (result, FALSE)); + aopPut (AOP (result), "a", offset, isOperandVolatile (result, FALSE)); + offset++; } } else diff --git a/src/mcs51/main.c b/src/mcs51/main.c index f84acfb8..22aa5427 100644 --- a/src/mcs51/main.c +++ b/src/mcs51/main.c @@ -49,7 +49,7 @@ static char *_mcs51_keywords[] = void mcs51_assignRegisters (eBBlock ** ebbs, int count); -static int regParmFlg = 0; /* determine if we can register a parameter */ +static int regParmFlg = 0; /* determine if we can register a parameter */ static void _mcs51_init (void) @@ -66,30 +66,32 @@ _mcs51_reset_regparm (void) static int _mcs51_regparm (sym_link * l) { + if (IS_SPEC(l) && (SPEC_NOUN(l) == V_BIT)) + return 0; if (options.parms_in_bank1 == 0) { - /* simple can pass only the first parameter in a register */ - if (regParmFlg) - return 0; + /* simple can pass only the first parameter in a register */ + if (regParmFlg) + return 0; - regParmFlg = 1; - return 1; + regParmFlg = 1; + return 1; } else { - int size = getSize(l); - int remain ; - - /* first one goes the usual way to DPTR */ - if (regParmFlg == 0) { - regParmFlg += 4 ; - return 1; - } - /* second one onwards goes to RB1_0 thru RB1_7 */ + int size = getSize(l); + int remain ; + + /* first one goes the usual way to DPTR */ + if (regParmFlg == 0) { + regParmFlg += 4 ; + return 1; + } + /* second one onwards goes to RB1_0 thru RB1_7 */ remain = regParmFlg - 4; - if (size > (8 - remain)) { - regParmFlg = 12 ; - return 0; - } - regParmFlg += size ; - return regParmFlg - size + 1; + if (size > (8 - remain)) { + regParmFlg = 12 ; + return 0; + } + regParmFlg += size ; + return regParmFlg - size + 1; } } @@ -141,11 +143,10 @@ static void _mcs51_genAssemblerPreamble (FILE * of) { if (options.parms_in_bank1) { - int i ; - for (i=0; i < 8 ; i++ ) - fprintf (of,"b1_%d = 0x%x \n",i,8+i); + int i ; + for (i=0; i < 8 ; i++ ) + fprintf (of,"b1_%d = 0x%x \n",i,8+i); } - } /* Generate interrupt vector table. */ @@ -175,7 +176,7 @@ _mcs51_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts) return TRUE; } -static void +static void _mcs51_genExtraAreas(FILE *of, bool hasMain) { tfprintf (of, "\t!area\n", port->mem.code_name); @@ -193,7 +194,7 @@ _mcs51_genInitStartup (FILE *of) tfprintf (of, "\t!global\n", "__sdcc_gsinit_startup"); tfprintf (of, "\t!global\n", "__sdcc_program_startup"); tfprintf (of, "\t!global\n", "__start__stack"); - + if (options.useXstack) { tfprintf (of, "\t!global\n", "__sdcc_init_xstack"); @@ -205,7 +206,7 @@ _mcs51_genInitStartup (FILE *of) { port->genXINIT(of); } - + if (!getenv("SDCC_NOGENRAMCLEAR")) tfprintf (of, "\t!global\n", "__mcs51_genRAMCLEAR"); } @@ -214,7 +215,7 @@ _mcs51_genInitStartup (FILE *of) /* Generate code to copy XINIT to XISEG */ static void _mcs51_genXINIT (FILE * of) { tfprintf (of, "\t!global\n", "__mcs51_genXINIT"); - + if (!getenv("SDCC_NOGENRAMCLEAR")) tfprintf (of, "\t!global\n", "__mcs51_genXRAMCLEAR"); } @@ -228,16 +229,16 @@ static bool cseCostEstimation (iCode *ic, iCode *pdic) /* if it is a pointer then return ok for now */ if (IC_RESULT(ic) && IS_PTR(result_type)) return 1; - - /* if bitwise | add & subtract then no since mcs51 is pretty good at it + + /* if bitwise | add & subtract then no since mcs51 is pretty good at it so we will cse only if they are local (i.e. both ic & pdic belong to the same basic block */ if (IS_BITWISE_OP(ic) || ic->op == '+' || ic->op == '-') { - /* then if they are the same Basic block then ok */ - if (ic->eBBlockNum == pdic->eBBlockNum) return 1; - else return 0; + /* then if they are the same Basic block then ok */ + if (ic->eBBlockNum == pdic->eBBlockNum) return 1; + else return 0; } - + /* for others it is cheaper to do the cse */ return 1; } @@ -262,7 +263,7 @@ oclsExpense (struct memmap *oclass) { if (IN_FARSPACE(oclass)) return 1; - + return 0; } @@ -279,7 +280,7 @@ instructionSize(char *inst, char *op1, char *op2) /* Based on the current (2003-08-22) code generation for the small library, the top instruction probability is: - + 57% mov/movx/movc 6% push 6% pop @@ -296,20 +297,20 @@ instructionSize(char *inst, char *op1, char *op2) if (*(inst+3)=='c') return 1; /* movc */ if (IS_C (op1) || IS_C (op2)) return 2; if (IS_A (op1)) - { - if (IS_Rn (op2) || IS_atRi (op2)) return 1; - return 2; - } + { + if (IS_Rn (op2) || IS_atRi (op2)) return 1; + return 2; + } if (IS_Rn(op1) || IS_atRi(op1)) - { - if (IS_A(op2)) return 1; - return 2; - } + { + if (IS_A(op2)) return 1; + return 2; + } if (strcmp (op1, "dptr") == 0) return 3; if (IS_A (op2) || IS_Rn (op2) || IS_atRi (op2)) return 2; return 3; } - + if (ISINST ("push")) return 2; if (ISINST ("pop")) return 2; @@ -327,7 +328,7 @@ instructionSize(char *inst, char *op1, char *op2) if (ISINST ("jb")) return 3; if (ISINST ("jnb")) return 3; if (ISINST ("jbc")) return 3; - if (ISINST ("jmp")) return 1; // always jmp @a+dptr + if (ISINST ("jmp")) return 1; // always jmp @a+dptr if (ISINST ("jz")) return 2; if (ISINST ("jnz")) return 2; if (ISINST ("cjne")) return 3; @@ -340,7 +341,7 @@ instructionSize(char *inst, char *op1, char *op2) if (ISINST ("acall")) return 2; if (ISINST ("ajmp")) return 2; - + if (ISINST ("add") || ISINST ("addc") || ISINST ("subb") || ISINST ("xch")) { if (IS_Rn(op2) || IS_atRi(op2)) return 1; @@ -356,15 +357,15 @@ instructionSize(char *inst, char *op1, char *op2) { if (IS_C(op1)) return 2; if (IS_A(op1)) - { - if (IS_Rn(op2) || IS_atRi(op2)) return 1; - return 2; - } + { + if (IS_Rn(op2) || IS_atRi(op2)) return 1; + return 2; + } else - { - if (IS_A(op2)) return 2; - return 3; - } + { + if (IS_A(op2)) return 2; + return 3; + } } if (ISINST ("clr") || ISINST ("setb") || ISINST ("cpl")) { @@ -391,7 +392,7 @@ newAsmLineNode (void) aln->size = 0; aln->regsRead = NULL; aln->regsWritten = NULL; - + return aln; } @@ -445,20 +446,20 @@ mcs51operandCompare (const void *key, const void *member) return strcmp((const char *)key, ((mcs51operanddata *)member)->name); } -static void +static void updateOpRW (asmLineNode *aln, char *op, char *optype) { mcs51operanddata *opdat; char *dot; - + dot = strchr(op, '.'); if (dot) *dot = '\0'; opdat = bsearch (op, mcs51operandDataTable, - sizeof(mcs51operandDataTable)/sizeof(mcs51operanddata), - sizeof(mcs51operanddata), mcs51operandCompare); - + sizeof(mcs51operandDataTable)/sizeof(mcs51operanddata), + sizeof(mcs51operanddata), mcs51operandCompare); + if (opdat && strchr(optype,'r')) { if (opdat->regIdx1 >= 0) @@ -480,12 +481,12 @@ updateOpRW (asmLineNode *aln, char *op, char *optype) if (!strcmp(op, "@r1")) aln->regsRead = bitVectSetBit (aln->regsRead, R1_IDX); if (strstr(op, "dptr")) - { - aln->regsRead = bitVectSetBit (aln->regsRead, DPL_IDX); - aln->regsRead = bitVectSetBit (aln->regsRead, DPH_IDX); - } + { + aln->regsRead = bitVectSetBit (aln->regsRead, DPL_IDX); + aln->regsRead = bitVectSetBit (aln->regsRead, DPH_IDX); + } if (strstr(op, "a+")) - aln->regsRead = bitVectSetBit (aln->regsRead, A_IDX); + aln->regsRead = bitVectSetBit (aln->regsRead, A_IDX); } } @@ -546,7 +547,7 @@ static mcs51opcodedata mcs51opcodeDataTable[] = {"xchd", "", "", "rw", "rw"}, {"xrl", "", "", "rw", "r"}, }; - + static int mcs51opcodeCompare (const void *key, const void *member) { @@ -564,7 +565,7 @@ asmLineNodeFromLineNode (lineNode *ln) mcs51opcodedata *opdat; p = ln->line; - + while (*p && isspace(*p)) p++; for (op = inst, opsize=1; *p; p++) { @@ -572,13 +573,13 @@ asmLineNodeFromLineNode (lineNode *ln) break; else if (opsize < sizeof(inst)) - *op++ = tolower(*p), opsize++; + *op++ = tolower(*p), opsize++; } *op = '\0'; if (*p == ';' || *p == ':' || *p == '=') return aln; - + while (*p && isspace(*p)) p++; if (*p == '=') return aln; @@ -589,7 +590,7 @@ asmLineNodeFromLineNode (lineNode *ln) *op++ = tolower(*p), opsize++; } *op = '\0'; - + if (*p == ',') p++; for (op = op2, opsize=1; *p && *p != ','; p++) { @@ -604,8 +605,8 @@ asmLineNodeFromLineNode (lineNode *ln) aln->regsWritten = newBitVect (END_IDX); opdat = bsearch (inst, mcs51opcodeDataTable, - sizeof(mcs51opcodeDataTable)/sizeof(mcs51opcodedata), - sizeof(mcs51opcodedata), mcs51opcodeCompare); + sizeof(mcs51opcodeDataTable)/sizeof(mcs51opcodedata), + sizeof(mcs51opcodedata), mcs51opcodeCompare); if (opdat) { @@ -625,7 +626,7 @@ getInstructionSize (lineNode *line) { if (!line->aln) line->aln = asmLineNodeFromLineNode (line); - + return line->aln->size; } @@ -634,7 +635,7 @@ getRegsRead (lineNode *line) { if (!line->aln) line->aln = asmLineNodeFromLineNode (line); - + return line->aln->regsRead; } @@ -643,7 +644,7 @@ getRegsWritten (lineNode *line) { if (!line->aln) line->aln = asmLineNodeFromLineNode (line); - + return line->aln->regsWritten; } @@ -670,22 +671,22 @@ PORT mcs51_port = { TARGET_ID_MCS51, "mcs51", - "MCU 8051", /* Target name */ - NULL, /* Processor name */ + "MCU 8051", /* Target name */ + NULL, /* Processor name */ { glue, - TRUE, /* Emit glue around main */ + TRUE, /* Emit glue around main */ MODEL_SMALL | MODEL_LARGE, MODEL_SMALL }, { _asmCmd, NULL, - "-plosgffc", /* Options with debug */ - "-plosgff", /* Options without debug */ + "-plosgffc", /* Options with debug */ + "-plosgff", /* Options without debug */ 0, ".asm", - NULL /* no do_assemble function */ + NULL /* no do_assemble function */ }, { _linkCmd, @@ -701,7 +702,7 @@ PORT mcs51_port = getRegsWritten }, { - /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */ + /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */ 1, 2, 2, 4, 1, 2, 3, 1, 4, 4 }, { @@ -754,7 +755,7 @@ PORT mcs51_port = _mcs51_getRegName, _mcs51_keywords, _mcs51_genAssemblerPreamble, - NULL, /* no genAssemblerEnd */ + NULL, /* no genAssemblerEnd */ _mcs51_genIVT, _mcs51_genXINIT, _mcs51_genInitStartup, @@ -763,21 +764,21 @@ PORT mcs51_port = NULL, NULL, NULL, - hasExtBitOp, /* hasExtBitOp */ - oclsExpense, /* oclsExpense */ + hasExtBitOp, /* hasExtBitOp */ + oclsExpense, /* oclsExpense */ FALSE, - TRUE, /* little endian */ - 0, /* leave lt */ - 0, /* leave gt */ - 1, /* transform <= to ! > */ - 1, /* transform >= to ! < */ - 1, /* transform != to !(a == b) */ - 0, /* leave == */ + TRUE, /* little endian */ + 0, /* leave lt */ + 0, /* leave gt */ + 1, /* transform <= to ! > */ + 1, /* transform >= to ! < */ + 1, /* transform != to !(a == b) */ + 0, /* leave == */ FALSE, /* No array initializer support. */ cseCostEstimation, - NULL, /* no builtin functions */ - GPOINTER, /* treat unqualified pointers as "generic" pointers */ - 1, /* reset labelKey to 1 */ - 1, /* globals & local static allowed */ + NULL, /* no builtin functions */ + GPOINTER, /* treat unqualified pointers as "generic" pointers */ + 1, /* reset labelKey to 1 */ + 1, /* globals & local static allowed */ PORT_MAGIC }; diff --git a/src/mcs51/ralloc.c b/src/mcs51/ralloc.c index 63479c48..ca0deef7 100644 --- a/src/mcs51/ralloc.c +++ b/src/mcs51/ralloc.c @@ -61,24 +61,24 @@ int mcs51_ptrRegReq; /* one byte pointer register required */ regs regs8051[] = { - {REG_GPR, R2_IDX, REG_GPR, "r2", "ar2", "0", 2, 1}, - {REG_GPR, R3_IDX, REG_GPR, "r3", "ar3", "0", 3, 1}, - {REG_GPR, R4_IDX, REG_GPR, "r4", "ar4", "0", 4, 1}, - {REG_GPR, R5_IDX, REG_GPR, "r5", "ar5", "0", 5, 1}, - {REG_GPR, R6_IDX, REG_GPR, "r6", "ar6", "0", 6, 1}, - {REG_GPR, R7_IDX, REG_GPR, "r7", "ar7", "0", 7, 1}, - {REG_PTR, R0_IDX, REG_PTR, "r0", "ar0", "0", 0, 1}, - {REG_PTR, R1_IDX, REG_PTR, "r1", "ar1", "0", 1, 1}, - {REG_GPR, X8_IDX, REG_GPR, "x8", "x8", "xreg", 0, 1}, - {REG_GPR, X9_IDX, REG_GPR, "x9", "x9", "xreg", 1, 1}, + {REG_GPR, R2_IDX, REG_GPR, "r2", "ar2", "0", 2, 1}, + {REG_GPR, R3_IDX, REG_GPR, "r3", "ar3", "0", 3, 1}, + {REG_GPR, R4_IDX, REG_GPR, "r4", "ar4", "0", 4, 1}, + {REG_GPR, R5_IDX, REG_GPR, "r5", "ar5", "0", 5, 1}, + {REG_GPR, R6_IDX, REG_GPR, "r6", "ar6", "0", 6, 1}, + {REG_GPR, R7_IDX, REG_GPR, "r7", "ar7", "0", 7, 1}, + {REG_PTR, R0_IDX, REG_PTR, "r0", "ar0", "0", 0, 1}, + {REG_PTR, R1_IDX, REG_PTR, "r1", "ar1", "0", 1, 1}, + {REG_GPR, X8_IDX, REG_GPR, "x8", "x8", "xreg", 0, 1}, + {REG_GPR, X9_IDX, REG_GPR, "x9", "x9", "xreg", 1, 1}, {REG_GPR, X10_IDX, REG_GPR, "x10", "x10", "xreg", 2, 1}, {REG_GPR, X11_IDX, REG_GPR, "x11", "x11", "xreg", 3, 1}, {REG_GPR, X12_IDX, REG_GPR, "x12", "x12", "xreg", 4, 1}, - {REG_CND, CND_IDX, REG_CND, "C", "psw", "0xd0", 0, 1}, - {0, DPL_IDX, 0, "dpl", "dpl", "0x82", 0, 0}, - {0, DPH_IDX, 0, "dph", "dph", "0x83", 0, 0}, - {0, B_IDX, 0, "b", "b", "0xf0", 0, 0}, - {0, A_IDX, 0, "a", "acc", "0xe0", 0, 0}, + {REG_CND, CND_IDX, REG_CND, "C", "psw", "0xd0", 0, 1}, + {0, DPL_IDX, 0, "dpl", "dpl", "0x82", 0, 0}, + {0, DPH_IDX, 0, "dph", "dph", "0x83", 0, 0}, + {0, B_IDX, 0, "b", "b", "0xf0", 0, 0}, + {0, A_IDX, 0, "a", "acc", "0xe0", 0, 0}, }; int mcs51_nRegs = 17; static void spillThis (symbol *); @@ -505,7 +505,10 @@ createStackSpil (symbol * sym) /* set the type to the spilling symbol */ sloc->type = copyLinkChain (sym->type); sloc->etype = getSpec (sloc->type); - SPEC_SCLS (sloc->etype) = S_DATA; + if (SPEC_SCLS (sloc->etype) != S_BIT) + { + SPEC_SCLS (sloc->etype) = S_DATA; + } SPEC_EXTR (sloc->etype) = 0; SPEC_STAT (sloc->etype) = 0; SPEC_VOLATILE(sloc->etype) = 0; @@ -1167,7 +1170,7 @@ serialRegAssign (eBBlock ** ebbs, int count) ebbs[i]->entryLabel != returnLabel)) continue; - /* of all instructions do */ + /* for all instructions do */ for (ic = ebbs[i]->sch; ic; ic = ic->next) { #if 1 @@ -1230,6 +1233,15 @@ serialRegAssign (eBBlock ** ebbs, int count) spillThis (sym); continue; } + + /* if this is a bit variable then don't use precious registers + along with expensive bit-to-char conversions but just spill + it */ + if (SPEC_NOUN(sym->etype) == V_BIT) { + spillThis (sym); + continue; + } + /* if trying to allocate this will cause a spill and there is nothing to spill or this one is rematerializable then @@ -1577,8 +1589,7 @@ mcs51_rUmaskForOp (operand * op) for (j = 0; j < sym->nRegs; j++) { if (sym->regs[j]) /* EEP - debug */ - rumask = bitVectSetBit (rumask, - sym->regs[j]->rIdx); + rumask = bitVectSetBit (rumask, sym->regs[j]->rIdx); } return rumask; @@ -2710,7 +2721,7 @@ accuse: } /*-----------------------------------------------------------------*/ -/* packForPush - hueristics to reduce iCode for pushing */ +/* packForPush - heuristics to reduce iCode for pushing */ /*-----------------------------------------------------------------*/ static void packForPush (iCode * ic, eBBlock ** ebpp, int blockno) diff --git a/support/regression/Makefile b/support/regression/Makefile index 26c118b0..24879d62 100644 --- a/support/regression/Makefile +++ b/support/regression/Makefile @@ -65,11 +65,13 @@ ALL_PORTS = $(filter-out CVS xa51 ucz80 gbz80,$(notdir $(wildcard $(PORTS_DIR)/* # These ports will be cleaned with 'make clean' CLEAN_PORTS = $(filter-out CVS,$(notdir $(wildcard $(PORTS_DIR)/*))) +MAKE_LIBRARY = + all: test-ports # Test all of the ports test-ports: - for i in $(ALL_PORTS); do $(MAKE) test-port PORT=$$i; done + for i in $(ALL_PORTS); do $(MAKE) make_library test-port PORT=$$i; done # Helper rule for testing the z80 port only test-z80: @@ -87,7 +89,10 @@ test-mcs51-large: $(MAKE) test-port PORT=mcs51-large test-mcs51-stack-auto: - $(MAKE) make-library test-port PORT=mcs51-stack-auto + $(MAKE) make_library test-port PORT=mcs51-stack-auto + +test-mcs51-xstack-auto: + $(MAKE) make_library test-port PORT=mcs51-xstack-auto # Helper rule for testing the ds390 port only test-ds390: @@ -143,6 +148,8 @@ ifdef PORT include $(PORTS_DIR)/$(PORT)/spec.mk endif +make_library: $(MAKE_LIBRARY) + SDCCFLAGS += -Ifwk/include -Itests -I$(INC_DIR) # List of intermediate files to keep. Pretty much keep everything as diff --git a/support/regression/fwk/lib/testfwk.c b/support/regression/fwk/lib/testfwk.c index 48d92317..4753dea3 100644 --- a/support/regression/fwk/lib/testfwk.c +++ b/support/regression/fwk/lib/testfwk.c @@ -13,6 +13,11 @@ #define _REENTRANT reentrant #endif +#if defined(SDCC_mcs51) +/* until changed, isr's must have a prototype in the module containing main */ +void T2_isr (void) interrupt 5; +#endif + /** Define this if the port's div or mod functions are broken. A slow loop based method will be substituded. */ @@ -105,14 +110,14 @@ void __printf(const char *szFormat, ...) REENTRANT int __numTests; int __numFailures; -void +void __fail(const char *szMsg, const char *szCond, const char *szFile, int line) { __printf("--- FAIL: \"%s\" on %s at %s:%u\n", szMsg, szCond, szFile, line); __numFailures++; } -int +int main(void) { TESTFUNP *cases; @@ -128,8 +133,8 @@ main(void) cases++; numCases++; } - - __printf("--- Summary: %u/%u/%u: %u failed of %u tests in %u cases.\n", + + __printf("--- Summary: %u/%u/%u: %u failed of %u tests in %u cases.\n", __numFailures, __numTests, numCases, __numFailures, __numTests, numCases ); diff --git a/support/regression/ports/mcs51-stack-auto/spec.mk b/support/regression/ports/mcs51-stack-auto/spec.mk index 831f0554..32154b2c 100644 --- a/support/regression/ports/mcs51-stack-auto/spec.mk +++ b/support/regression/ports/mcs51-stack-auto/spec.mk @@ -43,9 +43,7 @@ SOURCES = _atoi.c _atol.c _autobaud.c _bp.c _schar2fs.c \ OBJECTS = $(patsubst %.c,$(LIBDIR)/%.rel,$(SOURCES)) MODULES = $(patsubst %.c,%,$(SOURCES)) -.PHONY: make-library -make-library: $(LIBDIR) $(OBJECTS) lib-files - +MAKE_LIBRARY = $(LIBDIR) $(OBJECTS) lib-files $(LIBDIR): mkdir -p $(LIBDIR) diff --git a/support/regression/ports/mcs51-xstack-auto/spec.mk b/support/regression/ports/mcs51-xstack-auto/spec.mk new file mode 100644 index 00000000..ae82b657 --- /dev/null +++ b/support/regression/ports/mcs51-xstack-auto/spec.mk @@ -0,0 +1,8 @@ +# Port specification for the mcs51 port running with uCsim +# +# model small stack-auto + +include $(PORTS_DIR)/mcs51-stack-auto/spec.mk + +LIBSDCCFLAGS+= --xstack +SDCCFLAGS +=$(LIBSDCCFLAGS) diff --git a/support/regression/ports/mcs51/T2_isr.c b/support/regression/ports/mcs51/T2_isr.c new file mode 100644 index 00000000..2a248d15 --- /dev/null +++ b/support/regression/ports/mcs51/T2_isr.c @@ -0,0 +1,6 @@ +//dummy interrupt service routine +//just to make linker happy + +void T2_isr (void) interrupt 5 +{ +} diff --git a/support/regression/ports/mcs51/fwk.lib b/support/regression/ports/mcs51/fwk.lib new file mode 100644 index 00000000..c6898f8f --- /dev/null +++ b/support/regression/ports/mcs51/fwk.lib @@ -0,0 +1 @@ +T2_isr.rel diff --git a/support/regression/ports/mcs51/spec.mk b/support/regression/ports/mcs51/spec.mk index d686dc46..610a0660 100644 --- a/support/regression/ports/mcs51/spec.mk +++ b/support/regression/ports/mcs51/spec.mk @@ -17,10 +17,11 @@ OBJEXT = .rel EXEEXT = .ihx EXTRAS = $(PORTS_DIR)/$(PORT)/testfwk$(OBJEXT) $(PORTS_DIR)/$(PORT)/support$(OBJEXT) +FWKLIB = $(PORTS_DIR)/$(PORT)/T2_isr$(OBJEXT) # Rule to link into .ihx -%$(EXEEXT): %$(OBJEXT) $(EXTRAS) - $(SDCC) $(SDCCFLAGS) $(LINKFLAGS) -L $(LIBDIR) $(EXTRAS) $< -o $@ +%$(EXEEXT): %$(OBJEXT) $(EXTRAS) $(FWKLIB) $(PORTS_DIR)/$(PORT)/fwk.lib + $(SDCC) $(SDCCFLAGS) $(LINKFLAGS) -L $(LIBDIR) $(EXTRAS) $(PORTS_DIR)/$(PORT)/fwk.lib $< -o $@ %$(OBJEXT): %.c $(SDCC) $(SDCCFLAGS) -c $< -o $@ @@ -28,6 +29,9 @@ EXTRAS = $(PORTS_DIR)/$(PORT)/testfwk$(OBJEXT) $(PORTS_DIR)/$(PORT)/support$(OBJ $(PORTS_DIR)/$(PORT)/testfwk$(OBJEXT): fwk/lib/testfwk.c $(SDCC) $(SDCCFLAGS) -c $< -o $@ +$(PORTS_DIR)/$(PORT)/fwk.lib: + cp $(PORTS_DIR)/mcs51/fwk.lib $(PORTS_DIR)/$(PORT)/fwk.lib + # run simulator with 30 seconds timeout %.out: %$(EXEEXT) fwk/lib/timeout mkdir -p `dirname $@` diff --git a/support/regression/tests/bitvars.c b/support/regression/tests/bitvars.c new file mode 100644 index 00000000..6bcc1049 --- /dev/null +++ b/support/regression/tests/bitvars.c @@ -0,0 +1,24 @@ +/** Bit vars test. + +*/ +#include + +#if defined (SDCC_STACK_AUTO) || defined (SDCC_hc08) || defined (SDCC_z80) || defined (PORT_HOST) +#define NO_BITS +#endif + +#ifndef NO_BITS +char foo(bit a, bit b, char c) +{ + return a + b + c; +} +#endif + +void +testBits(void) +{ +#ifndef NO_BITS + bit x = 2; + ASSERT (foo(x,3,4) == 6); +#endif +} diff --git a/support/regression/tests/critical.c b/support/regression/tests/critical.c new file mode 100644 index 00000000..918cbdb4 --- /dev/null +++ b/support/regression/tests/critical.c @@ -0,0 +1,69 @@ +/* Keyword "critical" tests. + */ +#include + +#if defined(SDCC_mcs51) +#include <8052.h> + +typedef union +{ + unsigned int a; + struct + { + unsigned char b; + unsigned char c; + }; +} big; + +//must be at least 2 bytes big and volatile +volatile big global_var = { 0 }; + +unsigned int get_global (void) critical +{ + return global_var.a; +} +#endif + +void +testCritical(void) +{ +#if defined(SDCC_mcs51) + big x; + unsigned char i; + + //enable the interrupt and set it + ET2 = 1; + EA = 1; + TF2 = 1; + + critical x.a = global_var.a; + ASSERT(x.b == x.c); + + x.a = get_global(); + ASSERT(x.b == x.c); + + for (i=10; i!=0; i--) + { + critical x.a = global_var.a; + ASSERT(x.b == x.c); + + x.a = get_global(); + ASSERT(x.b == x.c); + } + //check the interrupt has run at all + ASSERT(x.a != 0); +#else + ASSERT(1); +#endif +} + +#if defined(SDCC_mcs51) +void T2_isr (void) interrupt 5 using 2 +{ + //do not clear flag ET2 so it keeps interrupting ! + global_var.b++; + if (global_var.b == 0) + global_var.b++; + global_var.c = global_var.b; +} +#endif -- 2.30.2