2004-01-11 Vangelis Rokas <vrokas@otenet.gr>
authorvrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 11 Jan 2004 15:26:54 +0000 (15:26 +0000)
committervrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 11 Jan 2004 15:26:54 +0000 (15:26 +0000)
SDCC source changes:
* src/SDCCopt.c (cntToFcall, cnvToFloatCast, cnvFromFloatCast,
convilong): modified to inform the pic16 port that builtin functions
are external

PIC16 PORT specific changes:
* src/pic16/device.c pic16_dump_equates() added,
processor registers declared internally by the port are emitted in
the translation as equates,
* src/pic16/gen.c: inline code is passed unprocessed to the
translation,
* (pic16_popGetLit2): fnuction modified to take second operand as
pCodeOp pointer and not as literal,
* (popRegFromIdx): prefixed with pic16_,
* (pic16_popCombine2): modified to receive already allocated pCode
operands,
* (pic16_pushpCodeOpReg, pic16_poppCodeOpReg): added
* (genFunction): initializes local stack frame and pushes on stack
all the registers used by this function,
* (genEndFunction): restores all registers from stack and restores
stack frame,
* src/pic16/glue.c (pic16emitRegularMap): various changes and
improvements,
* (pic16glue): changed the program startup sequence,
* added new dbName code 'A' for functions placed in absolute section
* src/pic16/main.c: added function attribute _naked,
* added pragma 'code' to place a fnuction at an absolute address,
* added command line arguments --debug-ralloc and --pcode-verbose,
* (_pic16_finiliseOptions): options.all_callee_saves is set by default
* src/pic16/pcode.c (pic16_pBlockConvert2Absolute) added,
* (pic16_newpCodeOpLit2): modified to take the second operand as
pCodeOp pointer,
* (pic16_printpBlock): modified to emit each function in a separate
section,
* (pic16_get_op): modified to use the gpasm modifiers LOW,HIGH and
UPPER for immediate operands,
* src/pic16/pcodepeeph.c: added peephole support for the LFSR
instruction,
* src/pic16/peeph.def: all peepholes with movff are commented out,
because there is a problem in the pcode peep optimizer,
* src/pic16/ralloc.c: the register allocator can now reuse local
function symbols for another function. This saves register usage.
* src/pic16/ralloc.h: added flag isLocal in structure regs,

Added file src/pic16/NOTES with information about program writing on
the current port version.

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3112 4a8a32a2-be11-0410-ad9d-d568d2c75423

16 files changed:
ChangeLog
src/SDCCopt.c
src/pic16/NOTES [new file with mode: 0644]
src/pic16/device.c
src/pic16/gen.c
src/pic16/gen.h
src/pic16/glue.c
src/pic16/main.c
src/pic16/main.h
src/pic16/pcode.c
src/pic16/pcode.h
src/pic16/pcodepeep.c
src/pic16/pcoderegs.c
src/pic16/peeph.def
src/pic16/ralloc.c
src/pic16/ralloc.h

index e66dbb3270245503ce1aeb7e839040fabee84959..df1568f37c8fb8a2eb0c31b6783ae60c8fee6ce5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,52 @@
+2004-01-11 Vangelis Rokas <vrokas@otenet.gr>
+       
+       SDCC source changes:
+       * src/SDCCopt.c (cntToFcall, cnvToFloatCast, cnvFromFloatCast,
+       convilong): modified to inform the pic16 port that builtin functions
+       are external
+       
+       PIC16 PORT specific changes:
+       * src/pic16/device.c pic16_dump_equates() added,
+       processor registers declared internally by the port are emitted in
+       the translation as equates,
+       * src/pic16/gen.c: inline code is passed unprocessed to the
+       translation,
+       * (pic16_popGetLit2): fnuction modified to take second operand as
+       pCodeOp pointer and not as literal,
+       * (popRegFromIdx): prefixed with pic16_,
+       * (pic16_popCombine2): modified to receive already allocated pCode
+       operands,
+       * (pic16_pushpCodeOpReg, pic16_poppCodeOpReg): added
+       * (genFunction): initializes local stack frame and pushes on stack
+       all the registers used by this function,
+       * (genEndFunction): restores all registers from stack and restores
+       stack frame,
+       * src/pic16/glue.c (pic16emitRegularMap): various changes and
+       improvements,
+       * (pic16glue): changed the program startup sequence,
+       * added new dbName code 'A' for functions placed in absolute section
+       * src/pic16/main.c: added function attribute _naked,
+       * added pragma 'code' to place a fnuction at an absolute address,
+       * added command line arguments --debug-ralloc and --pcode-verbose,
+       * (_pic16_finiliseOptions): options.all_callee_saves is set by default
+       * src/pic16/pcode.c (pic16_pBlockConvert2Absolute) added,
+       * (pic16_newpCodeOpLit2): modified to take the second operand as
+       pCodeOp pointer,
+       * (pic16_printpBlock): modified to emit each function in a separate
+       section,
+       * (pic16_get_op): modified to use the gpasm modifiers LOW,HIGH and
+       UPPER for immediate operands,
+       * src/pic16/pcodepeeph.c: added peephole support for the LFSR
+       instruction,
+       * src/pic16/peeph.def: all peepholes with movff are commented out,
+       because there is a problem in the pcode peep optimizer,
+       * src/pic16/ralloc.c: the register allocator can now reuse local
+       function symbols for another function. This saves register usage.
+       * src/pic16/ralloc.h: added flag isLocal in structure regs,
+
+       Added file src/pic16/NOTES with information about program writing on
+       the current port version.
+
 2004-01-11 Frieder Ferlemann <Frieder.Ferlemann@web.de>
 
        * src/mcs51/peephole.def: added peepholes 177.c,d (redundant moves)
index a4c7de2261b6a42e56537c9821350e8ce2ef8f14..05eab6f518d451b39e92f169410e71a509474135 100644 (file)
@@ -176,6 +176,20 @@ cnvToFcall (iCode * ic, eBBlock * ebp)
   IC_RESULT (newic) = IC_RESULT (ic);
   newic->lineno = lineno;
   newic->parmBytes+=bytesPushed;
+
+  if(TARGET_IS_PIC16) {
+       /* normally these functions aren't marked external, so we can use their
+        * _extern field to marked as already added to symbol table */
+
+       if(!SPEC_EXTR(func->etype)) {
+           memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
+               
+               SPEC_EXTR(func->etype) = 1;
+               seg = SPEC_OCLS( func->etype );
+               addSet(&seg->syms, func);
+       }
+  }
+
   addiCodeToeBBlock (ebp, newic, ip);
 }
 
@@ -250,9 +264,22 @@ found:
   newic = newiCode (CALL, operandFromSymbol (func), NULL);
   IC_RESULT (newic) = IC_RESULT (ic);
   newic->parmBytes+=bytesPushed;
+
+  if(TARGET_IS_PIC16) {
+       /* normally these functions aren't marked external, so we can use their
+        * _extern field to marked as already added to symbol table */
+
+       if(!SPEC_EXTR(func->etype)) {
+           memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
+               
+               SPEC_EXTR(func->etype) = 1;
+               seg = SPEC_OCLS( func->etype );
+               addSet(&seg->syms, func);
+       }
+  }
+
   addiCodeToeBBlock (ebp, newic, ip);
   newic->lineno = linenno;
-
 }
 
 /*-----------------------------------------------------------------*/
@@ -327,9 +354,22 @@ found:
   newic = newiCode (CALL, operandFromSymbol (func), NULL);
   IC_RESULT (newic) = IC_RESULT (ic);
   newic->parmBytes+=bytesPushed;
+
+  if(TARGET_IS_PIC16) {
+       /* normally these functions aren't marked external, so we can use their
+        * _extern field to marked as already added to symbol table */
+
+       if(!SPEC_EXTR(func->etype)) {
+           memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
+               
+               SPEC_EXTR(func->etype) = 1;
+               seg = SPEC_OCLS( func->etype );
+               addSet(&seg->syms, func);
+       }
+  }
+
   addiCodeToeBBlock (ebp, newic, ip);
   newic->lineno = lineno;
-
 }
 
 extern operand *geniCodeRValue (operand *, bool);
@@ -477,6 +517,20 @@ found:
   IC_RESULT (newic) = IC_RESULT (ic);
   newic->lineno = lineno;
   newic->parmBytes+=bytesPushed; // to clear the stack after the call
+
+  if(TARGET_IS_PIC16) {
+       /* normally these functions aren't marked external, so we can use their
+        * _extern field to marked as already added to symbol table */
+
+       if(!SPEC_EXTR(func->etype)) {
+           memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
+               
+               SPEC_EXTR(func->etype) = 1;
+               seg = SPEC_OCLS( func->etype );
+               addSet(&seg->syms, func);
+       }
+  }
+
   addiCodeToeBBlock (ebp, newic, ip);
 }
 
diff --git a/src/pic16/NOTES b/src/pic16/NOTES
new file mode 100644 (file)
index 0000000..d49eb7e
--- /dev/null
@@ -0,0 +1,105 @@
+NOTES file for SDCC pic16 port
+$Id$
+
+Current pic16 port status is: Development
+
+Some things may change without notification between port updates. The latest
+CVS snapshot is guarenteed to compile without problems, but does not
+guarantee backwards compatibility.
+
+For any questions please ask the current port
+developers.
+
+Current developer:
+Vangelis Rokas <vrokas@otenet.gr>
+
+Other people to contact:
+Scott Dattalo  <scott@dattalo.com>
+
+
+
+2004-Jan-11 Vangelis Rokas
+
+1. Compiling
+The current release of the port can produce object code which is not
+completely bug free. To use the new features the user should enable them via
+command line arguments. A sane set of command arguments that I use to test
+programs is:
+
+- debug options
+       --debug         enable sdcc debug information
+       --debug-xtra    enable pic16 port debug information (most useful)
+       --debug-ralloc  enable register allocator debug messages
+       --pcode-verbose enable verbose pcode generator messages
+
+- port options
+       --pgen-banksel  enable banksel directives for the assembler
+                       This will be turned on by default later, but left as
+                       is for now
+       --pomit-config-words    does not emit configuration instruction in
+                       the translation This is useful when copmiling
+                       multiple sources, when you do not want multiple
+                       config instructions in the end file
+       --pomit-ivt     disables the dumping of the interrupt vector tables
+                       in the translation for the same reasons as above
+       --penable-stack enables stack support. This option uses stack to
+                       pass function arguments, and reuses registers between
+                       functions by saving the registers used in the function
+                       on the stack
+
+- compiler options
+       --all-callee-saves      you may omit this options as the port
+                       enables it by default, all functions are currently
+                       compiled as reentrant and they are marked as
+                       callee-saves
+       --no-peep       peephole optimizer is better to be switched off,
+                       because it behaves strangely in some cases
+       --fommit-frame-pointer  this omits frame pointer in functions that
+                       don't use registers (maybe changed later, not
+                       important)
+
+
+2. Functions
+The current implementation puts every function in its own code section in
+PIC's program memory. This may not be the standard, but I think its more
+flexible.
+
+3. Pragmas
+Since SDCC is goind for a release, its better to document pragmas available.
+
+3.1. code
+The 'code' pragma emits a function's code at a specific address in program
+memory. Currently it is only used for functions.
+Syntax:
+#pragma code [function_name] [address]
+
+3.2. stack
+The 'stack' pragma initializes the stack/frame pointer at an address of the
+data ram other than the default (which is the end of the available data ram)
+Synatx:
+#pragma stack [address]
+
+3.3. maxram
+The 'maxram' pragma sets maximum data ram of the device. Currently is not
+used at all, but it may be useful in the future when devices with external
+memory will be supported.
+Syntax:
+#pragma maxram [max_address]
+
+
+4. Internal compiler functions
+Internal SDCC functions like, __fsmul, etc... are currently supported by the
+port, but the libraries for the pic16 port are not yet ready. So one cannot
+use long and float variables.
+
+
+5. Special Function Registers (SFRs)
+The processor SFRs are not anymore declared in any header file. The user can
+define by himself all the needed SFR's. The code to that is:
+
+sfr at [sfr_address] [sfr_name];
+
+Where sfr_address is the SFR address in the data ram, and sfr_name is the
+name of the SFR. i.e.:
+
+sfr at 0xf80 PORTA;
index b7eb78657786f8251a8c1edf38396ff1051e0bb7..9aeaeb38b4ebc9205b01d04f187604e30079519e 100644 (file)
@@ -339,8 +339,26 @@ void pic16_dump_map(void)
 }
 #endif
 
+extern char *iComments2;
 
-void pic16_dump_section(FILE *of, char *sname, set *section, int fix)
+void pic16_dump_equates(FILE *of, set *equs)
+{
+  regs *r;
+
+       r = setFirstItem(equs);
+       if(!r)return;
+       
+       fprintf(of, "%s", iComments2);
+       fprintf(of, ";\tEquates to used internal registers\n");
+       fprintf(of, "%s", iComments2);
+       
+       for(; r; r = setNextItem(equs)) {
+               fprintf(of, "%s\tequ\t0x%02x\n", r->name, r->address);
+       }
+}
+
+
+void pic16_dump_section(FILE *of, set *section, int fix)
 {
   static int abs_section_no=0;
   regs *r, *rprev;
@@ -552,11 +570,18 @@ void pic16_groupRegistersInSection(set *regset)
        for(reg=setFirstItem(regset); reg; reg = setNextItem(regset)) {
                if(reg->wasUsed
                        && !(reg->regop && SPEC_EXTR(OP_SYM_ETYPE(reg->regop)))) {
-                       if(reg->isFixed)
+
+                       if(reg->alias) {
+                               checkAddReg(&pic16_equ_data, reg);
+                       } else
+                       if(reg->isFixed) {
                                checkAddReg(&pic16_fix_udata, reg);
-               
-                       if(!reg->isFixed)
+                       } else
+                       if(!reg->isFixed) {
+//                             fprintf(stderr, "%s:%d adding symbol %s in relocatable udata section\n",
+//                                     __FILE__, __LINE__, reg->name);
                                checkAddReg(&pic16_rel_udata, reg);
+                       }
                }
        }
 }
index 7775b12c7b6220507ef30dc2947cbdfd27093804..9bd719d2b2c2936d1001b91d7b3b3aaf8c447442 100644 (file)
 #include "gen.h"
 #include "genutils.h"
 #include "device.h"
+#include "main.h"
 
 extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
 extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
 void pic16_genMult8X8_8 (operand *, operand *,operand *);
-pCode *pic16_AssembleLine(char *line);
+pCode *pic16_AssembleLine(char *line, int peeps);
 extern void pic16_printpBlock(FILE *of, pBlock *pb);
 static asmop *newAsmop (short type);
 static pCodeOp *pic16_popRegFromString(char *str, int size, int offset);
+extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...);
 static void mov2w (asmop *aop, int offset);
 static int aopIdx (asmop *aop, int offset);
 
@@ -184,6 +186,35 @@ void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, op
 
 }
 
+void pic16_emitcomment (char *fmt, ...)
+{
+    va_list ap;
+    char lb[INITIAL_INLINEASM];  
+    char *lbp = lb;
+
+    if(!pic16_debug_verbose)
+      return;
+
+    va_start(ap,fmt);   
+
+    lb[0] = ';';
+    vsprintf(lb+1,fmt,ap);
+
+    while (isspace(*lbp)) lbp++;
+
+    if (lbp && *lbp) 
+        lineCurr = (lineCurr ?
+                    connectLine(lineCurr,newLineNode(lb)) :
+                    (lineHead = newLineNode(lb)));
+    lineCurr->isInline = _G.inLine;
+    lineCurr->isDebug  = _G.debugLine;
+
+    pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb));
+    va_end(ap);
+
+//     fprintf(stderr, "%s\n", lb);
+}
+
 void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
 {
     va_list ap;
@@ -219,7 +250,6 @@ void DEBUGpic16_emitcode (char *inst,char *fmt, ...)
 //     fprintf(stderr, "%s\n", lb);
 }
 
-
 void pic16_emitpLabel(int key)
 {
   pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset));
@@ -1239,9 +1269,9 @@ pCodeOp *pic16_popGetLit(unsigned int lit)
 /*-----------------------------------------------------------------*/
 /* pic16_popGetLit2 - asm operator to pcode operator conversion    */
 /*-----------------------------------------------------------------*/
-pCodeOp *pic16_popGetLit2(unsigned int lit, unsigned int lit2)
+pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2)
 {
-  return pic16_newpCodeOpLit2(lit, lit2);
+  return pic16_newpCodeOpLit2(lit, arg2);
 }
 
 
@@ -1310,22 +1340,19 @@ static pCodeOp *pic16_popRegFromString(char *str, int size, int offset)
   return pcop;
 }
 
-static pCodeOp *popRegFromIdx(int rIdx)
+static pCodeOp *pic16_popRegFromIdx(int rIdx)
 {
   pCodeOp *pcop;
 
-  DEBUGpic16_emitcode ("; ***","%s,%d  , rIdx=0x%x",
-                      __FUNCTION__,__LINE__,rIdx);
-
-  pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+//     DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx);
 
-  PCOR(pcop)->rIdx = rIdx;
-  PCOR(pcop)->r = pic16_regWithIdx(rIdx);
-  PCOR(pcop)->r->isFree = 0;
-  PCOR(pcop)->r->wasUsed = 1;
-
-  pcop->type = PCOR(pcop)->r->pc_type;
+       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+       PCOR(pcop)->rIdx = rIdx;
+       PCOR(pcop)->r = pic16_regWithIdx(rIdx);
+       PCOR(pcop)->r->isFree = 0;
+       PCOR(pcop)->r->wasUsed = 1;
 
+       pcop->type = PCOR(pcop)->r->pc_type;
 
   return pcop;
 }
@@ -1340,22 +1367,37 @@ pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
   pCodeOp *temp;
   
        pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
+
+       /* comment the following check, so errors to throw up */
+//     if(!pcop2)return NULL;
+
        temp = pic16_popGet(aop_dst, offset);
        pcop2->pcop2 = temp;
        
   return PCOP(pcop2);
 }
 
-pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst)
+/*---------------------------------------------------------------------------------*/
+/* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with      */
+/*                     movff instruction                                           */
+/*---------------------------------------------------------------------------------*/
+pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
 {
   pCodeOpReg2 *pcop2;
 
-       pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
-       pcop2->pcop2 = pic16_popCopyReg(dst);
+       if(!noalloc) {
+               pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
+               pcop2->pcop2 = pic16_popCopyReg(dst);
+       } else {
+               /* the pCodeOp may be already allocated */
+               pcop2 = (pCodeOpReg2 *)(src);
+               pcop2->pcop2 = (pCodeOp *)(dst);
+       }
 
   return PCOP(pcop2);
 }
 
+
 /*-----------------------------------------------------------------*/
 /* pic16_popGet - asm operator to pcode operator conversion              */
 /*-----------------------------------------------------------------*/
@@ -1383,6 +1425,7 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname)
     case AOP_DPTR2:
     case AOP_ACC:
         DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type));
+        fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type));
        return NULL;
        
     case AOP_IMMD:
@@ -1702,6 +1745,17 @@ static void mov2w (asmop *aop, int offset)
 }
 
 
+void pic16_pushpCodeOpReg(pCodeOpReg *pcop)
+{
+       pic16_emitpcode(POC_MOVFF, pic16_popCombine2(pcop, &pic16_pc_postdec1, 0));
+}
+
+void pic16_poppCodeOpReg(pCodeOpReg *pcop)
+{
+       pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, pcop, 0));
+}
+
+
 /*-----------------------------------------------------------------*/
 /* pushw - pushes wreg to stack                                    */
 /*-----------------------------------------------------------------*/
@@ -1718,18 +1772,17 @@ void pushw(void)
 void pushaop(asmop *aop, int offset)
 {
         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-        pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1));
+        pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0));
 }
 
-#if 0
 /*-----------------------------------------------------------------*/
 /* popaop - pops aop from stack                                    */
 /*-----------------------------------------------------------------*/
 void popaop(asmop *aop, int offset)
 {
-       DEBUG
+       DEBUGpic16_emitcode("; ***", "%s  %d", __FUNCTION__, __LINE__);
+       pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0));
 }
-#endif
 
 void popaopidx(asmop *aop, int offset, int index)
 {
@@ -1740,7 +1793,7 @@ void popaopidx(asmop *aop, int offset, int index)
        if(STACK_MODEL_LARGE)ofs++;
 
        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs));
-        pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset))));
+        pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0));
 }
 
 /*-----------------------------------------------------------------*/
@@ -2228,10 +2281,10 @@ static void assignResultValue(operand * oper)
                if(USE_STACK) {
                        popaopidx(AOP(oper), size, GpsuedoStkPtr);
                } else {
-                       pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
+                       pic16_emitpcode(POC_MOVFW, pic16_popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
                }
 #else
-               pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
+               pic16_emitpcode(POC_MOVFW, pic16_popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr));
 #endif /* STACK_SUPPORT */
                GpsuedoStkPtr++;
 
@@ -2501,10 +2554,10 @@ static void genCall (iCode *ic)
                                                pushw();
                                                --psuedoStkPtr;         // sanity check
                                        } else {
-                                               pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
+                                               pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
                                        }
 #else
-                                       pic16_emitpcode(POC_MOVWF, popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
+                                       pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr));
 #endif /* STACK_SUPPORT */
                                }
                        
@@ -2543,7 +2596,7 @@ static void genCall (iCode *ic)
        }
 
 #if STACK_SUPPORT
-       if(USE_STACK) {
+       if(USE_STACK && stackParms>0) {
                pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
                pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
                if(STACK_MODEL_LARGE) {
@@ -2554,7 +2607,7 @@ static void genCall (iCode *ic)
 #endif
 
        /* adjust the stack for parameters if required */
-       fprintf(stderr, "%s:%d: ic->parmBytes= %d\n", __FILE__, __LINE__, ic->parmBytes);
+//     fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes);
 
        if (ic->parmBytes) {
          int i;
@@ -2740,205 +2793,221 @@ static bool inExcludeList(char *s)
 /*-----------------------------------------------------------------*/
 static void genFunction (iCode *ic)
 {
-    symbol *sym;
-    sym_link *ftype;
+  symbol *sym;
+  sym_link *ftype;
 
-    DEBUGpic16_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
+       DEBUGpic16_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key);
 
-    labelOffset += (max_key+4);
-    max_key=0;
-    GpsuedoStkPtr=0;
-    _G.nRegsSaved = 0;
-    /* create the function header */
-    pic16_emitcode(";","-----------------------------------------");
-    pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
-    pic16_emitcode(";","-----------------------------------------");
+       labelOffset += (max_key+4);
+       max_key=0;
+       GpsuedoStkPtr=0;
+       _G.nRegsSaved = 0;
+       /* create the function header */
+       pic16_emitcode(";","-----------------------------------------");
+       pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
+       pic16_emitcode(";","-----------------------------------------");
 
-    pic16_emitcode("","%s:",sym->rname);
-    pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,sym->rname));
+       pic16_emitcode("","%s:",sym->rname);
+       pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
 
-    ftype = operandType(IC_LEFT(ic));
+       {
+         absSym *ab;
 
-    /* if critical function then turn interrupts off */
-    if (IFFUNC_ISCRITICAL(ftype))
-        pic16_emitcode("clr","ea");
+               for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet))
+                       if(strcmp(ab->name, sym->name)) {
+                               pic16_pBlockConvert2Absolute(pb);
+                               break;
+                       }
+               
+       }
 
-    /* here we need to generate the equates for the
-       register bank if required */
-#if 0
-    if (FUNC_REGBANK(ftype) != rbank) {
-        int i ;
-
-        rbank = FUNC_REGBANK(ftype);
-        for ( i = 0 ; i < pic16_nRegs ; i++ ) {
-            if (strcmp(regspic16[i].base,"0") == 0)
-                pic16_emitcode("","%s = 0x%02x",
-                         regspic16[i].dname,
-                         8*rbank+regspic16[i].offset);
-            else
-                pic16_emitcode ("","%s = %s + 0x%02x",
-                          regspic16[i].dname,
-                          regspic16[i].base,
-                          8*rbank+regspic16[i].offset);
-        }
-    }
-#endif
+       ftype = operandType(IC_LEFT(ic));
 
-    /* if this is an interrupt service routine then
-    save acc, b, dpl, dph  */
-    if (IFFUNC_ISISR(sym->type)) {
+       if(IFFUNC_ISNAKED(ftype)) {
+               DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
+               return;
+       }
+       
+
+       /* if critical function then turn interrupts off */
+       if (IFFUNC_ISCRITICAL(ftype))
+               pic16_emitcode("clr","ea");
 
+       /* here we need to generate the equates for the
+        * register bank if required */
 #if 0
-       pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR)));
-       
-       /* what is the reason of having these 3 NOPS? VR - 030701 */
-       pic16_emitpcodeNULLop(POC_NOP);
-       pic16_emitpcodeNULLop(POC_NOP);
-       pic16_emitpcodeNULLop(POC_NOP);
+       if (FUNC_REGBANK(ftype) != rbank) {
+         int i ;
+
+               rbank = FUNC_REGBANK(ftype);
+               for ( i = 0 ; i < pic16_nRegs ; i++ ) {
+                       if (strcmp(regspic16[i].base,"0") == 0)
+                               pic16_emitcode("","%s = 0x%02x",
+                                       regspic16[i].dname,
+                                       8*rbank+regspic16[i].offset);
+                       else
+                               pic16_emitcode ("","%s = %s + 0x%02x",
+                                       regspic16[i].dname,
+                                       regspic16[i].base,
+                                       *rbank+regspic16[i].offset);
+               }
+       }
 #endif
 
-      pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_wsave));
-      pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
-      pic16_emitpcode(POC_CLRF,   pic16_popCopyReg(&pic16_pc_status));
-      pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_ssave));
+       /* if this is an interrupt service routine then
+        * save acc, b, dpl, dph  */
+       if (IFFUNC_ISISR(sym->type)) {
+               pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_wsave));
+               pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status));
+               pic16_emitpcode(POC_CLRF,   pic16_popCopyReg(&pic16_pc_status));
+               pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_ssave));
 
-      pic16_pBlockConvert2ISR(pb);
+               pic16_pBlockConvert2ISR(pb);
 #if 0  
-       if (!inExcludeList("acc"))          
-           pic16_emitcode ("push","acc");      
-       if (!inExcludeList("b"))
-           pic16_emitcode ("push","b");
-       if (!inExcludeList("dpl"))
-           pic16_emitcode ("push","dpl");
-       if (!inExcludeList("dph"))
-           pic16_emitcode ("push","dph");
-       if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
-       {
-           pic16_emitcode ("push", "dpx");
-           /* Make sure we're using standard DPTR */
-           pic16_emitcode ("push", "dps");
-           pic16_emitcode ("mov", "dps, #0x00");
-           if (options.stack10bit)
-           {   
-               /* This ISR could conceivably use DPTR2. Better save it. */
-               pic16_emitcode ("push", "dpl1");
-               pic16_emitcode ("push", "dph1");
-               pic16_emitcode ("push", "dpx1");
-           }
-       }
-       /* if this isr has no bank i.e. is going to
-          run with bank 0 , then we need to save more
-          registers :-) */
-       if (!FUNC_REGBANK(sym->type)) {
+               if (!inExcludeList("acc"))          
+                       pic16_emitcode ("push","acc");  
+               if (!inExcludeList("b"))
+                       pic16_emitcode ("push","b");
+               if (!inExcludeList("dpl"))
+                       pic16_emitcode ("push","dpl");
+               if (!inExcludeList("dph"))
+                       pic16_emitcode ("push","dph");
+               
+               if (options.model == MODEL_FLAT24 && !inExcludeList("dpx")) {
+                       pic16_emitcode ("push", "dpx");
+
+                       /* Make sure we're using standard DPTR */
+                       pic16_emitcode ("push", "dps");
+                       pic16_emitcode ("mov", "dps, #0x00");
+                       if (options.stack10bit) {       
+                               /* This ISR could conceivably use DPTR2. Better save it. */
+                               pic16_emitcode ("push", "dpl1");
+                               pic16_emitcode ("push", "dph1");
+                               pic16_emitcode ("push", "dpx1");
+                       }
+               }
 
-           /* if this function does not call any other
-              function then we can be economical and
-              save only those registers that are used */
-           if (! IFFUNC_HASFCALL(sym->type)) {
-               int i;
+               /* if this isr has no bank i.e. is going to
+                * run with bank 0 , then we need to save more
+                * registers :-) */
+               if (!FUNC_REGBANK(sym->type)) {
+
+                       /* if this function does not call any other
+                        * function then we can be economical and
+                        * save only those registers that are used */
+                       if (! IFFUNC_HASFCALL(sym->type)) {
+                         int i;
+
+                               /* if any registers used */
+                               if (sym->regsUsed) {
+                                       /* save the registers used */
+                                       for ( i = 0 ; i < sym->regsUsed->size ; i++) {
+                                               if (bitVectBitValue(sym->regsUsed,i) ||
+                                                       (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
+                                               pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);                           
+                                       }
+                               }
 
-               /* if any registers used */
-               if (sym->regsUsed) {
-                   /* save the registers used */
-                   for ( i = 0 ; i < sym->regsUsed->size ; i++) {
-                       if (bitVectBitValue(sym->regsUsed,i) ||
-                          (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
-                         pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname);                         
-                   }
+                       } else {
+                               /* this function has  a function call cannot
+                                * determines register usage so we will have the
+                                * entire bank */
+                               saverbank(0,ic,FALSE);
+                       }           
                }
-               
-           } else {
-               /* this function has  a function call cannot
-                  determines register usage so we will have the
-                  entire bank */
-               saverbank(0,ic,FALSE);
-           }       
-       }
 #endif
-    } else {
-       /* if callee-save to be used for this function
-          then save the registers being used in this function */
-       if (IFFUNC_CALLEESAVES(sym->type)) {
-           int i;
-           
-           /* if any registers used */
-           if (sym->regsUsed) {
-               /* save the registers used */
-               for ( i = 0 ; i < sym->regsUsed->size ; i++) {
-                   if (bitVectBitValue(sym->regsUsed,i) ||
-                      (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) {
-                     //pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname);
-                       _G.nRegsSaved++;
-                   }
-               }
-           }
-       }
-       
+       } else {
 #if STACK_SUPPORT
-       /* emit code to setup stack frame if user enabled,
-        * and function is not main() */
+               /* emit code to setup stack frame if user enabled,
+                * and function is not main() */
         
-       fprintf(stderr, "function name: %s\n", sym->name);
-       if(USE_STACK && strcmp(sym->name, "main")) {
-               /* setup the stack frame */
-               pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1));
-               pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l));
-               if(STACK_MODEL_LARGE)
-                       pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h));
-       }
+//             fprintf(stderr, "function name: %s\n", sym->name);
+               if(USE_STACK && strcmp(sym->name, "main")) {
+                       if(!options.ommitFramePtr || sym->regsUsed) {
+                       /* setup the stack frame */
+                               pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
+                               pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
+                               if(STACK_MODEL_LARGE)
+                                       pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
+                       }
+               }
 #endif
 
-    }
+               /* if callee-save to be used for this function
+               * then save the registers being used in this function */
+               if (IFFUNC_CALLEESAVES(sym->type)) {
+                 int i;
+           
+//                     fprintf(stderr, "%s:%d function sym->regsUsed= %p\n", __FILE__, __LINE__, sym->regsUsed);
+                       
+                       /* if any registers used */
+                       if (sym->regsUsed
+#if STACK_SUPPORT
+                               && USE_STACK
+#endif
+                               ) {
+                               /* save the registers used */
+                               DEBUGpic16_emitcode("; **", "Saving used registers in stack");
+                               for ( i = 0 ; i < sym->regsUsed->size ; i++) {
+                                       if (bitVectBitValue(sym->regsUsed,i)) {
+//                                             fprintf(stderr, "%s:%d function %s uses register %s\n",
+//                                                             __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
+//                                                             pic16_regWithIdx(i)->name);
+
+                                               pic16_pushpCodeOpReg( PCOR(pic16_popRegFromIdx(i) ));
+//                                             pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
+//                                                     PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
+//                                                     &pic16_pc_postdec1, 0));
+                                               _G.nRegsSaved++;
+                                       }
+                               }
+                       }
+               }
+       }
 
-    /* set the register bank to the desired value */
-    if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) {
-        pic16_emitcode("push","psw");
-        pic16_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff);   
-    }
 
-    if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
+       
+#if 0
+       if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
 
-       if (options.useXstack) {
-           pic16_emitcode("mov","r0,%s",spname);
-           pic16_emitcode("mov","a,_bp");
-           pic16_emitcode("movx","@r0,a");
-           pic16_emitcode("inc","%s",spname);
-       }
-       else
-       {
-           /* set up the stack */
-           pic16_emitcode ("push","_bp");     /* save the callers stack  */
+               if (options.useXstack) {
+                       pic16_emitcode("mov","r0,%s",spname);
+                       pic16_emitcode("mov","a,_bp");
+                       pic16_emitcode("movx","@r0,a");
+                       pic16_emitcode("inc","%s",spname);
+               } else {
+                       /* set up the stack */
+                       pic16_emitcode ("push","_bp");     /* save the callers stack  */
+               }
+               pic16_emitcode ("mov","_bp,%s",spname);
        }
-       pic16_emitcode ("mov","_bp,%s",spname);
-    }
-
+#endif
        DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
 
-    /* adjust the stack for the function */
-    if (sym->stack) {
+       /* adjust the stack for the function */
+       if (sym->stack) {
+         int i = sym->stack;
 
-       int i = sym->stack;
-       if (i > 256 ) 
-           werror(W_STACK_OVERFLOW,sym->name);
+               if (i > 127 ) 
+                       werror(W_STACK_OVERFLOW,sym->name);
 
-       if (i > 3 && sym->recvSize < 4) {              
-           pic16_emitcode ("mov","a,sp");
-           pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
-           pic16_emitcode ("mov","sp,a");
-          
+               if (i > 3 && sym->recvSize < 4) {              
+                       pic16_emitcode ("mov","a,sp");
+                       pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
+                       pic16_emitcode ("mov","sp,a");
+               } else
+                       while(i--)
+                               pic16_emitcode("inc","sp");
        }
-       else
-           while(i--)
-               pic16_emitcode("inc","sp");
-    }
 
-     if (sym->xstack) {
+       if (sym->xstack) {
                DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
-       pic16_emitcode ("mov","a,_spx");
-       pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
-       pic16_emitcode ("mov","_spx,a");
-    }    
 
+               pic16_emitcode ("mov","a,_spx");
+               pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
+               pic16_emitcode ("mov","_spx,a");
+       }
+    
 }
 
 /*-----------------------------------------------------------------*/
@@ -2950,10 +3019,17 @@ static void genEndFunction (iCode *ic)
 
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
+    if(IFFUNC_ISNAKED(sym->type)) {
+       DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
+       return;
+    }
+
+#if 0
     if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
     {
         pic16_emitcode ("mov","%s,_bp",spname);
     }
+#endif
 
     /* if use external stack but some variables were
     added to the local stack then decrement the
@@ -2965,6 +3041,7 @@ static void genEndFunction (iCode *ic)
     }
 
 
+#if 0
     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
        if (options.useXstack) {
            pic16_emitcode("mov","r0,%s",spname);
@@ -2977,6 +3054,7 @@ static void genEndFunction (iCode *ic)
            pic16_emitcode ("pop","_bp");
        }
     }
+#endif
 
     /* restore the register bank  */    
     if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
@@ -3071,20 +3149,28 @@ static void genEndFunction (iCode *ic)
         if (IFFUNC_ISCRITICAL(sym->type))
             pic16_emitcode("setb","ea");
        
-       if (IFFUNC_CALLEESAVES(sym->type)) {
-           int i;
-           
-           /* if any registers used */
-           if (sym->regsUsed) {
+       /* if any registers used */
+       if (sym->regsUsed
+#if STACK_SUPPORT
+               && USE_STACK
+#endif
+       ) {
+         int i;
                /* save the registers used */
-               for ( i = sym->regsUsed->size ; i >= 0 ; i--) {
-                   if (bitVectBitValue(sym->regsUsed,i) ||
-                      (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) )
-                     pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname);
+               DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
+               for ( i = sym->regsUsed->size; i >= 0; i--) {
+                       if (bitVectBitValue(sym->regsUsed,i)) {
+//                             fprintf(stderr, "%s:%d function %s uses register %s\n",
+//                                             __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
+//                                             pic16_regWithIdx(i)->name);
+        
+                               pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
+                                       &pic16_pc_preinc1,
+                                       PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
+                       }
                }
-           }
-           
        }
+       
 
        /* if debug then send end of function */
        if (currFunc) {
@@ -3104,20 +3190,14 @@ static void genEndFunction (iCode *ic)
         * and function is not main() */
         
        if(USE_STACK && strcmp(sym->name, "main")) {
-               /* restore stack frame */
-               if(STACK_MODEL_LARGE)
+               if(!options.ommitFramePtr || sym->regsUsed) {
+                       /* restore stack frame */
+                       if(STACK_MODEL_LARGE)
+                               pic16_emitpcode(POC_MOVFF,
+                                       pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2h, 0));
                        pic16_emitpcode(POC_MOVFF,
-                               pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2h ));
-               pic16_emitpcode(POC_MOVFF,
-                               pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2l ));
-
-/*
-       * I added this because of a mistake in the stack pointers design
-       * They should be removed though
-       
-                       pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc2, &pic16_pc_fsr2h));
-               pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc2, &pic16_pc_fsr2l));
-*/
+                                       pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2l, 0));
+               }
        }
 #endif
 
@@ -3169,7 +3249,7 @@ static void genRet (iCode *ic)
          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
        }
        if(size) {
-         pic16_emitpcode(POC_MOVWF,popRegFromIdx(offset + pic16_Gstack_base_addr));
+         pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr));
        }
        offset++;
       }
@@ -4469,11 +4549,11 @@ static void genCmp (operand *left,operand *right,
       /* Sigh. thus sucks... */
       if(size) {
        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
-       pic16_emitpcode(POC_MOVWF, popRegFromIdx(pic16_Gstack_base_addr));
+       pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
-       pic16_emitpcode(POC_XORWF, popRegFromIdx(pic16_Gstack_base_addr));
+       pic16_emitpcode(POC_XORWF, pic16_popRegFromIdx(pic16_Gstack_base_addr));
        pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
-       pic16_emitpcode(POC_SUBFW, popRegFromIdx(pic16_Gstack_base_addr));
+       pic16_emitpcode(POC_SUBFW, pic16_popRegFromIdx(pic16_Gstack_base_addr));
       } else {
        /* Signed char comparison */
        /* Special thanks to Nikolai Golovchenko for this snippet */
@@ -6231,7 +6311,8 @@ static void genInline (iCode *ic)
             *bp++ = '\0';
 
            if(*bp1)
-             pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
+             pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL));       //pic16_AssembleLine(bp1, 0));
+                                       // inline directly, no process
             bp1 = bp;
         } else {
             if (*bp == ':') {
@@ -6245,7 +6326,7 @@ static void genInline (iCode *ic)
         }
     }
     if ((bp1 != bp) && *bp1)
-      pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1));
+      pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL));              //pic16_AssembleLine(bp1, 0));
 
     Safe_free(buffer);
 
@@ -8512,6 +8593,7 @@ static void genConstPointerGet (operand *left,
 
   poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
     
+  /* this performs a goto to the specified address -- Why not to use pointer? -- VR */
   pic16_emitpcode(poc,pic16_popGet(AOP(left),1));
   pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath));
   pic16_emitpcode(poc,pic16_popGet(AOP(left),0));
@@ -8800,7 +8882,7 @@ static void genDataPointerSet(operand *right,
     while (size--) {
       if (offset) {
        sprintf(buffer,"(%s + %d)",l,offset);
-       fprintf(stderr,"oops  %s\n",buffer);
+       fprintf(stderr,"%s:%d: oops  %s\n",__FILE__, __LINE__, buffer);
       } else
        sprintf(buffer,"%s",l);
 
@@ -9355,7 +9437,7 @@ static void genAddrOf (iCode *ic)
   operand *result, *left;
   int size;
   symbol *sym; // = OP_SYMBOL(IC_LEFT(ic));
-  pCodeOp *pcop0, *pcop1;
+  pCodeOp *pcop0, *pcop1, *pcop2;
 
        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
@@ -9366,20 +9448,31 @@ static void genAddrOf (iCode *ic)
 
        size = AOP_SIZE(IC_RESULT(ic));
 
-       /* Assume that what we want the address of is in direct addressing space
+       if(pic16_debug_verbose) {
+               fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n",
+                       __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype)));
+       }
+       
+       /* Assume that what we want the address of is in data space
         * since there is no stack on the PIC, yet! -- VR */
+       /* low */
+       pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
 
-       pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, 0));
-       pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, 0));
-#if 0
-       pcop0 = pic16_newpCodeOp(sym->rname, PO_IMMEDIATE);
-       PCOI(pcop0)->offset = 0;
-       PCOI(pcop0)->index = 0;
-       pcop1 = pic16_newpCodeOp(sym->rname, PO_IMMEDIATE);
-       PCOI(pcop1)->offset = 1;
-       PCOI(pcop1)->index = 0;
-#endif
+       /* high */
+       pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
+       
+       /* upper */
+       pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
+       
 
+       if (size == 3) {
+               pic16_emitpcode(POC_MOVLW, pcop0);
+               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+               pic16_emitpcode(POC_MOVLW, pcop1);
+               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+               pic16_emitpcode(POC_MOVLW, pcop2);
+               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
+       } else
        if (size == 2) {
                pic16_emitpcode(POC_MOVLW, pcop0);
                pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
@@ -9748,149 +9841,174 @@ release:
 /*-----------------------------------------------------------------*/
 static void genCast (iCode *ic)
 {
-    operand *result = IC_RESULT(ic);
-    sym_link *ctype = operandType(IC_LEFT(ic));
-    sym_link *rtype = operandType(IC_RIGHT(ic));
-    operand *right = IC_RIGHT(ic);
-    int size, offset ;
-
-    DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* if they are equivalent then do nothing */
-    if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
-        return ;
-
-    pic16_aopOp(right,ic,FALSE) ;
-    pic16_aopOp(result,ic,FALSE);
-
-    DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
-
-    /* if the result is a bit */
-    if (AOP_TYPE(result) == AOP_CRY) {
-        /* if the right size is a literal then
-        we know what the value is */
-      DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
-        if (AOP_TYPE(right) == AOP_LIT) {
-
-         pic16_emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
-                     pic16_popGet(AOP(result),0));
+  operand *result = IC_RESULT(ic);
+  sym_link *ctype = operandType(IC_LEFT(ic));
+  sym_link *rtype = operandType(IC_RIGHT(ic));
+  operand *right = IC_RIGHT(ic);
+  int size, offset ;
 
-            if (((int) operandLitValue(right))) 
-             pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
-                      AOP(result)->aopu.aop_dir,
-                      AOP(result)->aopu.aop_dir);
-            else
-             pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
-                      AOP(result)->aopu.aop_dir,
-                      AOP(result)->aopu.aop_dir);
+       DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
+       /* if they are equivalent then do nothing */
+       if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
+               return ;
 
-            goto release;
-        }
+       pic16_aopOp(right,ic,FALSE) ;
+       pic16_aopOp(result,ic,FALSE);
 
-        /* the right is also a bit variable */
-        if (AOP_TYPE(right) == AOP_CRY) {
+       DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
 
-         emitCLRC;
-         pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
+       /* if the result is a bit */
+       if (AOP_TYPE(result) == AOP_CRY) {
+       
+               /* if the right size is a literal then
+                * we know what the value is */
+               DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+               if (AOP_TYPE(right) == AOP_LIT) {
+                       pic16_emitpcode(  ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF),
+                               pic16_popGet(AOP(result),0));
+
+                       if (((int) operandLitValue(right))) 
+                               pic16_emitcode("bsf","(%s >> 3), (%s & 7)",
+                                       AOP(result)->aopu.aop_dir,
+                                       AOP(result)->aopu.aop_dir);
+                       else
+                               pic16_emitcode("bcf","(%s >> 3), (%s & 7)",
+                                       AOP(result)->aopu.aop_dir,
+                                       AOP(result)->aopu.aop_dir);
+                       goto release;
+               }
 
-         pic16_emitcode("clrc","");
-         pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
-                  AOP(right)->aopu.aop_dir,
-                  AOP(right)->aopu.aop_dir);
-            pic16_aopPut(AOP(result),"c",0);
-            goto release ;
-        }
+               /* the right is also a bit variable */
+               if (AOP_TYPE(right) == AOP_CRY) {
+                       emitCLRC;
+                       pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
+
+                       pic16_emitcode("clrc","");
+                       pic16_emitcode("btfsc","(%s >> 3), (%s & 7)",
+                               AOP(right)->aopu.aop_dir,
+                               AOP(right)->aopu.aop_dir);
+                       pic16_aopPut(AOP(result),"c",0);
+                       goto release ;
+               }
 
-        /* we need to or */
-       if (AOP_TYPE(right) == AOP_REG) {
-         pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
-         pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
-         pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
+               /* we need to or */
+               if (AOP_TYPE(right) == AOP_REG) {
+                       pic16_emitpcode(POC_BCF,    pic16_popGet(AOP(result),0));
+                       pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0));
+                       pic16_emitpcode(POC_BSF,    pic16_popGet(AOP(result),0));
+               }
+               pic16_toBoolean(right);
+               pic16_aopPut(AOP(result),"a",0);
+               goto release ;
        }
-       pic16_toBoolean(right);
-       pic16_aopPut(AOP(result),"a",0);
-        goto release ;
-    }
 
-    if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
-      int offset = 1;
-      size = AOP_SIZE(result);
+       if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) {
+         int offset = 1;
 
-      DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
+               size = AOP_SIZE(result);
 
-      pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
-      pic16_emitpcode(POC_INCF,   pic16_popGet(AOP(result),0));
+               DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-      while (size--)
-       pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset++));
+               pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),0));
+               pic16_emitpcode(POC_BTFSC,  pic16_popGet(AOP(right),0));
+               pic16_emitpcode(POC_INCF,   pic16_popGet(AOP(result),0));
 
-      goto release;
-    }
+               while (size--)
+                       pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset++));
 
-    /* if they are the same size : or less */
-    if (AOP_SIZE(result) <= AOP_SIZE(right)) {
+               goto release;
+       }
 
-        /* if they are in the same place */
-      if (pic16_sameRegs(AOP(right),AOP(result)))
-       goto release;
+       /* if they are the same size : or less */
+       if (AOP_SIZE(result) <= AOP_SIZE(right)) {
+
+               /* if they are in the same place */
+               if (pic16_sameRegs(AOP(right),AOP(result)))
+                       goto release;
 
-      DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
+               DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
 #if 0
-      if (IS_PTR_CONST(rtype))
+               if (IS_PTR_CONST(rtype))
 #else
-      if (IS_CODEPTR(rtype))
+               if (IS_CODEPTR(rtype))
 #endif
-       DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
+                       DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__);
+
 #if 0
-      if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
+               if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
 #else
-      if (IS_CODEPTR(operandType(IC_RESULT(ic))))
+               if (IS_CODEPTR(operandType(IC_RESULT(ic))))
 #endif
-       DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
-
-      if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
-       pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
-       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
-       pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
-       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
-        if(AOP_SIZE(result) <2)
-         fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
-
-      } else {
-
-        /* if they in different places then copy */
-        size = AOP_SIZE(result);
-        offset = 0 ;
-        while (size--) {
-         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
-         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
-
-         //pic16_aopPut(AOP(result),
-         // pic16_aopGet(AOP(right),offset,FALSE,FALSE),
-         // offset);
-
-         offset++;
-        }
-      }
-      goto release;
-    }
+                       DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__);
 
+#if 0
+               if(AOP_TYPE(right) == AOP_IMMD) {
+                 pCodeOp *pcop0, *pcop1, *pcop2;
+                 symbol *sym = OP_SYMBOL( right );
+
+                       size = AOP_SIZE(result);
+                       /* low */
+                       pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
+                       /* high */
+                       pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
+                       /* upper */
+                       pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype))));
+       
+                       if (size == 3) {
+                               pic16_emitpcode(POC_MOVLW, pcop0);
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+                               pic16_emitpcode(POC_MOVLW, pcop1);
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+                               pic16_emitpcode(POC_MOVLW, pcop2);
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2));
+                       } else
+                       if (size == 2) {
+                               pic16_emitpcode(POC_MOVLW, pcop0);
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
+                               pic16_emitpcode(POC_MOVLW, pcop1);
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
+                       } else {
+                               pic16_emitpcode(POC_MOVLW, pcop0);
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
+                       }
+               } else
+#endif
+               if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
+                       pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0));
+                       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
+                       pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1));
+                       pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1));
+                       if(AOP_SIZE(result) <2)
+                               fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
+               } else {
+                       /* if they in different places then copy */
+                       size = AOP_SIZE(result);
+                       offset = 0 ;
+                       while (size--) {
+                               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset));
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset));
+                               offset++;
+                       }
+               }
+               goto release;
+       }
 
-    /* if the result is of type pointer */
-    if (IS_PTR(ctype)) {
+       /* if the result is of type pointer */
+       if (IS_PTR(ctype)) {
+         int p_type;
+         sym_link *type = operandType(right);
+         sym_link *etype = getSpec(type);
 
-       int p_type;
-       sym_link *type = operandType(right);
-       sym_link *etype = getSpec(type);
-      DEBUGpic16_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
+               DEBUGpic16_emitcode("; ***","%s  %d - pointer cast",__FUNCTION__,__LINE__);
 
-       /* pointer to generic pointer */
-       if (IS_GENPTR(ctype)) {
-           char *l = zero;
+               /* pointer to generic pointer */
+               if (IS_GENPTR(ctype)) {
+                 char *l = zero;
            
-           if (IS_PTR(type)) 
-               p_type = DCL_TYPE(type);
-           else {
+                       if (IS_PTR(type)) 
+                               p_type = DCL_TYPE(type);
+                       else {
                /* we have to go by the storage class */
                p_type = PTR_TYPE(SPEC_OCLS(etype));
 
@@ -9998,7 +10116,7 @@ static void genCast (iCode *ic)
       while (size--)
        pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(result),offset++));
     } else {
-      /* we need to extend the sign :{ */
+      /* we need to extend the sign :( */
 
       if(size == 1) {
        /* Save one instruction of casting char to int */
@@ -10196,13 +10314,20 @@ void genpic16Code (iCode *lic)
                         ic->level,ic->block);
                _G.debugLine = 0;
            }
-           pic16_addpCode2pBlock(pb,
-                           pic16_newpCodeCSource(ic->lineno, 
-                                           ic->filename, 
-                                           printCLine(ic->filename, ic->lineno)));
+           
+           if(!options.noCcodeInAsm) {
+               pic16_addpCode2pBlock(pb,
+                       pic16_newpCodeCSource(ic->lineno, ic->filename, 
+                               printCLine(ic->filename, ic->lineno)));
+           }
 
            cln = ic->lineno ;
        }
+       
+       if(options.iCodeInAsm) {
+               /* insert here code to print iCode as comment */
+       }
+       
        /* if the result is marked as
           spilt and rematerializable or code for
           this has already been generated then
index c37eebd69d8b8d1ba5ddf73915059a848fa1268a..54ed8d2061b62855ab491700c6a41642f602cafb 100644 (file)
@@ -163,12 +163,13 @@ pCodeOp *pic16_popGetLabel(unsigned int key);
 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
 pCodeOp *pic16_popCopyGPR2Bit(pCodeOp *pc, int bitval);
 pCodeOp *pic16_popGetLit(unsigned int lit);
-pCodeOp *pic16_popGetLit2(unsigned int lit, unsigned int lit2);
+pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2);
 pCodeOp *popGetWithString(char *str);
 pCodeOp *pic16_popGet (asmop *aop, int offset);//, bool bit16, bool dname);
 pCodeOp *pic16_popGetTempReg(void);
 void pic16_popReleaseTempReg(pCodeOp *pcop);
 
+pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc);
 
 void pic16_aopPut (asmop *aop, char *s, int offset);
 void pic16_outAcc(operand *result);
index 0d0407d06896c9e19ade81b9e012c463345050c0..88f4929123325f1bc4bc18ef2227779427db99fa 100644 (file)
@@ -69,7 +69,7 @@ extern void printPublics (FILE * afile);
 extern void printChar (FILE * ofile, char *s, int plen);
 void  pic16_pCodeInitRegisters(void);
 pCodeOp *pic16_popGetLit(unsigned int lit);
-pCodeOp *pic16_popGetLit2(unsigned int lit, unsigned int lit2);
+pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2);
 pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst);
 
@@ -112,156 +112,142 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
 
 //     fprintf(stderr, "%s:%d map name= %s\n", __FUNCTION__, __LINE__, map->sname);
        
-  if (addPublics)
-
-    fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
-
-  /* print the area name */
-  for (sym = setFirstItem (map->syms); sym;
-       sym = setNextItem (map->syms))
-    {
+       if(addPublics)
+               fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
 
+               /* print the area name */
+       for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
 #if 0
-       fprintf(stderr, "\t%s: sym: %s\tused: %d\n", map->sname, sym->name, sym->used);
-       printTypeChain( sym->type, stderr );
-       printf("\n");
+               fprintf(stderr, "\t%s: sym: %s\tused: %d\n", map->sname, sym->name, sym->used);
+               printTypeChain( sym->type, stderr );
+               printf("\n");
 #endif
-
-      /* if extern then add to externs */
-      if (IS_EXTERN (sym->etype)) {
-       addSetHead(&externs, sym);
-       continue;
-      }
-
-      /* if allocation required check is needed
-         then check if the symbol really requires
-         allocation only for local variables */
-      if (arFlag && !IS_AGGREGATE (sym->type) &&
-         !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
-         !sym->allocreq && sym->level)
-       continue;
-
-      /* if global variable & not static or extern
-         and addPublics allowed then add it to the public set */
-      if ((sym->used) && (sym->level == 0 ||
-          (sym->_isparm && !IS_REGPARM (sym->etype))) &&
-         addPublics &&
-         !IS_STATIC (sym->etype))
-       addSetHead (&publics, sym);
-
-      /* if extern then do nothing or is a function
-         then do nothing */
-      if (IS_FUNC (sym->type))
-       continue;
+               /* if extern then add to externs */
+               if (IS_EXTERN (sym->etype)) {
+//                     if(sym->used)                           // fixme
+                               addSetHead(&externs, sym);
+                       continue;
+               }
+               /* if allocation required check is needed
+                *  then check if the symbol really requires
+                * allocation only for local variables */
+                if (arFlag && !IS_AGGREGATE (sym->type) &&
+                       !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
+                       !sym->allocreq && sym->level)
+                       
+                       continue;
+
+               /* if global variable & not static or extern
+                * and addPublics allowed then add it to the public set */
+               if ((sym->used) && (sym->level == 0 ||
+                       (sym->_isparm && !IS_REGPARM (sym->etype))) &&
+                       addPublics &&
+                       !IS_STATIC (sym->etype) && !IS_FUNC(sym->type))
+               
+                       addSetHead (&publics, sym);
+
+               /* if extern then do nothing or is a function
+                * then do nothing */
+               if (IS_FUNC (sym->type) && !IS_STATIC(sym->etype)) {
+                       if(SPEC_OCLS(sym->etype) == code) {
+//                             fprintf(stderr, "%s:%d: symbol added: %s\n", __FILE__, __LINE__, sym->rname);
+                               addSetHead(&publics, sym);
+                       }
+                       continue;
+               }
 
 #if 0
-      /* print extra debug info if required */
-      if (options.debug || sym->level == 0)
-       {
-
-         cdbWriteSymbol (sym); //, cdbFile, FALSE, FALSE);
-
-         if (!sym->level)      /* global */
-           if (IS_STATIC (sym->etype))
-             fprintf (map->oFile, "F%s_", moduleName);         /* scope is file */
-           else
-             fprintf (map->oFile, "G_");       /* scope is global */
-         else
-           /* symbol is local */
-           fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
-         fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
-       }
+               /* print extra debug info if required */
+               if (options.debug || sym->level == 0) {
+                       cdbWriteSymbol (sym);   //, cdbFile, FALSE, FALSE);
+
+                       if (!sym->level)        /* global */
+                               if (IS_STATIC (sym->etype))
+                                       fprintf (map->oFile, "F%s_", moduleName);               /* scope is file */
+                               else
+                                       fprintf (map->oFile, "G_");     /* scope is global */
+                       else
+                               /* symbol is local */
+                               fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
+                       fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
+               }
 #endif
 
-       /* FIXME -- VR
-        * The equates are nice, but do not allow relocatable objects to
-        * be created in the form that I (VR) want to make SDCC to work */
+               /* FIXME -- VR
+                * The equates are nice, but do not allow relocatable objects to
+                * be created in the form that I (VR) want to make SDCC to work */
 
-      /* if is has an absolute address then generate
-         an equate for this no need to allocate space */
-      if (SPEC_ABSA (sym->etype))
-       {
-         //if (options.debug || sym->level == 0)
-//       fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
-//             sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
-
-         fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
-                  sym->rname,
-                  SPEC_ADDR (sym->etype));
+               /* if is has an absolute address then generate
+               an equate for this no need to allocate space */
+               if (SPEC_ABSA (sym->etype)) {
+//                     if (options.debug || sym->level == 0)
+//                             fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
+//                                     sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
 
+                       fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
+                               sym->rname,
+                               SPEC_ADDR (sym->etype));
 #if 1
-         /* emit only if it is global */
-         if(sym->level == 0) {
-           regs *reg;
-           operand *op;
-
-//             fprintf(stderr, "%s: implicit add of symbol = %s\n", __FUNCTION__, sym->name);
-               op = operandFromSymbol( sym );
-               reg = pic16_allocDirReg( op );
-               if(reg) {
-                       //continue;
-
-                       checkAddReg(&pic16_fix_udata, reg);
-                       /* and add to globals list */
-                       addSetHead(&publics, sym);
-               }
-         }
+                       /* emit only if it is global */
+                       if(sym->level == 0) {
+                         regs *reg;
+                         operand *op;
+//                             fprintf(stderr, "%s: implicit add of symbol = %s\n", __FUNCTION__, sym->name);
+                               op = operandFromSymbol( sym );
+                               reg = pic16_allocDirReg( op );
+                               if(reg) {
+                                       //continue;
+                                       checkAddReg(&pic16_fix_udata, reg);
+                                       /* and add to globals list */
+                                       addSetHead(&publics, sym);
+                               }
+                       }
 #endif
-       }
-      else
-       {
-         /* allocate space */
-
-         /* If this is a bit variable, then allocate storage after 8 bits have been declared */
-         /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
-         /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
-         if (IS_BITVAR (sym->etype))
-           {
-             bitvars++;
-           }
-         else
-           {
-             fprintf (map->oFile, "\t%s\n", sym->rname);
-             if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
-               {
-                 for (i = 1; i < size; i++)
-                   fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
+               } else {
+                       /* allocate space */
+                       /* If this is a bit variable, then allocate storage after 8 bits have been declared */
+                       /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
+                       /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
+                       if (IS_BITVAR (sym->etype)) {
+                               bitvars++;
+                       } else {
+                               fprintf (map->oFile, "\t%s\n", sym->rname);
+                               if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1) {
+                                       for (i = 1; i < size; i++)
+                                               fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
+                               }
+                       }
+//                     fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
                }
-           }
-         //fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
-       }
        
+               /* FIXME -- VR Fix the following, so that syms to be placed
+                * in the idata section and let linker decide about their fate */
 
-       /* FIXME -- VR Fix the following, so that syms to be placed
-        * in the idata section and let linker decide about their fate */
-
-       /* if it has an initial value then do it only if
-          it is a global variable */
-//     if(sym->ival && sym->level == 0) 
-               
+               /* if it has an initial value then do it only if
+                       it is a global variable */
 
 #if 1
-       if (sym->ival && sym->level == 0) {
-           ast *ival = NULL;
-
-//             if(SPEC_OCLS(sym->etype)==data) {
-//                     fprintf(stderr, "%s: sym %s placed in data\n", map->sname, sym->name);
-//             }
-
-//             fprintf(stderr, "'%s': sym '%s' has initial value\n", map->sname, sym->name);
-
-           if (IS_AGGREGATE (sym->type))
-               ival = initAggregates (sym, sym->ival, NULL);
-           else
-               ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
-                               decorateType (resolveSymbols (list2expr (sym->ival))));
-           codeOutFile = statsg->oFile;
-           GcurMemmap = statsg;
-           eBBlockFromiCode (iCodeFromAst (ival));
-           sym->ival = NULL;
-       }
+               if (sym->ival && sym->level == 0) {
+                 ast *ival = NULL;
+
+//                     if(SPEC_OCLS(sym->etype)==data) {
+//                             fprintf(stderr, "%s: sym %s placed in data\n", map->sname, sym->name);
+//                     }
+
+//                     fprintf(stderr, "'%s': sym '%s' has initial value\n", map->sname, sym->name);
+
+                       if (IS_AGGREGATE (sym->type))
+                               ival = initAggregates (sym, sym->ival, NULL);
+                       else
+                               ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
+                                       decorateType (resolveSymbols (list2expr (sym->ival))));
+                       codeOutFile = statsg->oFile;
+                       GcurMemmap = statsg;
+                       eBBlockFromiCode (iCodeFromAst (ival));
+                       sym->ival = NULL;
+               }
 #endif
-    }
+       }
 }
 
 
@@ -610,25 +596,15 @@ pic16emitMaps ()
 static void
 pic16createInterruptVect (FILE * vFile)
 {
-  mainf = newSymbol ("main", 0);
-  mainf->block = 0;
-
-  /* only if the main function exists */
-  if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
-    {
-      if (!options.cc_only)
-       werror (E_NO_MAIN);
-      return;
-    }
-
-  /* if the main is only a prototype ie. no body then do nothing */
-  if (!IFFUNC_HASBODY(mainf->type))
-    {
-      /* if ! compile only then main function should be present */
-      if (!options.cc_only)
-       werror (E_NO_MAIN);
-      return;
-    }
+       /* if the main is only a prototype ie. no body then do nothing */
+#if 0
+       if (!IFFUNC_HASBODY(mainf->type)) {
+               /* if ! compile only then main function should be present */
+               if (!options.cc_only)
+                       werror (E_NO_MAIN);
+               return;
+       }
+#endif
 
        if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
                fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
@@ -661,15 +637,15 @@ pic16initialComments (FILE * afile)
 /* printPublics - generates global declarations for publics        */
 /*-----------------------------------------------------------------*/
 static void
-pic16printPublics (FILE * afile)
+pic16printPublics (FILE *afile)
 {
   symbol *sym;
 
        fprintf (afile, "%s", iComments2);
-       fprintf (afile, "; publics variables in this module\n");
+       fprintf (afile, "; public variables in this module\n");
        fprintf (afile, "%s", iComments2);
 
-       for (sym = setFirstItem (publics); sym; sym = setNextItem (publics))
+       for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
                fprintf(afile, "\tglobal %s\n", sym->rname);
 }
 
@@ -682,11 +658,14 @@ pic16_printExterns(FILE *afile)
   symbol *sym;
 
        fprintf(afile, "%s", iComments2);
-       fprintf(afile, "; extern variables to this module\n");
+       fprintf(afile, "; extern variables in this module\n");
        fprintf(afile, "%s", iComments2);
        
        for(sym = setFirstItem(externs); sym; sym = setNextItem(externs))
                fprintf(afile, "\textern %s\n", sym->rname);
+
+       for(sym = setFirstItem(pic16_builtin_functions); sym; sym = setNextItem(pic16_builtin_functions))
+               fprintf(afile, "\textern _%s\n", sym->name);
 }
 
 /*-----------------------------------------------------------------*/
@@ -805,74 +784,78 @@ pic16glue ()
   FILE *asmFile;
   FILE *ovrFile = tempfile();
 
-  addSetHead(&tmpfileSet,ovrFile);
-  pic16_pCodeInitRegisters();
-
-  if (mainf && IFFUNC_HASBODY(mainf->type)) {
-
-    pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
-    pic16_addpBlock(pb);
-
-    /* entry point @ start of CSEG */
-    pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
-    /* put in the call to main */
-    pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
 
-    if (options.mainreturn) {
+       mainf = newSymbol ("main", 0);
+       mainf->block = 0;
 
-      pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
-      pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
+       mainf = findSymWithLevel(SymbolTab, mainf);
+#if 0
+       /* only if the main function exists */
+       if (!(mainf = findSymWithLevel (SymbolTab, mainf))) {
+               if (!options.cc_only)
+                       werror (E_NO_MAIN);
+               return;
+       }
+#endif
 
-    } else {
+//     fprintf(stderr, "main function= %p (%s)\thas body= %d\n", mainf, (mainf?mainf->name:NULL), mainf?IFFUNC_HASBODY(mainf->type):-1);
 
-      pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
-      pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
+       addSetHead(&tmpfileSet,ovrFile);
+       pic16_pCodeInitRegisters();
 
-    }
-  }
-
-#if STACK_SUPPORT
-       if(USE_STACK) {
-         pBlock *pb = pic16_newpCodeChain(NULL, 'X', pic16_newpCodeCharP("; Setup stack & frame register"));
+       if (mainf && IFFUNC_HASBODY(mainf->type)) {
+         pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
 
                pic16_addpBlock(pb);
-               pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, pic16_popGetLit2(1, stackPos)));
-               pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR, pic16_popGetLit2(2, stackPos)));
 
-       }
-#endif
+               /* entry point @ start of CSEG */
+               pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup\t;VR1",-1));
 
+               if(USE_STACK) {
+                       pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
+                               pic16_popGetLit2(1, pic16_popGetLit(stackPos))));
+                       pic16_addpCode2pBlock(pb, pic16_newpCode(POC_LFSR,
+                               pic16_popGetLit2(2, pic16_popGetLit(stackPos))));
+               }
 
-  /* At this point we've got all the code in the form of pCode structures */
-  /* Now it needs to be rearranged into the order it should be placed in the */
-  /* code space */
+               /* put in the call to main */
+               pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
 
-  pic16_movepBlock2Head('P');              // Last
-  pic16_movepBlock2Head(code->dbName);
-  pic16_movepBlock2Head('X');
-  pic16_movepBlock2Head(statsg->dbName);   // First
+               if (options.mainreturn) {
+                       pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
+                       pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
+               } else {
+                       pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
+                       pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
+               }
+       }
 
+       /* At this point we've got all the code in the form of pCode structures */
+       /* Now it needs to be rearranged into the order it should be placed in the */
+       /* code space */
 
-  /* print the global struct definitions */
-  if (options.debug)
-    cdbStructBlock (0);        //,cdbFile);
+       pic16_movepBlock2Head('P');              // Last
+       pic16_movepBlock2Head(code->dbName);
+       pic16_movepBlock2Head('X');
+       pic16_movepBlock2Head(statsg->dbName);   // First
 
-  vFile = tempfile();
-  /* PENDING: this isnt the best place but it will do */
-  if (port->general.glue_up_main) {
-    /* create the interrupt vector table */
+       /* print the global struct definitions */
+//     if (options.debug)
+//             cdbStructBlock (0);     //,cdbFile);
 
-       pic16createInterruptVect (vFile);
-  }
+       vFile = tempfile();
+       /* PENDING: this isnt the best place but it will do */
+       if (port->general.glue_up_main) {
+               /* create the interrupt vector table */
+               pic16createInterruptVect (vFile);
+       }
 
-  addSetHead(&tmpfileSet,vFile);
+       addSetHead(&tmpfileSet,vFile);
     
-  /* emit code for the all the variables declared */
-  pic16emitMaps ();
-  /* do the overlay segments */
-  pic16emitOverlay(ovrFile);
-
-
+       /* emit code for the all the variables declared */
+       pic16emitMaps ();
+       /* do the overlay segments */
+       pic16emitOverlay(ovrFile);
        pic16_AnalyzepCode('*');
 
 #if 0
@@ -886,200 +869,191 @@ pic16glue ()
        }
 #endif
 
-  pic16_InlinepCode();
-  pic16_AnalyzepCode('*');
-  pic16_pcode_test();
+       pic16_InlinepCode();
+       pic16_AnalyzepCode('*');
 
-  /* now put it all together into the assembler file */
-  /* create the assembler file name */
-    
-  if ((noAssemble || options.c1mode)  && fullDstFileName)
-    {
-      sprintf (buffer, fullDstFileName);
-    }
-  else
-    {
-      sprintf (buffer, dstFileName);
-      strcat (buffer, ".asm");
-    }
+       if(pic16_debug_verbose)
+               pic16_pcode_test();
 
-  if (!(asmFile = fopen (buffer, "w"))) {
-    werror (E_FILE_OPEN_ERR, buffer);
-    exit (1);
-  }
+       /* now put it all together into the assembler file */
+       /* create the assembler file name */
+       if ((noAssemble || options.c1mode)  && fullDstFileName) {
+               sprintf (buffer, fullDstFileName);
+       } else {
+               sprintf (buffer, dstFileName);
+               strcat (buffer, ".asm");
+       }
+
+       if (!(asmFile = fopen (buffer, "w"))) {
+               werror (E_FILE_OPEN_ERR, buffer);
+               exit (1);
+       }
     
-  /* initial comments */
-  pic16initialComments (asmFile);
+       /* initial comments */
+       pic16initialComments (asmFile);
     
-  /* print module name */
-  fprintf (asmFile, ";\t.module %s\n", moduleName);
+       /* print module name */
+       fprintf (asmFile, ";\t.module %s\n", moduleName);
     
-  /* Let the port generate any global directives, etc. */
-  if (port->genAssemblerPreamble)
-    {
-      port->genAssemblerPreamble(asmFile);
-    }
+       /* Let the port generate any global directives, etc. */
+       if (port->genAssemblerPreamble) {
+               port->genAssemblerPreamble(asmFile);
+       }
     
-  /* print the extern variables to this module */
-  pic16_printExterns(asmFile);
+       /* print the extern variables to this module */
+       pic16_printExterns(asmFile);
   
-  /* print the global variables in this module */
-  pic16printPublics (asmFile);
+       /* print the global variables in this module */
+       pic16printPublics (asmFile);
 
 #if 0
-  /* copy the sfr segment */
-  fprintf (asmFile, "%s", iComments2);
-  fprintf (asmFile, "; special function registers\n");
-  fprintf (asmFile, "%s", iComments2);
-  copyFile (asmFile, sfr->oFile);
+       /* copy the sfr segment */
+       fprintf (asmFile, "%s", iComments2);
+       fprintf (asmFile, "; special function registers\n");
+       fprintf (asmFile, "%s", iComments2);
+       copyFile (asmFile, sfr->oFile);
 #endif
     
 
-  /* Put all variables into a cblock */
-  pic16_AnalyzeBanking();
-  pic16_writeUsedRegs(asmFile);
-
-  /* create the overlay segments */
-  fprintf (asmFile, "%s", iComments2);
-  fprintf (asmFile, "; overlayable items in internal ram \n");
-  fprintf (asmFile, "%s", iComments2);    
-  copyFile (asmFile, ovrFile);
-
-  /* create the stack segment MOF */
-  if (mainf && IFFUNC_HASBODY(mainf->type)) {
-    fprintf (asmFile, "%s", iComments2);
-    fprintf (asmFile, "; Stack segment in internal ram \n");
-    fprintf (asmFile, "%s", iComments2);    
-    fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
-       ";__start__stack:\n;\t.ds\t1\n\n");
-  }
+       /* Put all variables into a cblock */
+       pic16_AnalyzeBanking();
+       pic16_writeUsedRegs(asmFile);
+
+       /* create the overlay segments */
+       fprintf (asmFile, "%s", iComments2);
+       fprintf (asmFile, "; overlayable items in internal ram \n");
+       fprintf (asmFile, "%s", iComments2);    
+       copyFile (asmFile, ovrFile);
+
+       /* create the stack segment MOF */
+       if (mainf && IFFUNC_HASBODY(mainf->type)) {
+               fprintf (asmFile, "%s", iComments2);
+               fprintf (asmFile, "; Stack segment in internal ram \n");
+               fprintf (asmFile, "%s", iComments2);    
+               fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
+                       ";__start__stack:\n;\t.ds\t1\n\n");
+       }
 
 #if 0
        /* no indirect data in pic */
-  /* create the idata segment */
-  fprintf (asmFile, "%s", iComments2);
-  fprintf (asmFile, "; indirectly addressable internal ram data\n");
-  fprintf (asmFile, "%s", iComments2);
-  copyFile (asmFile, idata->oFile);
+       /* create the idata segment */
+       fprintf (asmFile, "%s", iComments2);
+       fprintf (asmFile, "; indirectly addressable internal ram data\n");
+       fprintf (asmFile, "%s", iComments2);
+       copyFile (asmFile, idata->oFile);
 #endif
 
 
 #if 0
        /* no xdata in pic */
-  /* if external stack then reserve space of it */
-  if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
-    fprintf (asmFile, "%s", iComments2);
-    fprintf (asmFile, "; external stack \n");
-    fprintf (asmFile, "%s", iComments2);
-    fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
-    fprintf (asmFile,";\t.ds 256\n");
-  }
+       /* if external stack then reserve space of it */
+       if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
+               fprintf (asmFile, "%s", iComments2);
+               fprintf (asmFile, "; external stack \n");
+               fprintf (asmFile, "%s", iComments2);
+               fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
+               fprintf (asmFile,";\t.ds 256\n");
+       }
 #endif
 
 #if 0  
        /* no xdata in pic */
-  /* copy xtern ram data */
-  fprintf (asmFile, "%s", iComments2);
-  fprintf (asmFile, "; external ram data\n");
-  fprintf (asmFile, "%s", iComments2);
-  copyFile (asmFile, xdata->oFile);
+       /* copy xtern ram data */
+       fprintf (asmFile, "%s", iComments2);
+       fprintf (asmFile, "; external ram data\n");
+       fprintf (asmFile, "%s", iComments2);
+       copyFile (asmFile, xdata->oFile);
 #endif
 
-  /* copy the bit segment */
-  fprintf (asmFile, "%s", iComments2);
-  fprintf (asmFile, "; bit data\n");
-  fprintf (asmFile, "%s", iComments2);
-  copyFile (asmFile, bit->oFile);
-
+       /* copy the bit segment */
+       fprintf (asmFile, "%s", iComments2);
+       fprintf (asmFile, "; bit data\n");
+       fprintf (asmFile, "%s", iComments2);
+       copyFile (asmFile, bit->oFile);
 
-/* the following is commented out. the CODE directive will be
-   used instead before code */
-//  fprintf (asmFile, "\tORG 0\n");
 
-  /* copy the interrupt vector table */
-  if (mainf && IFFUNC_HASBODY(mainf->type)) {
-    fprintf (asmFile, "%s", iComments2);
-    fprintf (asmFile, "; interrupt vector \n");
-    fprintf (asmFile, "%s", iComments2);
-    copyFile (asmFile, vFile);
-  }
+       /* copy the interrupt vector table */
+       if(mainf && IFFUNC_HASBODY(mainf->type)) {
+               fprintf (asmFile, "%s", iComments2);
+               fprintf (asmFile, "; interrupt vector \n");
+               fprintf (asmFile, "%s", iComments2);
+               copyFile (asmFile, vFile);
+       }
     
-  /* copy global & static initialisations */
-  fprintf (asmFile, "%s", iComments2);
-  fprintf (asmFile, "; global & static initialisations\n");
-  fprintf (asmFile, "%s", iComments2);
+       /* copy global & static initialisations */
+       fprintf (asmFile, "%s", iComments2);
+       fprintf (asmFile, "; global & static initialisations\n");
+       fprintf (asmFile, "%s", iComments2);
     
 #if 0
-  /* FIXME 8051 Legacy -- VR */
-  /* Everywhere we generate a reference to the static_name area, 
-   * (which is currently only here), we immediately follow it with a 
-   * definition of the post_static_name area. This guarantees that
-   * the post_static_name area will immediately follow the static_name
-   * area.
-   */
-  fprintf (asmFile, ";\t.area %s\n", port->mem.static_name); /* MOF */
-  fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
-  fprintf (asmFile, ";\t.area %s\n", port->mem.static_name);
+       /* FIXME 8051 Legacy -- VR */
+       /* Everywhere we generate a reference to the static_name area, 
+       * (which is currently only here), we immediately follow it with a 
+       * definition of the post_static_name area. This guarantees that
+       * the post_static_name area will immediately follow the static_name
+       * area.
+       */
+       fprintf (asmFile, ";\t.area %s\n", port->mem.static_name); /* MOF */
+       fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
+       fprintf (asmFile, ";\t.area %s\n", port->mem.static_name);
 #endif
+       /* copy over code */
+       fprintf (asmFile, "%s", iComments2);
+       fprintf (asmFile, "\tcode\n");
+       fprintf (asmFile, "%s", iComments2);
+
 
-  if (mainf && IFFUNC_HASBODY(mainf->type)) {
-    fprintf (asmFile,"__sdcc_gsinit_startup:\n");
+       if(mainf && IFFUNC_HASBODY(mainf->type)) {
+               fprintf (asmFile,"__sdcc_gsinit_startup:\t\t;VRokas\n");
 
 #if 0
-       /* FIXME 8051 legacy (?!) - VR 20-Jun-2003 */
-    /* if external stack is specified then the
-       higher order byte of the xdatalocation is
-       going into P2 and the lower order going into
-       spx */
-    if (options.useXstack) {
-      fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
-             (((unsigned int)options.xdata_loc) >> 8) & 0xff);
-      fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
-             (unsigned int)options.xdata_loc & 0xff);
-    }
+               /* FIXME 8051 legacy (?!) - VR 20-Jun-2003 */
+               /* if external stack is specified then the
+                * higher order byte of the xdatalocation is
+                * going into P2 and the lower order going into */
+       
+               if (options.useXstack) {
+                       fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
+                                       (((unsigned int)options.xdata_loc) >> 8) & 0xff);
+                       fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
+                                       (unsigned int)options.xdata_loc & 0xff);
+               }
 #endif
+       }
 
-  }
+//     copyFile (stderr, code->oFile);
 
-  /* copy over code */
-  fprintf (asmFile, "%s", iComments2);
-  fprintf (asmFile, "\tcode\n");
-  fprintf (asmFile, "%s", iComments2);
-  fprintf (asmFile, ";\t.area %s\n", port->mem.code_name);
 
-  if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
-    {
-      /* This code is generated in the post-static area.
-       * This area is guaranteed to follow the static area
-       * by the ugly shucking and jiving about 20 lines ago.
-       */
-//      fprintf(asmFile, ";\t.area %s\n", port->mem.post_static_name);
-      fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
-    }
-       
+       if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type)) {
+               fprintf (asmFile,"\tgoto\t__sdcc_program_startup\t;VR2\n");
+       }
 
-  //copyFile (stderr, code->oFile);
 
-               fprintf(asmFile, "; I code from now on!\n");
+       fprintf(asmFile, "; I code from now on!\n");
        pic16_copypCode(asmFile, 'I');
 
+       fprintf(asmFile, "; A code from now on!\n");
+       pic16_copypCode(asmFile, 'A');
+
        
-//             fprintf(asmFile, "; dbName from now on!\n");
-       fprintf(asmFile, "__sdcc_program_startup:\n");
+       if(pic16_debug_verbose)
+               fprintf(asmFile, "; dbName from now on!\n");
        pic16_copypCode(asmFile, statsg->dbName);
 
+       if(pic16_debug_verbose)
                fprintf(asmFile, "; X code from now on!\n");
        pic16_copypCode(asmFile, 'X');
 
+       if(pic16_debug_verbose)
                fprintf(asmFile, "; M code from now on!\n");
        pic16_copypCode(asmFile, 'M');
 
+
        pic16_copypCode(asmFile, code->dbName);
 
        pic16_copypCode(asmFile, 'P');
 
        fprintf (asmFile,"\tend\n");
-
        fclose (asmFile);
 
        rm_tmpfiles();
index 0eed2092696a7c76b8a8ca563778885f65461a4a..c3ce60ac1e220d17c0feb9e1f6827829ec12c25b 100644 (file)
@@ -63,6 +63,7 @@ static char *_pic16_keywords[] =
   "_xdata",
   "_pdata",
   "_idata",
+  "_naked",
   NULL
 };
 
@@ -117,10 +118,13 @@ _pic16_regparm (sym_link * l)
 }
 
 
+set *absSymSet;
+
 static int
 _process_pragma(const char *sz)
 {
   static const char *WHITE = " \t";
+  
   char *ptr = strtok((char *)sz, WHITE);
 
        if (startsWith (ptr, "maxram")) {
@@ -143,9 +147,29 @@ _process_pragma(const char *sz)
 //             fprintf(stderr, "Initializing stack pointer to 0x%x\n", (int)floatFromVal(constVal(stackPos)));
                stackPosVal = constVal( stackPosS );
                stackPos = (unsigned int)floatFromVal( stackPosVal );
+
+         return 0;
        }
+       
+       if(startsWith(ptr, "code")) {
+         char *symname = strtok((char *)NULL, WHITE);
+         char *location = strtok((char *)NULL, WHITE);
+         absSym *absS;
+         value *addr;
 
-  return 0;
+               absS = Safe_calloc(1, sizeof(absSym));
+               absS->name = Safe_strdup( symname );
+               addr = constVal( location );
+               absS->address = (unsigned int)floatFromVal( addr );
+
+               addSet(&absSymSet, absS);
+               fprintf(stderr, "%s:%d symbol %s will be placed in location 0x%06x in code memory\n",
+                       __FILE__, __LINE__, symname, absS->address);
+
+         return 0;
+       }         
+
+  return 1;
 }
 
 #define REP_UDATA      "--preplace-udata-with="
@@ -172,6 +196,8 @@ _process_pragma(const char *sz)
 
 
 extern int pic16_debug_verbose;
+extern int pic16_ralloc_debug;
+extern int pic16_pcode_verbose;
 
 OPTION pic16_optionsTable[]= {
        { 0,    "--pgen-banksel",       &pic16_options.gen_banksel,     "generate BANKSEL assembler directives"},
@@ -183,6 +209,9 @@ OPTION pic16_optionsTable[]= {
        { 0,    STACK_MODEL,    NULL,   "use stack model 'small' (default) or 'large'"},
 
        { 0,    "--debug-xtra",         &pic16_debug_verbose,   "show more debug info in assembly output"},
+       { 0,    "--debug-ralloc",       &pic16_ralloc_debug,    "dump register allocator debug file *.d"},
+       { 0,    "--pcode-verbose",      &pic16_pcode_verbose,   "dump pcode related info"},
+               
        { 0,    REP_UDATA,      NULL,   "Place udata variables at another section: udata_acs, udata_ovr, udata_shr"},
 
 #if 0
@@ -375,6 +404,8 @@ _pic16_finaliseOptions (void)
        port->mem.default_local_map = data;
        port->mem.default_globl_map = data;
 
+       options.all_callee_saves = 1;           // always callee saves
+
        setMainValue("mcu", pic16_processor_base_name() );
        addSet(&preArgvSet, Safe_strdup("-DMCU={mcu}"));
 }
@@ -473,10 +504,10 @@ _pic16_getRegName (struct regs *reg)
 }
 
 
-#if 0
+#if 1
 static  char *_pic16_mangleFunctionName(char *sz)
 {
-       fprintf(stderr, "mangled function name: %s\n", sz);
+//     fprintf(stderr, "mangled function name: %s\n", sz);
 
   return sz;
 }
@@ -736,7 +767,7 @@ PORT pic16_port =
   _pic16_reset_regparm,
   _pic16_regparm,
   _process_pragma,                             /* process a pragma */
-  NULL,                                //_pic16_mangleFunctionName,                            /* mangles function name */
+  _pic16_mangleFunctionName,                           /* mangles function name */
   _hasNativeMulFor,
   hasExtBitOp,                 /* hasExtBitOp */
   oclsExpense,                 /* oclsExpense */
index b58617272225a2fec123ac399522b2d0f3e9507e..087476d0a230a4dcb21e036d2ad892daed5cb97e 100644 (file)
@@ -27,4 +27,12 @@ typedef struct {
        unsigned int addr_udatashr;
 } pic16_sectioninfo_t;
 
+typedef struct absSym {
+       char *name;
+       unsigned int address;
+} absSym;
+
+extern set *absSymSet;
+
+
 #endif
index 1623b998ee4d3545b30175c5f8973a01a2772710..d6d80458138cfb69579523d8922b23e4d52c58d7 100644 (file)
@@ -26,6 +26,7 @@
 #include "newalloc.h"
 
 
+#include "main.h"
 #include "pcode.h"
 #include "pcodeflow.h"
 #include "ralloc.h"
@@ -52,12 +53,12 @@ static peepCommand peepCommands[] = {
 
 
 // Eventually this will go into device dependent files:
-pCodeOpReg pic16_pc_status    = {{PO_STATUS,  "_STATUS"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_status    = {{PO_STATUS,  "STATUS"}, -1, NULL,0,NULL};
 pCodeOpReg pic16_pc_indf0     = {{PO_INDF0,   "INDF0"}, -1, NULL,0,NULL};
 pCodeOpReg pic16_pc_fsr0      = {{PO_FSR0,    "FSR0"}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_intcon    = {{PO_INTCON,  "_INTCON"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_intcon    = {{PO_INTCON,  "INTCON"}, -1, NULL,0,NULL};
 pCodeOpReg pic16_pc_pcl       = {{PO_PCL,     "PCL"}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_pclath    = {{PO_PCLATH,  "_PCLATH"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_pclath    = {{PO_PCLATH,  "PCLATH"}, -1, NULL,0,NULL};
 pCodeOpReg pic16_pc_wreg      = {{PO_WREG,    "WREG"}, -1, NULL,0,NULL};
 pCodeOpReg pic16_pc_bsr       = {{PO_BSR,     "BSR"}, -1, NULL,0,NULL};
 
@@ -66,6 +67,7 @@ pCodeOpReg pic16_pc_fsr1h     = {{PO_FSR0,    "FSR1H"}, -1, NULL, 0, NULL};
 pCodeOpReg pic16_pc_fsr2l      = {{PO_FSR0,    "FSR2L"}, -1, NULL, 0, NULL};
 pCodeOpReg pic16_pc_fsr2h      = {{PO_FSR0,    "FSR2H"}, -1, NULL, 0, NULL};
 pCodeOpReg pic16_pc_postinc1   = {{PO_FSR0,    "POSTINC1"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_preinc1    = {{PO_FSR0,    "PREINC1"}, -1, NULL, 0, NULL};
 
 pCodeOpReg pic16_pc_plusw2     = {{PO_FSR0,    "PLUSW2"}, -1, NULL, 0, NULL};
 pCodeOpReg pic16_pc_preinc2    = {{PO_FSR0,    "PREINC1"}, -1, NULL, 0, NULL};
@@ -89,6 +91,8 @@ static int peepOptimizing = 1;        /* run the peephole optimizer if nonzero *
 static int functionInlining = 1;      /* inline functions if nonzero */
 int pic16_debug_verbose = 0;                /* Set true to inundate .asm file */
 
+int pic16_pcode_verbose = 0;
+
 //static int GpCodeSequenceNumber = 1;
 static int GpcFlowSeq = 1;
 
@@ -2539,22 +2543,24 @@ void  pic16_pCodeInitRegisters(void)
        pic16_initStack(0xfff, 8);
        pic16_init_pic(port->processor);
 
-       pic16_pc_status.r = pic16_allocProcessorRegister(IDX_STATUS,"_STATUS", PO_STATUS, 0x00);
-       pic16_pc_pcl.r = pic16_allocProcessorRegister(IDX_PCL,"_PCL", PO_PCL, 0x80);
-       pic16_pc_pclath.r = pic16_allocProcessorRegister(IDX_PCLATH,"_PCLATH", PO_PCLATH, 0x80);
-       pic16_pc_fsr0.r = pic16_allocProcessorRegister(IDX_FSR0,"_FSR0", PO_FSR0, 0x80);
-       pic16_pc_indf0.r = pic16_allocProcessorRegister(IDX_INDF0,"_INDF0", PO_INDF0, 0x80);
-       pic16_pc_intcon.r = pic16_allocProcessorRegister(IDX_INTCON,"_INTCON", PO_INTCON, 0x80);
-       pic16_pc_wreg.r = pic16_allocProcessorRegister(IDX_WREG,"_WREG", PO_WREG, 0x80);
-
-       pic16_pc_fsr1l.r = pic16_allocProcessorRegister(IDX_FSR1L, "_FSR1L", PO_FSR0, 0x80);
-       pic16_pc_fsr1h.r = pic16_allocProcessorRegister(IDX_FSR1H, "_FSR1H", PO_FSR0, 0x80);
-       pic16_pc_fsr2l.r = pic16_allocProcessorRegister(IDX_FSR2L, "_FSR2L", PO_FSR0, 0x80);
-       pic16_pc_fsr2h.r = pic16_allocProcessorRegister(IDX_FSR2H, "_FSR2H", PO_FSR0, 0x80);
-       pic16_pc_postinc1.r = pic16_allocProcessorRegister(IDX_POSTINC1, "_POSTINC1", PO_FSR0, 0x80);
-       pic16_pc_postdec1.r = pic16_allocProcessorRegister(IDX_POSTDEC1, "_POSTDEC1", PO_FSR0, 0x80);
-       pic16_pc_preinc2.r = pic16_allocProcessorRegister(IDX_PREINC2, "_PREINC2", PO_FSR0, 0x80);
-       pic16_pc_plusw2.r = pic16_allocProcessorRegister(IDX_PLUSW2, "_PLUSW2", PO_FSR0, 0x80);
+       pic16_pc_status.r = pic16_allocProcessorRegister(IDX_STATUS,"STATUS", PO_STATUS, 0x80);
+       pic16_pc_pcl.r = pic16_allocProcessorRegister(IDX_PCL,"PCL", PO_PCL, 0x80);
+       pic16_pc_pclath.r = pic16_allocProcessorRegister(IDX_PCLATH,"PCLATH", PO_PCLATH, 0x80);
+       pic16_pc_fsr0.r = pic16_allocProcessorRegister(IDX_FSR0,"FSR0", PO_FSR0, 0x80);
+       pic16_pc_indf0.r = pic16_allocProcessorRegister(IDX_INDF0,"INDF0", PO_INDF0, 0x80);
+       pic16_pc_intcon.r = pic16_allocProcessorRegister(IDX_INTCON,"INTCON", PO_INTCON, 0x80);
+       pic16_pc_wreg.r = pic16_allocProcessorRegister(IDX_WREG,"WREG", PO_WREG, 0x80);
+
+       pic16_pc_fsr1l.r = pic16_allocProcessorRegister(IDX_FSR1L, "FSR1L", PO_FSR0, 0x80);
+       pic16_pc_fsr1h.r = pic16_allocProcessorRegister(IDX_FSR1H, "FSR1H", PO_FSR0, 0x80);
+       pic16_pc_fsr2l.r = pic16_allocProcessorRegister(IDX_FSR2L, "FSR2L", PO_FSR0, 0x80);
+       pic16_pc_fsr2h.r = pic16_allocProcessorRegister(IDX_FSR2H, "FSR2H", PO_FSR0, 0x80);
+       pic16_pc_postinc1.r = pic16_allocProcessorRegister(IDX_POSTINC1, "POSTINC1", PO_FSR0, 0x80);
+       pic16_pc_postdec1.r = pic16_allocProcessorRegister(IDX_POSTDEC1, "POSTDEC1", PO_FSR0, 0x80);
+       pic16_pc_preinc1.r = pic16_allocProcessorRegister(IDX_PREINC1, "PREINC1", PO_FSR0, 0x80);
+       
+       pic16_pc_preinc2.r = pic16_allocProcessorRegister(IDX_PREINC2, "PREINC2", PO_FSR0, 0x80);
+       pic16_pc_plusw2.r = pic16_allocProcessorRegister(IDX_PLUSW2, "PLUSW2", PO_FSR0, 0x80);
        
        pic16_pc_status.rIdx = IDX_STATUS;
        pic16_pc_fsr0.rIdx = IDX_FSR0;
@@ -2569,6 +2575,7 @@ void  pic16_pCodeInitRegisters(void)
        pic16_pc_fsr2h.rIdx = IDX_FSR2H;
        pic16_pc_postinc1.rIdx = IDX_POSTINC1;
        pic16_pc_postdec1.rIdx = IDX_POSTDEC1;
+       pic16_pc_preinc1.rIdx = IDX_PREINC1;
        pic16_pc_preinc2.rIdx = IDX_PREINC2;
        pic16_pc_plusw2.rIdx = IDX_PLUSW2;
        
@@ -2741,9 +2748,13 @@ int pic16_getpCode(char *mnem,unsigned dest)
   while(pci) {
 
     if(STRCASECMP(pci->mnemonic, mnem) == 0) {
-      if((pci->num_ops <= 1) || (pci->isModReg == dest) || (pci->isBitInst) ||
-         (pci->num_ops <= 2 && pci->isAccess) ||
-         (pci->num_ops <= 2 && pci->isFastCall))
+      if((pci->num_ops <= 1)
+       || (pci->isModReg == dest)
+       || (pci->isBitInst)
+       || (pci->num_ops <= 2 && pci->isAccess)
+       || (pci->num_ops <= 2 && pci->isFastCall)
+       || (pci->num_ops <= 2 && pci->is2MemOp)
+       || (pci->num_ops <= 2 && pci->is2LitOp) )
        return(pci->op);
     }
 
@@ -2828,6 +2839,14 @@ void pic16_pBlockConvert2ISR(pBlock *pb)
   pb->dbName = 'I';
 }
 
+void pic16_pBlockConvert2Absolute(pBlock *pb)
+{
+       if(!pb)return;
+       if(pb->cmemmap)pb->cmemmap = NULL;
+       
+       pb->dbName = 'A';
+}
+  
 /*-----------------------------------------------------------------*/
 /* pic16_movepBlock2Head - given the dbname of a pBlock, move all  */
 /*                   instances to the front of the doubly linked   */
@@ -3121,7 +3140,6 @@ pCode *pic16_newpCodeFunction(char *mod,char *f)
   pCodeFunction *pcf;
 
   pcf = Safe_calloc(1,sizeof(pCodeFunction));
-  //_ALLOC(pcf,sizeof(pCodeFunction));
 
   pcf->pc.type = PC_FUNCTION;
   pcf->pc.prev = pcf->pc.next = NULL;
@@ -3135,14 +3153,12 @@ pCode *pic16_newpCodeFunction(char *mod,char *f)
   pcf->ncalled = 0;
 
   if(mod) {
-    //_ALLOC_ATOMIC(pcf->modname,strlen(mod)+1);
     pcf->modname = Safe_calloc(1,strlen(mod)+1);
     strcpy(pcf->modname,mod);
   } else
     pcf->modname = NULL;
 
   if(f) {
-    //_ALLOC_ATOMIC(pcf->fname,strlen(f)+1);
     pcf->fname = Safe_calloc(1,strlen(f)+1);
     strcpy(pcf->fname,f);
   } else
@@ -3266,10 +3282,10 @@ pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...)
 {
   pCodeAsmDir *pcad;
   va_list ap;
-  char buffer[256];            // how long can a directive be?!
+  char buffer[512];
   char *lbp=buffer;
   
-       pcad = Safe_alloc(/*1, */sizeof(pCodeAsmDir));
+       pcad = Safe_calloc(1, sizeof(pCodeAsmDir));
        pcad->pc.type = PC_ASMDIR;
        pcad->pc.prev = pcad->pc.next = NULL;
        pcad->pc.pb = NULL;
@@ -3278,11 +3294,15 @@ pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...)
        pcad->pc.print = genericPrint;
 
        if(asdir && *asdir) {
+               
+               while(isspace(*asdir))asdir++;  // strip any white space from the beginning
+               
                pcad->directive = Safe_strdup( asdir );
        }
        
        va_start(ap, argfmt);
        
+       memset(buffer, 0, sizeof(buffer));
        if(argfmt && *argfmt)
                vsprintf(buffer, argfmt, ap);
        
@@ -3444,24 +3464,25 @@ pCodeOp *pic16_newpCodeOpLit(int lit)
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-pCodeOp *pic16_newpCodeOpLit2(int lit, int lit2)
+pCodeOp *pic16_newpCodeOpLit2(int lit, pCodeOp *arg2)
 {
-  char *s = buffer;
+  char *s = buffer, tbuf[256], *tb=tbuf;
   pCodeOp *pcop;
 
 
+  tb = pic16_get_op(arg2, NULL, 0);
   pcop = Safe_calloc(1,sizeof(pCodeOpLit2) );
   pcop->type = PO_LITERAL;
 
   pcop->name = NULL;
-  if(lit>=0 && lit2>=0) {
-    sprintf(s,"0x%02x,0x%02x",lit, lit2);
+  if(lit>=0) {
+    sprintf(s,"0x%02x, %s",lit, tb);
     if(s)
       pcop->name = Safe_strdup(s);
   }
 
   ((pCodeOpLit2 *)pcop)->lit = lit;
-  ((pCodeOpLit2 *)pcop)->lit2 = lit2;
+  ((pCodeOpLit2 *)pcop)->arg2 = arg2;
 
   return pcop;
 }
@@ -3480,10 +3501,11 @@ pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space)
                PCOI(pcop)->r = r;
                
                if(r) {
-//                     fprintf(stderr, " pic16_newpCodeOpImmd reg %s exists\n",name);
+                       fprintf(stderr, "%s:%d %s reg %s exists\n",__FILE__, __LINE__, __FUNCTION__, name);
                        PCOI(pcop)->rIdx = r->rIdx;
                } else {
-                       fprintf(stderr, " pic16_newpCodeOpImmd reg %s doesn't exist\n",name);
+                       fprintf(stderr, "%s:%d %s reg %s doesn't exist\n",
+                               __FILE__, __LINE__, __FUNCTION__, name);
                        PCOI(pcop)->rIdx = -1;
                }
 //                     fprintf(stderr,"%s %s %d\n",__FUNCTION__,name,offset);
@@ -3585,13 +3607,17 @@ pCodeOp *pic16_newpCodeOpReg(int rIdx)
 pCodeOp *pic16_newpCodeOpRegFromStr(char *name)
 {
   pCodeOp *pcop;
+  regs *r;
 
   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-  PCOR(pcop)->r = pic16_allocRegByName(name, 1);
+  PCOR(pcop)->r = r = pic16_allocRegByName(name, 1);
   PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
   pcop->type = PCOR(pcop)->r->pc_type;
   pcop->name = PCOR(pcop)->r->name;
 
+  fprintf(stderr, "%s:%d %s allocates register %s rIdx:0x%02x\n",
+       __FILE__, __LINE__, __FUNCTION__, r->name, r->rIdx);
+
   return pcop;
 }
 
@@ -3799,15 +3825,36 @@ void pic16_printpBlock(FILE *of, pBlock *pb)
 {
   pCode *pc;
 
-  if(!pb)
-    return;
+       if(!pb)return;
 
-  if(!of)
-    of = stderr;
+       if(!of)of=stderr;
 
-  for(pc = pb->pcHead; pc; pc = pc->next)
-    printpCode(of,pc);
+#if 0
+       if(pb->dbName == 'A') {
+         absSym *ab;
+
+               PCF(pb->pcHead)->
+               for(ab=setFirstItem(absSymSet); ab; ab=setNextItem(absSymSet))
+                       if(strcmp(ab->name, 
+//             fprintf(of, "%s\tcode\t%d"
+       }
+#endif
 
+       for(pc = pb->pcHead; pc; pc = pc->next) {
+               if(isPCF(pc) && PCF(pc)->fname) {
+                       fprintf(of, "S_%s_%s\tcode", PCF(pc)->modname, PCF(pc)->fname);
+                       if(pb->dbName == 'A') {
+                         absSym *ab;
+                               for(ab=setFirstItem(absSymSet); ab; ab=setNextItem(absSymSet))
+                                       if(strcmp(ab->name, PCF(pc)->fname)) {
+                                               fprintf(of, "\t0X%06X", ab->address);
+                                               break;
+                                       }
+                       }
+                       fprintf(of, "\n");
+               }
+               printpCode(of,pc);
+       }
 }
 
 /*-----------------------------------------------------------------*/
@@ -3876,6 +3923,9 @@ static void genericDestruct(pCode *pc)
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
+/* modifiers for constant immediate */
+const char *immdmod[3]={"LOW", "HIGH", "UPPER"};
+
 char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size)
 {
   regs *r;
@@ -3911,32 +3961,67 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size)
 
 
     case PO_IMMEDIATE:
-      s = buffer;
-
-      if(PCOI(pcop)->_const) {
+       s = buffer;
+
+       if(PCOI(pcop)->offset && PCOI(pcop)->offset<4) {
+               if(PCOI(pcop)->index) {
+                       SAFE_snprintf(&s,&size, "%s(%s + %d)",
+                               immdmod[ PCOI(pcop)->offset ],
+                               pcop->name,
+                               PCOI(pcop)->index);
+               } else {
+                       SAFE_snprintf(&s,&size,"%s(%s)",
+                               immdmod[ PCOI(pcop)->offset ],
+                               pcop->name);
+               }
+       } else {
+               if(PCOI(pcop)->index) {
+                       SAFE_snprintf(&s,&size, "%s(%s + %d)",
+                               immdmod[ 0 ],
+                               pcop->name,
+                               PCOI(pcop)->index);
+               } else {
+                       SAFE_snprintf(&s,&size, "%s(%s)",
+                               immdmod[ 0 ],
+                               pcop->name);
+               }
+       }
+               
+#if 0
+       if(PCOI(pcop)->_const) {
+               if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) {
+                       if(PCOI(pcop)->index) {
+                               SAFE_snprintf(&s,&size,"%s(%s + %d)",
+                                       immdmod[ PCOI(pcop)->offset ],
+                                       pcop->name,
+                                       PCOI(pcop)->index);
+                       } else {
+                               SAFE_snprintf(&s,&size,"%s(%s)",
+                                       immdmod[ PCOI(pcop)->offset ],
+                                       pcop->name);
+                       }
 
-       if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) {
-         SAFE_snprintf(&s,&size,"(((%s+%d) >> %d)&0xff)",
-                       pcop->name,
-                       PCOI(pcop)->index,
-                       8 * PCOI(pcop)->offset );
-       } else
-         SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index);
-      } else {
-      
-       if( PCOI(pcop)->index) { // && PCOI(pcc->pcop)->offset<4) {
-         SAFE_snprintf(&s,&size,"(%s + %d)",
-                       pcop->name,
-                       PCOI(pcop)->index );
+               } else {
+                       if(PCOI(pcop)->index)
+                               SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index);
+                       else
+                               SAFE_snprintf(&s,&size,"LOW(%s)",pcop->name);
+               }
        } else {
-         if(PCOI(pcop)->offset)
-           SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset);
-         else
-           SAFE_snprintf(&s,&size,"%s",pcop->name);
+               if( PCOI(pcop)->index) { // && PCOI(pcc->pcop)->offset<4) 
+                       SAFE_snprintf(&s,&size,"(%s + %d)",
+                               pcop->name,
+                               PCOI(pcop)->index );
+               } else {
+                       if(PCOI(pcop)->offset)
+                               SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset);
+                       else
+                               SAFE_snprintf(&s,&size,"(%s)",pcop->name);
+               }
        }
-      }
+#endif
 
-      return buffer;
+       return buffer;
 
     case PO_DIR:
       s = buffer;
@@ -4104,11 +4189,13 @@ static char *pic16_pCode2str(char *str, size_t size, pCode *pc)
   char *s = str;
   regs *r;
 
-       if(PCI(pc)->pci_magic != PCI_MAGIC) {
-               fprintf(stderr, "%s:%d: pCodeInstruction initialization error in instruction %s\n",
-                       __FILE__, __LINE__, PCI(pc)->mnemonic);
+#if 0
+       if(isPCI(pc) && (PCI(pc)->pci_magic != PCI_MAGIC)) {
+               fprintf(stderr, "%s:%d: pCodeInstruction initialization error in instruction %s, magic is %x (defaut: %x)\n",
+                       __FILE__, __LINE__, PCI(pc)->mnemonic, PCI(pc)->pci_magic, PCI_MAGIC);
                exit(-1);
        }
+#endif
 
   switch(pc->type) {
 
@@ -4118,7 +4205,7 @@ static char *pic16_pCode2str(char *str, size_t size, pCode *pc)
     if( (PCI(pc)->num_ops >= 1) && (PCI(pc)->pcop)) {
 
        if(PCI(pc)->is2MemOp) {
-               SAFE_snprintf(&s,&size, "%s,%s", 
+               SAFE_snprintf(&s,&size, "%s, %s", 
                pic16_get_op(PCOP(PCI(pc)->pcop), NULL, 0),
                pic16_get_op2(PCOP(PCI(pc)->pcop), NULL, 0));
                break;
@@ -4193,7 +4280,7 @@ static char *pic16_pCode2str(char *str, size_t size, pCode *pc)
     SAFE_snprintf(&s,&size,";\t--FLOW change\n");
     break;
   case PC_CSOURCE:
-    SAFE_snprintf(&s,&size,";#CSRC\t%s %d\n; %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
+    SAFE_snprintf(&s,&size,";#CSRC\t%s %d\t%s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
     break;
   case PC_ASMDIR:
        SAFE_snprintf(&s,&size,"\t%s\t%s\n", PCAD(pc)->directive, PCAD(pc)->arg?PCAD(pc)->arg:"");
@@ -4278,7 +4365,7 @@ static void genericPrint(FILE *of, pCode *pc)
     break;
 
   case PC_CSOURCE:
-    fprintf(of,";#CSRC\t%s %d\n;  %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
+    fprintf(of,";#CSRC\t%s %d\t\t%s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
     break;
   case PC_ASMDIR:
        {
@@ -4309,27 +4396,42 @@ static void pCodePrintFunction(FILE *of, pCode *pc)
   if(!pc || !of)
     return;
 
+#if 0
   if( ((pCodeFunction *)pc)->modname) 
     fprintf(of,"F_%s",((pCodeFunction *)pc)->modname);
+#endif
 
   if(PCF(pc)->fname) {
     pBranch *exits = PCF(pc)->to;
     int i=0;
-    fprintf(of,"%s\t;Function start\n",PCF(pc)->fname);
+    fprintf(of,"%s", PCF(pc)->fname);
+    
+//     if(pic16_pcode_verbose)
+               fprintf(of, "\t;Function start");
+    
+    fprintf(of, "\n");
+    
     while(exits) {
       i++;
       exits = exits->next;
     }
     //if(i) i--;
-    fprintf(of,"; %d exit point%c\n",i, ((i==1) ? ' ':'s'));
+
+       if(pic16_pcode_verbose)
+               fprintf(of,"; %d exit point%c\n",i, ((i==1) ? ' ':'s'));
     
-  }else {
-    if((PCF(pc)->from && 
-       PCF(pc)->from->pc->type == PC_FUNCTION &&
-       PCF(PCF(pc)->from->pc)->fname) )
-      fprintf(of,"; exit point of %s\n",PCF(PCF(pc)->from->pc)->fname);
-    else
-      fprintf(of,"; exit point [can't find entry point]\n");
+  } else {
+       if((PCF(pc)->from && 
+               PCF(pc)->from->pc->type == PC_FUNCTION &&
+               PCF(PCF(pc)->from->pc)->fname) ) {
+
+               if(pic16_pcode_verbose)
+                       fprintf(of,"; exit point of %s\n",PCF(PCF(pc)->from->pc)->fname);
+       } else {
+               if(pic16_pcode_verbose)
+                       fprintf(of,"; exit point [can't find entry point]\n");
+       }
+       fprintf(of, "\n");
   }
 }
 /*-----------------------------------------------------------------*/
@@ -5279,9 +5381,14 @@ static void LinkFlow(pBlock *pb)
       //pc->print(stderr,pc);
 
       if(!(pcol && isPCOLAB(pcol))) {
-       if((PCI(pc)->op != POC_RETLW) && (PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL) && (PCI(pc)->op != POC_RETFIE) ) {
-         pc->print(stderr,pc);
-         fprintf(stderr, "ERROR: %s, branch instruction doesn't have label\n",__FUNCTION__);
+       if((PCI(pc)->op != POC_RETLW)
+               && (PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL) && (PCI(pc)->op != POC_RETFIE) ) {
+       
+               /* continue if label is '$' which assembler knows how to parse */
+               if(((PCI(pc)->pcop->type == PO_STR) && !strcmp(PCI(pc)->pcop->name, "$")))continue;
+
+               pc->print(stderr,pc);
+               fprintf(stderr, "ERROR: %s, branch instruction doesn't have label\n",__FUNCTION__);
        }
        continue;
       }
@@ -6360,6 +6467,8 @@ static void pBlockStats(FILE *of, pBlock *pb)
   pCode *pc;
   regs  *r;
 
+       if(!pic16_pcode_verbose)return;
+       
   fprintf(of,";***\n;  pBlock Stats: dbName = %c\n;***\n",getpBlock_dbName(pb));
 
   // for now just print the first element of each set
index 2b57ef5d2f36fd181ee4541a5157847df5961d90..e2391114e2eabf02af56a3f43cd274c5e2daaf4a 100644 (file)
@@ -364,7 +364,7 @@ typedef struct pCodeOpLit2
 {
   pCodeOp pcop;
   int lit;
-  int lit2;
+  pCodeOp *arg2;
 } pCodeOpLit2;
 
 
@@ -910,11 +910,12 @@ void pic16_AssignRegBanks(void);
 void pic16_printCallTree(FILE *of);
 void pCodePeepInit(void);
 void pic16_pBlockConvert2ISR(pBlock *pb);
+void pic16_pBlockConvert2Absolute(pBlock *pb);
 
 pCodeOp *pic16_newpCodeOpLabel(char *name, int key);
 pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space);
 pCodeOp *pic16_newpCodeOpLit(int lit);
-pCodeOp *pic16_newpCodeOpLit2(int lit, int lit2);
+pCodeOp *pic16_newpCodeOpLit2(int lit, pCodeOp *arg2);
 pCodeOp *pic16_newpCodeOpBit(char *name, int bit,int inBitSpace);
 pCodeOp *pic16_newpCodeOpRegFromStr(char *name);
 pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE p);
@@ -927,7 +928,7 @@ struct regs * pic16_getRegFromInstruction(pCode *pc);
 struct regs * pic16_getRegFromInstruction2(pCode *pc);
 
 extern void pic16_pcode_test(void);
-
+extern int pic16_debug_verbose;
 /*-----------------------------------------------------------------*
  * pCode objects.
  *-----------------------------------------------------------------*/
@@ -945,6 +946,7 @@ extern pCodeOpReg pic16_pc_fsr2l;
 extern pCodeOpReg pic16_pc_fsr2h;
 extern pCodeOpReg pic16_pc_postinc1;
 extern pCodeOpReg pic16_pc_postdec1;
+extern pCodeOpReg pic16_pc_preinc1;
 extern pCodeOpReg pic16_pc_preinc2;
 extern pCodeOpReg pic16_pc_plusw2;
 
index 69ce8a42651e1aeec1b5e352922cfcde9ef7a9e3..4b6c1a96e7c509c45a4b07bdb1d47e63f21dc388 100644 (file)
@@ -46,9 +46,10 @@ int pic16_getpCodePeepCommand(char *cmd);
 void pic16_pBlockMergeLabels(pBlock *pb);
 char *pCode2str(char *str, int size, pCode *pc);
 char *pic16_get_op( pCodeOp *pcop,char *buf,int buf_size);
+pCodeOp *pic16_popCombine2(pCodeOp *, pCodeOp *, int);
 
 extern pCodeInstruction *pic16Mnemonics[];
-
+static int parsing_peeps=1;
 
 #define IS_PCCOMMENT(x) ( x && (x->type==PC_COMMENT))
 
@@ -203,7 +204,10 @@ typedef enum {
   ALT_MNEM1B,
   ALT_MNEM2,
   ALT_MNEM2A,
-  ALT_MNEM3
+  ALT_MNEM2B,
+  ALT_MNEM3,
+  ALT_MNEM4,
+  ALT_MNEM4a
 } altPatterns;
 
 static char alt_comment[]   = { PCP_COMMENT, 0};
@@ -215,7 +219,10 @@ static char alt_mnem1a[]    = { PCP_STR, PCP_WILDVAR, 0};
 static char alt_mnem1b[]    = { PCP_STR, PCP_NUMBER, 0};
 static char alt_mnem2[]     = { PCP_STR, PCP_STR, PCP_COMMA, PCP_STR, 0};
 static char alt_mnem2a[]    = { PCP_STR, PCP_WILDVAR, PCP_COMMA, PCP_STR, 0};
+//static char alt_mnem2b[]    = { PCP_STR, PCP_WILDVAR, PCP_COMMA, PCP_WILDVAR, 0};
 static char alt_mnem3[]     = { PCP_STR, PCP_STR, PCP_COMMA, PCP_NUMBER, 0};
+static char alt_mnem4[]            = { PCP_STR, PCP_NUMBER, PCP_COMMA, PCP_STR, 0};    // for lfsr 0 , name
+static char alt_mnem4a[]    = { PCP_STR, PCP_NUMBER, PCP_COMMA, PCP_NUMBER, 0}; // for lfsr 0 , value
 
 static void * cvt_altpat_label(void *pp,pCodeWildBlock *pcwb);
 static void * cvt_altpat_comment(void *pp,pCodeWildBlock *pcwb);
@@ -226,12 +233,19 @@ static void * cvt_altpat_mnem1a(void *pp,pCodeWildBlock *pcwb);
 static void * cvt_altpat_mnem1b(void *pp,pCodeWildBlock *pcwb);
 static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb);
 static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb);
+//static void * cvt_altpat_mnem2b(void *pp, pCodeWildBlock *pcwb);
 static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem4(void *pp, pCodeWildBlock *pcwb);
+static void * cvt_altpat_mnem4a(void *pp, pCodeWildBlock *pcwb);
 
+/* NOTE: Order is important in the following table */
 static pcPattern altArr[] = {
   {ALT_LABEL,        alt_label,  cvt_altpat_label},
   {ALT_COMMENT,      alt_comment,cvt_altpat_comment},
+  {ALT_MNEM4a,       alt_mnem4a, cvt_altpat_mnem4a},
+  {ALT_MNEM4,        alt_mnem4,  cvt_altpat_mnem4},
   {ALT_MNEM3,        alt_mnem3,  cvt_altpat_mnem3},
+//  {ALT_MNEM2B,       alt_mnem2b, cvt_altpat_mnem2b},
   {ALT_MNEM2A,       alt_mnem2a, cvt_altpat_mnem2a},
   {ALT_MNEM2,        alt_mnem2,  cvt_altpat_mnem2},
   {ALT_MNEM1B,       alt_mnem1b, cvt_altpat_mnem1b},
@@ -434,8 +448,10 @@ static void * cvt_altpat_mnem1(void *pp,pCodeWildBlock *pcwb)
 
   if(pic16Mnemonics[opcode]->isBitInst)
     pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_BIT);
-  else
-    pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
+  else {
+//     fprintf(stderr, "%s:%d tok.s= %s\n", __FILE__, __LINE__, p[1].pct[0].tok.s);
+    pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_STR);   //GPR_REGISTER);
+  }
 
 
   pci = PCI(pic16_newpCode(opcode, pcosubtype));
@@ -567,7 +583,6 @@ static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb)
          p[3].pct[0].tok.s,
          dest));
 
-
   opcode = pic16_getpCode(p->pct[0].tok.s,dest);
   if(opcode < 0) {
     fprintf(stderr, "Bad mnemonic\n");
@@ -581,8 +596,15 @@ static void * cvt_altpat_mnem2(void *pp,pCodeWildBlock *pcwb)
       return NULL;
     }
       
+  } else
+  if(pic16Mnemonics[opcode]->is2MemOp) {
+       /* support for movff instruction */
+       pcosubtype = pic16_popCombine2(
+               pic16_newpCodeOp(p[1].pct[0].tok.s, PO_GPR_REGISTER),
+               pic16_newpCodeOp(p[3].pct[0].tok.s, PO_GPR_REGISTER), 0);
   } else
     pcosubtype = pic16_newpCodeOp(p[1].pct[0].tok.s,PO_GPR_REGISTER);
 
 
   pci = PCI(pic16_newpCode(opcode,pcosubtype));
@@ -637,6 +659,13 @@ static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb)
   if(pic16Mnemonics[opcode]->isBitInst)
     pcosubtype = pic16_newpCodeOp(NULL,PO_BIT);
   else
+  if(pic16Mnemonics[opcode]->is2MemOp) {
+       return NULL;
+       /* support for movff instruction */
+       pcosubtype = pic16_popCombine2(
+               pic16_newpCodeOp(p[1].pct[0].tok.s, PO_GPR_REGISTER),
+               pic16_newpCodeOp(p[3].pct[0].tok.s, PO_GPR_REGISTER), 0);
+  } else
     pcosubtype = pic16_newpCodeOp(NULL,PO_GPR_REGISTER);
 
 
@@ -657,6 +686,70 @@ static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb)
 
 }
 
+#if 0
+/*-----------------------------------------------------------------*/
+/* cvt_altpat_mem2b - convert assembly line type to a pCode        */
+/*                    instruction with 2 wild operands             */
+/*                                                                 */
+/*  pp[0] - mnem                                                   */
+/*  pp[1] - wild var                                               */
+/*  pp[2] - comma                                                  */
+/*  pp[3] - wild var                                               */
+/*                                                                 */
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem2b(void *pp,pCodeWildBlock *pcwb)
+{
+  parsedPattern *p = pp;
+  int opcode;
+  int dest;
+
+  pCodeInstruction *pci=NULL;
+  pCodeOp *pcosubtype;
+
+  if(!pcwb) {
+    fprintf(stderr,"ERROR %s:%d - can't assemble line\n",__FILE__,__LINE__);
+    return NULL;
+  }
+
+  dest = cvt_extract_destination(&p[3]);
+
+  DFPRINTF((stderr,"altpat_mnem2b %s src %d dst (%d)\n",
+         p->pct[0].tok.s,
+         p[1].pct[1].tok.n,
+         p[3].pct[1].tok.n));
+
+
+  opcode = pic16_getpCode(p->pct[0].tok.s,dest);
+  if(opcode < 0) {
+    fprintf(stderr, "Bad mnemonic\n");
+    return NULL;
+  }
+
+  if(pic16Mnemonics[opcode]->is2MemOp) {
+       /* support for movff instruction */
+       pcosubtype = pic16_popCombine2(
+               pic16_newpCodeOp(NULL, PO_GPR_REGISTER),
+               pic16_newpCodeOp(NULL, PO_GPR_REGISTER), 0);
+  } else pcosubtype = NULL;
+
+  pci = PCI(pic16_newpCode(opcode,
+                    pic16_newpCodeOpWild(p[1].pct[1].tok.n, pcwb, pcosubtype)));
+
+  /* Save the index of the maximum wildcard variable */
+  //if(p[1].pct[1].tok.n > sMaxWildVar)
+  //  sMaxWildVar = p[1].pct[1].tok.n;
+
+  if(p[1].pct[1].tok.n > pcwb->nvars)
+    pcwb->nvars = p[1].pct[1].tok.n;
+
+  if(!pci)
+    fprintf(stderr,"couldn't find mnemonic\n");
+
+  return pci;
+
+}
+#endif
+
 
 /*-----------------------------------------------------------------*/
 /* cvt_altpat_mem3 -  convert assembly line type to a pCode        */
@@ -716,6 +809,110 @@ static void * cvt_altpat_mnem3(void *pp,pCodeWildBlock *pcwb)
 
 }
 
+/*-----------------------------------------------------------------*/
+/* cvt_altpat_mem4 -  convert assembly line type to a pCode        */
+/*                    This rule is for lfsr instruction            */
+/*                                                                 */
+/*                                                                 */
+/*  pp[0] - mnem                                                   */
+/*  pp[1] - number                                                 */
+/*  pp[2] - comma                                                  */
+/*  pp[3] - source                                                 */
+/*                                                                 */
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem4(void *pp, pCodeWildBlock *pcwb)
+{
+  parsedPattern *p = pp;
+  int opcode;
+  int dest;  // or could be bit position in the register
+
+  pCodeInstruction *pci=NULL;
+  pCodeOp *pcosubtype=NULL;
+
+  dest = cvt_extract_destination(&p[3]);
+
+  DFPRINTF((stderr,"altpat_mnem4 %s fsr %d source %s\n",
+         p->pct[0].tok.s,
+         p[1].pct[0].tok.n,
+         p[3].pct[0].tok.s));
+
+  opcode = pic16_getpCode(p->pct[0].tok.s,0);
+  if(opcode < 0) {
+    fprintf(stderr, "Bad mnemonic\n");
+    return NULL;
+  }
+  DFPRINTF((stderr, "Found mnemonic opcode= %d\n", opcode));
+
+  if(pic16Mnemonics[opcode]->is2LitOp) {
+    pcosubtype = pic16_newpCodeOpLit2(p[1].pct[0].tok.n, pic16_newpCodeOp(p[3].pct[0].tok.s, PO_STR));
+  }
+
+  if(pcosubtype == NULL) {
+    fprintf(stderr, "Bad operand\n");
+    return NULL;
+  }
+
+  pci = PCI(pic16_newpCode(opcode, pcosubtype));
+
+  if(!pci)
+    fprintf(stderr,"couldn't find mnemonic\n");
+
+  return pci;
+
+}
+
+/*-----------------------------------------------------------------*/
+/* cvt_altpat_mem4a -  convert assembly line type to a pCode       */
+/*                    This rule is for lfsr instruction            */
+/*                                                                 */
+/*                                                                 */
+/*  pp[0] - mnem                                                   */
+/*  pp[1] - number                                                 */
+/*  pp[2] - comma                                                  */
+/*  pp[3] - value                                                  */
+/*                                                                 */
+/*-----------------------------------------------------------------*/
+static void * cvt_altpat_mnem4a(void *pp, pCodeWildBlock *pcwb)
+{
+  parsedPattern *p = pp;
+  int opcode;
+  int dest;  // or could be bit position in the register
+
+  pCodeInstruction *pci=NULL;
+  pCodeOp *pcosubtype=NULL;
+
+  dest = cvt_extract_destination(&p[3]);
+
+  DFPRINTF((stderr,"altpat_mnem4a %s fsr %d value 0x%02x\n",
+         p->pct[0].tok.s,
+         p[1].pct[0].tok.n,
+         p[3].pct[0].tok.n));
+
+  opcode = pic16_getpCode(p->pct[0].tok.s,0);
+  if(opcode < 0) {
+    fprintf(stderr, "Bad mnemonic\n");
+    return NULL;
+  }
+  DFPRINTF((stderr, "Found mnemonic opcode= %d\n", opcode));
+
+  if(pic16Mnemonics[opcode]->is2LitOp) {
+    pcosubtype = pic16_newpCodeOpLit2(p[1].pct[0].tok.n, pic16_newpCodeOpLit(p[3].pct[0].tok.n));
+  }
+
+  if(pcosubtype == NULL) {
+    fprintf(stderr, "Bad operand\n");
+    return NULL;
+  }
+
+  pci = PCI(pic16_newpCode(opcode, pcosubtype));
+
+  if(!pci)
+    fprintf(stderr,"couldn't find mnemonic\n");
+
+  return pci;
+
+}
+
 /*-----------------------------------------------------------------*/
 /* tokenizeLineNode - Convert a string (of char's) that was parsed */
 /*                    by SDCCpeeph.c into a string of tokens.      */
@@ -785,12 +982,12 @@ static void tokenizeLineNode(char *ln)
       break;
 
 
-    default:
-      if(isalpha(*ln) || (*ln == '_') ) {
+    default:                           // hack to allow : goto $
+      if(isalpha(*ln) || (*ln == '_')  || (!parsing_peeps && (*ln == '$'))) {
        char buffer[50];
        int i=0;
 
-       while( (isalpha(*ln)  ||  isdigit(*ln) || (*ln == '_')) && i<49)
+       while( (isalpha(*ln)  ||  isdigit(*ln) || (*ln == '_') || (*ln == '$')) && i<49)
          buffer[i++] = *ln++;
 
        ln--;
@@ -800,10 +997,12 @@ static void tokenizeLineNode(char *ln)
        tokArr[tokIdx++].tt = PCT_STRING;
 
       } else {
-       fprintf(stderr, "Error while parsing peep rules (check peeph.def)\n");
-       fprintf(stderr, "Line: %s\n",lnstart);
-       fprintf(stderr, "Token: '%c'\n",*ln);
-       exit(1);
+       if(parsing_peeps) {
+               fprintf(stderr, "Error while parsing peep rules (check peeph.def)\n");
+               fprintf(stderr, "Line: %s\n",lnstart);
+               fprintf(stderr, "Token: '%c'\n",*ln);
+               exit(1);
+       }
       }
     }
 
@@ -915,11 +1114,11 @@ static int altComparePattern( char *pct, parsedPattern *pat, int max_tokens)
   while(i < max_tokens) {
 
     if(*pct == 0) {
-      //DFPRINTF((stderr,"matched\n"));
+       DFPRINTF((stderr,"matched\n"));
       return i;
     }
 
-    //dump1Token(*pat); DFPRINTF((stderr,"\n"));
+//     dump1Token(*pat); DFPRINTF((stderr,"\n"));
 
     if( !pat || !pat->pcp )
       return 0;
@@ -927,7 +1126,7 @@ static int altComparePattern( char *pct, parsedPattern *pat, int max_tokens)
     if (pat->pcp->pt != *pct)  
       return 0;
 
-    //DFPRINTF((stderr," pct=%d\n",*pct));
+       DFPRINTF((stderr," pct=%d\n",*pct));
     pct++;
     pat++;
     i++;
@@ -1122,7 +1321,7 @@ static int parseTokens(pCodeWildBlock *pcwb, pCode **pcret)
          parsedPatArr[lparsedPatIdx].pct = &tokArr[ltokIdx];
          lparsedPatIdx++;
 
-         //dump1Token(tokArr[ltokIdx].tt);
+//             dump1Token(tokArr[ltokIdx].tt);
 
          if(advTokIdx(&ltokIdx, strlen(pcpArr[lpcpIdx].tokens) ) ) {
            DFPRINTF((stderr," reached end \n"));
@@ -1216,9 +1415,10 @@ static void  peepRuleBlock2pCodeBlock(  lineNode *ln, pCodeWildBlock *pcwb)
 }
 
 /*-----------------------------------------------------------------*/
-/*                                                                 */
+/* pic16_AssembleLine - parse line and return the pCode equivalent */
+/*                      peeps=1 if parsing peep rules, 0 otherwise */
 /*-----------------------------------------------------------------*/
-pCode *pic16_AssembleLine(char *line)
+pCode *pic16_AssembleLine(char *line, int peeps)
 {
   pCode *pc=NULL;
 
@@ -1227,11 +1427,18 @@ pCode *pic16_AssembleLine(char *line)
     return NULL;
   }
 
+  parsing_peeps = peeps;
+
   tokenizeLineNode(line);
     
   if(parseTokens(NULL,&pc))
     fprintf(stderr, "WARNING: unable to assemble line:\n%s\n",line);
+  else {
+       DFPRINTF((stderr, "pc= %p\n", pc));
+//     if(pc)pc->print(stderr, pc);
+  }
 
+  parsing_peeps = 1;
   return pc;
 
 }
@@ -1708,14 +1915,37 @@ static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
            return pCodeOpCompare(PCI(pcs)->pcop, peepBlock->target.wildpCodeOps[index]);
          }
 
-         {
+         if(PCI(pcs)->pcop) {
            char *n;
 
            switch(PCI(pcs)->pcop->type) {
            case PO_GPR_TEMP:
            case PO_FSR0:
              //case PO_INDF0:
-             n = PCOR(PCI(pcs)->pcop)->r->name;
+               n = PCOR(PCI(pcs)->pcop)->r->name;
+
+             break;
+           default:
+             n = PCI(pcs)->pcop->name;
+           }
+
+           if(peepBlock->target.vars[index])
+             return  (strcmp(peepBlock->target.vars[index],n) == 0);
+           else {
+             DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n));
+             peepBlock->target.vars[index] = n;
+             return 1;
+           }
+         }
+         
+         if(PCI(pcs)->is2MemOp) {
+           char *n;
+
+           switch(PCOP(PCOR2(PCI(pcs))->pcop2)->type) {
+           case PO_GPR_TEMP:
+           case PO_FSR0:
+             //case PO_INDF0:
+               n = PCOR(PCOR2(PCI(pcs))->pcop2)->r->name;
 
              break;
            default:
@@ -2110,7 +2340,7 @@ int pic16_pCodePeepMatchRule(pCode *pc)
         inefficient code with the optimized version */
 #ifdef PCODE_DEBUG
       DFPRINTF((stderr, "Found a pcode peep match:\nRule:\n"));
-      printpCodeString(stderr,peepBlock->target.pb->pcHead,10);
+//      printpCodeString(stderr,peepBlock->target.pb->pcHead,10);
       DFPRINTF((stderr,"first thing matched\n"));
       pc->print(stderr,pc);
       if(pcin) {
index 8ea1e52cd6cb08c3624233fee59329a6f186300b..0a772a8d7287d887977e78cde6b2198e38ea48db 100644 (file)
@@ -819,6 +819,8 @@ void pic16_pCodeRegOptimizeRegUsage(int level)
   } while( passes && ((total_registers_saved != saved) || (passes==OPT_PASSES-1)) );
 
   if(total_registers_saved == t) 
+
+  if(pic16_debug_verbose)
     fprintf(stderr, "No registers saved on this pass\n");
 
 
index 2eb4dcbfb782e87d1960da7979c4e3a07ebae1b9..15987cef412c858ed30390ce8931d4fd198b352c 100644 (file)
@@ -287,6 +287,8 @@ replace restart {
 
 
 // From: Vangelis Rokas (vrokas@otenet.gr)
+// movff peeps are disabled for the moment
+// until support is added in the pcodepeeph.c
 
 //replace {
 //     movf    %1,w
@@ -323,10 +325,10 @@ replace restart {
 //     movwf   %3
 //}
 
-replace {
-       movff   %1,%2
-} by {
-       ;       peep xxx - test peep to see if peep rules can handle movff
-       movf    %1,w
-       movwf   %2
-}
+//replace {
+//     movff   %1,%2
+//} by {
+//     ;       peep xxx - test peep to see if peep rules can handle movff
+//     movf    %1,w
+//     movwf   %2
+//}
index cb96f41e1b37f5943dfb359fcab2dd69cbbd45d9..848702fe658937c38aed87c0f057e00b62c8ea52 100644 (file)
@@ -29,6 +29,7 @@
 #include "ralloc.h"
 #include "pcode.h"
 #include "gen.h"
+#include "device.h"
 
 #if defined(__BORLANDC__) || defined(_MSC_VER)
 #define STRCASECMP stricmp
@@ -79,9 +80,11 @@ static hTab  *dynDirectRegNames= NULL;
 
 set *pic16_rel_udata=NULL;
 set *pic16_fix_udata=NULL;
+set *pic16_equ_data=NULL;
 
+set *pic16_builtin_functions=NULL;
 
-static int dynrIdx=0x20;
+static int dynrIdx=0x10;               //0x20;         // starting temporary register rIdx
 static int rDirectIdx=0;
 
 int pic16_nRegs = 128;   // = sizeof (regspic16) / sizeof (regs);
@@ -93,7 +96,7 @@ int pic16_Gstack_base_addr=0; /* The starting address of registers that
 
 
 static void spillThis (symbol *);
-static int debug = 1;
+int pic16_ralloc_debug = 0;
 static FILE *debugF = NULL;
 /*-----------------------------------------------------------------*/
 /* debugLog - open a file for debugging information                */
@@ -108,7 +111,7 @@ debugLog (char *fmt,...)
   //char *bufferP=buffer;
   va_list ap;
 
-  if (!debug || !dstFileName)
+  if (!pic16_ralloc_debug || !dstFileName)
     return;
 
 
@@ -149,8 +152,10 @@ debugLog (char *fmt,...)
 static void
 debugNewLine (void)
 {
-  if (debugF)
-    fputc ('\n', debugF);
+       if(!pic16_ralloc_debug)return;
+       
+       if (debugF)
+               fputc ('\n', debugF);
 }
 /*-----------------------------------------------------------------*/
 /* debugLogClose - closes the debug log file (if opened)           */
@@ -158,244 +163,142 @@ debugNewLine (void)
 static void
 debugLogClose (void)
 {
-  if (debugF)
-    {
-      fclose (debugF);
-      debugF = NULL;
-    }
+       if (debugF) {
+               fclose (debugF);
+               debugF = NULL;
+       }
 }
+
 #define AOP(op) op->aop
 
 static char *
 debugAopGet (char *str, operand * op)
 {
-  if (str)
-    debugLog (str);
+       if(!pic16_ralloc_debug)return NULL;
 
-  printOperand (op, debugF);
-  debugNewLine ();
+       if (str)
+               debugLog (str);
 
-  return NULL;
+       printOperand (op, debugF);
+       debugNewLine ();
 
+  return NULL;
 }
 
 static char *
 decodeOp (unsigned int op)
 {
+       if (op < 128 && op > ' ') {
+               buffer[0] = (op & 0xff);
+               buffer[1] = 0;
+         return buffer;
+       }
 
-  if (op < 128 && op > ' ')
-    {
-      buffer[0] = (op & 0xff);
-      buffer[1] = 0;
-      return buffer;
-    }
+       switch (op) {
+               case IDENTIFIER:        return "IDENTIFIER";
+               case TYPE_NAME:         return "TYPE_NAME";
+               case CONSTANT:          return "CONSTANT";
+               case STRING_LITERAL:    return "STRING_LITERAL";
+               case SIZEOF:            return "SIZEOF";
+               case PTR_OP:            return "PTR_OP";
+               case INC_OP:            return "INC_OP";
+               case DEC_OP:            return "DEC_OP";
+               case LEFT_OP:           return "LEFT_OP";
+               case RIGHT_OP:          return "RIGHT_OP";
+               case LE_OP:             return "LE_OP";
+               case GE_OP:             return "GE_OP";
+               case EQ_OP:             return "EQ_OP";
+               case NE_OP:             return "NE_OP";
+               case AND_OP:            return "AND_OP";
+               case OR_OP:             return "OR_OP";
+               case MUL_ASSIGN:        return "MUL_ASSIGN";
+               case DIV_ASSIGN:        return "DIV_ASSIGN";
+               case MOD_ASSIGN:        return "MOD_ASSIGN";
+               case ADD_ASSIGN:        return "ADD_ASSIGN";
+               case SUB_ASSIGN:        return "SUB_ASSIGN";
+               case LEFT_ASSIGN:       return "LEFT_ASSIGN";
+               case RIGHT_ASSIGN:      return "RIGHT_ASSIGN";
+               case AND_ASSIGN:        return "AND_ASSIGN";
+               case XOR_ASSIGN:        return "XOR_ASSIGN";
+               case OR_ASSIGN:         return "OR_ASSIGN";
+               case TYPEDEF:           return "TYPEDEF";
+               case EXTERN:            return "EXTERN";
+               case STATIC:            return "STATIC";
+               case AUTO:              return "AUTO";
+               case REGISTER:          return "REGISTER";
+               case CODE:              return "CODE";
+               case EEPROM:            return "EEPROM";
+               case INTERRUPT:         return "INTERRUPT";
+               case SFR:               return "SFR";
+               case AT:                return "AT";
+               case SBIT:              return "SBIT";
+               case REENTRANT:         return "REENTRANT";
+               case USING:             return "USING";
+               case XDATA:             return "XDATA";
+               case DATA:              return "DATA";
+               case IDATA:             return "IDATA";
+               case PDATA:             return "PDATA";
+               case VAR_ARGS:          return "VAR_ARGS";
+               case CRITICAL:          return "CRITICAL";
+               case NONBANKED:         return "NONBANKED";
+               case BANKED:            return "BANKED";
+               case CHAR:              return "CHAR";
+               case SHORT:             return "SHORT";
+               case INT:               return "INT";
+               case LONG:              return "LONG";
+               case SIGNED:            return "SIGNED";
+               case UNSIGNED:          return "UNSIGNED";
+               case FLOAT:             return "FLOAT";
+               case DOUBLE:            return "DOUBLE";
+               case CONST:             return "CONST";
+               case VOLATILE:          return "VOLATILE";
+               case VOID:              return "VOID";
+               case BIT:               return "BIT";
+               case STRUCT:            return "STRUCT";
+               case UNION:             return "UNION";
+               case ENUM:              return "ENUM";
+               case ELIPSIS:           return "ELIPSIS";
+               case RANGE:             return "RANGE";
+               case FAR:               return "FAR";
+               case CASE:              return "CASE";
+               case DEFAULT:           return "DEFAULT";
+               case IF:                return "IF";
+               case ELSE:              return "ELSE";
+               case SWITCH:            return "SWITCH";
+               case WHILE:             return "WHILE";
+               case DO:                return "DO";
+               case FOR:               return "FOR";
+               case GOTO:              return "GOTO";
+               case CONTINUE:          return "CONTINUE";
+               case BREAK:             return "BREAK";
+               case RETURN:            return "RETURN";
+               case INLINEASM:         return "INLINEASM";
+               case IFX:               return "IFX";
+               case ADDRESS_OF:        return "ADDRESS_OF";
+               case GET_VALUE_AT_ADDRESS:      return "GET_VALUE_AT_ADDRESS";
+               case SPIL:              return "SPIL";
+               case UNSPIL:            return "UNSPIL";
+               case GETHBIT:           return "GETHBIT";
+               case BITWISEAND:        return "BITWISEAND";
+               case UNARYMINUS:        return "UNARYMINUS";
+               case IPUSH:             return "IPUSH";
+               case IPOP:              return "IPOP";
+               case PCALL:             return "PCALL";
+               case ENDFUNCTION:       return "ENDFUNCTION";
+               case JUMPTABLE:         return "JUMPTABLE";
+               case RRC:               return "RRC";
+               case RLC:               return "RLC";
+               case CAST:              return "CAST";
+               case CALL:              return "CALL";
+               case PARAM:             return "PARAM  ";
+               case NULLOP:            return "NULLOP";
+               case BLOCK:             return "BLOCK";
+               case LABEL:             return "LABEL";
+               case RECEIVE:           return "RECEIVE";
+               case SEND:              return "SEND";
+       }
+       sprintf (buffer, "unkown op %d %c", op, op & 0xff);
 
-  switch (op)
-    {
-    case IDENTIFIER:
-      return "IDENTIFIER";
-    case TYPE_NAME:
-      return "TYPE_NAME";
-    case CONSTANT:
-      return "CONSTANT";
-    case STRING_LITERAL:
-      return "STRING_LITERAL";
-    case SIZEOF:
-      return "SIZEOF";
-    case PTR_OP:
-      return "PTR_OP";
-    case INC_OP:
-      return "INC_OP";
-    case DEC_OP:
-      return "DEC_OP";
-    case LEFT_OP:
-      return "LEFT_OP";
-    case RIGHT_OP:
-      return "RIGHT_OP";
-    case LE_OP:
-      return "LE_OP";
-    case GE_OP:
-      return "GE_OP";
-    case EQ_OP:
-      return "EQ_OP";
-    case NE_OP:
-      return "NE_OP";
-    case AND_OP:
-      return "AND_OP";
-    case OR_OP:
-      return "OR_OP";
-    case MUL_ASSIGN:
-      return "MUL_ASSIGN";
-    case DIV_ASSIGN:
-      return "DIV_ASSIGN";
-    case MOD_ASSIGN:
-      return "MOD_ASSIGN";
-    case ADD_ASSIGN:
-      return "ADD_ASSIGN";
-    case SUB_ASSIGN:
-      return "SUB_ASSIGN";
-    case LEFT_ASSIGN:
-      return "LEFT_ASSIGN";
-    case RIGHT_ASSIGN:
-      return "RIGHT_ASSIGN";
-    case AND_ASSIGN:
-      return "AND_ASSIGN";
-    case XOR_ASSIGN:
-      return "XOR_ASSIGN";
-    case OR_ASSIGN:
-      return "OR_ASSIGN";
-    case TYPEDEF:
-      return "TYPEDEF";
-    case EXTERN:
-      return "EXTERN";
-    case STATIC:
-      return "STATIC";
-    case AUTO:
-      return "AUTO";
-    case REGISTER:
-      return "REGISTER";
-    case CODE:
-      return "CODE";
-    case EEPROM:
-      return "EEPROM";
-    case INTERRUPT:
-      return "INTERRUPT";
-    case SFR:
-      return "SFR";
-    case AT:
-      return "AT";
-    case SBIT:
-      return "SBIT";
-    case REENTRANT:
-      return "REENTRANT";
-    case USING:
-      return "USING";
-    case XDATA:
-      return "XDATA";
-    case DATA:
-      return "DATA";
-    case IDATA:
-      return "IDATA";
-    case PDATA:
-      return "PDATA";
-    case VAR_ARGS:
-      return "VAR_ARGS";
-    case CRITICAL:
-      return "CRITICAL";
-    case NONBANKED:
-      return "NONBANKED";
-    case BANKED:
-      return "BANKED";
-    case CHAR:
-      return "CHAR";
-    case SHORT:
-      return "SHORT";
-    case INT:
-      return "INT";
-    case LONG:
-      return "LONG";
-    case SIGNED:
-      return "SIGNED";
-    case UNSIGNED:
-      return "UNSIGNED";
-    case FLOAT:
-      return "FLOAT";
-    case DOUBLE:
-      return "DOUBLE";
-    case CONST:
-      return "CONST";
-    case VOLATILE:
-      return "VOLATILE";
-    case VOID:
-      return "VOID";
-    case BIT:
-      return "BIT";
-    case STRUCT:
-      return "STRUCT";
-    case UNION:
-      return "UNION";
-    case ENUM:
-      return "ENUM";
-    case ELIPSIS:
-      return "ELIPSIS";
-    case RANGE:
-      return "RANGE";
-    case FAR:
-      return "FAR";
-    case CASE:
-      return "CASE";
-    case DEFAULT:
-      return "DEFAULT";
-    case IF:
-      return "IF";
-    case ELSE:
-      return "ELSE";
-    case SWITCH:
-      return "SWITCH";
-    case WHILE:
-      return "WHILE";
-    case DO:
-      return "DO";
-    case FOR:
-      return "FOR";
-    case GOTO:
-      return "GOTO";
-    case CONTINUE:
-      return "CONTINUE";
-    case BREAK:
-      return "BREAK";
-    case RETURN:
-      return "RETURN";
-    case INLINEASM:
-      return "INLINEASM";
-    case IFX:
-      return "IFX";
-    case ADDRESS_OF:
-      return "ADDRESS_OF";
-    case GET_VALUE_AT_ADDRESS:
-      return "GET_VALUE_AT_ADDRESS";
-    case SPIL:
-      return "SPIL";
-    case UNSPIL:
-      return "UNSPIL";
-    case GETHBIT:
-      return "GETHBIT";
-    case BITWISEAND:
-      return "BITWISEAND";
-    case UNARYMINUS:
-      return "UNARYMINUS";
-    case IPUSH:
-      return "IPUSH";
-    case IPOP:
-      return "IPOP";
-    case PCALL:
-      return "PCALL";
-    case ENDFUNCTION:
-      return "ENDFUNCTION";
-    case JUMPTABLE:
-      return "JUMPTABLE";
-    case RRC:
-      return "RRC";
-    case RLC:
-      return "RLC";
-    case CAST:
-      return "CAST";
-    case CALL:
-      return "CALL";
-    case PARAM:
-      return "PARAM  ";
-    case NULLOP:
-      return "NULLOP";
-    case BLOCK:
-      return "BLOCK";
-    case LABEL:
-      return "LABEL";
-    case RECEIVE:
-      return "RECEIVE";
-    case SEND:
-      return "SEND";
-    }
-  sprintf (buffer, "unkown op %d %c", op, op & 0xff);
   return buffer;
 }
 /*-----------------------------------------------------------------*/
@@ -403,18 +306,14 @@ decodeOp (unsigned int op)
 static char *
 debugLogRegType (short type)
 {
+       if(!pic16_ralloc_debug)return NULL;
+       switch (type) {
+               case REG_GPR: return "REG_GPR";
+               case REG_PTR: return "REG_PTR";
+               case REG_CND: return "REG_CND";
+       }
+       sprintf (buffer, "unknown reg type %d", type);
 
-  switch (type)
-    {
-    case REG_GPR:
-      return "REG_GPR";
-    case REG_PTR:
-      return "REG_PTR";
-    case REG_CND:
-      return "REG_CND";
-    }
-
-  sprintf (buffer, "unknown reg type %d", type);
   return buffer;
 }
 
@@ -459,6 +358,7 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i
        }
 
 //     fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
+
        dReg->isFree = 0;
        dReg->wasUsed = 1;
 
@@ -516,8 +416,12 @@ regFindFree (set *dRegs)
   for (dReg = setFirstItem(dRegs) ; dReg ; 
        dReg = setNextItem(dRegs)) {
 
-    if(dReg->isFree)
+//     fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
+//             __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
+
+    if(dReg->isFree) {
       return dReg;
+    }
   }
 
   return NULL;
@@ -560,7 +464,7 @@ pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
 {
   regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
 
-//  fprintf(stderr,"pic16_allocInternalRegister %s addr =0x%x\n",name,rIdx);
+//  fprintf(stderr,"%s:%d: %s  %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
 
   if(reg) {
     reg->wasUsed = 0;
@@ -575,12 +479,42 @@ pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
 static regs *
 allocReg (short type)
 {
+  regs * reg=NULL;
+  
+#if 0
+  if(dynrIdx > pic16_nRegs)
+       return NULL;
+#endif
+
+#if STACK_SUPPORT
+       if(USE_STACK) {
+               /* try to reuse some unused registers */
+               reg = regFindFree( pic16_dynAllocRegs );
+       }
+#endif
 
-  debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
-  //fprintf(stderr,"allocReg\n");
+       if(!reg) {
+               reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
+               addSet(&pic16_dynAllocRegs, reg);
+       }
+       reg->isFree=0;
 
+       debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
 
-  return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
+//     fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
+//             __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
+
+       if(reg) {
+               reg->accessBank = 1;    /* this is a temporary register alloc in accessBank */
+               reg->isLocal = 1;       /* this is a local frame register */
+       }
+       
+#if STACK_SUPPORT
+       if (currFunc)
+               currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
+#endif
+  return (reg);                // addSet(&pic16_dynAllocRegs,reg);
 
 }
 
@@ -707,6 +641,12 @@ pic16_allocDirReg (operand *op )
     /* Register wasn't found in hash, so let's create
      * a new one and put it in the hash table AND in the 
      * dynDirectRegNames set */
+    if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
+       if(pic16_debug_verbose)
+                       fprintf(stderr, "%s:%d symbol %s in codespace\n", __FILE__, __LINE__,
+                               OP_SYMBOL(op)->name);
+       return NULL;
+    }
     if(!IS_CONFIG_ADDRESS(address)) {
       //fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
 
@@ -731,15 +671,6 @@ pic16_allocDirReg (operand *op )
       debugLog ("  -- %s is declared at address 0x30000x\n",name);
       fprintf(stderr, "  -- %s is declared at address 0x30000x\n",name);
 
-/*
-       fprintf(stderr, "  setting config word to %x\n", 
-                 (int) floatFromVal (op->operand.valOperand)); //IC_RIGHT(ic)->operand.valOperand));
-
-       pic16_assignConfigWordValue(  SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
-                               (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
-*/
-
-
       return NULL;
     }
   }
@@ -905,7 +836,7 @@ pic16_findFreeReg(short type)
   case REG_GPR:
     if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
       return dReg;
-    return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
+    return allocReg( REG_GPR );                //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
 
   case REG_STK:
 
@@ -928,6 +859,7 @@ static void
 freeReg (regs * reg)
 {
        debugLog ("%s\n", __FUNCTION__);
+//     fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
        reg->isFree = 1;
 }
 
@@ -938,20 +870,27 @@ freeReg (regs * reg)
 static int
 nFreeRegs (int type)
 {
+  regs *reg;
+  int nfr=0;
+
+
+               /* although I fixed the register allocation/freeing scheme
+                * the for loop below doesn't give valid results. I do not
+                * know why yet. -- VR 10-Jan-2003 */
+                
+       return 100;
+
+
   /* dynamically allocate as many as we need and worry about
    * fitting them into a PIC later */
 
-  return 100;
-#if 0
-  int i;
-  int nfr = 0;
-
   debugLog ("%s\n", __FUNCTION__);
-  for (i = 0; i < pic16_nRegs; i++)
-    if (regspic16[i].isFree && regspic16[i].type == type)
-      nfr++;
+
+       for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
+               if((reg->type == type) && reg->isFree)nfr++;
+
+       fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
   return nfr;
-#endif
 }
 
 /*-----------------------------------------------------------------*/
@@ -988,8 +927,9 @@ static void writeSetUsedRegs(FILE *of, set *dRegs)
 
 extern void pic16_groupRegistersInSection(set *regset);
 
-extern void pic16_dump_map(void);
-extern void pic16_dump_section(FILE *of, char *sname, set *section, int fix);
+extern void pic16_dump_equates(FILE *of, set *equs);
+//extern void pic16_dump_map(void);
+extern void pic16_dump_section(FILE *of, set *section, int fix);
 
 
 static void packBits(set *bregs)
@@ -1142,9 +1082,11 @@ void pic16_writeUsedRegs(FILE *of)
 //     pic16_dump_map();
 //     pic16_dump_cblock(of);
 
-       pic16_dump_section(of, "ud1", pic16_rel_udata, 0);
-       pic16_dump_section(of, "ud2", pic16_fix_udata, 1);
-
+       pic16_dump_equates(of, pic16_equ_data);
+       
+       pic16_dump_section(of, pic16_rel_udata, 0);
+       pic16_dump_section(of, pic16_fix_udata, 1);
+       
 #if 0
        bitEQUs(of,pic16_dynDirectBitRegs);
        aliasEQUs(of,pic16_dynAllocRegs,0);
@@ -2607,17 +2549,10 @@ DEFSETFUNC (pic16_deallocReg)
 void
 pic16_freeAllRegs ()
 {
-  //  int i;
-
   debugLog ("%s\n", __FUNCTION__);
 
   applyToSet(pic16_dynAllocRegs,markRegFree);
   applyToSet(pic16_dynStackRegs,markRegFree);
-
-/*
-  for (i = 0; i < pic16_nRegs; i++)
-    regspic16[i].isFree = 1;
-*/
 }
 
 /*-----------------------------------------------------------------*/
@@ -2625,20 +2560,9 @@ pic16_freeAllRegs ()
 void
 pic16_deallocateAllRegs ()
 {
-  //  int i;
-
   debugLog ("%s\n", __FUNCTION__);
 
   applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
-
-/*
-  for (i = 0; i < pic16_nRegs; i++) {
-    if(regspic16[i].pc_type == PO_GPR_TEMP) {
-      regspic16[i].isFree = 1;
-      regspic16[i].wasUsed = 0;
-    }
-  }
-*/
 }
 
 
@@ -2804,6 +2728,15 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
        return 0;
 
     }
+
+#if 0
+       if(ic->op == CALL || ic->op == PCALL) {
+               addSet(&pic16_builtin_functions, OP_SYMBOL( IC_LEFT(ic)));
+               debugLog ("%d This is a call, function: %s\n", __LINE__, OP_SYMBOL(IC_LEFT(ic))->name);
+               return 0;
+       }
+#endif
+
   /* find the definition of iTempNN scanning backwards if we find a 
      a use of the true symbol before we find the definition then 
      we cannot pack */
@@ -2821,6 +2754,7 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
          break;
        }
 
+
       if (SKIP_IC2 (dic))
        continue;
 
@@ -3510,10 +3444,11 @@ packForPush (iCode * ic, eBBlock * ebp)
 
 static void printSymType(char * str, sym_link *sl)
 {
-  debugLog ("    %s Symbol type: ",str);
-  printTypeChain( sl, debugF);
-  debugLog ("\n");
-
+       if(!pic16_ralloc_debug)return;
+       
+       debugLog ("    %s Symbol type: ",str);
+       printTypeChain( sl, debugF);
+       debugLog ("\n");
 }
 
 /*-----------------------------------------------------------------*/
@@ -3525,35 +3460,33 @@ static void isData(sym_link *sl)
 {
   FILE *of = stderr;
 
-  if(!sl)
-    return;
-
-  if(debugF)
-    of = debugF;
-
-  for ( ; sl; sl=sl->next) {
-    if(!IS_DECL(sl) ) {
-      switch (SPEC_SCLS(sl)) {
+       if(!pic16_ralloc_debug)return;
        
-      case S_DATA: fprintf (of, "data "); break;
-      case S_XDATA: fprintf (of, "xdata "); break;
-      case S_SFR: fprintf (of, "sfr "); break;
-      case S_SBIT: fprintf (of, "sbit "); break;
-      case S_CODE: fprintf (of, "code "); break;
-      case S_IDATA: fprintf (of, "idata "); break;
-      case S_PDATA: fprintf (of, "pdata "); break;
-      case S_LITERAL: fprintf (of, "literal "); break;
-      case S_STACK: fprintf (of, "stack "); break;
-      case S_XSTACK: fprintf (of, "xstack "); break;
-      case S_BIT: fprintf (of, "bit "); break;
-      case S_EEPROM: fprintf (of, "eeprom "); break;
-      default: break;
-      }
-
-    }
+       if(!sl)return;
+
+       if(debugF)
+               of = debugF;
+
+       for ( ; sl; sl=sl->next) {
+               if(!IS_DECL(sl) ) {
+                       switch (SPEC_SCLS(sl)) {
+                               case S_DATA: fprintf (of, "data "); break;
+                               case S_XDATA: fprintf (of, "xdata "); break;
+                               case S_SFR: fprintf (of, "sfr "); break;
+                               case S_SBIT: fprintf (of, "sbit "); break;
+                               case S_CODE: fprintf (of, "code "); break;
+                               case S_IDATA: fprintf (of, "idata "); break;
+                               case S_PDATA: fprintf (of, "pdata "); break;
+                               case S_LITERAL: fprintf (of, "literal "); break;
+                               case S_STACK: fprintf (of, "stack "); break;
+                               case S_XSTACK: fprintf (of, "xstack "); break;
+                               case S_BIT: fprintf (of, "bit "); break;
+                               case S_EEPROM: fprintf (of, "eeprom "); break;
+                               default: break;
+                       }
 
-  }
-    
+               }
+       }
 }
 
 /*--------------------------------------------------------------------*/
@@ -3606,7 +3539,7 @@ pic16_packRegisters (eBBlock * ebp)
       sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
 
       debugAopGet ("x  left:", IC_LEFT (ic));
-#if 1
+#if 0
       if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
 #else
       if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
@@ -3892,7 +3825,7 @@ dumpEbbsToDebug (eBBlock ** ebbs, int count)
 {
   int i;
 
-  if (!debug || !debugF)
+  if (!pic16_ralloc_debug || !debugF)
     return;
 
   for (i = 0; i < count; i++)
@@ -3982,6 +3915,8 @@ pic16_assignRegisters (eBBlock ** ebbs, int count)
   /* and serially allocate registers */
   serialRegAssign (ebbs, count);
 
+  //pic16_freeAllRegs();
+
   /* if stack was extended then tell the user */
   if (_G.stackExtend)
     {
@@ -4022,7 +3957,7 @@ pic16_assignRegisters (eBBlock ** ebbs, int count)
   setToNull ((void *) &_G.stackSpil);
   setToNull ((void *) &_G.spiltSet);
   /* mark all registers as free */
-  //pic16_freeAllRegs ();
+  pic16_freeAllRegs ();
 
   debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
   debugLogClose ();
index 547ce9302bf5bce6872c8283da709fd3a3dc731a..de67f9bd76223e87fa23b890c1f27eea7d6b4bff 100644 (file)
@@ -77,6 +77,7 @@ typedef struct regs
     unsigned isBitField:1;      /* True if reg is type bit OR is holder for several bits */
     unsigned isEmitted:1;       /* True if the reg has been written to a .asm file */
     unsigned accessBank:1;     /* True if the reg is explicit placed in access bank */
+    unsigned isLocal:1;                /* True if the reg is allocated in function's local frame */
     unsigned address;           /* reg's address if isFixed | isMapped is true */
     unsigned size;              /* 0 for byte, 1 for int, 4 for long */
     unsigned alias;             /* Alias mask if register appears in multiple banks */
@@ -102,8 +103,11 @@ extern set *pic16_dynDirectRegs;
 extern set *pic16_dynDirectBitRegs;
 extern set *pic16_dynInternalRegs;
 
+extern set *pic16_builtin_functions;
+
 extern set *pic16_rel_udata;
 extern set *pic16_fix_udata;
+extern set *pic16_equ_data;
 
 regs *pic16_regWithIdx (int);
 regs *pic16_dirregWithName (char *name );
@@ -133,6 +137,7 @@ regs *pic16_allocRegByName (char *name, int size );
 #define IDX_FSR2H      0xfda
 #define IDX_POSTINC1   0xfe6
 #define IDX_POSTDEC1   0xfe5
+#define IDX_PREINC1    0xfe4
 #define IDX_PREINC2    0xfdc
 #define IDX_PLUSW2     0xfdb