* .version: changed to version 2.5.3
authormaartenbrock <maartenbrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 3 Sep 2005 10:35:46 +0000 (10:35 +0000)
committermaartenbrock <maartenbrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 3 Sep 2005 10:35:46 +0000 (10:35 +0000)
* 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

20 files changed:
.version
ChangeLog
doc/sdccman.lyx
src/SDCCicode.c
src/SDCCmem.c
src/SDCCsymt.c
src/avr/main.c
src/ds390/main.c
src/hc08/main.c
src/mcs51/gen.c
src/mcs51/main.c
src/mcs51/peeph.def
src/mcs51/ralloc.c
src/pic/main.c
src/pic16/main.c
src/port.h
src/xa51/main.c
src/z80/main.c
support/regression/tests/bitvars.c
support/regression/tests/funptrs.c

index f225a78adf0534ad898ee7521a19aa40897f53ba..aedc15bb0c6e24f27eedf7684532f8039cabb92c 100644 (file)
--- a/.version
+++ b/.version
@@ -1 +1 @@
-2.5.2
+2.5.3
index 40c1ba3cc7fb91c40dd26fab5ab0909aee5181bc..b0a320318d87bb6e027f8391afb2c20cdb76ad80 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,41 @@
+2005-09-03 Maarten Brock <sourceforge.brock AT dse.nl>
+
+       * .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 <borut.razem AT siol.net>
 
        * device/lib/Makefile.in: cp on sparc-solaris (SunOS) and on
index 6b0c34f62e2481a33e6cecbd3b8fdd88f1bcff4b..31ab8d0d037da4e501d6e3247155842b76ff2cbb 100644 (file)
@@ -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 <Value>}
+
+\end_inset 
+
+\SpecialChar ~
+<Name> 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 <Value>}
+
+\end_inset 
+
+\SpecialChar ~
+<Name> 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 <name>
+\begin_inset LatexCommand \index{\#pragma codeseg}
+
+\end_inset 
+
+- Use this name (max.
+ 8 characters) for the code segment.
+\layout Itemize
+
+constseg <name>
+\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:
index 26dbaab3401565922200bf8caf65b503b15a1509..ee4783cd8978a02ffd7092349b093201d450e4f6 100644 (file)
@@ -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:
index ddf5ce66bb7e202d10356bfb47f01cf28402a2ac..35b0d9e1f3bb4198bbc694b081484b8bd1a3c80a 100644 (file)
@@ -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;
     }
index c1bdae25ea296d09230145938c6e19770ee8b39a..a34b6bb736d602c8ddbc209803c53f2cbbffef60 100644 (file)
@@ -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;
index aa9a9d3e9440dc47f12905de3b50772a9d480e11..828c3c033f19bee402fa721fa54dd7f2210cde01 100644 (file)
@@ -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
index 639ab5df969230f386be201ddbe3f1b66ddfa9d8..a2e54083077fccf695156f1f7567b2e234ce1386 100644 (file)
@@ -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;
index 1e15fd5b32998683319029d086bc342e1d62c877..a86d3a127bdc1160baf373b2b9931b74e06a475a 100644 (file)
@@ -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);
     
index 6f9f7252436fbd581ca7899f30b17f23f288bbf9..2ac72db6827595ded9969aea21d9a12828242e7c 100644 (file)
@@ -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);
index a8854a78b672ebabc630183756e6595e327b79b5..e3788b230c73686258b1aa9457993fa8bfaa595c 100644 (file)
@@ -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;
         }
index f6b05b3b53e59094796ef2cdf261cfd7e0add2b2..d4eea55ec05a7a46ac5a259718b5f4dfddf2c003 100644 (file)
@@ -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
index 9251cd32624f899be4b338be921e82e53b2cc4fa..e983d48ae692bc768447ed980d691629a9075036 100644 (file)
@@ -984,6 +984,7 @@ updateRegUsage (iCode * ic)
       else
         {
           ic->riu |= (1<<regs8051[reg].offset);
+          BitBankUsed |= (reg >= 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
     {
index c646ae652c1b8e8b169f7fe547ed8638bc9755cd..7ff316565e1eebe43d8effb9f3952269c232ebda 100644 (file)
@@ -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 */
index 4eb914b6369877b60d7b3e94db321afa5fb24747..67c857909c90ce5e0edd3c37870873b4ea04332d 100644 (file)
@@ -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*/) {
index e44e610b403596f7da37d00506192986259c64f8..fa127a4e50f350b69a2280442262f82b4929c5ab 100644 (file)
@@ -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
index 8030dbddf546d0251078e59f60b72b7ab2a91fe3..a9b329cbcab4f3db73732f0b3199852fac466383 100755 (executable)
@@ -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
index 33f5bbd4ce46bec44e6c2cbc4bb36765f2a1b5bf..248e31b5112d41f835028b0e24168c598309ed36 100644 (file)
@@ -119,7 +119,7 @@ _reset_regparm (void)
 }
 
 static int
-_reg_parm (sym_link * l)
+_reg_parm (sym_link * l, bool reentrant)
 {
   if (options.noRegParams) 
     {
index 6fbee3b9a985288faede643845f902fa29e00ec7..abe33473c63875c3ff77cb4d0524d36f26b340c3 100644 (file)
@@ -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
 
index ad5248b8426a070a6f50cbe812696f4007a5f807..546eb6b57c22170d210c36508d87a5be7db7bdab 100644 (file)
@@ -1,8 +1,15 @@
 /** Function pointer tests.
 
-    type: char, int, long
+    type: BOOL, char, int, long
  */
 #include <testfwk.h>
+#include <stdbool.h>
+
+#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.
 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);
+}
+