2004-10-16 Vangelis Rokas <vrokas AT otenet.gr>
authorvrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 16 Oct 2004 14:48:33 +0000 (14:48 +0000)
committervrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 16 Oct 2004 14:48:33 +0000 (14:48 +0000)
* device/include/pic16/math.h: included sdcc-lib.h,
* device/lib/pic16/startup/crt*.c: startup function marked _naked
* src/pic16/gen.c (struct _G): added field useWreg, is set to 1 when
WREG holds the first byte function parameters,
* (aopForSym): take special case for symbols which are in FARSPACE
but in CODESPACE too,
* (assignResultValue): modified to take into account _G.useWreg,
* (genCall): don't use wreg for parameter passing when function is
declared as reentrant, too, added optimization INCF to stack
pointer when stack parameter count is 1,
* (genFunction, genEndFunction): refurnished and fixed to not using
wreg for passing parameters when function has varargs or is
reentrant, fixed bug with symbol name compare for generating
functions in absolute address,
* (pic16_storeForReturn): refurnished,
* (genCmp): began writing a new version of the function, not ready
yet, therefore it is disabled,
* (genAssign): do not read code memory when assigning a function to
a pointer function,
* src/pic16/glue.c (pic16emitStaticSeg): abSym->name is defined an
array of characters, not pointer,
* (pic16initialComments): in debug mode emit an .ident directive for
the assembler,
* (_process_pragma): emit a new warning type (internal to pic16)
when setting stack to default length, emit a similar warning when
placing a function at absolute address and address is not word aligned
* (_pic16_parseOptions): added 'return TRUE' statement,
* (_pic16_linkEdit): if compiling a source, then add the source's
file object, first in the list of objects to link,

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

13 files changed:
ChangeLog
device/include/pic16/math.h
device/lib/pic16/startup/crt0.c
device/lib/pic16/startup/crt0i.c
device/lib/pic16/startup/crt0iz.c
src/pic16/gen.c
src/pic16/gen.h
src/pic16/genarith.c
src/pic16/glue.c
src/pic16/main.c
src/pic16/main.h
src/pic16/pcode.c
src/pic16/ralloc.h

index 993a42279328fd9ee24afa6afe03cdd91113e3cb..c7fa4c679ed54bbbf5b16891b5195a76f1f4b8a2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2004-10-16 Vangelis Rokas <vrokas AT otenet.gr>
+
+       * src/pic16/gen.c (struct _G): added field useWreg, is set to 1 when
+       WREG holds the first byte function parameters,
+       * (aopForSym): take special case for symbols which are in FARSPACE
+       but in CODESPACE too,
+       * (assignResultValue): modified to take into account _G.useWreg,
+       * (genCall): don't use wreg for parameter passing when function is
+       declared as reentrant, too, added optimization INCF to stack
+       pointer when stack parameter count is 1,
+       * (genFunction, genEndFunction): refurnished and fixed to not using
+       wreg for passing parameters when function has varargs or is
+       reentrant, fixed bug with symbol name compare for generating
+       functions in absolute address,
+       * (pic16_storeForReturn): refurnished,
+       * (genCmp): began writing a new version of the function, not ready
+       yet, therefore it is disabled,
+       * (genAssign): do not read code memory when assigning a function to
+       a pointer function,
+       * src/pic16/glue.c (pic16emitStaticSeg): abSym->name is defined an
+       array of characters, not pointer,
+       * (pic16initialComments): in debug mode emit an .ident directive for
+       the assembler,
+       * (_process_pragma): emit a new warning type (internal to pic16)
+       when setting stack to default length, emit a similar warning when
+       placing a function at absolute address and address is not word aligned
+       * (_pic16_parseOptions): added 'return TRUE' statement,
+       * (_pic16_linkEdit): if compiling a source, then add the source's
+       file object, first in the list of objects to link,
+
 2004-10-13 Slade Rich <slade_rich AT users.sourceforge.net>
 
        * src/pic/pcoderegs.c : increased count on regUsedinRange to prevent unnecessary warning.
index 3dc9ecb253b9414c1a5732bb3456be47cb390b9a..3ea9245a7b34492376eb496b7cf67957fd022e62 100644 (file)
@@ -28,6 +28,7 @@
 #ifndef __PIC16_MATH_H
 #define __PIC16_MATH_H 1
 
+#include <sdcc-lib.h>
 
 #define PI          3.1415926536
 #define TWO_PI      6.2831853071
index 34692f1fea902568f7f19f15edb3b86f2241ab57..bd34113b2b670e577214f3bd235b6b6af64e5616 100644 (file)
@@ -19,7 +19,7 @@ extern void main (void);
 
 /* prototype for the startup function */
 void _entry (void) _naked interrupt 0;
-void _startup (void);
+void _startup (void) _naked;
 
 
 /*
@@ -32,7 +32,7 @@ void _entry (void) _naked interrupt 0
 }
 
 
-void _startup (void)
+void _startup (void) _naked
 {
        _asm
                // Initialize the stack pointer
index 4b1751f9be1a8126c4a1e2e4338ddcdbcdbac507..0fc9c1652bde987add918450abf6cc94261980d0 100644 (file)
@@ -29,7 +29,7 @@ extern void main (void);
 
 /* prototype for the startup function */
 void _entry (void) _naked interrupt 0;
-void _startup (void);
+void _startup (void) _naked;
 
 /* prototype for the initialized data setup */
 void _do_cinit (void);
@@ -45,7 +45,7 @@ void _entry (void) _naked interrupt 0
 }
 
 
-void _startup (void)
+void _startup (void) _naked
 {
        _asm
                // Initialize the stack pointer
index ea6c7da084fe6090916297c2133e1a926898a0a3..55d339b4c792bf53903d6fb18bf0f49212b8be28 100644 (file)
@@ -30,7 +30,7 @@ extern void main (void);
 
 /* prototype for the startup function */
 void _entry (void) _naked interrupt 0;
-void _startup (void);
+void _startup (void) _naked;
 
 /* prototype for the initialized data setup */
 void _do_cinit (void);
@@ -46,7 +46,7 @@ void _entry (void) _naked interrupt 0
 }
 
 
-void _startup (void)
+void _startup (void) _naked
 {
        _asm
                // Initialize the stack pointer
index 097259d4bc1e2cd79e447470b873c0992d487a98..1424a756b39162f2de134babf4eb9e74651d07ec 100644 (file)
@@ -139,6 +139,7 @@ static struct {
     bitVect *fregsUsed;
     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
@@ -737,6 +738,23 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
        return aop;
     }
 #endif
+
+#if 0
+    /* special case for a function */
+    if (IS_FUNC(sym->type)) {   
+        sym->aop = aop = newAsmop(AOP_PCODE);
+        //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
+       aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0);
+       PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
+       PCOI(aop->aopu.pcop)->index = 0;
+        aop->size = FPTRSIZE; 
+       DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
+        return aop;
+    }
+#endif
+
+
+
     //DEBUGpic16_emitcode(";","%d",__LINE__);
     /* if in bit space */
     if (IN_BITSPACE(space)) {
@@ -756,7 +774,8 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
         return aop;
     }
 
-    if (IN_FARSPACE(space)) {
+
+    if (IN_FARSPACE(space) && !IN_CODESPACE(space)) {
         sym->aop = aop = newAsmop (AOP_DIR);
         aop->aopu.aop_dir = sym->rname ;
         aop->size = getSize(sym->type);
@@ -765,22 +784,8 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result)
         return aop;
     }
 
-#if 0                                                                                          // patch 14
-    /* special case for a function */
-    if (IS_FUNC(sym->type)) {   
-        sym->aop = aop = newAsmop(AOP_IMMD);    
-        //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
-       aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
-        strcpy(aop->aopu.aop_immd,sym->rname);
-        aop->size = FPTRSIZE; 
-       DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
-        return aop;
-    }
-#endif                                                                                         // patch 14
-
 
     /* only remaining is far space */
-    /* in which case DPTR gets the address */
     sym->aop = aop = newAsmop(AOP_PCODE);
 
 /* change the next if to 1 to revert to good old immediate code */
@@ -2818,35 +2823,34 @@ static void assignResultValue(operand * oper, int rescall)
       int areg = 0;            /* matching argument register */
       
       areg = SPEC_ARGREG( OP_SYM_ETYPE( oper ) ) - 1;
-      /* its called from genReceive (probably) */
-      if(!GpsuedoStkPtr) {
+
+
+      /* its called from genReceive (probably) -- VR */
+      if(!GpsuedoStkPtr && _G.useWreg) {
 //        DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr);
+
         /* The last byte in the assignment is in W */
         if(areg <= GpsuedoStkPtr) {
           size--;
           pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), offset /*size*/));
           offset++;
         }
-       GpsuedoStkPtr++;
-       _G.stack_lat = AOP_SIZE(oper)-1;
       }
+//      GpsuedoStkPtr++;
+      _G.stack_lat = AOP_SIZE(oper)-1;
 
       while (size) {
-//        DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr);
-//        DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2");
-        if(areg <= GpsuedoStkPtr) {
-          size--;
-          popaopidx(AOP(oper), offset, GpsuedoStkPtr);
-          offset++;
-        }
-       GpsuedoStkPtr++;
+        size--;
+        GpsuedoStkPtr++;
+        popaopidx(AOP(oper), offset, GpsuedoStkPtr);
+        offset++;
       }
     }
 }
 
 
 /*-----------------------------------------------------------------*/
-/* genIpush - genrate code for pushing this gets a little complex  */
+/* genIpush - generate code for pushing this gets a little complex */
 /*-----------------------------------------------------------------*/
 static void genIpush (iCode *ic)
 {
@@ -3107,7 +3111,7 @@ static void genCall (iCode *ic)
           }
 
           /* save last parameter to stack if functions has varargs */
-          if(IFFUNC_HASVARARGS(ftype))pushw();
+          if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype))pushw();
           else use_wreg = 1;           /* last parameter in WREG */
           
           _G.stackRegSet = _G.sendSet;
@@ -3143,8 +3147,12 @@ static void genCall (iCode *ic)
     stackParms -= use_wreg;
       
     if(stackParms>0) {
-      pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
-      pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
+      if(stackParms == 1) {
+        pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1l));
+      } else {
+        pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms));
+        pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l ));
+      }
       if(STACK_MODEL_LARGE) {
         emitSKPNC;
         pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h ));
@@ -3250,10 +3258,8 @@ static void genPcall (iCode *ic)
           pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE);
       }
 
-      if(IFFUNC_HASVARARGS(ftype))
-        pushw();
-      else
-        use_wreg = 1;          /* last parameter in WREG */
+      if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype))pushw();
+      else use_wreg = 1;               /* last parameter in WREG */
 
       _G.stackRegSet = _G.sendSet;
       _G.sendSet = NULL;
@@ -3272,7 +3278,7 @@ static void genPcall (iCode *ic)
     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosh));
     pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 2, 0));
     pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu));
-  
+
     /* make the call by writing the pointer into pc */
     pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu)));
     pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath)));
@@ -3374,269 +3380,190 @@ static void genFunction (iCode *ic)
   symbol *sym;
   sym_link *ftype;
   
-       DEBUGpic16_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,pic16_labelOffset,max_key);
+    DEBUGpic16_emitcode ("; ***","%s  %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,pic16_labelOffset,max_key);
 
-       pic16_labelOffset += (max_key+4);
-       max_key=0;
-       GpsuedoStkPtr=0;
-       _G.nRegsSaved = 0;
+    pic16_labelOffset += (max_key+4);
+    max_key=0;
+    GpsuedoStkPtr=0;
+    _G.nRegsSaved = 0;
        
-       ftype = operandType(IC_LEFT(ic));
-       sym = OP_SYMBOL(IC_LEFT(ic));
+    ftype = operandType(IC_LEFT(ic));
+    sym = OP_SYMBOL(IC_LEFT(ic));
 
-       if(IFFUNC_ISISR(sym->type /*ftype*/)) {
-               /* create an absolute section at the interrupt vector:
-                * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */
-         symbol *asym;
-         char asymname[128];
-         pBlock *apb;
+    if(IFFUNC_ISISR(sym->type /*ftype*/)) {
+      /* create an absolute section at the interrupt vector:
+       * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */
+      symbol *asym;
+      char asymname[128];
+      pBlock *apb;
 
-               {
-                 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;
-                               }
-                       }
+        {
+          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;
-               }
-
-               sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name);
-               asym = newSymbol(asymname, 0);
-
-               apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
-               pic16_addpBlock( apb );
-
-               pic16_addpCode2pBlock(apb,
-                       pic16_newpCodeCharP(";-----------------------------------------"));
+            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;
+        }
 
+        sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name);
+        asym = newSymbol(asymname, 0);
 
-               pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
+        apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section"));
+        pic16_addpBlock( apb );
 
-               pic16_addpCode2pBlock(apb,
-                       pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
+        pic16_addpCode2pBlock(apb, pic16_newpCodeCharP(";-----------------------------------------"));
+        pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name));
+        pic16_addpCode2pBlock(apb, pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname )));
                
-               /* mark the end of this tiny function */
-               pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
-
-               {
-                 absSym *abSym;
-
-                       abSym = Safe_calloc(1, sizeof(absSym));
-                       abSym->name = Safe_strdup( asymname );
-
-                       switch( _G.interruptvector ) {
-                               case 0: abSym->address = 0x000000; break;
-                               case 1: abSym->address = 0x000008; break;
-                               case 2: abSym->address = 0x000018; break;
-                       }
+        /* mark the end of this tiny function */
+        pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL));
 
-                       /* relocate interrupt vectors if needed */
-                       abSym->address += pic16_options.ivt_loc;
-
-                       addSet(&absSymSet, abSym);
-               }
-       }
+       {
+         absSym *abSym;
 
+           abSym = Safe_calloc(1, sizeof(absSym));
+           strcpy(abSym->name, asymname);
 
-       /* create the function header */
-       pic16_emitcode(";","-----------------------------------------");
-       pic16_emitcode(";"," function %s",sym->name);
-       pic16_emitcode(";","-----------------------------------------");
+           switch( _G.interruptvector ) {
+             case 0: abSym->address = 0x000000; break;
+              case 1: abSym->address = 0x000008; break;
+              case 2: abSym->address = 0x000018; break;
+            }
 
-       pic16_emitcode("","%s:",sym->rname);
-       pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
+            /* relocate interrupt vectors if needed */
+            abSym->address += pic16_options.ivt_loc;
 
+            addSet(&absSymSet, abSym);
+        }
+    }
 
-       {
-         absSym *ab;
+    /* create the function header */
+    pic16_emitcode(";","-----------------------------------------");
+    pic16_emitcode(";"," function %s",sym->name);
+    pic16_emitcode(";","-----------------------------------------");
 
-               for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet))
-                       if(!strcmp(ab->name, sym->name)) {
-                               pic16_pBlockConvert2Absolute(pb);
-                               break;
-                       }
+    pic16_emitcode("","%s:",sym->rname);
+    pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname));
 
-       }
 
+    {
+      absSym *ab;
 
-       if(IFFUNC_ISNAKED(ftype)) {
-               DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
-               return;
-       }
-       
-       /* if critical function then turn interrupts off */
-       if (IFFUNC_ISCRITICAL(ftype)) {
-         //pic16_emitcode("clr","ea");
+        for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet)) {
+          if(!strcmp(ab->name, sym->rname)) {
+            pic16_pBlockConvert2Absolute(pb);
+            break;
+          }
         }
+    }
 
-        _G.fregsUsed = sym->regsUsed;
-
-       /* if this is an interrupt service routine then
-        * save acc, b, dpl, dph  */
-       if (IFFUNC_ISISR(sym->type)) {
-         int i;
-
-               _G.usefastretfie = 1;   /* use shadow registers by default */
-               /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
-               if(!(_G.interruptvector == 1)) {
 
-                       /* do not save WREG,STATUS,BSR for high priority interrupts
-                        * because they are stored in the hardware shadow registers already */
-                       _G.usefastretfie = 0;
-                       pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
-                       pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
-                       pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
-               }
+    if(IFFUNC_ISNAKED(ftype)) {
+      DEBUGpic16_emitcode("; ***", "_naked function, no prologue");
+      return;
+    }
+       
+    /* if critical function then turn interrupts off */
+    if (IFFUNC_ISCRITICAL(ftype)) {
+      //pic16_emitcode("clr","ea");
+    }
 
+    _G.fregsUsed = sym->regsUsed;
 
-                /* these should really be optimized somehow, because not all
-                 * interrupt handlers modify them */
-               pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
-               pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
-               pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
-               pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
+    /* if this is an interrupt service routine then
+     * save wreg, status, bsr, prodl, prodh, fsr0l, fsr0h */
+    if (IFFUNC_ISISR(sym->type)) {
+        _G.usefastretfie = 1;  /* use shadow registers by default */
+        
+        /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */
+        if(!(_G.interruptvector == 1)) {
+          /* do not save WREG,STATUS,BSR for high priority interrupts
+           * because they are stored in the hardware shadow registers already */
+          _G.usefastretfie = 0;
+          pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
+          pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status ));
+          pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
+        }
 
-//                pic16_pBlockConvert2ISR(pb);
+        /* these should really be optimized somehow, because not all
+         * interrupt handlers modify them */
+        pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
+        pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
+        pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l ));
+        pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
+        
+//        pic16_pBlockConvert2ISR(pb);
                 
-               /* if any registers used */
-               if (sym->regsUsed) {
-                       /* save the registers used */
-                       DEBUGpic16_emitcode("; **", "Saving used registers in stack");
-                       for ( i = 0 ; i < sym->regsUsed->size ; i++) {
-                               if (bitVectBitValue(sym->regsUsed,i)) {
-#if 0
-                                       fprintf(stderr, "%s:%d function %s uses register %s\n",
-                                                       __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
-                                                       pic16_regWithIdx(i)->name);
-#endif
-
-                                       pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
-                                       _G.nRegsSaved++;
-
-                                       if(!pic16_regWithIdx(i)->wasUsed) {
-                                               fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n",
-                                                       __FILE__, __LINE__, pic16_regWithIdx(i)->name);
+    }
 
-                                               pic16_regWithIdx(i)->wasUsed = 1;
-                                       }
-                               }
-                       }
-               }
-       } else {
-               /* emit code to setup stack frame if user enabled,
-                * and function is not main() */
+    /* emit code to setup stack frame if user enabled,
+     * and function is not main() */
         
-//             fprintf(stderr, "function name: %s\n", sym->name);
-               if(strcmp(sym->name, "main")) {
-                       if(/*!options.ommitFramePtr || sym->regsUsed*/1) {
-                       /* setup the stack frame */
-                               pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
-                               pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
-                               if(STACK_MODEL_LARGE)
-                                       pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
-                       }
-               }
-
-               /* if callee-save to be used for this function
-               * then save the registers being used in this function */
-//             if (IFFUNC_CALLEESAVES(sym->type))
-               {
-                 int i;
-
-//                     fprintf(stderr, "%s:%d function sym->regsUsed= %d\n", __FILE__, __LINE__, sym->regsUsed->size);
-
-//                     pic16_emitpcomment("entry regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
-
-                       /* if any registers used */
-                       if (sym->regsUsed) {
-                               /* save the registers used */
-                               DEBUGpic16_emitcode("; **", "Saving used registers in stack");
-                               for ( i = 0 ; i < sym->regsUsed->size ; i++) {
-                                       if (bitVectBitValue(sym->regsUsed,i)) {
-
-#if 0
-                                               fprintf(stderr, "%s:%d function %s uses register %s (wasUsed: %d, %p)\n",
-                                                               __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
-                                                               pic16_regWithIdx(i)->name,
-                                                               pic16_regWithIdx(i)->wasUsed,
-                                                               pic16_regWithIdx(i));
-#endif
-
-                                               pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
-
-//                                             pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
-//                                                     PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))),
-//                                                     &pic16_pc_postdec1, 0));
+    //fprintf(stderr, "function name: %s\n", sym->name);
+    if(strcmp(sym->name, "main")) {
+      if(1  /*!options.ommitFramePtr || sym->regsUsed*/) {
+        /* setup the stack frame */
+        pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
+        pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
+        if(STACK_MODEL_LARGE)
+          pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0));
+      }
+    }
 
-                                               _G.nRegsSaved++;
+    if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
+          && sym->stack) {
 
-                                               if(!pic16_regWithIdx(i)->wasUsed) {
-                                                       fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n",
-                                                               __FILE__, __LINE__, pic16_regWithIdx(i)->name);
+      if (sym->stack > 127)werror(W_STACK_OVERFLOW, sym->name);
 
-                                                       pic16_regWithIdx(i)->wasUsed = 1;
-                                               }
-                                       
-                                       }
-                               }
-                       }
-               }
-       }
+      pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
+      pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_fsr1l));
+      emitSKPNC;
+      pic16_emitpcode(POC_DECF, pic16_popCopyReg(&pic16_pc_fsr1h));
+    }
+          
+    if(IFFUNC_HASVARARGS(sym->type) || IFFUNC_ISREENT(sym->type))
+      _G.useWreg = 0;
+    else _G.useWreg = 1;
 
+    /* if callee-save to be used for this function
+     * then save the registers being used in this function */
+//    if (IFFUNC_CALLEESAVES(sym->type))
+    {
+      int i;
 
+        /* if any registers used */
+        if (sym->regsUsed) {
+          /* save the registers used */
+          DEBUGpic16_emitcode("; **", "Saving used registers in stack");
+          for ( i = 0 ; i < sym->regsUsed->size ; i++) {
+            if (bitVectBitValue(sym->regsUsed,i)) {
+              pic16_pushpCodeOp( pic16_popRegFromIdx(i) );
+              _G.nRegsSaved++;
+
+              if(!pic16_regWithIdx(i)->wasUsed) {
+                fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n",
+                              __FILE__, __LINE__, pic16_regWithIdx(i)->name);
+                pic16_regWithIdx(i)->wasUsed = 1;
+              }
+            }
+          }
+        }
+    }
        
-#if 0
-       if (IFFUNC_ISREENT(sym->type) || options.stackAuto) {
-
-               if (options.useXstack) {
-                       pic16_emitcode("mov","r0,%s",spname);
-                       pic16_emitcode("mov","a,_bp");
-                       pic16_emitcode("movx","@r0,a");
-                       pic16_emitcode("inc","%s",spname);
-               } else {
-                       /* set up the stack */
-                       pic16_emitcode ("push","_bp");     /* save the callers stack  */
-               }
-               pic16_emitcode ("mov","_bp,%s",spname);
-       }
-#endif
-       DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
-
-       /* adjust the stack for the function */
-       if (sym->stack) {
-         int i = sym->stack;
-
-               if (i > 127 ) 
-                       werror(W_STACK_OVERFLOW,sym->name);
-
-               if (i > 3 && sym->recvSize < 4) {              
-                       pic16_emitcode ("mov","a,sp");
-                       pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff));
-                       pic16_emitcode ("mov","sp,a");
-               } else
-                       while(i--)
-                               pic16_emitcode("inc","sp");
-       }
-
-       if (sym->xstack) {
-               DEBUGpic16_emitcode("; ", "%s", __FUNCTION__);
-
-               pic16_emitcode ("mov","a,_spx");
-               pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff));
-               pic16_emitcode ("mov","_spx,a");
-       }
-    
+    DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack);
+//    fprintf(stderr, "Function '%s' uses %d bytes of stack\n", sym->name, sym->stack);
 }
 
 /*-----------------------------------------------------------------*/
@@ -3644,13 +3571,13 @@ static void genFunction (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genEndFunction (iCode *ic)
 {
-    symbol *sym = OP_SYMBOL(IC_LEFT(ic));
+  symbol *sym = OP_SYMBOL(IC_LEFT(ic));
 
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
     if(IFFUNC_ISNAKED(sym->type)) {
-       DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
-       return;
+      DEBUGpic16_emitcode("; ***", "_naked function, no epilogue");
+      return;
     }
 
     _G.stack_lat = 0;
@@ -3662,171 +3589,105 @@ static void genEndFunction (iCode *ic)
       /* TODO: add code here -- VR */
     }
     
-
-#if 0
-    if (IFFUNC_ISREENT(sym->type) || options.stackAuto)
-    {
-        pic16_emitcode ("mov","%s,_bp",spname);
-    }
-#endif
-
-    /* if use external stack but some variables were
-    added to the local stack then decrement the
-    local stack */
-    if (options.useXstack && sym->stack) {      
-        pic16_emitcode("mov","a,sp");
-        pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff);
-        pic16_emitcode("mov","sp,a");
+    if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)
+          && sym->stack) {
+      pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack));
+      pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(&pic16_pc_fsr1l));
+      emitSKPNC;
+      pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1h));
     }
 
+    /* now we need to restore the registers */
+    /* if any registers used */
+    if (sym->regsUsed) {
+      int i;
 
-#if 0
-    if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) {
-       if (options.useXstack) {
-           pic16_emitcode("mov","r0,%s",spname);
-           pic16_emitcode("movx","a,@r0");
-           pic16_emitcode("mov","_bp,a");
-           pic16_emitcode("dec","%s",spname);
-       }
-       else
-       {
-           pic16_emitcode ("pop","_bp");
-       }
+        /* restore registers used */
+        DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
+        for ( i = sym->regsUsed->size; i >= 0; i--) {
+          if (bitVectBitValue(sym->regsUsed,i)) {
+            pic16_poppCodeOp( pic16_popRegFromIdx(i) );
+            _G.nRegsSaved--;
+          }
+        }
     }
-#endif
-
-       if (IFFUNC_ISISR(sym->type)) {
-               /* now we need to restore the registers */
-               /* if any registers used */
-               if (sym->regsUsed) {
-                 int i;
-
-                       /* restore registers used */
-                       DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
-                       for ( i = sym->regsUsed->size; i >= 0; i--) {
-                               if (bitVectBitValue(sym->regsUsed,i)) {
 
-//                                     fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
-//                                                     __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
-//                                                     pic16_regWithIdx(i)->name);
-
-                                       pic16_poppCodeOp( pic16_popRegFromIdx(i) );
+    if(strcmp(sym->name, "main")) {
+      if(1/*!options.ommitFramePtr ||*/ /*sym->regsUsed*/) {
+        /* restore stack frame */
+        if(STACK_MODEL_LARGE)
+          pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
+        pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
+      }
+    }
 
-//                                     pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
-//                                                     &pic16_pc_preinc1,
-//                                                     PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
+    _G.useWreg = 0;
 
-                               }
-                       }
-               }
-       
-               pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
-               pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
-               pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
-               pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
-
-               if(!(_G.interruptvector == 1)) {
-                       /* do not restore interrupt vector for WREG,STATUS,BSR
-                        * for high priority interrupt, see genFunction */
-                        
-                       pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
-                       pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
-                       pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
-               }
-       
-               _G.interruptvector = 0;         /* sanity check */
+    if (IFFUNC_ISISR(sym->type)) {
+      pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h ));
+      pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l));
+      pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh ));
+      pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl ));
 
-//             pic16_pBlockConvert2ISR(pb);
+      if(!(_G.interruptvector == 1)) {
+        /* do not restore interrupt vector for WREG,STATUS,BSR
+         * for high priority interrupt, see genFunction */
+       pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr ));
+       pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status ));
+       pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg ));
+      }
+      _G.interruptvector = 0;          /* sanity check */
 
 
-               /* if debug then send end of function */
-/*     if (options.debug && currFunc)  */
-               if (currFunc) {
-                       debugFile->writeEndFunction (currFunc, ic, 1);
-               }
-       
-               if(_G.usefastretfie)
-                       pic16_emitpcode(POC_RETFIE, pic16_newpCodeOpLit(1));
-               else
-               pic16_emitpcodeNULLop(POC_RETFIE);
-               _G.usefastretfie = 0;
-       } else {
-               if (IFFUNC_ISCRITICAL(sym->type))
-                       pic16_emitcode("setb","ea");
+      /* if debug then send end of function */
+/*     if (options.debug && currFunc)  */
+      if (currFunc) {
+        debugFile->writeEndFunction (currFunc, ic, 1);
+      }
        
+      if(_G.usefastretfie)
+        pic16_emitpcode(POC_RETFIE, pic16_newpCodeOpLit(1));
+      else
+        pic16_emitpcodeNULLop(POC_RETFIE);
 
-//             pic16_emitpcomment("exit regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
+      pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
+      
+      _G.usefastretfie = 0;
+      return;
+    }
 
-               /* if any registers used */
-               if (sym->regsUsed) {
-                 int i;
-                       /* save the registers used */
-                       DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
-                       for ( i = sym->regsUsed->size; i >= 0; i--) {
-                               if (bitVectBitValue(sym->regsUsed,i)) {
-       
-//                                     fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
-//                                                     __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
-//                                                     pic16_regWithIdx(i)->name);
-       
-                                       pic16_poppCodeOp( pic16_popRegFromIdx(i) );
-                                       
-//                                     pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
-//                                             &pic16_pc_preinc1,
-//                                             PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
+    if (IFFUNC_ISCRITICAL(sym->type)) {
+      pic16_emitcode("setb","ea");
+    }
 
-                                       _G.nRegsSaved--;
-                               }
-                       }
-               }
-       
-//             pic16_emitpcomment("%s: _G.nRegsSaved upon exit from function: %d\n", __FUNCTION__, _G.nRegsSaved);
-               /* if debug then send end of function */
-               if (currFunc) {
-                       debugFile->writeEndFunction (currFunc, ic, 1);
-               }
+    /* if debug then send end of function */
+    if (currFunc) {
+      debugFile->writeEndFunction (currFunc, ic, 1);
+    }
 
-               /* insert code to restore stack frame, if user enabled it
-                * and function is not main() */
+    /* insert code to restore stack frame, if user enabled it
+     * and function is not main() */
         
 
-               if(strcmp(sym->name, "main")) {
-                       if(1/*!options.ommitFramePtr ||*/ /*sym->regsUsed*/) {
-                               /* restore stack frame */
-                               if(STACK_MODEL_LARGE)
-                                       pic16_emitpcode(POC_MOVFF,
-                                               pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
-                               pic16_emitpcode(POC_MOVFF,
-                                               pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
-                       }
-               }
-
-               pic16_emitpcodeNULLop(POC_RETURN);
-
-               /* Mark the end of a function */
-               pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
-       }
+    pic16_emitpcodeNULLop(POC_RETURN);
 
+    /* Mark the end of a function */
+    pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
 }
 
 
 void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest)
 {
-
-       if(is_LitOp(op)) {
-               pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset)); // patch 12
-
-               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));
-                       return;
-               }
-               
-               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
-                       pic16_popGet(AOP(op), offset), dest));
-       }
+  if(is_LitOp(op)) {
+    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));
+      return;
+    }
+    pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op), offset), dest));
+  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -4740,6 +4601,7 @@ static int genChkZeroes(operand *op, int lit,  int size)
 /*-----------------------------------------------------------------*/
 /* genCmp :- greater or less than comparison                       */
 /*-----------------------------------------------------------------*/
+#if 1
 static void genCmp (operand *left,operand *right,
                     operand *result, iCode *ifx, int sign)
 {
@@ -4889,169 +4751,636 @@ static void genCmp (operand *left,operand *right,
          pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
          pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),1));
 
-         while(size > 1)
-           pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
+         while(size > 1)
+           pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size--));
+
+         if(rFalseIfx.condition) {
+           emitSKPZ;
+           pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
+
+         } else {
+           emitSKPNZ;
+         }
+
+         genSkipc(&rFalseIfx);
+         pic16_emitpLabel(truelbl->key);
+         if(ifx) ifx->generated = 1;
+         return;
+
+       }
+
+       if(size == 1) {
+
+         if( (lit & 0xff) == 0) {
+           /* lower byte is zero */
+           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+           i = ((lit >> 8) & 0xff) ^0x80;
+           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
+           pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
+           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
+           genSkipc(&rFalseIfx);
+
+
+           if(ifx) ifx->generated = 1;
+           return;
+
+         }
+       } else {
+         /* Special cases for signed longs */
+         if( (lit & 0xffffff) == 0) {
+           /* lower byte is zero */
+           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+           i = ((lit >> 8*3) & 0xff) ^0x80;
+           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
+           pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
+           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
+           genSkipc(&rFalseIfx);
+
+
+           if(ifx) ifx->generated = 1;
+           return;
+
+         }
+
+       }
+
+
+       if(lit & (0x80 << (size*8))) {
+         /* lit is negative */
+         DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+
+         //genSkipCond(&rFalseIfx,left,size,7);
+
+         pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),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));
+
+
+       } else {
+         /* lit is positive */
+         DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
+         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+         if(rFalseIfx.condition)
+           pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
+         else
+           pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
+
+       }
+
+       /*
+         This works, but is only good for ints.
+         It also requires a "known zero" register.
+         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
+         pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
+         pic16_emitpcode(POC_RLCFW,  pic16_popCopyReg(&pic16_pc_kzero));
+         pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
+         pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
+         genSkipc(&rFalseIfx);
+
+         pic16_emitpLabel(truelbl->key);
+         if(ifx) ifx->generated = 1;
+         return;
+       **/
+         
+       /* There are no more special cases, so perform a general compare */
+  
+       pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
+       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
+
+       while(size--) {
+
+         pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
+         emitSKPNZ;
+         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
+       }
+       //rFalseIfx.condition ^= 1;
+       genSkipc(&rFalseIfx);
+
+       pic16_emitpLabel(truelbl->key);
+
+       if(ifx) ifx->generated = 1;
+       return;
+
+
+      }
+
+
+      /* sign is out of the way. So now do an unsigned compare */
+      DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
+
+
+      /* General case - compare to an unsigned literal on the right.*/
+
+      i = (lit >> (size*8)) & 0xff;
+      pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
+      pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
+      while(size--) {
+       i = (lit >> (size*8)) & 0xff;
+
+       if(i) {
+         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
+         emitSKPNZ;
+         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),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(left),size));
+       }
+      }
+
+
+      pic16_emitpLabel(lbl->key);
+//     pic16_emitpLabel(truelbl->key);
+      //if(emitFinalCheck)
+      genSkipc(&rFalseIfx);
+      if(sign)
+       pic16_emitpLabel(truelbl->key);
+
+      if(ifx) ifx->generated = 1;
+      return;
+
+
+    }
+#endif  // _swapp
+
+    if(AOP_TYPE(left) == AOP_LIT) {
+      //symbol *lbl = newiTempLabel(NULL);
+
+      //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
+
+
+      DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
+
+      /* Special cases */
+      if((lit == 0) && (sign == 0)){
+
+       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 */
+
+         int lp1 = (lit+1) & 0xff;
+
+         DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
+         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_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 */
+
+         switch(lit & 0xff ) {
+         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;
+
+           if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+             goto check_carry;
+
+           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;
+
+           if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+             goto check_carry;
+
+           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;
+
+           if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+             goto check_carry;
+
+           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;
+
+
+          if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+            goto check_carry;
+
+         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;
+
+            if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+              goto check_carry;
+
+           return;
+         }
+
+
+         lit++;
+         DEBUGpic16_emitcode ("; ***","%s  %d lit =0x%x",__FUNCTION__,__LINE__,lit);
+         i = (lit >> (size*8)) & 0xff;
+
+         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
+         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
+
+         while(size--) {
+           i = (lit >> (size*8)) & 0xff;
+
+           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));
+           }
+         }
+
 
-         if(rFalseIfx.condition) {
-           emitSKPZ;
-           pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
+         pic16_emitpLabel(lbl->key);
 
-         } else {
-           emitSKPNZ;
-         }
+         rFalseIfx.condition ^= 1;
 
          genSkipc(&rFalseIfx);
-         pic16_emitpLabel(truelbl->key);
-         if(ifx) ifx->generated = 1;
-         return;
-
        }
 
-       if(size == 1) {
+       if(sign)
+         pic16_emitpLabel(truelbl->key);
+       if(ifx) ifx->generated = 1;
 
-         if( (lit & 0xff) == 0) {
-           /* lower byte is zero */
-           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
-           i = ((lit >> 8) & 0xff) ^0x80;
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
-           genSkipc(&rFalseIfx);
+            if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+              goto check_carry;
 
+       return;
+      }
+    }
+    /* Compare two variables */
 
-           if(ifx) ifx->generated = 1;
-           return;
+    DEBUGpic16_emitcode(";sign","%d",sign);
 
-         }
-       } else {
-         /* Special cases for signed longs */
-         if( (lit & 0xffffff) == 0) {
-           /* lower byte is zero */
-           DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
-           i = ((lit >> 8*3) & 0xff) ^0x80;
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
-           pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
-           genSkipc(&rFalseIfx);
+    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));
 
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       genSkipc(&rFalseIfx);
+         
+       if(ifx) ifx->generated = 1;
 
-           if(ifx) ifx->generated = 1;
-           return;
+            if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+              goto check_carry;
 
-         }
+       return;
+      }
 
-       }
+    } else {
 
+      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
+      pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
+    }
 
-       if(lit & (0x80 << (size*8))) {
-         /* lit is negative */
-         DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
 
-         //genSkipCond(&rFalseIfx,left,size,7);
+    /* The rest of the bytes of a multi-byte compare */
+    while (size) {
 
-         pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+      emitSKPZ;
+      pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(lbl->key));
+      size--;
 
-         if(rFalseIfx.condition)
-           pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
-         else
-           pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
+      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
+      pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
 
 
-       } else {
-         /* lit is positive */
-         DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
-         pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
-         if(rFalseIfx.condition)
-           pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(rFalseIfx.lbl->key));
-         else
-           pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(truelbl->key));
+    }
 
-       }
+    pic16_emitpLabel(lbl->key);
 
-       /*
-         This works, but is only good for ints.
-         It also requires a "known zero" register.
-         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(mlit & 0xff));
-         pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));
-         pic16_emitpcode(POC_RLCFW,  pic16_popCopyReg(&pic16_pc_kzero));
-         pic16_emitpcode(POC_ADDLW, pic16_popGetLit( ((mlit>>8) & 0xff)));
-         pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),1));
-         genSkipc(&rFalseIfx);
+    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;
 
-         pic16_emitpLabel(truelbl->key);
-         if(ifx) ifx->generated = 1;
-         return;
-       **/
-         
-       /* There are no more special cases, so perform a general compare */
-  
-       pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
-       pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
 
-       while(size--) {
+            if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
+              goto check_carry;
 
-         pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
-         emitSKPNZ;
-         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
-       }
-       //rFalseIfx.condition ^= 1;
-       genSkipc(&rFalseIfx);
+    return;
 
-       pic16_emitpLabel(truelbl->key);
+  }
 
-       if(ifx) ifx->generated = 1;
-       return;
+check_carry:
+  if ((AOP_TYPE(result) != AOP_CRY) 
+       && AOP_SIZE(result)) {
+    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
+    if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
 
-      }
+    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 */
+  }
 
+}
 
-      /* sign is out of the way. So now do an unsigned compare */
-      DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
+#else  /* old version of genCmp() */
 
+/* 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;
+  DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-      /* General case - compare to an unsigned literal on the right.*/
 
-      i = (lit >> (size*8)) & 0xff;
-      pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
-      pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
-      while(size--) {
-       i = (lit >> (size*8)) & 0xff;
+  /* 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));
 
-       if(i) {
-         pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
-         emitSKPNZ;
-         pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),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(left),size));
-       }
-      }
+  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 */
+  
 
-      pic16_emitpLabel(lbl->key);
-//     pic16_emitpLabel(truelbl->key);
-      //if(emitFinalCheck)
-      genSkipc(&rFalseIfx);
-      if(sign)
-       pic16_emitpLabel(truelbl->key);
+  /* 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;
 
-      if(ifx) ifx->generated = 1;
-      return;
+      lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
 
+//      lit = (lit - 1) & mask;
+      right = left;
+      left = tmp;
+      rFalseIfx.condition ^= 1;
+  } else
+  if ((AOP_TYPE(left) == AOP_LIT)) {
+    /* float compares are handled by support functions */
+    lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
+  }
 
-    }
-#endif  // _swapp
 
-    if(AOP_TYPE(left) == AOP_LIT) {
-      //symbol *lbl = newiTempLabel(NULL);
+  //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);
 
-      //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
+  } else {
+    symbol *lbl  = newiTempLabel(NULL);
 
+    if(AOP_TYPE(left) == AOP_LIT) {
+      DEBUGpic16_emitcode(";left lit","lit = 0x%x, sign=%d",lit,sign);
 
-      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)){
@@ -5083,7 +5412,7 @@ static void genCmp (operand *left,operand *right,
 
          int lp1 = (lit+1) & 0xff;
 
-         DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit);
+         DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x condition = %d",__LINE__,lit, rFalseIfx.condition);
          switch (lp1) {
          case 0:
            rFalseIfx.condition ^= 1;
@@ -5095,11 +5424,27 @@ static void genCmp (operand *left,operand *right,
            genSkipz2(&rFalseIfx,1);
            break;
          default:
-           pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
+           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 {
@@ -5422,6 +5767,9 @@ check_carry:
   }
 
 }
+#endif
+
+
 
 /*-----------------------------------------------------------------*/
 /* genCmpGt :- greater than comparison                             */
@@ -10959,14 +11307,6 @@ static void genGenPointerSet (operand *right,
         sym = newSymbol( fgptrput, 0 );
         strcpy(sym->rname, fgptrput);
         checkAddSym(&externs, sym);
-
-#if 0
-       sym = newSymbol("__GPTRREG", 0);
-        strcpy(sym->rname, "__GPTRREG");
-        checkAddSym(&externs, sym);
-#endif
-
-//          fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fgptrget);
     }
 
 release:
@@ -11292,16 +11632,20 @@ static void genAssign (iCode *ic)
 //                     sizeof(unsigned long int), sizeof(float));
 
   if(AOP_TYPE(right) != AOP_LIT
-       && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))) {
+       && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))
+       && !IS_FUNC(OP_SYM_TYPE(right))
+       ) {
        DEBUGpic16_emitcode(";   ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__);
-       fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name);
+//     fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name);
 
        // set up table pointer
        if( (AOP_TYPE(right) == AOP_PCODE)
                && ((AOP(right)->aopu.pcop->type == PO_IMMEDIATE)
-               || (AOP(right)->aopu.pcop->type == PO_DIR)))
+//             || (AOP(right)->aopu.pcop->type == PO_DIR)
+                )
+               )
        {
-               fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__);
+//             fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__);
                pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),0));
                pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl));
                pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),1));
@@ -11309,7 +11653,7 @@ static void genAssign (iCode *ic)
                pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),2));
                pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru));
        } else {
-               fprintf(stderr, "%s:%d inside block 2\n", __FILE__, __LINE__);
+//             fprintf(stderr, "%s:%d inside block 2\n", __FILE__, __LINE__);
                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),0),
                                pic16_popCopyReg(&pic16_pc_tblptrl)));
                pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),1),
index 72f700d18d0e6bee726913124620bbc35aa43700..8cb59d4981cdfcfb6aff2c598c4c769a2aec883a 100644 (file)
@@ -162,6 +162,7 @@ void pic16_emitDebuggerSymbol (char *);
 bool pic16_sameRegs (asmop *aop1, asmop *aop2 );
 char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname);
 void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result);
+void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result);
 
 
 bool pic16_genPlusIncr (iCode *ic);
index 81ef668107f2113b171fb7fc35890e9ad3eba339..ad1a172b0e77947fc004f5233b2c04b9e94b4383 100644 (file)
@@ -998,6 +998,8 @@ void pic16_genPlus (iCode *ic)
                                }
                                pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i));
                        }
+                       
+                       DEBUGpic16_pic16_AopTypeSign(__LINE__, NULL, right, NULL);
 
                        // add leftover bytes
                        if (SPEC_USIGN(getSpec(operandType(right)))) {
index ac5172e262670eec461d8687f2f7bbde697c950b..73b13398cb04534c156be14a11bf2087ca34df0c 100644 (file)
@@ -1276,11 +1276,11 @@ CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
              resolveIvalSym (sym->ival, sym->type);
              asym = newSymbol(sym->rname, 0);
              abSym = Safe_calloc(1, sizeof(absSym));
-             abSym->name = Safe_strdup( sym->rname );
+             strcpy(abSym->name, sym->rname);
              abSym->address = SPEC_ADDR( sym->etype );
              addSet(&absSymSet, abSym);
              
-             pb = pic16_newpCodeChain(NULL, 'A',pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
+             pb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute Ival"));
              pic16_addpBlock(pb);
 
              pcf = pic16_newpCodeFunction(moduleName, asym->name);
@@ -1450,6 +1450,11 @@ pic16initialComments (FILE * afile)
        if(pic16_mplab_comp)
                fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n");
        fprintf (afile, iComments2);
+
+       if(options.debug) {
+               fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]\"\n",
+                               SDCC_VERSION_STR, getBuildNumber() );
+       }
 }
 
 /*-----------------------------------------------------------------*/
index dcd664f9dea2ba7fd519b574721cf4b49baefde9..ab2748f087a6ebc0213d42adffd3df642b720924 100644 (file)
@@ -156,6 +156,8 @@ _process_pragma(const char *sz)
                        maxRAMaddress = (int)floatFromVal(maxRAMVal);
                        pic16_setMaxRAM(maxRAMaddress);
                }
+
+          return 0;
        }
        
        /* #pragma stack [stack-position] [stack-len] */
@@ -178,7 +180,10 @@ _process_pragma(const char *sz)
 
                if(stackLen < 1) {
                        stackLen = 64;
-                       fprintf(stderr, "%s:%d setting stack to default size %d\n", __FILE__, __LINE__, stackLen);
+                       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, "Initializing stack pointer at 0x%x len 0x%x\n", stackPos, stackLen);
@@ -210,13 +215,20 @@ _process_pragma(const char *sz)
          value *addr;
 
                absS = Safe_calloc(1, sizeof(absSym));
-               absS->name = Safe_strdup( symname );
+               sprintf(absS->name, "_%s", symname);
+               
                addr = constVal( location );
                absS->address = (unsigned int)floatFromVal( addr );
 
+               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);
+                }
+
                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);
+//             fprintf(stderr, "%s:%d symbol %s will be placed in location 0x%06x in code memory\n",
+//                     __FILE__, __LINE__, symname, absS->address);
 
          return 0;
        }
@@ -402,6 +414,8 @@ _pic16_parseOptions (int *pargc, char **argv, int *i)
         if(ISOPT(USE_CRT)) {
             pic16_options.no_crt = 0;
             pic16_options.crt_name = Safe_strdup( getStringArg(USE_CRT, argv, i, *pargc) );
+
+            return TRUE;
         }
         
   return FALSE;
@@ -471,7 +485,7 @@ static void _pic16_linkEdit(void)
         *
         */
         
-       sprintf(lfrm, "{linker} {incdirs} {lflags} -o {outfile} {spec_ofiles} {ofiles} {libs}");
+       sprintf(lfrm, "{linker} {incdirs} {lflags} -o {outfile} {user_ofile} {spec_ofiles} {ofiles} {libs}");
                 
        shash_add(&linkValues, "linker", "gplink");
 
@@ -485,7 +499,8 @@ static void _pic16_linkEdit(void)
 
        if(fullSrcFileName) {
                sprintf(temp, "%s.o", dstFileName);
-               addSetHead(&relFilesSet, Safe_strdup(temp));
+//             addSetHead(&relFilesSet, Safe_strdup(temp));
+                shash_add(&linkValues, "user_ofile", temp);
        }
 
        if(!pic16_options.no_crt)
index 7e392925f4144c374f7ba94689e059455c115649..813eead64efc3e7ef71b38c0836c689f2f4d179d 100644 (file)
@@ -13,7 +13,7 @@ typedef struct {
 } pic16_sectioninfo_t;
 
 typedef struct absSym {
-       char *name;
+       char name[SDCC_SYMNAME_MAX+1];
        unsigned int address;
 } absSym;
 
index f520ff06fa8a9af9038ed6650cb9ca75bfe8e349..14b8863d6c5ba71f8d45658806654fdb7c79baa2 100644 (file)
@@ -4418,7 +4418,9 @@ void pic16_printpBlock(FILE *of, pBlock *pb)
                        if(pb->dbName == 'A') {
                          absSym *ab;
                                for(ab=setFirstItem(absSymSet); ab; ab=setNextItem(absSymSet)) {
+//                                     fprintf(stderr, "%s:%d testing %s <-> %s\n", __FILE__, __LINE__, PCF(pc)->fname, ab->name);
                                        if(!strcmp(ab->name, PCF(pc)->fname)) {
+//                                             fprintf(stderr, "%s:%d address = %x\n", __FILE__, __LINE__, ab->address);
                                                fprintf(of, "\t0X%06X", ab->address);
                                                break;
                                        }
index 0f9574b849c1d63a6cc7b224bf7ebb77f9082c1b..c1d5bc7340c62ae19c421606965ce79ad3267b35 100644 (file)
@@ -127,22 +127,23 @@ regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alia
 
 /* Define register address that are constant across PIC16 family */
 #define IDX_TMR0    0xfd6
-#define IDX_PCL     0xff9
 #define IDX_STATUS  0xfd8
-#define IDX_PCLATH  0xffa
-#define IDX_PCLATU  0xffb /* patch 14 */
 #define IDX_INTCON  0xff2
 #define IDX_WREG    0xfe8
 #define IDX_BSR     0xfe0
 
-#define IDX_TOSL    0xffd /* patch 14 */
-#define IDX_TOSH    0xffe /* patch 14 */
-#define IDX_TOSU    0xfff /* patch 14 */
+#define IDX_PCL     0xff9
+#define IDX_PCLATH  0xffa
+#define IDX_PCLATU  0xffb 
+
+#define IDX_TOSL    0xffd
+#define IDX_TOSH    0xffe
+#define IDX_TOSU    0xfff
 
-#define IDX_TBLPTRL 0xff6 /* patch 15 */
-#define IDX_TBLPTRH 0xff7 /* patch 15 */
-#define IDX_TBLPTRU 0xff8 /* patch 15 */
-#define IDX_TABLAT  0xff5 /* patch 15 */
+#define IDX_TBLPTRL 0xff6
+#define IDX_TBLPTRH 0xff7
+#define IDX_TBLPTRU 0xff8
+#define IDX_TABLAT  0xff5
 
 #define IDX_FSR0    0xfe9
 #define IDX_FSR0L   0xfe9