]> git.gag.com Git - fw/sdcc/commitdiff
* device/lib/pic16/startup/crt0i.c (_cinit): local variables where
authorvrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 14 Mar 2005 01:24:58 +0000 (01:24 +0000)
committervrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 14 Mar 2005 01:24:58 +0000 (01:24 +0000)
moved to level 0 and declared as static. Also they are explicit
placed in access bank. This was necessery because some times they
might cross memory bank boundaries. crt0iz.c is *NOT* updated!!!
* src/pic16/device.h: added flag OPTIMIZE_CMP to enable some compare
optimizations. Currently only compare to unsigned char is implemented,
* src/pic16/gen.c: added fReturnIdx array,
* (struct resolvedIfx) is moved to gen.h and made public,
* (struct _G): added sregsAlloc and sregsAllocSet fields,
* (aopForSym): added an optimization to directly store in stack of
the operand of a SEND iCode,
* (pic16_aopOp): don't return return registers as strings (AOP_STR)
but as registers instead (AOP_REG) using the fReturnIdx array,
* (pic16_freeAsmop): remove the freed register from the
_G.sregsAlloc field,
* (pic16_aopGet): in case AOP_STR, the compare to 'a' is changed to
a compare of 'WREG',
* (pic16_popGetTempRegCond): changed function prototype, now
function takes also a bitVector argument v which holds the current
set of registers that are allocated for stack access by aopForSym,
registers allocated in aopForSym for accessing stack symbols are not
any more part of the functions usedRegs field,
* (genCall): some times aopOp is called for a stack variable to be
send, aopForSym might perform the push, if this is true make sure
that genCall doesn't push the variable twice by testing _G.resDirect,
* (genFunction): changed testing for unspecified interrupt number
from 256 to INTNO_UNSPEC,
* modified selection scheme of frame pointer generation. Previously
if function did use local registers a frame pointer was generated,
now a frame pointer is generated only if function has arguments
(that need PLUSW2 register access), or has stack arguments, or the
compiler is not instructed to omit the frame pointer,
* (genEndFunction): before restoring local registers that were saved
in the function preamble, also restore the registers that *might*
have been allocated for stack access,
* (genRet): removed some old comments,
* (genCmp, the active (RN's) version): added a call to the
pic16_genCmp_special function to perform the compare with a more
robust and optimized way,
* (genInline): a feature has been added in inline code generation,
which allows a wildcard variable substitution when writing inline
assembly. Code is incomplete and experimental therefore undocumented,
* (genCast): changed order of aopOp for result and right to allow
aopForSym to directly load the result if possible,
* src/pic16/genutils.c (selectCompareOp, pic16_genCmp_special): NEW,
perform an optimized compare on some selected special occasions,
* src/pic16/genutils.h: declaration of resolvedIfx structure from gen.c,
* src/pic16/glue.c (pic16createInterrupVect): make sure we never
generate an IVT any more,
* src/pic16/main.c (pic16_optionsTable): added command line option
--optimize-cmp,
* (_pic16_initPaths): when calling C preprocessor define pic18fXXXX
macro too, when calling assembler define pic18fXXXX *and* __18Fxxxx
macros,
* src/pic16/NOTES: Raphael Neider added in list of active developers
* src/pic16/pcode.c (OPT_TYPE_STR): added strings jumptable_begin and
jumptable_end to prevent bug #,
* (pic16_pciADDWFC, ADDFWC, COMF, CLRF): added some missing flags in
inCond and outCond fields,
* src/pic16/pcoderegs.c (pCodeOptime2pCodes): add a fix for bug #,
* src/pic16/ralloc.c (serialRegAssign): explicit set willCS to 0 to
turn off register spilling,
* (packRegsForOneUse): synced with other ports' versions although it
is not used currently,
* (pic16_packRegisters): added an optimization while reading
structure bitfields, some registers may be saved (malloc code is
decreased by 80 bytes)

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

16 files changed:
ChangeLog
device/lib/pic16/startup/crt0i.c
src/SDCCicode.c
src/pic16/NOTES
src/pic16/device.h
src/pic16/gen.c
src/pic16/gen.h
src/pic16/genutils.c
src/pic16/genutils.h
src/pic16/glue.c
src/pic16/main.c
src/pic16/pcode.c
src/pic16/pcode.h
src/pic16/pcoderegs.c
src/pic16/peeph.def
src/pic16/ralloc.c

index 808c82c8c1af72c48fcb48bcf2a6f8063402e90c..99640ebc31ff4be2e4e223373423562d2ea722ee 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,73 @@
+2005-03-12 Vangelis Rokas <vrokas AT users.sourceforge.net>
+
+       * device/lib/pic16/startup/crt0i.c (_cinit): local variables where
+       moved to level 0 and declared as static. Also they are explicit
+       placed in access bank. This was necessery because some times they
+       might cross memory bank boundaries. crt0iz.c is *NOT* updated!!!
+       * src/pic16/device.h: added flag OPTIMIZE_CMP to enable some compare
+       optimizations. Currently only compare to unsigned char is implemented,
+       * src/pic16/gen.c: added fReturnIdx array,
+       * (struct resolvedIfx) is moved to gen.h and made public,
+       * (struct _G): added sregsAlloc and sregsAllocSet fields,
+       * (aopForSym): added an optimization to directly store in stack of
+       the operand of a SEND iCode,
+       * (pic16_aopOp): don't return return registers as strings (AOP_STR)
+       but as registers instead (AOP_REG) using the fReturnIdx array,
+       * (pic16_freeAsmop): remove the freed register from the
+       _G.sregsAlloc field,
+       * (pic16_aopGet): in case AOP_STR, the compare to 'a' is changed to
+       a compare of 'WREG',
+       * (pic16_popGetTempRegCond): changed function prototype, now
+       function takes also a bitVector argument v which holds the current
+       set of registers that are allocated for stack access by aopForSym,
+       registers allocated in aopForSym for accessing stack symbols are not
+       any more part of the functions usedRegs field,
+       * (genCall): some times aopOp is called for a stack variable to be
+       send, aopForSym might perform the push, if this is true make sure
+       that genCall doesn't push the variable twice by testing _G.resDirect,
+       * (genFunction): changed testing for unspecified interrupt number
+       from 256 to INTNO_UNSPEC,
+       * modified selection scheme of frame pointer generation. Previously
+       if function did use local registers a frame pointer was generated,
+       now a frame pointer is generated only if function has arguments
+       (that need PLUSW2 register access), or has stack arguments, or the
+       compiler is not instructed to omit the frame pointer,
+       * (genEndFunction): before restoring local registers that were saved
+       in the function preamble, also restore the registers that *might*
+       have been allocated for stack access,
+       * (genRet): removed some old comments,
+       * (genCmp, the active (RN's) version): added a call to the
+       pic16_genCmp_special function to perform the compare with a more
+       robust and optimized way,
+       * (genInline): a feature has been added in inline code generation,
+       which allows a wildcard variable substitution when writing inline
+       assembly. Code is incomplete and experimental therefore undocumented,
+       * (genCast): changed order of aopOp for result and right to allow
+       aopForSym to directly load the result if possible,
+       * src/pic16/genutils.c (selectCompareOp, pic16_genCmp_special): NEW,
+       perform an optimized compare on some selected special occasions,
+       * src/pic16/genutils.h: declaration of resolvedIfx structure from gen.c,
+       * src/pic16/glue.c (pic16createInterrupVect): make sure we never
+       generate an IVT any more,
+       * src/pic16/main.c (pic16_optionsTable): added command line option
+       --optimize-cmp,
+       * (_pic16_initPaths): when calling C preprocessor define pic18fXXXX
+       macro too, when calling assembler define pic18fXXXX *and* __18Fxxxx
+       macros,
+       * src/pic16/NOTES: Raphael Neider added in list of active developers
+       * src/pic16/pcode.c (OPT_TYPE_STR): added strings jumptable_begin and
+       jumptable_end to prevent bug #,
+       * (pic16_pciADDWFC, ADDFWC, COMF, CLRF): added some missing flags in
+       inCond and outCond fields,
+       * src/pic16/pcoderegs.c (pCodeOptime2pCodes): add a fix for bug #,
+       * src/pic16/ralloc.c (serialRegAssign): explicit set willCS to 0 to
+       turn off register spilling,
+       * (packRegsForOneUse): synced with other ports' versions although it
+       is not used currently,
+       * (pic16_packRegisters): added an optimization while reading
+       structure bitfields, some registers may be saved (malloc code is
+       decreased by 80 bytes)
+
 2005-03-12 Vangelis Rokas <vrokas AT users.sourceforge.net>
 
        * src/SDCCcse.c (cseBBlock): inside 'do operand lookup' loop test if
index 75dd6b48c2844439cac9b21d68962c3557b0cce8..9459d62c3aa2c040a00b1d9651c9c75a3a1d5000 100644 (file)
@@ -86,6 +86,14 @@ extern code struct
 #define tblrdpostinc   tblrd*+
 
 
+#pragma udata access _do_cinit_prom, _do_cinit_curr_byte
+#pragma udata access _do_cinit_ curr_entry, _do_cinit_data_ptr
+
+static short long _do_cinit_prom;
+static unsigned short _do_cinit_curr_byte;
+static unsigned short _do_cinit_curr_entry;
+static short long _do_cinit_data_ptr;
+
 /* the variable initialisation routine */
 void _do_cinit (void)
 {
@@ -93,10 +101,6 @@ void _do_cinit (void)
    * we'll make the assumption in the following code that these statics
    * will be allocated into the same bank.
    */
-  static short long prom;
-  static unsigned short curr_byte;
-  static unsigned short curr_entry;
-  static short long data_ptr;
 
 
        /* TBLPTR = &cinit */
@@ -112,13 +116,13 @@ void _do_cinit (void)
        
        /* curr_entry = cinit.num_init */
        _asm
-               movlb __do_cinit_data_ptr_1_1
+               movlb __do_cinit_data_ptr
                tblrdpostinc
                movf _TABLAT, 0, 0
-               movwf __do_cinit_curr_entry_1_1, 1
+               movwf __do_cinit_curr_entry, 1
                tblrdpostinc
                movf _TABLAT, 0, 0
-               movwf __do_cinit_curr_entry_1_1+1, 1
+               movwf __do_cinit_curr_entry+1, 1
        _endasm;
 
 
@@ -126,7 +130,7 @@ void _do_cinit (void)
        _asm
 test:
        bnz done1
-       tstfsz __do_cinit_curr_entry_1_1, 1
+       tstfsz __do_cinit_curr_entry, 1
        bra cont1
 
 done1:
@@ -148,17 +152,17 @@ cont1:
                /* read the source address low */
                tblrdpostinc
                movf _TABLAT, 0, 0
-               movwf __do_cinit_prom_1_1, 1
+               movwf __do_cinit_prom, 1
                
                /* source address high */
                tblrdpostinc
                movf _TABLAT, 0, 0
-               movwf __do_cinit_prom_1_1 + 1, 1
+               movwf __do_cinit_prom + 1, 1
 
                /* source address upper */
                tblrdpostinc
                movf _TABLAT, 0, 0
-               movwf __do_cinit_prom_1_1 + 2, 1
+               movwf __do_cinit_prom + 2, 1
 
                /* skip a byte since it's stored as a 32bit int */
                tblrdpostinc
@@ -181,10 +185,10 @@ cont1:
                /* read the destination address directly into FSR0 */
                tblrdpostinc
                movf _TABLAT, 0, 0
-               movwf __do_cinit_curr_byte_1_1, 1
+               movwf __do_cinit_curr_byte, 1
                tblrdpostinc
                movf _TABLAT, 0, 0
-               movwf __do_cinit_curr_byte_1_1+1, 1
+               movwf __do_cinit_curr_byte+1, 1
 
                /* skip two bytes since it's stored as a 32bit int */
                tblrdpostinc
@@ -200,29 +204,29 @@ cont1:
   
        /*  data_ptr = TBLPTR */
        _asm
-               movff _TBLPTRL, __do_cinit_data_ptr_1_1
-               movff _TBLPTRH, __do_cinit_data_ptr_1_1 + 1
-               movff _TBLPTRU, __do_cinit_data_ptr_1_1 + 2
+               movff _TBLPTRL, __do_cinit_data_ptr
+               movff _TBLPTRH, __do_cinit_data_ptr + 1
+               movff _TBLPTRU, __do_cinit_data_ptr + 2
        _endasm;
   
       
        /* now assign the source address to the table pointer */
        /*  TBLPTR = prom */
        _asm
-               movff __do_cinit_prom_1_1, _TBLPTRL
-               movff __do_cinit_prom_1_1 + 1, _TBLPTRH
-               movff __do_cinit_prom_1_1 + 2, _TBLPTRU
+               movff __do_cinit_prom, _TBLPTRL
+               movff __do_cinit_prom + 1, _TBLPTRH
+               movff __do_cinit_prom + 2, _TBLPTRU
        _endasm;
 
        /* do the copy loop */
        _asm
 
                /* determine if we have any more bytes to copy */
-               movlb __do_cinit_curr_byte_1_1
-               movf __do_cinit_curr_byte_1_1, 1, 1
+               movlb __do_cinit_curr_byte
+               movf __do_cinit_curr_byte, 1, 1
 copy_loop:
                bnz copy_one_byte // copy_one_byte
-               movf __do_cinit_curr_byte_1_1 + 1, 1, 1
+               movf __do_cinit_curr_byte + 1, 1, 1
                bz done_copying
 
 copy_one_byte:
@@ -231,9 +235,9 @@ copy_one_byte:
                movwf _POSTINC0, 0
 
                /* decrement byte counter */
-               decf __do_cinit_curr_byte_1_1, 1, 1
+               decf __do_cinit_curr_byte, 1, 1
                bnc copy_loop // copy_loop
-               decf __do_cinit_curr_byte_1_1 + 1, 1, 1
+               decf __do_cinit_curr_byte + 1, 1, 1
 
                bra copy_loop
 done_copying:
@@ -242,14 +246,14 @@ done_copying:
        /* restore the table pointer for the next entry */
        /*  TBLPTR = data_ptr */
        _asm
-               movff __do_cinit_data_ptr_1_1, _TBLPTRL
-               movff __do_cinit_data_ptr_1_1 + 1, _TBLPTRH
-               movff __do_cinit_data_ptr_1_1 + 2, _TBLPTRU
+               movff __do_cinit_data_ptr, _TBLPTRL
+               movff __do_cinit_data_ptr + 1, _TBLPTRH
+               movff __do_cinit_data_ptr + 2, _TBLPTRU
        _endasm;
 
   
        /* next entry... */
-       curr_entry--;
+       _do_cinit_curr_entry--;
 
        _asm
                goto test;
index b989c88dd6fd79ab1e2724fc72971947bfc8f240..4d0a9f4bf1d4a488b6c1c19f077fe91c19ffca2d 100644 (file)
@@ -233,7 +233,8 @@ printOperand (operand * op, FILE * file)
 
     case SYMBOL:
 #define REGA 1
-#if REGA
+//#if REGA     /* { */
+    if(REGA && !getenv("PRINT_SHORT_OPERANDS")) {
       fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d a2p%d re%d rm%d nos%d ru%d dp%d}",          /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}"  , */
               (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
               op->key,
@@ -276,28 +277,26 @@ printOperand (operand * op, FILE * file)
              fprintf (file, "]");
            }
        }
-#else
-
+//#else                /* } else { */
+    } else {
+      /* (getenv("PRINT_SHORT_OPERANDS") != NULL) */
       fprintf (file, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
 
-#if 0
-
-      fprintf (file, "[lr%d:%d so:%d]",
+      if(getenv("PRINT_SHORT_OPERANDS")[0] < '1')
+        {
+          fprintf (file, "[lr%d:%d so:%d]",
               OP_LIVEFROM (op), OP_LIVETO (op),
-              OP_SYMBOL (op)->stack
-       );
-#endif
-
-#if 1
-      {
-       fprintf (file, "{");
-       printTypeChain (operandType (op), file);
-       if (SPIL_LOC (op) && IS_ITEMP (op))
-         fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
-       fprintf (file, "}");
+              OP_SYMBOL (op)->stack);
+        }
 
-      }
-#endif
+      if(getenv("PRINT_SHORT_OPERANDS")[0] < '2')
+        {
+          fprintf (file, "{");
+          printTypeChain (operandType (op), file);
+          if (SPIL_LOC (op) && IS_ITEMP (op))
+              fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
+          fprintf (file, "}");
+        }
 
       /* if assigned to registers */
       if (OP_SYMBOL (op)->nRegs)
@@ -323,7 +322,8 @@ printOperand (operand * op, FILE * file)
              fprintf (file, "]");
            }
        }
-#endif
+//#endif               /* } */
+    }
       break;
 
     case TYPE:
index 4c6e5b140611986050346cc7096d32bfd13beab4..35cf93184a69dc0f64b108d9f9fec0698573b5b8 100644 (file)
@@ -1,4 +1,4 @@
-NOTES file for SDCC pic16 port
+lNOTES file for SDCC pic16 port
 $Id$
 
 Current pic16 port status is: Development
@@ -11,7 +11,8 @@ For any questions please ask the current port
 developers.
 
 Current developer:
-Vangelis Rokas <vrokas AT otenet.gr>
+Vangelis Rokas <vrokas AT users.sourceforge.net>
+Raphael Neider <rneider AT web.de>
 
 Other people to contact:
 Scott Dattalo  <scott AT dattalo.com>
index 1bcafdd4df995107941a0387c9936d488212b000..db4acee49945b4b213ded3d20344ebd54f077c29 100644 (file)
@@ -88,6 +88,7 @@ typedef struct PIC16_device {
 
 #define OF_LR_SUPPORT          0x00000001
 #define OF_OPTIMIZE_GOTO       0x00000002
+#define OF_OPTIMIZE_CMP                0x00000004
 
 typedef struct {
   int no_banksel;
@@ -113,6 +114,8 @@ typedef struct {
 extern set *fix_idataSymSet;
 extern set *rel_idataSymSet;
 
+extern set *asmInlineMap;
+
 typedef struct {
   unsigned long isize;
   unsigned long adsize;
index dcc0b93d794fa4dc02c99323551d017c3623d3e5..41b5a82a15b1790c932c2c2cbee6c304a36ef8d1 100644 (file)
@@ -1,4 +1,4 @@
-/*-------------------------------------------------------------------------
+ /*-------------------------------------------------------------------------
  gen.c - source file for code generation for pic16
 
   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
@@ -135,6 +135,7 @@ static char *one  = "#0x01";
  
 
 char *fReturnpic16[] = {"WREG", "PRODL", "PRODH", "FSR0L" };
+int fReturnIdx[] = {IDX_WREG, IDX_PRODL, IDX_PRODH, IDX_FSR0L };
 unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */
 static char **fReturn = fReturnpic16;
 
@@ -154,22 +155,14 @@ static struct {
     set *sendSet;
     set *stackRegSet;
     int usefastretfie;
-    bitVect *fregsUsed;
+    bitVect *fregsUsed;                        /* registers used in function */
+    bitVect *sregsAlloc;
+    set *sregsAllocSet;                        /* registers used to store stack variables */
     int stack_lat;                     /* stack offset latency */
     int resDirect;
     int useWreg;                       /* flag when WREG is used to pass function parameter */
 } _G;
 
-/* Resolved ifx structure. This structure stores information
-   about an iCode ifx that makes it easier to generate code.
-*/
-typedef struct resolvedIfx {
-  symbol *lbl;     /* pointer to a label */
-  int condition;   /* true or false ifx */
-  int generated;   /* set true when the code associated with the ifx
-                   * is generated */
-} resolvedIfx;
-
 extern int pic16_ptrRegReq ;
 extern int pic16_nRegs;
 extern FILE *codeOutFile;
@@ -683,19 +676,25 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
         aop->size = getSize(sym->type);
 
 
-        DEBUGpic16_emitcode("; +++", "%s:%d", __FILE__, __LINE__);
-        if((ic->op == '=') && IC_RESULT(ic) && AOP( IC_RESULT(ic) )
-          && (AOP_TYPE(IC_RESULT(ic)) == AOP_REG) ) {
+        DEBUGpic16_emitcode("; +++ ", "%s:%d\top = %s", __FILE__, __LINE__, pic16_decodeOp(ic->op));
+        if((ic->op == '=' /*|| ic->op == CAST*/) && IC_RESULT(ic) && AOP( IC_RESULT(ic) )
+          && (AOP_TYPE(IC_RESULT(ic)) == AOP_REG)) {
           pic16_DumpAop("aopForSym", AOP( IC_RESULT(ic) ));
           
           for(i=0;i<aop->size;i++)
             aop->aopu.stk.pop[i] = pcop[i] = pic16_popRegFromIdx( AOP(IC_RESULT(ic))->aopu.aop_reg[i]->rIdx);
             _G.resDirect = 1;  /* notify that result will be loaded directly from aopForSym */
         } else
+        if(1 && ic->op == SEND) {
+
+          /* if SEND do the send here */
+          _G.resDirect = 1;
+        } else {
           for(i=0;i<aop->size;i++) {
-            aop->aopu.stk.pop[i] = pcop[i] = pic16_popGetTempRegCond( _G.fregsUsed, 0 );
-            _G.fregsUsed = bitVectSetBit(_G.fregsUsed, PCOR(pcop[i])->r->rIdx);
+            aop->aopu.stk.pop[i] = pcop[i] = pic16_popGetTempRegCond(_G.fregsUsed, _G.sregsAlloc, 0 );
+            _G.sregsAlloc = bitVectSetBit(_G.sregsAlloc, PCOR(pcop[i])->r->rIdx);
           }
+        }
 
 
 //        fprintf(stderr, "%s:%d\t%s\tsym size %d\n", __FILE__, __LINE__, __FUNCTION__, aop->size);
@@ -722,9 +721,17 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
              assert (soffs < 0);
              soffs++;
            } // if
-           pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + i /*+ _G.stack_lat*/));
-           pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
-                           pic16_popCopyReg( pic16_frame_plusw ), pcop[i]));
+
+            if(1 && ic->op == SEND) {
+              pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + aop->size - i - 1 /*+ _G.stack_lat*/));
+              pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                    pic16_popCopyReg( pic16_frame_plusw ),
+                    pic16_popCopyReg(pic16_stack_postdec )));
+            } else {
+              pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + i /*+ _G.stack_lat*/));
+              pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                 pic16_popCopyReg( pic16_frame_plusw ), pcop[i]));
+            }
          }
        }
        
@@ -1233,10 +1240,10 @@ void pic16_aopOp (operand *op, iCode *ic, bool result)
 
          unsigned i;
 
-         aop = op->aop = sym->aop = newAsmop(AOP_STR);
+         aop = op->aop = sym->aop = newAsmop(AOP_REG);
          aop->size = getSize(sym->type);
          for ( i = 0 ; i < pic16_fReturnSizePic ; i++ )
-           aop->aopu.aop_str[i] = fReturn[i];
+           aop->aopu.aop_reg[i] = PCOR(pic16_popRegFromIdx( fReturnIdx[i] ))->r;
 
          DEBUGpic16_emitcode(";","%d",__LINE__);
          return;
@@ -1376,8 +1383,13 @@ void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
               }
 
               if(!_G.resDirect) {
-                for(i=0;i<aop->size;i++)
+                for(i=0;i<aop->size;i++) {
                   PCOR(aop->aopu.stk.pop[i] )->r->isFree = 1;
+
+                  if(bitVectBitValue(_G.sregsAlloc, PCOR(aop->aopu.stk.pop[i])->r->rIdx))
+                      bitVectUnSetBit(_G.sregsAlloc, PCOR(aop->aopu.stk.pop[i])->r->rIdx);
+                }
+                  
               }
               _G.resDirect = 0;
           }
@@ -1550,9 +1562,14 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
        
     case AOP_STR:
        aop->coff = offset ;
-       if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
-           dname)
-           return "acc";
+
+//     if (strcmp(aop->aopu.aop_str[offset],"a") == 0 &&
+//         dname)
+//         return "acc";
+        if(!strcmp(aop->aopu.aop_str[offset], "WREG")) {
+          aop->type = AOP_ACC;
+          return Safe_strdup("WREG");
+        }
         DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]);
        
        return aop->aopu.aop_str[offset];
@@ -1656,13 +1673,15 @@ pCodeOp *pic16_popGetTempReg(int lock)
 }
 
 /*-----------------------------------------------------------------*/
-/* pic16_popGetTempRegCond - create a new temporary pCodeOp, but   */
-/*                            don't save if inside v               */
+/* pic16_popGetTempRegCond - create a new temporary pCodeOp which  */
+/*                           is not part of f, but don't save if   */
+/*                           inside v                              */
 /*-----------------------------------------------------------------*/
-pCodeOp *pic16_popGetTempRegCond(bitVect *v, int lock)
+pCodeOp *pic16_popGetTempRegCond(bitVect *f, bitVect *v, int lock)
 {
-  pCodeOp *pcop;
+  pCodeOp *pcop=NULL;
   symbol *cfunc;
+  int i;
 
 //    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
@@ -1675,15 +1694,58 @@ pCodeOp *pic16_popGetTempRegCond(bitVect *v, int lock)
     cfunc = currFunc;
     currFunc = NULL;
 
-    pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
-    if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
-      PCOR(pcop)->r->wasUsed=1;
-      PCOR(pcop)->r->isFree=0;
+    i = bitVectFirstBit(f);
+    while(i < 128) {
 
-      if(!bitVectBitValue(v, PCOR(pcop)->r->rIdx)) {
-      /* push value on stack */
-        pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
+      /* bypass registers that are used by function */
+      if(!bitVectBitValue(f, i)) {
+      
+        /* bypass registers that are already allocated for stack access */
+        if(!bitVectBitValue(v, i))  {
+        
+//          debugf("getting register rIdx = %d\n", i);
+          /* ok, get the operand */
+          pcop = pic16_newpCodeOpReg( i );
+    
+          /* should never by NULL */
+          assert( pcop != NULL );
+
+          
+          /* sanity check */
+          if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
+            int found=0;
+            
+              PCOR(pcop)->r->wasUsed=1;
+              PCOR(pcop)->r->isFree=0;
+
+
+              {
+                regs *sr;
+              
+                  for(sr=setFirstItem(_G.sregsAllocSet);sr;sr=setNextItem(_G.sregsAllocSet)) {
+
+                    if(sr->rIdx == PCOR(pcop)->r->rIdx) {
+                      /* already used in previous steps, break */
+                      found=1;          
+                      break;
+                    }
+                  }
+              }
+
+              /* caller takes care of the following */
+//              bitVectSetBit(v, i);
+
+              if(!found) {
+                /* push value on stack */
+                pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
+                addSet(&_G.sregsAllocSet, PCOR(pcop)->r);
+              }
+          
+            break;
+          }
+        }
       }
+      i++;
     }
 
     currFunc = cfunc;
@@ -1703,6 +1765,7 @@ void pic16_popReleaseTempReg(pCodeOp *pcop, int lock)
 
   if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
     PCOR(pcop)->r->isFree = 1;
+
     pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) );
   }
 }
@@ -2380,7 +2443,7 @@ void pic16_poppCodeOp(pCodeOp *pcop)
 void pushw(void)
 {
   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-  pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec )); //&pic16_pc_postdec1));
+  pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec ));
   if(pic16_options.gstack)
     pic16_testStackOverflow();
 }
@@ -2395,10 +2458,10 @@ void pushaop(asmop *aop, int offset)
 
   if(is_LitAOp(aop)) {
     pic16_emitpcode(POC_MOVLW, pic16_popGet(aop, offset));
-    pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec ));       //&pic16_pc_postdec1));
+    pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec ));
   } else {
     pic16_emitpcode(POC_MOVFF,
-      pic16_popGet2p(pic16_popGet(aop, offset), pic16_popCopyReg( pic16_stack_postdec )));     //&pic16_pc_postdec1)));
+      pic16_popGet2p(pic16_popGet(aop, offset), pic16_popCopyReg( pic16_stack_postdec )));
   }
 
   if(pic16_options.gstack)
@@ -3311,7 +3374,9 @@ static void genCall (iCode *ic)
 
 //                pushaop(AOP(IC_LEFT(sic)), size);
                 pic16_mov2w (AOP(IC_LEFT(sic)), size);
-                pushw();
+
+                if(!_G.resDirect)
+                  pushw();
               }
             }
 
@@ -3588,34 +3653,16 @@ static void genFunction (iCode *ic)
 
 //        debugf("interrupt number: %hhi\n", FUNC_INTNO(sym->type));
 
-#if 0
-        {
-          int i, found=-1;
-
-            sym = OP_SYMBOL( IC_LEFT(ic));
-            for(i=0;i<=2;i++) {
-              if(interrupts[i]->name
-                    && !STRCASECMP(interrupts[i]->name, sym->name)) {
-                  found = i;
-                  break;
-              }
-            }
-                       
-            if(found == -1) {
-              fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n",
-                            __FILE__, __LINE__, sym->name);
-//              assert( 0 );
-            }
-            _G.interruptvector = found;
-        }
-#endif
-
-        if(FUNC_INTNO(sym->type) == 256)
+        if(FUNC_INTNO(sym->type) == INTNO_UNSPEC)
           sprintf(asymname, "ivec_%s", sym->name);
         else
           sprintf(asymname, "ivec_0x%x_%s", FUNC_INTNO(sym->type), sym->name);
         asym = newSymbol(asymname, 0);
 
+        /* FIXME: when an interrupt is declared as naked, do not emit the special
+         * wrapper segment at vector address. The user should take care for this
+         * instead. -- VR */
+        
         apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
         pic16_addpBlock( apb );
 
@@ -3638,6 +3685,7 @@ static void genFunction (iCode *ic)
               case 2: abSym->address = 0x000018; break;
               
               default:
+                fprintf(stderr, "no interrupt number is given\n");
                 abSym->address = -1; break;
             }
 
@@ -3680,7 +3728,10 @@ static void genFunction (iCode *ic)
       //pic16_emitcode("clr","ea");
     }
 
+    currFunc = sym;            /* update the currFunc symbol */
     _G.fregsUsed = sym->regsUsed;
+    _G.sregsAlloc = newBitVect(128);
+    
 
     /* if this is an interrupt service routine then
      * save wreg, status, bsr, prodl, prodh, fsr0l, fsr0h */
@@ -3705,15 +3756,19 @@ static void genFunction (iCode *ic)
         pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
         
 //        pic16_pBlockConvert2ISR(pb);
-                
     }
 
     /* emit code to setup stack frame if user enabled,
      * and function is not main() */
     
-    //fprintf(stderr, "function name: %s\n", sym->name);
+//    debugf(stderr, "function name: %s ARGS=%p\n", sym->name, FUNC_ARGS(sym->type));
     if(strcmp(sym->name, "main")) {
-      if(0 || !options.ommitFramePtr || sym->regsUsed) {
+      if(0 
+        || !options.ommitFramePtr 
+//        || sym->regsUsed
+        || IFFUNC_ARGS(sym->type)
+        || FUNC_HASSTACKPARM(sym->etype)
+        ) {
         /* setup the stack frame */
         if(STACK_MODEL_LARGE)
           pic16_pushpCodeOp(pic16_popCopyReg(pic16_framepnt_hi));
@@ -3802,6 +3857,17 @@ static void genEndFunction (iCode *ic)
     
     /* now we need to restore the registers */
     /* if any registers used */
+
+    /* first restore registers that might be used for stack access */
+    if(_G.sregsAllocSet) {
+    regs *sr;
+    
+      _G.sregsAllocSet = reverseSet( _G.sregsAllocSet );
+      for(sr=setFirstItem(_G.sregsAllocSet) ; sr; sr=setNextItem(_G.sregsAllocSet)) {
+        pic16_poppCodeOp( pic16_popRegFromIdx( sr->rIdx ) );
+      }
+    }
+
     if (sym->regsUsed) {
       int i;
 
@@ -3815,9 +3881,10 @@ static void genEndFunction (iCode *ic)
           }
         }
         pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_END));
-
     }
 
+      
+
     if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
           && sym->stack) {
       if (sym->stack == 1) {
@@ -3836,7 +3903,12 @@ static void genEndFunction (iCode *ic)
     }
 
     if(strcmp(sym->name, "main")) {
-      if(0 || !options.ommitFramePtr || sym->regsUsed) {
+      if(0
+        || !options.ommitFramePtr
+//        || sym->regsUsed
+        || IFFUNC_ARGS(sym->type)
+        || FUNC_HASSTACKPARM(sym->etype)
+        ) {
         /* restore stack frame */
         if(STACK_MODEL_LARGE)
           pic16_poppCodeOp( pic16_popCopyReg( pic16_framepnt_hi ));
@@ -3899,36 +3971,39 @@ static void genEndFunction (iCode *ic)
 }
 
 
-void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
+void pic16_storeForReturn(iCode *ic, /*operand *op,*/ int offset, pCodeOp *dest)
 {
   unsigned long lit=1;
-  // this fails for is_LitOp(op) (if op is an AOP_PCODE)
-  if(AOP_TYPE(op) == AOP_LIT) {
-    if(!IS_FLOAT(operandType( op ))) {
-      lit = (unsigned long)floatFromVal(AOP(op)->aopu.aop_lit);
-    } else {
-      union {
-        unsigned long lit_int;
-        float lit_float;
-      } info;
+  operand *op;
+
+    op = IC_LEFT(ic);
+  
+    // this fails for is_LitOp(op) (if op is an AOP_PCODE)
+    if(AOP_TYPE(op) == AOP_LIT) {
+      if(!IS_FLOAT(operandType( op ))) {
+        lit = (unsigned long)floatFromVal(AOP(op)->aopu.aop_lit);
+      } else {
+        union {
+          unsigned long lit_int;
+          float lit_float;
+        } info;
        
-      /* take care if literal is a float */
-      info.lit_float = floatFromVal(AOP(op)->aopu.aop_lit);
-      lit = info.lit_int;
+        /* take care if literal is a float */
+        info.lit_float = floatFromVal(AOP(op)->aopu.aop_lit);
+        lit = info.lit_int;
+      }
     }
-  }
 
-  if(is_LitOp(op)) {
-      if(lit == 0) {
+    if(is_LitOp(op)) {
+      if(/*(OP_LIVETO(op) <= ic->seq) &&*/ (lit == 0)) {
         pic16_emitpcode(POC_CLRF, dest);
       } else {
         pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset));
         if(dest->type != PO_WREG)pic16_emitpcode(POC_MOVWF, dest);
       }
-  } else {
-    if(dest->type == PO_WREG && (offset == 0)) {
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset));
+    } else {
+      if(dest->type == PO_WREG && (offset == 0)) {
+        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset));
       return;
     }
     pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op), offset), dest));
@@ -3956,27 +4031,16 @@ static void genRet (iCode *ic)
        size = AOP_SIZE(IC_LEFT(ic));
 
        if(size <= 4) {
-               if(size>3) {
-                       pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l));
-//                     pic16_emitpcode(POC_MOVFF,
-//                             pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l)));
-               }
-               if(size>2) {
-                       pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh));
-//                     pic16_emitpcode(POC_MOVFF,
-//                             pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh)));
-               }
-               if(size>1) {
-                       pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl));
-//                     pic16_emitpcode(POC_MOVFF,
-//                             pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl)));
-               }
-
-//             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0));  // patch 12
+         if(size>3)
+           pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 3, pic16_popCopyReg(&pic16_pc_fsr0l));
+          
+          if(size>2)
+            pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 2, pic16_popCopyReg(&pic16_pc_prodh));
 
-               pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg));  // patch 12
-//             pic16_emitpcode(POC_MOVFF,
-//                     pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg)));
+          if(size>1)
+            pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 1, pic16_popCopyReg(&pic16_pc_prodl));
+          
+          pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 0, pic16_popCopyReg(&pic16_pc_wreg));
 
        } else {
                /* >32-bits, setup stack and FSR0 */
@@ -4878,11 +4942,6 @@ static int genChkZeroes(operand *op, int lit,  int size)
 }
 #endif
 
-#if !defined(__BORLANDC__) && !defined(_MSC_VER)
-#define DEBUGpc(fmt,...)  DEBUGpic16_emitcode("; =:=", "%s:%s:%d: " fmt, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
-#endif
-#define isAOP_LIT(x)      (AOP_TYPE(x) == AOP_LIT)
-#define isAOP_REGlike(x)  (AOP_TYPE(x) == AOP_REG || AOP_TYPE(x) == AOP_DIR || AOP_TYPE(x) == AOP_PCODE || AOP_TYPE(x) == AOP_STA)
 
 /*-----------------------------------------------------------------*/
 /* mov2w_regOrLit :- move to WREG either the offset's byte from    */
@@ -4901,7 +4960,7 @@ void mov2w_regOrLit (asmop *aop, unsigned long lit, int offset) {
 /* genCmp :- greater or less than comparison                       */
 /*-----------------------------------------------------------------*/
 
-#if USE_SIMPLE_GENCMP
+#if USE_SIMPLE_GENCMP          /* { */
 
 /* genCmp performs a left < right comparison, stores
  * the outcome in result (if != NULL) and generates
@@ -4937,6 +4996,10 @@ static void genCmp (operand *left,operand *right,
   
   resolveIfx (&rIfx, ifx);
 
+  /* handle for special cases */
+  if(pic16_genCmp_special(left, right, result, ifx, &rIfx, sign))
+      return;
+
   /**********************************************************************
    * handle bits - bit compares are promoted to int compares seemingly! *
    **********************************************************************/
@@ -5122,7 +5185,7 @@ correct_result_in_carry:
   } // if
 }
 
-#elif 1
+#elif 1                /* } */
                /* { */
       /* original code */
 static void genCmp (operand *left,operand *right,
@@ -5845,7 +5908,7 @@ check_carry:
 
 }
 
-#else  /* old version of genCmp() */   /* } else { */
+#elif 0        /* VR version of genCmp() */    /* } else { */
 
 /* check all condition and return appropriate instruction, POC_CPFSGT or POC_CPFFSLT */
 static int selectCompareOp(resolvedIfx *rIfx, iCode *ifx,
@@ -5955,10 +6018,6 @@ static void compareAop(resolvedIfx *resIfx, iCode *ifx, symbol *falselbl,
   }
 }
 
-
-  
-
-#if 1  /* { */
 static void genCmp (operand *left, operand *right,
                     operand *result, iCode *ifx, int sign)
 {
@@ -6050,621 +6109,164 @@ static void genCmp (operand *left, operand *right,
         if(lit < 0) {
           
           /* literal is negative:
-           *  a. if carry is set, too, continue compare,
-           *  b. if carry is zero, then continue depending on cmpop ^ condition:
-           *   1. '<' return true (literal < variable),
-           *   2. '>' return false (literal > variable) */
-//          pic16_emitpcode(POC_BC, pic16_popGetLabel( tlbl1->key ));
-          pic16_emitpcode(POC_BTFSS, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7));
-          
-          if(!(cmpop ^ rFalseIfx.condition))pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key ));
-          else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key));
-        }
-#if 1
-        else {
-          /* lit == 0 */
-          pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7));
-          
-          if(!(cmpop ^ rFalseIfx.condition))pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key ));
-          else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key));
-        }
-#endif
-        
-        
-        pic16_emitpLabel( tlbl1->key );
-#endif /* } */
-
-        compareAopfirstpass=1;
-//        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
-//        pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right), size));
-//        pic16_emitpcode(POC_MOVWF, pct);
-
-//        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x80));
-        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size)));
-//        compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
-        compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, pct2, tlbl);
-
-        /* generic case */        
-          while( size-- ) {
-//            pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
-//            pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0));
-//            pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right), size));
-//            pic16_emitpcode(POC_MOVWF, pct);
-
-//            pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x80));
-            pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x0));
-            compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, pct2, tlbl);
-//            compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
-//            compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl);
-          }
-//        }
-        
-        if(ifx)ifx->generated = 1;
-
-        if(AOP_SIZE(result)) {
-          pic16_emitpLabel(tlbl->key);
-          pic16_emitpLabel(falselbl->key);
-          pic16_outBitOp( result, pct2 );
-        } else {
-          pic16_emitpLabel(tlbl->key);
-        }
-      } else {
-
-
-        /* unsigned compare */      
-        DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
-    
-        compareAopfirstpass=1;
-        while(size--) {
-          
-          pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size)));
-          compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL);
-
-        }
-
-        if(ifx)ifx->generated = 1;
-
-
-        if(AOP_SIZE(result)) {
-          pic16_emitpLabel(falselbl->key);
-          pic16_outBitC( result );
-        }
-
-      }
-    } else {
-      /* compare registers */
-      DEBUGpic16_emitcode ("; ***","%s: %d: compare registers", __FUNCTION__, __LINE__);
-
-
-      if(sign) {
-        pCodeOp *pct, *pct2;
-        
-        /* signed compare */
-        DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__);
-
-        pct = pic16_popCopyReg(&pic16_pc_prodl);       /* first temporary register */
-        pct2 = pic16_popCopyReg(&pic16_pc_prodh);      /* second temporary register */
-        tlbl = newiTempLabel( NULL );
-        
-        compareAopfirstpass=1;
-
-        size--;
-        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size));
-//        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
-        pic16_emitpcode(POC_MOVWF, pct);
-
-        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
-//        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
-
-        /* WREG already holds left + 0x80 */
-        compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
-        
-        while( size-- ) {
-          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size));
-//          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
-          pic16_emitpcode(POC_MOVWF, pct);
-                
-          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
-//          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
-
-          /* WREG already holds left + 0x80 */
-          compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
-//          compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl);
-        }
-        
-        if(ifx)ifx->generated = 1;
-
-        if(AOP_SIZE(result)) {
-          pic16_emitpLabel(tlbl->key);
-          pic16_emitpLabel(falselbl->key);
-          pic16_outBitOp( result, pct2 );
-        } else {
-          pic16_emitpLabel(tlbl->key);
-        }
-
-      } else {
-        /* unsigned compare */      
-        DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
-
-        compareAopfirstpass=1;
-        while(size--) {
-          
-          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
-          compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL);
-
-        }
-
-        if(ifx)ifx->generated = 1;
-        if(AOP_SIZE(result)) {
-
-          pic16_emitpLabel(falselbl->key);
-          pic16_outBitC( result );
-        }
-
-      }
-    }
-}
-
-#else    /* } else { */
-
-/* new version of genCmp -- VR 20041012 */
-static void genCmp (operand *left,operand *right,
-                    operand *result, iCode *ifx, int sign)
-{
-  int size; //, offset = 0 ;
-  unsigned long lit = 0L,i = 0;
-  resolvedIfx rFalseIfx;
-  int willCheckCarry=0;
-  //  resolvedIfx rTrueIfx;
-  symbol *truelbl;
-
-    FENTRY;
-  
-  /* General concept:
-   * subtract right from left if at the end the carry flag is set then we
-   * know that left is greater than right */
-            
-  resolveIfx(&rFalseIfx,ifx);
-  truelbl  = newiTempLabel(NULL);
-  size = max(AOP_SIZE(left),AOP_SIZE(right));
-
-  DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
-
-  /* POC_CPFSGT        compare f, wreg, skip if f greater than wreg
-   * POC_CPFSLT compare f, wreg, skip if f less then wreg */
-  
-
-  /* if literal is on the right then swap with left */
-  if ((AOP_TYPE(right) == AOP_LIT)) {
-    operand *tmp = right ;
-    unsigned long mask = (0x100 << (8*(size-1))) - 1;
-
-      lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-
-//      lit = (lit - 1) & mask;
-      right = left;
-      left = tmp;
-      rFalseIfx.condition ^= 1;                /* reverse compare */
-  } else
-  if ((AOP_TYPE(left) == AOP_LIT)) {
-    /* float compares are handled by support functions */
-    lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
-  }
-
-
-  //if(IC_TRUE(ifx) == NULL)
-  /* if left & right are bit variables */
-  if (AOP_TYPE(left) == AOP_CRY &&
-      AOP_TYPE(right) == AOP_CRY ) {
-
-    pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
-    pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
-
-  } else {
-    symbol *lbl  = newiTempLabel(NULL);
-
-    if(AOP_TYPE(left) == AOP_LIT) {
-      DEBUGpic16_emitcode(";left lit","lit = 0x%x, sign=%d",lit,sign);
-
-      if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
-        willCheckCarry = 1;
-      else willCheckCarry = 0;
-
-      /* Special cases */
-      if((lit == 0) && (sign == 0)) {
-        /* unsigned compare to 0 */
-        DEBUGpic16_emitcode("; unsigned compare to 0","lit = 0x%x, sign=%d",lit,sign);
-        
-       size--;
-       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-       while(size) 
-         pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
-
-       genSkipz2(&rFalseIfx,0);
-       if(ifx)ifx->generated = 1;
-       return;
-      }
-
-      if(size==1) {
-       /* Special cases */
-       lit &= 0xff;
-       if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
-         /* degenerate compare can never be true */
-         if(rFalseIfx.condition == 0)
-           pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
-
-         if(ifx) ifx->generated = 1;
-         return;
-       }
-
-       if(sign) {
-         /* signed comparisons to a literal byte */
-          DEBUGpic16_emitcode(";signed compare to literal","%d: lit = 0x%x, sign=%d",__LINE__, lit,sign);
-
-         int lp1 = (lit+1) & 0xff;
-
-         DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x condition = %d lp1 = %i",__LINE__,lit, rFalseIfx.condition, lp1);
-         switch (lp1) {
-         case 0:
-           rFalseIfx.condition ^= 1;
-           genSkipCond(&rFalseIfx,right,0,7);
-           break;
-         case 0x7f:
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-           pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
-           genSkipz2(&rFalseIfx,1);
-           break;
-         default:
-           pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit ));
-           
-           if(rFalseIfx.condition)
-             pic16_emitpcode(POC_CPFSLT, pic16_popGet(AOP(right), 0));
-            else
-              pic16_emitpcode(POC_CPFSGT, pic16_popGet(AOP(right), 0));
-
-           if(willCheckCarry) {
-              if(!rFalseIfx.condition) { emitCLRC; emitSETC; }
-              else { emitSETC; emitCLRC; }
-              
-            } else {
-              pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
-            }              
-                     
-/*         pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
-           rFalseIfx.condition ^= 1;
-           genSkipc(&rFalseIfx);
-*/
-           break;
-         }
-       } else {
-         /* unsigned comparisons to a literal byte */
-          DEBUGpic16_emitcode("; unsigned compare to literal","%d: lit = 0x%x, sign=%d",__LINE__, lit,sign);
-
-         switch(lit & 0xff ) {
-                         /* special cases */
-         case 0:
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-           genSkipz2(&rFalseIfx,0);
-           break;
-         case 0x7f:
-           rFalseIfx.condition ^= 1;
-           genSkipCond(&rFalseIfx,right,0,7);
-           break;
-         default:
-           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
-           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
-           DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-           rFalseIfx.condition ^= 1;
-           if (AOP_TYPE(result) == AOP_CRY)
-             genSkipc(&rFalseIfx);
-           else {
-             pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
-             pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
-           }         
-           break;
-         }
-       }
-
-       if(ifx) ifx->generated = 1;
-       if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
-               goto check_carry;
-       return;
-
-      } else {
-
-       /* Size is greater than 1 */
-
-       if(sign) {
-         int lp1 = lit+1;
-
-         size--;
-
-         if(lp1 == 0) {
-           /* this means lit = 0xffffffff, or -1 */
-
-
-           DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
-           rFalseIfx.condition ^= 1;
-           genSkipCond(&rFalseIfx,right,size,7);
-           if(ifx) ifx->generated = 1;
-           return;
-         }
-
-         if(lit == 0) {
-           int s = size;
-
-           if(rFalseIfx.condition) {
-             pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-           }
-
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-           while(size--)
-             pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
-
-
-           emitSKPZ;
-           if(rFalseIfx.condition) {
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
-             pic16_emitpLabel(truelbl->key);
-           }else {
-             rFalseIfx.condition ^= 1;
-             genSkipCond(&rFalseIfx,right,s,7);
-           }
-
-           if(ifx) ifx->generated = 1;
-           return;
-         }
-
-         if((size == 1) &&  (0 == (lp1&0xff))) {
-           /* lower byte of signed word is zero */
-           DEBUGpic16_emitcode(";left lit","line = %d  0x%x+1 low byte is zero",__LINE__,lit);
-           i = ((lp1 >> 8) & 0xff) ^0x80;
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
-           rFalseIfx.condition ^= 1;
-           genSkipc(&rFalseIfx);
-
-
-           if(ifx) ifx->generated = 1;
-           return;
-         }
-
-         if(lit & (0x80 << (size*8))) {
-           /* Lit is less than zero */
-           DEBUGpic16_emitcode(";left lit","line = %d  0x%x is less than 0",__LINE__,lit);
-           //rFalseIfx.condition ^= 1;
-           //genSkipCond(&rFalseIfx,left,size,7);
-           //rFalseIfx.condition ^= 1;
-           pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-           //pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-
-           if(rFalseIfx.condition)
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
-           else
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-
-
-         } else {
-           /* Lit is greater than or equal to zero */
-           DEBUGpic16_emitcode(";left lit","line = %d  0x%x is greater than 0",__LINE__,lit);
-           //rFalseIfx.condition ^= 1;
-           //genSkipCond(&rFalseIfx,right,size,7);
-           //rFalseIfx.condition ^= 1;
-
-           //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
-           //pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
-
-           pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-           if(rFalseIfx.condition)
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-           else
-             pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
-
-         }
-
-
-         pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
-         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
-
-         while(size--) {
-
-           pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
-           emitSKPNZ;
-           pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
-         }
-         rFalseIfx.condition ^= 1;
-         //rFalseIfx.condition = 1;
-         genSkipc(&rFalseIfx);
-
-         pic16_emitpLabel(truelbl->key);
-
-         if(ifx) ifx->generated = 1;
-         return;
-         // end of if (sign)
-       } else {
-
-         /* compare word or long to an unsigned literal on the right.*/
-
-
-         size--;
-         if(lit < 0xff) {
-           DEBUGpic16_emitcode ("; ***","%s  %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
-           switch (lit) {
-           case 0:
-             break; /* handled above */
-/*
-           case 0xff:
-             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-             while(size--)
-               pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
-             genSkipz2(&rFalseIfx,0);
-             break;
-*/
-           default:
-             pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-             while(--size)
-               pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
-
-             emitSKPZ;
-             if(rFalseIfx.condition)
-               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
-             else
-               pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-
-
-             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
-             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
-
-             rFalseIfx.condition ^= 1;
-             genSkipc(&rFalseIfx);
-           }
-
-           pic16_emitpLabel(truelbl->key);
-
-           if(ifx) ifx->generated = 1;
-           return;
-         }
-
+           *  a. if carry is set, too, continue compare,
+           *  b. if carry is zero, then continue depending on cmpop ^ condition:
+           *   1. '<' return true (literal < variable),
+           *   2. '>' return false (literal > variable) */
+//          pic16_emitpcode(POC_BC, pic16_popGetLabel( tlbl1->key ));
+          pic16_emitpcode(POC_BTFSS, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7));
+          
+          if(!(cmpop ^ rFalseIfx.condition))pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key ));
+          else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key));
+        }
+#if 1
+        else {
+          /* lit == 0 */
+          pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7));
+          
+          if(!(cmpop ^ rFalseIfx.condition))pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key ));
+          else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key));
+        }
+#endif
+        
+        
+        pic16_emitpLabel( tlbl1->key );
+#endif /* } */
 
-         lit++;
-         DEBUGpic16_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
-         i = (lit >> (size*8)) & 0xff;
+        compareAopfirstpass=1;
+//        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
+//        pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right), size));
+//        pic16_emitpcode(POC_MOVWF, pct);
 
-         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
-         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
+//        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x80));
+        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size)));
+//        compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
+        compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, pct2, tlbl);
 
-         while(size--) {
-           i = (lit >> (size*8)) & 0xff;
+        /* generic case */        
+          while( size-- ) {
+//            pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
+//            pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0));
+//            pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right), size));
+//            pic16_emitpcode(POC_MOVWF, pct);
 
-           if(i) {
-             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
-             emitSKPNZ;
-             pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
-           } else {
-             /* this byte of the lit is zero, 
-              * if it's not the last then OR in the variable */
-             if(size)
-               pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
-           }
-         }
+//            pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x80));
+            pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x0));
+            compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, pct2, tlbl);
+//            compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
+//            compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl);
+          }
+//        }
+        
+        if(ifx)ifx->generated = 1;
 
+        if(AOP_SIZE(result)) {
+          pic16_emitpLabel(tlbl->key);
+          pic16_emitpLabel(falselbl->key);
+          pic16_outBitOp( result, pct2 );
+        } else {
+          pic16_emitpLabel(tlbl->key);
+        }
+      } else {
 
-         pic16_emitpLabel(lbl->key);
 
-         rFalseIfx.condition ^= 1;
+        /* unsigned compare */      
+        DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
+    
+        compareAopfirstpass=1;
+        while(size--) {
+          
+          pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size)));
+          compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL);
 
-         genSkipc(&rFalseIfx);
-       }
+        }
 
-       if(sign)
-         pic16_emitpLabel(truelbl->key);
-       if(ifx) ifx->generated = 1;
-       return;
-      }
-    }
-    /* Compare two variables */
+        if(ifx)ifx->generated = 1;
 
-    DEBUGpic16_emitcode(";sign","%d",sign);
 
-    size--;
-    if(sign) {
-      /* Sigh. thus sucks... */
-      if(size) {
-       pCodeOp *pctemp;
-       
-       pctemp = pic16_popGetTempReg(1);
-       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
-       pic16_emitpcode(POC_MOVWF, pctemp);             //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
-       pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
-       pic16_emitpcode(POC_XORWF, pctemp);             //pic16_popRegFromIdx(pic16_Gstack_base_addr));
-       pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
-       pic16_emitpcode(POC_SUBFW, pctemp);             //pic16_popRegFromIdx(pic16_Gstack_base_addr));
-       pic16_popReleaseTempReg(pctemp, 1);
-      } else {
-       /* Signed char comparison */
-       /* Special thanks to Nikolai Golovchenko for this snippet */
-       pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
-       pic16_emitpcode(POC_RRCFW,  pic16_popGet(AOP(left),0)); /* could be any register */
-       pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
-       pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
-       pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
+        if(AOP_SIZE(result)) {
+          pic16_emitpLabel(falselbl->key);
+          pic16_outBitC( result );
+        }
 
-       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       genSkipc(&rFalseIfx);
-         
-       if(ifx) ifx->generated = 1;
-       return;
       }
-
     } else {
-
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-      pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
-    }
+      /* compare registers */
+      DEBUGpic16_emitcode ("; ***","%s: %d: compare registers", __FUNCTION__, __LINE__);
 
 
-    /* The rest of the bytes of a multi-byte compare */
-    while (size) {
+      if(sign) {
+        pCodeOp *pct, *pct2;
+        
+        /* signed compare */
+        DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__);
 
-      emitSKPZ;
-      pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(lbl->key));
-      size--;
+        pct = pic16_popCopyReg(&pic16_pc_prodl);       /* first temporary register */
+        pct2 = pic16_popCopyReg(&pic16_pc_prodh);      /* second temporary register */
+        tlbl = newiTempLabel( NULL );
+        
+        compareAopfirstpass=1;
 
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
-      pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
+        size--;
+        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size));
+//        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
+        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
+        pic16_emitpcode(POC_MOVWF, pct);
 
+        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
+//        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
+        pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
 
-    }
+        /* WREG already holds left + 0x80 */
+        compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
+        
+        while( size-- ) {
+          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size));
+//          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
+          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
+          pic16_emitpcode(POC_MOVWF, pct);
+                
+          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
+//          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
+          pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
 
-    pic16_emitpLabel(lbl->key);
+          /* WREG already holds left + 0x80 */
+          compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
+//          compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl);
+        }
+        
+        if(ifx)ifx->generated = 1;
 
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || 
-       (AOP_TYPE(result) == AOP_REG)) {
-      pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
-    } else {
-      genSkipc(&rFalseIfx);
-    }        
-    //genSkipc(&rFalseIfx);
-    if(ifx) ifx->generated = 1;
+        if(AOP_SIZE(result)) {
+          pic16_emitpLabel(tlbl->key);
+          pic16_emitpLabel(falselbl->key);
+          pic16_outBitOp( result, pct2 );
+        } else {
+          pic16_emitpLabel(tlbl->key);
+        }
 
-    return;
+      } else {
+        /* unsigned compare */      
+        DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
 
-  }
+        compareAopfirstpass=1;
+        while(size--) {
+          
+          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
+          compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL);
 
-check_carry:
-  if ((AOP_TYPE(result) != AOP_CRY) 
-       && AOP_SIZE(result)) {
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+        }
 
-    if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
+        if(ifx)ifx->generated = 1;
+        if(AOP_SIZE(result)) {
 
-    pic16_outBitC(result);
-  } else {
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* if the result is used in the next
-       ifx conditional branch then generate
-       code a little differently */
-    if (ifx )
-      genIfxJump (ifx,"c");
-    else
-      pic16_outBitC(result);
-    /* leave the result in acc */
-  }
+          pic16_emitpLabel(falselbl->key);
+          pic16_outBitC( result );
+        }
 
+      }
+    }
 }
-#endif /* } */
-
 
 #endif /* } */
 
@@ -8629,6 +8231,7 @@ static void genXor (iCode *ic, iCode *ifx)
 static void genInline (iCode *ic)
 {
   char *buffer, *bp, *bp1;
+  char *cbuf;
     
        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
@@ -8636,14 +8239,67 @@ static void genInline (iCode *ic)
 
        buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
        strcpy(buffer,IC_INLINE(ic));
-
+       
        while((bp1=strstr(bp, "\\n"))) {
          *bp1++ = '\n';
          *bp1++ = ' ';
          bp = bp1;
         }
         bp = bp1 = buffer;
-        
+
+       cbuf = Safe_strdup( buffer );
+
+        if(asmInlineMap)
+        {
+          symbol *sym;
+          char *s;
+          int cblen;
+
+            cbuf = Safe_strdup(buffer);
+            cblen = strlen(buffer)+1;
+            memset(cbuf, 0, cblen);
+
+            bp = buffer;
+            bp1 = cbuf;
+            while(*bp) {
+              if(*bp != '%')*bp1++ = *bp++;
+              else {
+                int i;
+
+                  bp++;
+                  i = *bp - '0';
+                  if(i>elementsInSet(asmInlineMap))break;
+                  
+                  bp++;
+                  s = indexSet(asmInlineMap, i);
+                  DEBUGpc("searching symbol s = `%s'", s);
+                  sym = findSym(SymbolTab, NULL, s);
+
+                  if(sym->reqv) {
+                    strcat(bp1, sym->reqv->operand.symOperand->regs[0]->name);
+                  } else {
+                    strcat(bp1, sym->rname);
+                  }
+                  
+                  while(*bp1)bp1++;
+              }
+              
+              if(strlen(bp1) > cblen - 16) {
+                int i = strlen(cbuf);
+                cblen += 50;
+                cbuf = realloc(cbuf, cblen);
+                memset(cbuf+i, 0, 50);
+                bp1 = cbuf + i;
+              }
+            }
+            
+            free(buffer);
+            buffer = Safe_strdup( cbuf );
+            free(cbuf);
+            
+            bp = bp1 = buffer;
+        }
+
        /* emit each line as a code */
        while (*bp) {
                if (*bp == '\n') {
@@ -11046,6 +10702,8 @@ static void genDataPointerGet(operand *left,
        DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        pic16_aopOp(result, ic, TRUE);
 
+       FENTRY;
+
        size = AOP_SIZE(result);
 //     fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size);
 
@@ -11096,8 +10754,8 @@ static void genDataPointerGet(operand *left,
        while (size--) {
                DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset);
                
-               if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE
-                       || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) {
+//             pic16_DumpOp("(result)",result);
+               if(is_LitAOp(AOP(result))) {
                        pic16_mov2w(AOP(left), offset); // patch 8
                        pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset));
                } else {
@@ -12677,8 +12335,8 @@ static void genAddrOf (iCode *ic)
       /* get address of symbol on stack */
       DEBUGpic16_emitcode(";    ", "%s symbol %s on stack", __FUNCTION__, sym->name);
 #if 0
-      fprintf(stderr, "%s:%d symbol %s on stack offset %d\n", __FILE__, __LINE__,
-                  OP_SYMBOL(left)->name, OP_SYMBOL(left)->stack);
+      fprintf(stderr, "%s:%d symbol %s on stack offset %i\n", __FILE__, __LINE__,
+                  OP_SYMBOL(IC_LEFT(ic))->name, OP_SYMBOL(IC_LEFT(ic))->stack);
 #endif
 
       // operands on stack are accessible via "FSR2 + index" with index
@@ -13054,9 +12712,10 @@ static void genJumpTab (iCode *ic)
     pic16_emitpcode(POC_MOVWF , pic16_popCopyReg(&pic16_pc_pcl));
 
     pic16_emitpLabelFORCE(jtab->key);
-
 #endif
+
     pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
+//          pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN));
 
     pic16_emitpinfo (INF_OPTIMIZATION, pic16_newpCodeOpOpt (OPT_JUMPTABLE_BEGIN, ""));
     /* now generate the jump labels */
@@ -13220,8 +12879,8 @@ static void genCast (iCode *ic)
 //     if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic)))
 //             return ;
 
-       pic16_aopOp(right,ic,FALSE) ;
        pic16_aopOp(result,ic,FALSE);
+       pic16_aopOp(right,ic,FALSE) ;
 
        DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result);
 
@@ -13467,6 +13126,8 @@ static void genCast (iCode *ic)
            goto release ;
        }
        
+       
+       assert( 0 );
        /* just copy the pointers */
        size = AOP_SIZE(result);
        offset = 0 ;
@@ -13494,8 +13155,10 @@ static void genCast (iCode *ic)
     /* we move to result for the size of source */
     size = AOP_SIZE(right);
     offset = 0 ;
+
     while (size--) {
-      mov2f(AOP(result), AOP(right), offset);
+      if(!_G.resDirect)
+        mov2f(AOP(result), AOP(right), offset);
       offset++;
     }
 
index 73b037d4b6644b816598dc75cc0ecc162927ac57..bafe4f8c9a9345f0121dc36387eee7efdbe7c548 100644 (file)
@@ -188,7 +188,7 @@ pCodeOp *pic16_popGetLit2(int lit, pCodeOp *arg2);
 pCodeOp *popGetWithString(char *str);
 pCodeOp *pic16_popGet (asmop *aop, int offset);//, bool bit16, bool dname);
 pCodeOp *pic16_popGetTempReg(int lock);
-pCodeOp *pic16_popGetTempRegCond(bitVect *, int lock);
+pCodeOp *pic16_popGetTempRegCond(bitVect *, bitVect *, int lock);
 void pic16_popReleaseTempReg(pCodeOp *pcop, int lock);
 
 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc);
index 55e5bbe9d3572bf9262d77b7b1b75ad8d4a0529b..35273afbf2d39487191aac78a1b58e5c711f8dbf 100644 (file)
@@ -54,6 +54,7 @@
 #include "SDCCpeeph.h"
 #include "ralloc.h"
 #include "pcode.h"
+#include "device.h"
 #include "gen.h"
 
 #include "genutils.h"
@@ -463,3 +464,95 @@ void gpsimDebug_StackDump(char *fname, int line, char *info)
 
   gpsimio2_lit('\n');
 }
+
+
+
+/* check all condition and return appropriate instruction, POC_CPFSGT or POC_CPFFSLT */
+static int selectCompareOp(resolvedIfx *rIfx, iCode *ifx,
+        operand *result, int offset, int invert_op)
+{
+  /* add code here */
+  
+  /* check condition, > or < ?? */
+  if(rIfx->condition != 0)invert_op ^= 1;
+  
+  if(ifx && IC_FALSE(ifx))invert_op ^= 1;
+
+  if(!ifx)invert_op ^= 1;
+
+  DEBUGpic16_emitcode("; +++", "%s:%d %s] rIfx->condition= %d, ifx&&IC_FALSE(ifx)= %d, invert_op = %d",
+      __FILE__, __LINE__, __FUNCTION__, rIfx->condition, (ifx && IC_FALSE(ifx)), invert_op);
+  
+  /* do selection */
+  if(!invert_op)return POC_CPFSGT;
+  else return POC_CPFSLT;
+}
+
+/* return 1 if function handles compare, 0 otherwise */
+/* this functions handles special cases like:
+ * reg vs. zero
+ * reg vs. one
+ */
+int pic16_genCmp_special(operand *left, operand *right, operand *result,
+                    iCode *ifx, resolvedIfx *rIfx, int sign)
+{
+  int size;
+  int offs;
+  symbol *tmplbl;
+  unsigned long lit;
+  int op, cmp_op=0;
+
+    FENTRY;
+    
+    if(!(pic16_options.opt_flags & OF_OPTIMIZE_CMP))return 0;
+
+    size = max(AOP_SIZE(left), AOP_SIZE(right));
+    
+    if(!isAOP_REGlike(left)) {
+      operand *dummy;
+
+        dummy = left;
+        left = right;
+        right = dummy;
+        
+        /* invert comparing operand */
+//        cmp_op ^= 1;
+        rIfx->condition ^= 1;
+    }
+    
+    
+    if(isAOP_REGlike(left) && isAOP_LIT(right)) {
+      /* comparing register vs. literal */
+      lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+      
+      
+      if(size == 1) {
+        op = selectCompareOp(rIfx, ifx, result, offs, cmp_op);
+        
+        DEBUGpic16_emitcode("%%", "comparing operand %s, condition: %d", (op==POC_CPFSLT?"POC_CPFSLT":"POC_CPFSGT"), rIfx->condition);
+
+        if(!sign) {
+          /* unsigned compare */
+          switch( lit ) {
+            case 0:
+              if(ifx && IC_FALSE(ifx)) {
+                tmplbl = newiTempLabel( NULL );
+                pic16_emitpcode(POC_TSTFSZ, pic16_popGet(AOP(left), 0));
+                pic16_emitpcode(POC_BRA, pic16_popGetLabel(tmplbl->key));
+                pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx->lbl->key));
+                pic16_emitpLabel(tmplbl->key);
+
+                ifx->generated = 1;
+                return 1;
+              }
+              break;
+          }    /* switch */
+
+        }      /* if(!sign) */
+
+      }                /* if(size==1) */
+
+    }          /* */
+      
+  return 0;
+}
index 2c81d09a7255e237cebd2f33eb4f31d6bbc9914e..2ada0772e952793f0d9b098346ac7be42073765d 100644 (file)
 #include "common.h"
 
 
+#if !defined(__BORLANDC__) && !defined(_MSC_VER)
+#define DEBUGpc(fmt,...)  DEBUGpic16_emitcode("; =:=", "%s:%s:%d: " fmt, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#endif
+#define isAOP_LIT(x)      (AOP_TYPE(x) == AOP_LIT)
+#define isAOP_REGlike(x)  (AOP_TYPE(x) == AOP_REG || AOP_TYPE(x) == AOP_DIR || AOP_TYPE(x) == AOP_PCODE || AOP_TYPE(x) == AOP_STA)
+
+
+/* Resolved ifx structure. This structure stores information
+ * about an iCode ifx that makes it easier to generate code.
+ */
+typedef struct resolvedIfx {
+  symbol *lbl;     /* pointer to a label */
+  int condition;   /* true or false ifx */
+  int generated;   /* set true when the code associated with the ifx
+                   * is generated */
+} resolvedIfx;
+
+
 /*
  * The various GEN_xxxxx macros handle which functions
  * should be included in the gen.c source. We are going to use
@@ -38,6 +56,9 @@ void gpsimio2_lit(unsigned char lit);
 
 void gpsimDebug_StackDump(char *fname, int line, char *info);
 
+int pic16_genCmp_special(operand *left, operand *right, operand *result,
+                    iCode *ifx, resolvedIfx *rIfx, int sign);
+
 #ifndef debugf
 #define debugf(frm, rest)       _debugf(__FILE__, __LINE__, frm, rest)
 #endif
index 673e9e8ce67627a35e320d53536b1b27740ad4b4..af1307abdb60c88730c0bcb9026094624d9a81f2 100644 (file)
@@ -1402,7 +1402,7 @@ pic16createInterruptVect (FILE * vFile)
                return;
        }
 #endif
-
+#if 0
        if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
                fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
                fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
@@ -1413,6 +1413,7 @@ pic16createInterruptVect (FILE * vFile)
                        port->genIVT(vFile, interrupts, maxInterrupts);
                }
        }
+#endif
        
 }
 
index ac4e22e1afc775151e96e34013d830ae1d550cf1..606eea417a79be65a18493b63ab09a2b68861d7d 100644 (file)
@@ -140,6 +140,8 @@ set *sectNames=NULL;                        /* list of section listed in pragma directives */
 set *sectSyms=NULL;                    /* list of symbols set in a specific section */
 set *wparamList=NULL;
 
+set *asmInlineMap=NULL;
+
 struct {
   unsigned ignore: 1;
   unsigned want_libc: 1;
@@ -154,190 +156,209 @@ _process_pragma(const char *sz)
 {
   static const char *WHITE = " \t\n";
   static const char *WHITECOMMA = " \t\n,";
-  
-  char *ptr = strtok((char *)sz, WHITE);
+  char *ptr = strtok((char *)sz, WHITE);
 
-       /* #pragma maxram [maxram] */
-       if (startsWith (ptr, "maxram")) {
-         char *maxRAM = strtok((char *)NULL, WHITE);
+    /* #pragma maxram [maxram] */
+    if (startsWith (ptr, "maxram")) {
+      char *maxRAM = strtok((char *)NULL, WHITE);
 
-               if (maxRAM != (char *)NULL) {
-                 int maxRAMaddress;
-                 value *maxRAMVal;
+        if (maxRAM != (char *)NULL) {
+          int maxRAMaddress;
+          value *maxRAMVal;
 
-                       maxRAMVal = constVal(maxRAM);
-                       maxRAMaddress = (int)floatFromVal(maxRAMVal);
-                       pic16_setMaxRAM(maxRAMaddress);
-               }
-
-          return 0;
-       }
-       
-       /* #pragma stack [stack-position] [stack-len] */
-       if(startsWith(ptr, "stack")) {
-         char *stackPosS = strtok((char *)NULL, WHITE);
-         char *stackLenS = strtok((char *)NULL, WHITE);
-         value *stackPosVal;
-         value *stackLenVal;
-         regs *reg;
-         symbol *sym;
-
-               stackPosVal = constVal( stackPosS );
-               stackPos = (unsigned int)floatFromVal( stackPosVal );
+            maxRAMVal = constVal(maxRAM);
+            maxRAMaddress = (int)floatFromVal(maxRAMVal);
+            pic16_setMaxRAM(maxRAMaddress);
+        }
 
-               
-               if(stackLenS) {
-                       stackLenVal = constVal( stackLenS );
-                       stackLen = (unsigned int)floatFromVal( stackLenVal );
-               }
+        return 0;
+    }
+  
+  /* #pragma stack [stack-position] [stack-len] */
+  if(startsWith(ptr, "stack")) {
+    char *stackPosS = strtok((char *)NULL, WHITE);
+    char *stackLenS = strtok((char *)NULL, WHITE);
+    value *stackPosVal;
+    value *stackLenVal;
+    regs *reg;
+    symbol *sym;
+
+      stackPosVal = constVal( stackPosS );
+      stackPos = (unsigned int)floatFromVal( stackPosVal );
+
+      if(stackLenS) {
+        stackLenVal = constVal( stackLenS );
+        stackLen = (unsigned int)floatFromVal( stackLenVal );
+      }
 
-               if(stackLen < 1) {
-                       stackLen = 64;
-                       fprintf(stderr, "%s:%d: warning: setting stack to default size %d (0x%04x)\n",
-                                     filename, lineno-1, stackLen, stackLen);
+      if(stackLen < 1) {
+        stackLen = 64;
+        fprintf(stderr, "%s:%d: warning: setting stack to default size %d (0x%04x)\n",
+                filename, lineno-1, stackLen, stackLen);
                         
-//                     fprintf(stderr, "%s:%d setting stack to default size %d\n", __FILE__, __LINE__, stackLen);
-               }
+//      fprintf(stderr, "%s:%d setting stack to default size %d\n", __FILE__, __LINE__, stackLen);
+      }
 
-//             fprintf(stderr, "Initializing stack pointer at 0x%x len 0x%x\n", stackPos, stackLen);
-                               
-               reg=newReg(REG_SFR, PO_SFR_REGISTER, stackPos, "_stack", stackLen-1, 0, NULL);
-               addSet(&pic16_fix_udata, reg);
-               
-               reg = newReg(REG_SFR, PO_SFR_REGISTER, stackPos + stackLen-1, "_stack_end", 1, 0, NULL);
-               addSet(&pic16_fix_udata, reg);
+//      fprintf(stderr, "Initializing stack pointer at 0x%x len 0x%x\n", stackPos, stackLen);
+        
+      reg=newReg(REG_SFR, PO_SFR_REGISTER, stackPos, "_stack", stackLen-1, 0, NULL);
+      addSet(&pic16_fix_udata, reg);
+    
+      reg = newReg(REG_SFR, PO_SFR_REGISTER, stackPos + stackLen-1, "_stack_end", 1, 0, NULL);
+      addSet(&pic16_fix_udata, reg);
+    
+      sym = newSymbol("stack", 0);
+      sprintf(sym->rname, "_%s", sym->name);
+      addSet(&publics, sym);
+
+      sym = newSymbol("stack_end", 0);
+      sprintf(sym->rname, "_%s", sym->name);
+      addSet(&publics, sym);
+    
+      initsfpnt = 1;    // force glue() to initialize stack/frame pointers */
 
-               sym = newSymbol("stack", 0);
-               sprintf(sym->rname, "_%s", sym->name);
-               addSet(&publics, sym);
+    return 0;
+  }
+  
+  /* #pragma code [symbol] [location] */
+  if(startsWith(ptr, "code")) {
+    char *symname = strtok((char *)NULL, WHITE);
+    char *location = strtok((char *)NULL, WHITE);
+    absSym *absS;
+    value *addr;
+
+      absS = Safe_calloc(1, sizeof(absSym));
+      sprintf(absS->name, "_%s", symname);
+    
+      addr = constVal( location );
+      absS->address = (unsigned int)floatFromVal( addr );
 
-               sym = newSymbol("stack_end", 0);
-               sprintf(sym->rname, "_%s", sym->name);
-               addSet(&publics, sym);
-               
-               initsfpnt = 1;          // force glue() to initialize stack/frame pointers */
+      if((absS->address % 2) != 0) {
+        absS->address--;
+        fprintf(stderr, "%s:%d: warning: code memory locations should be word aligned, will locate to 0x%06x instead\n",
+                filename, lineno-1, absS->address);
+      }
 
-         return 0;
-       }
-       
-       /* #pragma code [symbol] [location] */
-       if(startsWith(ptr, "code")) {
-         char *symname = strtok((char *)NULL, WHITE);
-         char *location = strtok((char *)NULL, WHITE);
-         absSym *absS;
-         value *addr;
-
-               absS = Safe_calloc(1, sizeof(absSym));
-               sprintf(absS->name, "_%s", 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);
 
-               if((absS->address % 2) != 0) {
-                 absS->address--;
-                 fprintf(stderr, "%s:%d: warning: code memory locations should be word aligned, will locate to 0x%06x instead\n",
-                                     filename, lineno-1, absS->address);
-                }
+    return 0;
+  }
 
-               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);
+  /* #pragma udata [section-name] [symbol] */
+  if(startsWith(ptr, "udata")) {
+    char *sectname = strtok((char *)NULL, WHITE);
+    char *symname = strtok((char *)NULL, WHITE);
+    symbol *nsym;
+    sectSym *ssym;
+    sectName *snam;
+    int found=0;
+    
+      while(symname) {
+        ssym = Safe_calloc(1, sizeof(sectSym));
+        ssym->name = Safe_calloc(1, strlen(symname)+2);
+        sprintf(ssym->name, "_%s", symname);
+        ssym->reg = NULL;
 
-         return 0;
-       }
+        addSet(&sectSyms, ssym);
+
+        nsym = newSymbol(symname, 0);
+        strcpy(nsym->rname, ssym->name);
 
-       /* #pragma udata [section-name] [symbol] */
-       if(startsWith(ptr, "udata")) {
-         char *sectname = strtok((char *)NULL, WHITE);
-         char *symname = strtok((char *)NULL, WHITE);
-         symbol *nsym;
-         sectSym *ssym;
-         sectName *snam;
-         int found=0;
-         
-               while(symname) {
-                       ssym = Safe_calloc(1, sizeof(sectSym));
-                       ssym->name = Safe_calloc(1, strlen(symname)+2);
-                       sprintf(ssym->name, "_%s", symname);
-                       ssym->reg = NULL;
-
-                       addSet(&sectSyms, ssym);
-
-                        nsym = newSymbol(symname, 0);
-                        strcpy(nsym->rname, ssym->name);
 #if 0
-                       checkAddSym(&publics, nsym);
+        checkAddSym(&publics, nsym);
 #endif
 
-                       found = 0;
-                       for(snam=setFirstItem(sectNames);snam;snam=setNextItem(sectNames)) {
-                               if(!strcmp(sectname, snam->name)){ found=1; break; }
-                       }
-                       
-                       if(!found) {
-                               snam = Safe_calloc(1, sizeof(sectName));
-                               snam->name = Safe_strdup( sectname );
-                               snam->regsSet = NULL;
-                               
-                               addSet(&sectNames, snam);
-                       }
-                       
-                       ssym->section = snam;
-                               
+        found = 0;
+        for(snam=setFirstItem(sectNames);snam;snam=setNextItem(sectNames)) {
+          if(!strcmp(sectname, snam->name)){ found=1; break; }
+        }
+      
+        if(!found) {
+          snam = Safe_calloc(1, sizeof(sectName));
+          snam->name = Safe_strdup( sectname );
+          snam->regsSet = NULL;
+        
+          addSet(&sectNames, snam);
+        }
+      
+        ssym->section = snam;
+        
 #if 0
-                       fprintf(stderr, "%s:%d placing symbol %s at section %s (%p)\n", __FILE__, __LINE__,
-                               ssym->name, snam->name, snam);
+        fprintf(stderr, "%s:%d placing symbol %s at section %s (%p)\n", __FILE__, __LINE__,
+           ssym->name, snam->name, snam);
 #endif
 
-                       symname = strtok((char *)NULL, WHITE);
-               }
+        symname = strtok((char *)NULL, WHITE);
+    }
 
-         return 0;
-       }
-       
-       /* #pragma wparam function1[, function2[,...]] */
-       if(startsWith(ptr, "wparam")) {
-         char *fname = strtok((char *)NULL, WHITECOMMA);
-         
-            while(fname) {
-              addSet(&wparamList, Safe_strdup(fname));
+    return 0;
+  }
+  
+  /* #pragma wparam function1[, function2[,...]] */
+  if(startsWith(ptr, "wparam")) {
+    char *fname = strtok((char *)NULL, WHITECOMMA);
+
+      
+      while(fname) {
+        fprintf(stderr, "PIC16 Warning: `%s' wparam pragma is obsolete. use function attribute `wparam' instead.\n", fname);
+        addSet(&wparamList, Safe_strdup(fname));
               
-//              debugf("passing with WREG to %s\n", fname);
-              fname = strtok((char *)NULL, WHITECOMMA);
-            }
+//        debugf("passing with WREG to %s\n", fname);
+        fname = strtok((char *)NULL, WHITECOMMA);
+      }
             
-          return 0;
-        }
+      return 0;
+  }
         
-        /* #pragma library library_module */
-        if(startsWith(ptr, "library")) {
-          char *lmodule = strtok((char *)NULL, WHITE);
+  /* #pragma library library_module */
+  if(startsWith(ptr, "library")) {
+  char *lmodule = strtok((char *)NULL, WHITE);
         
-            if(lmodule) {
-              /* lmodule can be:
-               * c     link the C library
-               * math  link the math library
-               * io    link the IO library
-               * debug link the debug libary
-               * anything else, will link as-is */
-              if(!strcmp(lmodule, "c"))libflags.want_libc = 1;
-              else if(!strcmp(lmodule, "math"))libflags.want_libm = 1;
-              else if(!strcmp(lmodule, "io"))libflags.want_libio = 1;
-              else if(!strcmp(lmodule, "debug"))libflags.want_libdebug = 1;
-              else if(!strcmp(lmodule, "ignore"))libflags.ignore = 1;
-              else {
-                if(!libflags.ignore) {
-                  fprintf(stderr, "link library %s\n", lmodule);
-                  addSetHead(&libFilesSet, lmodule);
-                }
-              }
-            }
-            
-            return 0;
+    if(lmodule) {
+      /* lmodule can be:
+       * c     link the C library
+       * math  link the math library
+       * io    link the IO library
+       * debug link the debug libary
+       * anything else, will link as-is */
+       
+      if(!strcmp(lmodule, "c"))libflags.want_libc = 1;
+      else if(!strcmp(lmodule, "math"))libflags.want_libm = 1;
+      else if(!strcmp(lmodule, "io"))libflags.want_libio = 1;
+      else if(!strcmp(lmodule, "debug"))libflags.want_libdebug = 1;
+      else if(!strcmp(lmodule, "ignore"))libflags.ignore = 1;
+      else {
+        if(!libflags.ignore) {
+          fprintf(stderr, "link library %s\n", lmodule);
+          addSetHead(&libFilesSet, lmodule);
         }
-                
-              
-       
+      }
+    }
+    
+    return 0;
+  }
+      
+  if(startsWith(ptr, "inline")) {
+    char *tmp = strtok((char *)NULL, WHITECOMMA);
+
+      while(tmp) {
+        addSet(&asmInlineMap, Safe_strdup( tmp ));
+        tmp = strtok((char *)NULL, WHITECOMMA);
+      }
+
+      {
+        char *s;
+          
+          for(s = setFirstItem(asmInlineMap); s ; s = setNextItem(asmInlineMap)) {
+            debugf("inline asm: `%s'\n", s);
+          }
+      }
+      
+      return 0;
+  }
+  
   return 1;
 }
 
@@ -349,7 +370,7 @@ _process_pragma(const char *sz)
 #define ALT_ASM                "--asm="
 #define ALT_LINK       "--link="
 
-#define IVT_LOC                "--ivt-loc"
+#define IVT_LOC                "--ivt-loc="
 #define NO_DEFLIBS     "--nodefaultlibs"
 #define MPLAB_COMPAT   "--mplab-comp"
 
@@ -359,6 +380,7 @@ _process_pragma(const char *sz)
 #define        OFMSG_LRSUPPORT "--flr-support"
 
 #define OPTIMIZE_GOTO   "--optimize-goto"
+#define        OPTIMIZE_CMP    "--optimize-cmp"
 
 char *alt_asm=NULL;
 char *alt_link=NULL;
@@ -399,8 +421,8 @@ OPTION pic16_optionsTable[]= {
        { 0,    USE_CRT,        NULL,   "use <crt-o> run-time initialization module"},
        { 0,    "--no-crt",     &pic16_options.no_crt,  "do not link any default run-time initialization module"},
        { 0,    "--gstack",     &pic16_options.gstack,  "trace stack pointer push/pop to overflow"},
-//     { 0,    OFMSG_LRSUPPORT,        NULL,           "use support functions for local register store/restore"},
        { 0,    OPTIMIZE_GOTO,  NULL,                   "try to use (conditional) BRA instead of GOTO"},
+       { 0,    OPTIMIZE_CMP,   NULL,                   "try to optimize some compares"},
        { 0,    NULL,           NULL,   NULL}
        };
 
@@ -462,6 +484,7 @@ _pic16_parseOptions (int *pargc, char **argv, int *i)
 
     if(ISOPT(IVT_LOC)) {
       pic16_options.ivt_loc = getIntArg(IVT_LOC, argv, i, *pargc);
+      fprintf(stderr, "%s:%d setting interrupt vector addresses 0x%x\n", __FILE__, __LINE__, pic16_options.ivt_loc);
       return TRUE;
     }
        
@@ -492,12 +515,16 @@ _pic16_parseOptions (int *pargc, char **argv, int *i)
     }
 #endif
 
-#if 1
     if (ISOPT(OPTIMIZE_GOTO)) {
       pic16_options.opt_flags |= OF_OPTIMIZE_GOTO;
       return TRUE;
     }
-#endif
+
+    if(ISOPT(OPTIMIZE_CMP)) {
+      pic16_options.opt_flags |= OF_OPTIMIZE_CMP;
+      return TRUE;
+    }
+    
 
   return FALSE;
 }
@@ -515,6 +542,9 @@ static void _pic16_initPaths(void)
     setMainValue("mcu", pic16->name[2] );
     addSet(&preArgvSet, Safe_strdup("-D{mcu}"));
 
+    setMainValue("mcu1", pic16->name[1] );
+    addSet(&preArgvSet, Safe_strdup("-D__{mcu1}"));
+
     sprintf(pic16incDir, "%s%cpic16", INCLUDE_DIR_SUFFIX, DIR_SEPARATOR_CHAR);
     sprintf(pic16libDir, "%s%cpic16", LIB_DIR_SUFFIX, DIR_SEPARATOR_CHAR);
 
@@ -661,6 +691,15 @@ _pic16_finaliseOptions (void)
     if(options.model == MODEL_LARGE)
       addSet(&asmOptionsSet, Safe_strdup("-DSDCC_MODEL_LARGE"));
     
+    {
+      char buf[128];
+
+        sprintf(buf, "-D%s -D%s", pic16->name[2], pic16->name[1]);
+        *(strrchr(buf, 'f')) = 'F';
+        addSet(&asmOptionsSet, Safe_strdup( buf ));
+    }
+    
+    
     if(STACK_MODEL_LARGE) {
       addSet(&preArgvSet, Safe_strdup("-DSTACK_MODEL_LARGE"));
       addSet(&asmOptionsSet, Safe_strdup("-DSTACK_MODEL_LARGE"));
index e2d9ea3ac3b34af2ffe535edf5a3779c4054af39..d6a4205bbd4fc538da4e50cdf36769733414bc43 100644 (file)
@@ -127,7 +127,7 @@ pCodeOpReg *pic16_frame_plusw;
 pCodeOpReg pic16_pc_gpsimio   = {{PO_GPR_REGISTER, "GPSIMIO"}, -1, NULL, 0, NULL};
 pCodeOpReg pic16_pc_gpsimio2  = {{PO_GPR_REGISTER, "GPSIMIO2"}, -1, NULL, 0, NULL};
 
-char *OPT_TYPE_STR[] = { "begin", "end" };
+char *OPT_TYPE_STR[] = { "begin", "end", "jumptable_begin", "jumptable_end" };
 char *LR_TYPE_STR[] = { "entry begin", "entry end", "exit begin", "exit end" };
 
 
@@ -281,7 +281,7 @@ pCodeInstruction pic16_pciADDWFC = { // mdubuc - New
   0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
-  (PCC_REGISTER | PCC_Z), // outCond
+  (PCC_REGISTER | PCC_Z | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond
   PCI_MAGIC
 };
 
@@ -309,7 +309,7 @@ pCodeInstruction pic16_pciADDFWC = {
   0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
-  (PCC_W | PCC_Z), // outCond
+  (PCC_W | PCC_Z | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond
   PCI_MAGIC
 };
 
@@ -868,7 +868,7 @@ pCodeInstruction pic16_pciCOMF = {
   0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,  // inCond
-  PCC_REGISTER  , // outCond
+  (PCC_REGISTER | PCC_Z | PCC_N) , // outCond
   PCI_MAGIC
 };
 
@@ -924,7 +924,7 @@ pCodeInstruction pic16_pciCLRF = {
   0,   // second literal operand
   POC_NOP,
   PCC_REGISTER, // inCond
-  PCC_REGISTER , // outCond
+  (PCC_REGISTER | PCC_Z), // outCond
   PCI_MAGIC
 };
 
index 43657a5d949d55082718bca950be0de0c73a2f5a..1787df9c4ffa8a07887ccb54a848c37defeb8ebc 100644 (file)
@@ -1010,6 +1010,7 @@ pCodeOp *pic16_newpCodeOpLit(int lit);
 pCodeOp *pic16_newpCodeOpLit2(int lit, pCodeOp *arg2);
 pCodeOp *pic16_newpCodeOpBit(char *name, int bit,int inBitSpace, PIC_OPTYPE subt);
 pCodeOp *pic16_newpCodeOpRegFromStr(char *name);
+pCodeOp *pic16_newpCodeOpReg(int rIdx);
 pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE p);
 pCodeOp *pic16_pCodeOpCopy(pCodeOp *pcop);
 
index 807d9c043558bdc39a156a180e5acc1f74790808..ffa28c93add7d197d4ed5f3b115826fc21744634 100644 (file)
@@ -168,6 +168,7 @@ static void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl)
     reg = pic16_getRegFromInstruction(pc);
 
     if(reg && (reg->type != REG_TMP)) {
+
 #if 0
       fprintf(stderr, "reg= %p\n", reg);
       fprintf(stderr, "flow seq %d, inst seq %d  %s  ",PCODE(pcfl)->seq,pc->seq,reg->name);
@@ -358,6 +359,9 @@ static void  RemoveRegsFromSet(set *regset)
            fprintf(stderr,"reg %s, type =%d\n",r->name, r->type);
          }
 
+
+         pc->print(stderr, pc);
+
          fprintf(stderr,"%s:%d: removing reg %s because it is used only once\n",__FILE__, __LINE__, reg->name);
 
 
@@ -470,6 +474,8 @@ static int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *re
 
   int t = total_registers_saved;
 
+  if(reg->type == REG_SFR)return 0;
+
   if(pc2->seq < pc1->seq) {
     pct1 = pc2;
     pc2 = pc1;
@@ -508,7 +514,27 @@ static int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *re
     PCI(newpc)->pcflow = PCFL(pcfl_used);
     newpc->seq = pc2->seq;
 
-    Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free);
+    /* take care if register is used after pc2, if yes, then don't delete
+     * clrf reg, because, reg should be initialized with zero */
+    {
+      pCode *spc;
+      int maxSeq=0;
+
+        for(spc=setFirstItem(reg->reglives.usedpCodes);spc;spc=setNextItem(reg->reglives.usedpCodes)) {
+          if(maxSeq < spc->seq)maxSeq = spc->seq;
+        }
+
+//        fprintf(stderr, "pc1->seq = %d\tpc2->seq = %d\tspc->seq = %d\n", pc1->seq, pc2->seq, maxSeq);
+
+        if(maxSeq > pc2->seq) {
+          /* this means that a pCode uses register after pc2, then
+           * we can't delete pc1 pCode */
+          Remove2pcodes(pcfl_used, NULL, pc2, reg, can_free);
+        } else {
+          /* we can remove both pCodes */
+          Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free);
+        }
+    }
     total_registers_saved++;  // debugging stats.
 
   } else if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_IORFW) ){
@@ -827,6 +853,7 @@ void pic16_pCodeRegOptimizeRegUsage(int level)
 
   if(!register_optimization)
     return;
+
 #define OPT_PASSES 4
   passes = OPT_PASSES;
 
index 9819a9465ddf9121ac5e0e39430df387deda747c..dffb192d06220ae967e400ac03e3cd0b5cdcf433 100644 (file)
@@ -293,3 +293,16 @@ replace restart {
         movf    %2,w
 }
 
+replace restart {
+       movf    %1,w
+       xorlw   %2
+       bz      %3
+       bra     %4
+%3:    %5
+} by {
+       ;       peep 101 - test for equality
+       movlw   %2
+       cpfseq  %1
+       bra     %4
+%3:    %5
+}
index 032029018a5063f812e4f538a0d07978806a2ef2..1ffe986308f70d90adb9ad85d7b8e6418d4d3124 100644 (file)
@@ -737,7 +737,7 @@ pic16_allocDirReg (operand *op )
 
 
        if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {
-#if 1
+#if 0
                if(pic16_debug_verbose)
                {
                        fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,
@@ -2304,6 +2304,10 @@ serialRegAssign (eBBlock ** ebbs, int count)
                 or this one is rematerializable then
                 spill this one */
              willCS = willCauseSpill (sym->nRegs, sym->regType);
+
+             /* explicit turn off register spilling */
+             willCS = 0;
+             
              spillable = computeSpillable (ic);
              if (sym->remat ||
                  (willCS && bitVectIsZero (spillable)))
@@ -2319,12 +2323,13 @@ serialRegAssign (eBBlock ** ebbs, int count)
                 have been allocated after sym->liveFrom but freed
                 before ic->seq. This is complicated, so spill this
                 symbol instead and let fillGaps handle the allocation. */
+#if 0
              if (sym->liveFrom < ic->seq)
                {
                    spillThis (sym);
                    continue;                 
                }
-
+#endif
              /* if it has a spillocation & is used less than
                 all other live ranges then spill this */
                if (willCS) {
@@ -3322,11 +3327,17 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
   if (!IS_SYMOP (op))
     return NULL;
 
+  if(OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly)
+    return NULL;
+
   /* only upto 2 bytes since we cannot predict
      the usage of b, & acc */
-  if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) &&       /* was 2, changed to 3 -- VR */
-      ic->op != RETURN &&
-      ic->op != SEND)
+  if (getSize (operandType (op)) > (pic16_fReturnSizePic - 1)
+      && ic->op != RETURN
+      && ic->op != SEND
+      && !POINTER_SET(ic)
+      && !POINTER_GET(ic)
+      )
     return NULL;
 
   /* this routine will mark the a symbol as used in one 
@@ -3335,10 +3346,18 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
      that definition is either a return value from a 
      function or does not contain any variables in
      far space */
+
+#if 0
   uses = bitVectCopy (OP_USES (op));
   bitVectUnSetBit (uses, ic->key);     /* take away this iCode */
   if (!bitVectIsZero (uses))   /* has other uses */
     return NULL;
+#endif
+
+#if 1
+  if (bitVectnBitsOn (OP_USES (op)) > 1)
+    return NULL;
+#endif
 
   /* if it has only one defintion */
   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
@@ -3367,6 +3386,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
        }
       dic = dic->next;
     }
+  else
+    {
 
 
   /* otherwise check that the definition does
@@ -3388,6 +3409,7 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
   if (POINTER_GET (dic) &&
       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
     return NULL;
+    }
 
   sic = dic;
 
@@ -3418,7 +3440,7 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
          operation is a '*','/' or '%' then 'b' may
          cause a problem */
       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
-         getSize (operandType (op)) >= 3)
+         getSize (operandType (op)) >= 2)
        return NULL;
 
       /* if left or right or result is in far space */
@@ -3969,6 +3991,32 @@ pic16_packRegisters (eBBlock * ebp)
           debugLog ("  marking as a pointer (get) =>");
           debugAopGet ("  left:", IC_LEFT (ic));
         }
+        
+        if(getenv("OPTIMIZE_BITFIELD_POINTER_GET")) {
+          if(IS_ITEMP(IC_LEFT(ic)) && IS_BITFIELD(OP_SYM_ETYPE(IC_LEFT(ic)))) {
+            iCode *dic = ic->prev;
+
+            fprintf(stderr, "%s:%d might give opt POINTER_GET && IS_BITFIELD(IC_LEFT)\n", __FILE__, __LINE__);
+          
+            if(dic && dic->op == '='
+              && isOperandEqual(IC_RESULT(dic), IC_LEFT(ic))) {
+              
+                fprintf(stderr, "%s:%d && prev is '=' && prev->result == ic->left\n", __FILE__, __LINE__);
+
+
+                /* replace prev->left with ic->left */
+                IC_LEFT(ic) = IC_RIGHT(dic);
+                IC_RIGHT(ic->prev) = NULL;
+                
+                /* remove ic->prev iCode (assignment) */
+                remiCodeFromeBBlock (ebp, dic);
+                bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,ic->key);
+
+
+                hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
+            }
+          }
+        }
       }
 
        //debugLog("  %d   %s\n", __LINE__, __FUNCTION__);