* device/lib/Makefile.in: fixed bug in target objects-pic16,
[fw/sdcc] / src / pic16 / pcode.c
index 12ca4c6c0a6106075a3939f16eeb0ccb19b0ae65..619e67b19cc3c71eb6924cb2aba898bbfae8be93 100644 (file)
@@ -100,6 +100,14 @@ pCodeOpReg pic16_pc_plusw2 = {{PO_INDF0,   "PLUSW2"}, -1, NULL, 0, NULL};
 pCodeOpReg pic16_pc_prodl      = {{PO_PRODL, "PRODL"}, -1, NULL, 0, NULL};
 pCodeOpReg pic16_pc_prodh      = {{PO_PRODH, "PRODH"}, -1, NULL, 0, NULL};
 
+/* EEPROM registers */
+pCodeOpReg pic16_pc_eecon1     = {{PO_SFR_REGISTER, "EECON1"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_eecon2     = {{PO_SFR_REGISTER, "EECON2"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_eedata     = {{PO_SFR_REGISTER, "EEDATA"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_eeadr      = {{PO_SFR_REGISTER, "EEADR"}, -1, NULL, 0, NULL};
+
+
+
 pCodeOpReg pic16_pc_kzero     = {{PO_GPR_REGISTER,  "KZ"}, -1, NULL,0,NULL};
 pCodeOpReg pic16_pc_wsave     = {{PO_GPR_REGISTER,  "WSAVE"}, -1, NULL,0,NULL};
 pCodeOpReg pic16_pc_ssave     = {{PO_GPR_REGISTER,  "SSAVE"}, -1, NULL,0,NULL};
@@ -2682,6 +2690,33 @@ pCodeInstruction pic16_pciXORLW = {
 };
 
 
+pCodeInstruction pic16_pciBANKSEL = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   genericDestruct,
+   genericPrint},
+  POC_BANKSEL,
+  "BANKSEL",
+  NULL, // from branch
+  NULL, // to branch
+  NULL, // label
+  NULL, // operand
+  NULL, // flow block
+  NULL, // C source 
+  0,    // num ops
+  0,0,  // dest, bit instruction
+  0,0,  // branch, skip
+  0,    // literal operand
+  0,    // RAM access bit
+  0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
+  POC_NOP,
+  PCC_NONE,   // inCond
+  PCC_NONE, // outCond
+  PCI_MAGIC
+};
+
+
 #define MAX_PIC16MNEMONICS 100
 pCodeInstruction *pic16Mnemonics[MAX_PIC16MNEMONICS];
 
@@ -2784,13 +2819,10 @@ void  pic16_pCodeInitRegisters(void)
        pic16_pc_tosh.r = pic16_allocProcessorRegister(IDX_TOSH,"TOSH", PO_SFR_REGISTER, 0x80);
        pic16_pc_tosu.r = pic16_allocProcessorRegister(IDX_TOSU,"TOSU", PO_SFR_REGISTER, 0x80);
 
-       pic16_pc_tblptrl.r = pic16_allocProcessorRegister(IDX_TBLPTRL,"TBLPTRL", PO_SFR_REGISTER, 0x80); // patch 15
-       pic16_pc_tblptrh.r = pic16_allocProcessorRegister(IDX_TBLPTRH,"TBLPTRH", PO_SFR_REGISTER, 0x80); // patch 15
-       pic16_pc_tblptru.r = pic16_allocProcessorRegister(IDX_TBLPTRU,"TBLPTRU", PO_SFR_REGISTER, 0x80); // patch 15
-       pic16_pc_tablat.r = pic16_allocProcessorRegister(IDX_TABLAT,"TABLAT", PO_SFR_REGISTER, 0x80); // patch 15
-
-
-//     pic16_pc_fsr0.r = pic16_allocProcessorRegister(IDX_FSR0,"FSR0", PO_FSR0, 0x80); // deprecated !
+       pic16_pc_tblptrl.r = pic16_allocProcessorRegister(IDX_TBLPTRL,"TBLPTRL", PO_SFR_REGISTER, 0x80);
+       pic16_pc_tblptrh.r = pic16_allocProcessorRegister(IDX_TBLPTRH,"TBLPTRH", PO_SFR_REGISTER, 0x80);
+       pic16_pc_tblptru.r = pic16_allocProcessorRegister(IDX_TBLPTRU,"TBLPTRU", PO_SFR_REGISTER, 0x80);
+       pic16_pc_tablat.r = pic16_allocProcessorRegister(IDX_TABLAT,"TABLAT", PO_SFR_REGISTER, 0x80);
 
        pic16_pc_fsr0l.r = pic16_allocProcessorRegister(IDX_FSR0L, "FSR0L", PO_FSR0, 0x80);
        pic16_pc_fsr0h.r = pic16_allocProcessorRegister(IDX_FSR0H, "FSR0H", PO_FSR0, 0x80);
@@ -2819,6 +2851,13 @@ void  pic16_pCodeInitRegisters(void)
        
        pic16_pc_prodl.r = pic16_allocProcessorRegister(IDX_PRODL, "PRODL", PO_PRODL, 0x80);
        pic16_pc_prodh.r = pic16_allocProcessorRegister(IDX_PRODH, "PRODH", PO_PRODH, 0x80);
+
+
+       pic16_pc_eecon1.r = pic16_allocProcessorRegister(IDX_EECON1, "EECON1", PO_SFR_REGISTER, 0x80);
+       pic16_pc_eecon2.r = pic16_allocProcessorRegister(IDX_EECON2, "EECON2", PO_SFR_REGISTER, 0x80);
+       pic16_pc_eedata.r = pic16_allocProcessorRegister(IDX_EEDATA, "EEDATA", PO_SFR_REGISTER, 0x80);
+       pic16_pc_eeadr.r = pic16_allocProcessorRegister(IDX_EEADR, "EEADR", PO_SFR_REGISTER, 0x80);
+
        
        pic16_pc_status.rIdx = IDX_STATUS;
        pic16_pc_intcon.rIdx = IDX_INTCON;
@@ -2870,6 +2909,12 @@ void  pic16_pCodeInitRegisters(void)
        pic16_pc_wsave.rIdx = IDX_WSAVE;
        pic16_pc_ssave.rIdx = IDX_SSAVE;
 
+       pic16_pc_eecon1.rIdx = IDX_EECON1;
+       pic16_pc_eecon2.rIdx = IDX_EECON2;
+       pic16_pc_eedata.rIdx = IDX_EEDATA;
+       pic16_pc_eeadr.rIdx = IDX_EEADR;
+       
+
        /* probably should put this in a separate initialization routine */
        pb_dead_pcodes = newpBlock();
 
@@ -2981,7 +3026,7 @@ void pic16initMnemonics(void)
   pic16Mnemonics[POC_RETURN] = &pic16_pciRETURN;
   pic16Mnemonics[POC_RLCF] = &pic16_pciRLCF;
   pic16Mnemonics[POC_RLCFW] = &pic16_pciRLCFW;
-  pic16Mnemonics[POC_RLNCF] = &pic16_pciRLNCF; // was [POC_RLCF] !!!
+  pic16Mnemonics[POC_RLNCF] = &pic16_pciRLNCF;
   pic16Mnemonics[POC_RLNCFW] = &pic16_pciRLNCFW;
   pic16Mnemonics[POC_RRCF] = &pic16_pciRRCF;
   pic16Mnemonics[POC_RRCFW] = &pic16_pciRRCFW;
@@ -2997,18 +3042,19 @@ void pic16initMnemonics(void)
   pic16Mnemonics[POC_SUBFWB_D1] = &pic16_pciSUBFWB_D1;
   pic16Mnemonics[POC_SWAPF] = &pic16_pciSWAPF;
   pic16Mnemonics[POC_SWAPFW] = &pic16_pciSWAPFW;
-  pic16Mnemonics[POC_TBLRD] = &pic16_pciTBLRD;                 // patch 15
-  pic16Mnemonics[POC_TBLRD_POSTINC] = &pic16_pciTBLRD_POSTINC; //
-  pic16Mnemonics[POC_TBLRD_POSTDEC] = &pic16_pciTBLRD_POSTDEC; //
-  pic16Mnemonics[POC_TBLRD_PREINC] = &pic16_pciTBLRD_PREINC;   //
-  pic16Mnemonics[POC_TBLWT] = &pic16_pciTBLWT;                 //
-  pic16Mnemonics[POC_TBLWT_POSTINC] = &pic16_pciTBLWT_POSTINC; //
-  pic16Mnemonics[POC_TBLWT_POSTDEC] = &pic16_pciTBLWT_POSTDEC; //
-  pic16Mnemonics[POC_TBLWT_PREINC] = &pic16_pciTBLWT_PREINC;   // patch 15
+  pic16Mnemonics[POC_TBLRD] = &pic16_pciTBLRD;
+  pic16Mnemonics[POC_TBLRD_POSTINC] = &pic16_pciTBLRD_POSTINC;
+  pic16Mnemonics[POC_TBLRD_POSTDEC] = &pic16_pciTBLRD_POSTDEC;
+  pic16Mnemonics[POC_TBLRD_PREINC] = &pic16_pciTBLRD_PREINC;
+  pic16Mnemonics[POC_TBLWT] = &pic16_pciTBLWT;
+  pic16Mnemonics[POC_TBLWT_POSTINC] = &pic16_pciTBLWT_POSTINC;
+  pic16Mnemonics[POC_TBLWT_POSTDEC] = &pic16_pciTBLWT_POSTDEC;
+  pic16Mnemonics[POC_TBLWT_PREINC] = &pic16_pciTBLWT_PREINC;
   pic16Mnemonics[POC_TSTFSZ] = &pic16_pciTSTFSZ;
   pic16Mnemonics[POC_XORLW] = &pic16_pciXORLW;
   pic16Mnemonics[POC_XORWF] = &pic16_pciXORWF;
   pic16Mnemonics[POC_XORFW] = &pic16_pciXORFW;
+  pic16Mnemonics[POC_BANKSEL] = &pic16_pciBANKSEL;
 
   for(i=0; i<MAX_PIC16MNEMONICS; i++)
     if(pic16Mnemonics[i])
@@ -3646,7 +3692,8 @@ pCode *pic16_newpCodeLabel(char *name, int key)
   pcl->pc.print = pCodePrintLabel;
 
   pcl->key = key;
-
+  pcl->force = 0;
+  
   pcl->label = NULL;
   if(key>0) {
     sprintf(s,"_%05d_DS_",key);
@@ -3664,6 +3711,15 @@ pCode *pic16_newpCodeLabel(char *name, int key)
 
 }
 
+pCode *pic16_newpCodeLabelFORCE(char *name, int key)
+{
+  pCodeLabel *pcl = (pCodeLabel *)pic16_newpCodeLabel(name, key);
+  
+       pcl->force = 1;
+  
+  return ( (pCode *)pcl );
+}
+
 
 /*-----------------------------------------------------------------*/
 /* newpBlock - create and return a pointer to a new pBlock         */
@@ -3843,6 +3899,8 @@ pCodeOp *pic16_newpCodeOpWild(int id, pCodeWildBlock *pcwb, pCodeOp *subtype)
   PCOW(pcop)->subtype = subtype;
   PCOW(pcop)->matched = NULL;
 
+  PCOW(pcop)->pcop2 = NULL;
+  
   return pcop;
 }
 
@@ -3854,33 +3912,52 @@ pCodeOp *pic16_newpCodeOpWild2(int id, int id2, pCodeWildBlock *pcwb, pCodeOp *s
   pCodeOp *pcop;
 
 
-  if(!pcwb || !subtype || !subtype2) {
-    fprintf(stderr, "Wild opcode declaration error: %s-%d\n",__FILE__,__LINE__);
-    exit(1);
-  }
+       if(!pcwb || !subtype || !subtype2) {
+               fprintf(stderr, "Wild opcode declaration error: %s-%d\n",__FILE__,__LINE__);
+               exit(1);
+       }
 
-  pcop = Safe_calloc(1,sizeof(pCodeOpWild));
-  pcop->type = PO_WILD;
-  sprintf(s,"%%%d",id);
-  pcop->name = Safe_strdup(s);
+       pcop = Safe_calloc(1,sizeof(pCodeOpWild));
+       pcop->type = PO_WILD;
+       sprintf(s,"%%%d",id);
+       pcop->name = Safe_strdup(s);
 
-  PCOW(pcop)->id = id;
-  PCOW(pcop)->pcwb = pcwb;
-  PCOW(pcop)->subtype = subtype;
-  PCOW(pcop)->matched = NULL;
+       PCOW(pcop)->id = id;
+       PCOW(pcop)->pcwb = pcwb;
+       PCOW(pcop)->subtype = subtype;
+       PCOW(pcop)->matched = NULL;
+
+       PCOW(pcop)->pcop2 = Safe_calloc(1, sizeof(pCodeOpWild));
+
+       if(!subtype2->name) {
+               PCOW(pcop)->pcop2 = Safe_calloc(1, sizeof(pCodeOpWild));
+               PCOW2(pcop)->pcop.type = PO_WILD;
+               sprintf(s, "%%%d", id2);
+               PCOW2(pcop)->pcop.name = Safe_strdup(s);
+               PCOW2(pcop)->id = id2;
+               PCOW2(pcop)->subtype = subtype2;
+
+//             fprintf(stderr, "%s:%d %s [wild,wild] for name: %s (%d)\tname2: %s (%d)\n", __FILE__, __LINE__, __FUNCTION__,
+//                             pcop->name, id, PCOW2(pcop)->pcop.name, id2);
+       } else {
+               PCOW2(pcop)->pcop2 = pic16_pCodeOpCopy( subtype2 );
+
+//             fprintf(stderr, "%s:%d %s [wild,str] for name: %s (%d)\tname2: %s (%d)\n", __FILE__, __LINE__, __FUNCTION__,
+//                             pcop->name, id, PCOW2(pcop)->pcop.name, id2);
+       }
+  
 
-  PCOW(pcop)->id2 = id2;
-  PCOW(pcop)->subtype2 = subtype2;
 
   return pcop;
 }
 
+
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-pCodeOp *pic16_newpCodeOpBit(char *s, int bit, int inBitSpace)
+pCodeOp *pic16_newpCodeOpBit(char *s, int bit, int inBitSpace, PIC_OPTYPE subt)
 {
   pCodeOp *pcop;
-
+  
   pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) );
   pcop->type = PO_GPR_BIT;
   if(s)
@@ -3890,6 +3967,7 @@ pCodeOp *pic16_newpCodeOpBit(char *s, int bit, int inBitSpace)
 
   PCORB(pcop)->bit = bit;
   PCORB(pcop)->inBitSpace = inBitSpace;
+  PCORB(pcop)->subtype = subt;
 
   /* pCodeOpBit is derived from pCodeOpReg. We need to init this too */
   PCOR(pcop)->r = NULL;
@@ -3897,6 +3975,7 @@ pCodeOp *pic16_newpCodeOpBit(char *s, int bit, int inBitSpace)
   return pcop;
 }
 
+
 /*-----------------------------------------------------------------*
  * pCodeOp *pic16_newpCodeOpReg(int rIdx) - allocate a new register
  *
@@ -3962,7 +4041,7 @@ pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE type)
   switch(type) {
   case PO_BIT:
   case PO_GPR_BIT:
-    pcop = pic16_newpCodeOpBit(name, -1,0);
+    pcop = pic16_newpCodeOpBit(name, -1,0, type);
     break;
 
   case PO_LITERAL:
@@ -3995,6 +4074,7 @@ pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE type)
   return pcop;
 }
 
+#define DB_ITEMS_PER_LINE      8
 
 typedef struct DBdata
   {
@@ -4004,18 +4084,46 @@ typedef struct DBdata
 
 struct DBdata DBd;
 static int DBd_init = -1;
-static int DB_prev = -1;
+
+/*-----------------------------------------------------------------*/
+/*    Initialiase "DB" data buffer                                 */
+/*-----------------------------------------------------------------*/
+void pic16_initDB(void)
+{
+       DBd_init = -1;
+}
+
+
+/*-----------------------------------------------------------------*/
+/*    Flush pending "DB" data to a pBlock                          */
+/*                                                                 */
+/* ptype - type of p pointer, 'f' file pointer, 'p' pBlock pointer */
+/*-----------------------------------------------------------------*/
+void pic16_flushDB(char ptype, void *p)
+{
+       if (DBd.count>0) {
+               if(ptype == 'p')
+                       pic16_addpCode2pBlock(((pBlock *)p),pic16_newpCodeAsmDir("DB", "%s", DBd.buffer));
+               else
+               if(ptype == 'f')
+                       fprintf(((FILE *)p), "\tdb\t%s\n", DBd.buffer);
+                else {
+                       /* sanity check */
+                       fprintf(stderr, "PIC16 port error: could not emit initial value data\n");
+                }
+
+               DBd.count = 0;
+               DBd.buffer[0] = '\0';
+       }
+}
+
 
 /*-----------------------------------------------------------------*/
 /*    Add "DB" directives to a pBlock                              */
 /*-----------------------------------------------------------------*/
-void pic16_emitDB(pBlock *pb, char c)
+void pic16_emitDB(char c, char ptype, void *p)
 {
   int l;
-  char *frm, tbuf[8];;
-  char frm_alnum[]="%c";
-  char frm_other[]="0x%02x";
-
 
        if (DBd_init<0) {
         // we need to initialize
@@ -4025,55 +4133,37 @@ void pic16_emitDB(pBlock *pb, char c)
        }
 
        l = strlen(DBd.buffer);
+       sprintf(DBd.buffer+l,"%s0x%02x", (DBd.count>0?", ":""), c & 0xff);
 
-       if(isprint( c ))frm = frm_alnum;
-       else frm = frm_other;
-       sprintf(tbuf, frm, c & 0xff);
-       
-       if(!isprint(DB_prev)) {
-               if(isprint(c))
-                       if(DBd.count)strcat(DBd.buffer, ", \"");
-                       else strcat(DBd.buffer, "\"");
-               else if(DBd.count) strcat(DBd.buffer, ", ");
-       } else
-               if(!isprint(c))strcat(DBd.buffer, "\", ");
+//     fprintf(stderr, "%s:%d DBbuffer: '%s'\n", __FILE__, __LINE__, DBd.buffer);
        
-       strcat(DBd.buffer, tbuf);
+       DBd.count++;
+       if (DBd.count>= DB_ITEMS_PER_LINE)
+               pic16_flushDB(ptype, p);
+}
 
-#if 0          
-       if (DBd.count>0) {
-               sprintf(DBd.buffer+l,", 0x%02x", c & 0xff);
-       } else {
-               sprintf(DBd.buffer,"0x%02x", c & 0xff);
-       }
-#endif
+void pic16_emitDS(char *s, char ptype, void *p)
+{
+  int l;
 
-       DBd.count++;
-       DB_prev = c;
-       
-       if (DBd.count>=16) {
-               if(isprint(c))strcat(DBd.buffer, "\"");
-               pic16_addpCode2pBlock(pb,pic16_newpCodeAsmDir("DB", "%s", DBd.buffer));
+       if (DBd_init<0) {
+        // we need to initialize
+               DBd_init = 0;
                DBd.count = 0;
                DBd.buffer[0] = '\0';
-               DB_prev = 0;
        }
-}
 
-/*-----------------------------------------------------------------*/
-/*    Flush pending "DB" data to a pBlock                          */
-/*-----------------------------------------------------------------*/
-void pic16_flushDB(pBlock *pb)
-{
-  if (DBd.count>0)
-    {
-       if(isprint(DB_prev))strcat(DBd.buffer, "\"");
-       pic16_addpCode2pBlock(pb,pic16_newpCodeAsmDir("DB", "%s", DBd.buffer));
-       DBd.count = 0;
-       DBd.buffer[0] = '\0';
-    }
+       l = strlen(DBd.buffer);
+       sprintf(DBd.buffer+l,"%s%s", (DBd.count>0?", ":""), s);
+
+//     fprintf(stderr, "%s:%d DBbuffer: '%s'\n", __FILE__, __LINE__, DBd.buffer);
+
+       DBd.count++;    //=strlen(s);
+       if (DBd.count>=16)
+               pic16_flushDB(ptype, p);
 }
 
+
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 void pic16_pCodeConstString(char *name, char *value)
@@ -4095,9 +4185,9 @@ void pic16_pCodeConstString(char *name, char *value)
   pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(name,-1));
 
   do {
-        pic16_emitDB(pb, *value);
+        pic16_emitDB(*value, 'p', (void *)pb);
   }while (*value++);
-  pic16_flushDB(pb);
+  pic16_flushDB('p', (void *)pb);
 }
 
 /*-----------------------------------------------------------------*/
@@ -4932,9 +5022,9 @@ static pBranch *pBranchFind(pBranch *pb,pCode *pc)
 }
 
 /*-----------------------------------------------------------------*/
-/* pCodeUnlink - Unlink the given pCode from its pCode chain.      */
+/* pic16_pCodeUnlink - Unlink the given pCode from its pCode chain.      */
 /*-----------------------------------------------------------------*/
-static void pCodeUnlink(pCode *pc)
+void pic16_pCodeUnlink(pCode *pc)
 {
   pBranch *pb1,*pb2;
   pCode *pc1;
@@ -4952,21 +5042,21 @@ static void pCodeUnlink(pCode *pc)
 
   /* Remove the branches */
 
-  pb1 = pc->from;
+  pb1 = PCI(pc)->from;
   while(pb1) {
-    pc1 = pb1->pc;    /* Get the pCode that branches to the
+    PCI(pc1) = pb1->pc;    /* Get the pCode that branches to the
                       * one we're unlinking */
 
     /* search for the link back to this pCode (the one we're
      * unlinking) */
-    if(pb2 = pBranchFind(pc1->to,pc)) {
-      pb2->pc = pc->to->pc;  // make the replacement
+    if((pb2 = pBranchFind(PCI(pc1)->to,pc))) {
+      pb2->pc = PCI(pc)->to->pc;  // make the replacement
 
       /* if the pCode we're unlinking contains multiple 'to'
        * branches (e.g. this a skip instruction) then we need
        * to copy these extra branches to the chain. */
-      if(pc->to->next)
-       pic16_pBranchAppend(pb2, pc->to->next);
+      if(PCI(pc)->to->next)
+       pic16_pBranchAppend(pb2, PCI(pc)->to->next);
     }
     
     pb1 = pb1->next;
@@ -5162,7 +5252,7 @@ pCode * pic16_findNextInstruction(pCode *pci)
 }
 
 /*-----------------------------------------------------------------*/
-/* pic16_findNextInstruction - given a pCode, find the next instruction  */
+/* pic16_findPrevInstruction - given a pCode, find the next instruction  */
 /*                       in the linked list                        */
 /*-----------------------------------------------------------------*/
 pCode * pic16_findPrevInstruction(pCode *pci)
@@ -5170,6 +5260,8 @@ pCode * pic16_findPrevInstruction(pCode *pci)
   pCode *pc = pci;
 
   while(pc) {
+    pc = pc->prev;
+
     if((pc->type == PC_OPCODE)
        || (pc->type == PC_WILD)
        || (pc->type == PC_ASMDIR)
@@ -5181,7 +5273,6 @@ pCode * pic16_findPrevInstruction(pCode *pci)
     fprintf(stderr,"pic16_findPrevInstruction:  ");
     printpCode(stderr, pc);
 #endif
-    pc = pc->next;
   }
 
   //fprintf(stderr,"Couldn't find instruction\n");
@@ -5217,7 +5308,7 @@ static pCode * findFunctionEnd(pCode *pc)
 static void AnalyzeLabel(pCode *pc)
 {
 
-  pCodeUnlink(pc);
+  pic16_pCodeUnlink(pc);
 
 }
 #endif
@@ -5272,8 +5363,6 @@ regs * pic16_getRegFromInstruction(pCode *pc)
   case PO_FSR0:
     return PCOR(PCI(pc)->pcop)->r;
 
-    //    return typeRegWithIdx (PCOR(PCI(pc)->pcop)->rIdx, REG_SFR, 0);
-
   case PO_BIT:
   case PO_GPR_TEMP:
 //     fprintf(stderr, "pic16_getRegFromInstruction - bit or temp\n");
@@ -5283,16 +5372,13 @@ regs * pic16_getRegFromInstruction(pCode *pc)
     if(PCOI(PCI(pc)->pcop)->r)
       return (PCOI(PCI(pc)->pcop)->r);
 
-    //fprintf(stderr, "pic16_getRegFromInstruction - immediate\n");
-    return pic16_dirregWithName(PCI(pc)->pcop->name);
-    //return NULL; // PCOR(PCI(pc)->pcop)->r;
-
   case PO_GPR_BIT:
     return PCOR(PCI(pc)->pcop)->r;
 
   case PO_DIR:
 //     fprintf(stderr, "pic16_getRegFromInstruction - dir\n");
     return PCOR(PCI(pc)->pcop)->r;
+
   case PO_LITERAL:
     //fprintf(stderr, "pic16_getRegFromInstruction - literal\n");
     break;
@@ -5301,7 +5387,7 @@ regs * pic16_getRegFromInstruction(pCode *pc)
 //     fprintf(stderr, "pic16_getRegFromInstruction - unknown reg type %d\n",PCI(pc)->pcop->type);
 //     genericPrint(stderr, pc);
 //     assert( 0 );
-    break;
+       break;
   }
 
   return NULL;
@@ -5869,8 +5955,11 @@ int pic16_isPCinFlow(pCode *pc, pCode *pcflow)
 /*                                                                 */
 /* position == 0: insert before                                    */
 /* position == 1: insert after pc                                  */
-/* position == 2: 0 previous was a skip instruction                */
+/* position == 2: like 0 but previous was a skip instruction       */
 /*-----------------------------------------------------------------*/
+pCodeOp *pic16_popGetLabel(unsigned int key);
+extern int pic16_labelOffset;
+
 static void insertBankSwitch(int position, pCode *pc)
 {
   pCode *new_pc;
@@ -5882,13 +5971,15 @@ static void insertBankSwitch(int position, pCode *pc)
        /* emit BANKSEL [symbol] */
 
        reg = pic16_getRegFromInstruction(pc);
-       if(!reg)return;
+       if(!reg) {
+               if(!(PCI(pc)->pcop && PCI(pc)->pcop->type == PO_GPR_BIT))return;
+       }
        new_pc = pic16_newpCodeAsmDir("BANKSEL", "%s", pic16_get_op_from_instruction(PCI(pc)));
        
 //     position = 0;           // position is always before (sanity check!)
 
 #if 0
-       fprintf(stderr, "%s:%d: inserting bank switch\tbank = %d\n", __FUNCTION__, __LINE__, bsr);
+       fprintf(stderr, "%s:%d: inserting bank switch\n", __FUNCTION__, __LINE__);
        pc->print(stderr, pc);
 #endif
 
@@ -5896,27 +5987,65 @@ static void insertBankSwitch(int position, pCode *pc)
                case 1: {
                        /* insert the bank switch after this pc instruction */
                        pCode *pcnext = pic16_findNextInstruction(pc);
-                       pic16_pCodeInsertAfter(pc, new_pc);
-                       if(pcnext)pc = pcnext;
+
+                               pic16_pCodeInsertAfter(pc, new_pc);
+                               if(pcnext)pc = pcnext;
                }; break;
                
                case 0:
                        /* insert the bank switch BEFORE this pc instruction */
                        pic16_pCodeInsertAfter(pc->prev, new_pc);
                        break;
+
+               case 2: {
+                       /* just like 0, but previous was a skip instruction,
+                        * so some care should be taken */
+                         symbol *tlbl;
+                         pCode *pcnext, *pcprev, *npci;;
+                         PIC_OPCODE ipci;
+                         
+                               pic16_labelOffset += 10000;
+                               tlbl = newiTempLabel(NULL);
+                               
+                               /* invert skip instruction */
+                               pcprev = pic16_findPrevInstruction(pc);
+                               ipci = PCI(pcprev)->inverted_op;
+                               npci = pic16_newpCode(ipci, PCI(pcprev)->pcop);
+
+#if 1
+                               PCI(npci)->from = PCI(pcprev)->from;
+                               PCI(npci)->to = PCI(pcprev)->to;
+                               PCI(npci)->label = PCI(pcprev)->label;
+                               PCI(npci)->pcflow = PCI(pcprev)->pcflow;
+                               PCI(npci)->cline = PCI(pcprev)->cline;
+#endif
+
+//                             memmove(PCI(pcprev), PCI(npci), sizeof(pCode) + sizeof(PIC_OPCODE) + sizeof(char const * const));
+
+#if 1
+                               pic16_pCodeInsertAfter(pcprev->prev, npci);
+                               /* unlink the pCode */
+                               pcprev->prev->next = pcprev->next;
+                               pcprev->next->prev = pcprev->prev;
+#endif
+                               
+                               pcnext = pic16_newpCode(POC_GOTO, pic16_popGetLabel(tlbl->key));
+                               pic16_pCodeInsertAfter(pc->prev, pcnext);
+                               pic16_pCodeInsertAfter(pc->prev, new_pc);
+                               
+                               pcnext = pic16_newpCodeLabel(NULL,tlbl->key+100+pic16_labelOffset);
+                               pic16_pCodeInsertAfter(pc, pcnext);
+                       }; break;
        }
        
 
        /* Move the label, if there is one */
-
        if(PCI(pc)->label) {
 //             fprintf(stderr, "%s:%d: moving label due to bank switch directive src= 0x%p dst= 0x%p\n",
 //                     __FILE__, __LINE__, pc, new_pc);
                PCAD(new_pc)->pci.label = PCI(pc)->label;
                PCI(pc)->label = NULL;
        }
-
-//  fprintf(stderr, "BankSwitch has been inserted\n");
 }
 
 
@@ -6175,7 +6304,8 @@ static void pBlockRemoveUnusedLabels(pBlock *pb)
     /* This pCode is a label, so search the pBlock to see if anyone
      * refers to it */
 
-    if( (pcl->key>0) && (!findInstructionUsingLabel(pcl, pb->pcHead))) {
+    if( (pcl->key>0) && (!findInstructionUsingLabel(pcl, pb->pcHead))
+       && (!pcl->force)) {
     //if( !findInstructionUsingLabel(pcl, pb->pcHead)) {
       /* Couldn't find an instruction that refers to this label
        * So, unlink the pCode label from it's pCode chain
@@ -6301,6 +6431,12 @@ static int OptimizepCode(char dbName)
   return matches;
 }
 
+
+
+const char *pic16_pCodeOpType(pCodeOp *pcop);
+const char *pic16_pCodeOpSubType(pCodeOp *pcop);
+
+
 /*-----------------------------------------------------------------*/
 /* pic16_popCopyGPR2Bit - copy a pcode operator                          */
 /*-----------------------------------------------------------------*/
@@ -6309,7 +6445,8 @@ pCodeOp *pic16_popCopyGPR2Bit(pCodeOp *pc, int bitval)
 {
   pCodeOp *pcop;
 
-  pcop = pic16_newpCodeOpBit(pc->name, bitval, 0);
+//  fprintf(stderr, "%s:%d pc type: %s\n", __FILE__, __LINE__, pic16_pCodeOpType(pc));
+  pcop = pic16_newpCodeOpBit(pc->name, bitval, 0, pc->type);
 
   if( !( (pcop->type == PO_LABEL) ||
         (pcop->type == PO_LITERAL) ||
@@ -6339,102 +6476,83 @@ static void pic16_FixRegisterBanking(pBlock *pb)
   pCode *pc=NULL;
   pCode *pcprev=NULL;
   regs *reg, *prevreg;
-
+  int flag=0;
+  
        if(!pb)
                return;
 
        pc = pic16_findNextpCode(pb->pcHead, PC_OPCODE);
-       if(!pc)
-               return;
+       if(!pc)return;
 
        /* loop through all of the flow blocks with in one pblock */
 
 //     fprintf(stderr,"%s:%d: Register banking\n", __FUNCTION__, __LINE__);
 
-  prevreg = NULL;
-  do {
-    /* at this point, pc should point to a PC_FLOW object */
-    /* for each flow block, determine the register banking 
-       requirements */
+       prevreg = NULL;
+       do {
+               /* at this point, pc should point to a PC_FLOW object */
+               /* for each flow block, determine the register banking 
+                * requirements */
 
-      if(isPCI(pc) && !PCI(pc)->is2MemOp) {
+               if(!isPCI(pc))goto loop;
+
+               if(PCI(pc)->is2MemOp)goto loop;
+       
                reg = pic16_getRegFromInstruction(pc);
 
 #if 0
+               pc->print(stderr, pc);
                fprintf(stderr, "reg = %p\n", reg);
+
                if(reg) {
                        fprintf(stderr, "%s:%d:  %s  %d\n",__FUNCTION__, __LINE__, reg->name, reg->rIdx);
-                       fprintf(stderr, "addr = 0x%03x, bank = %d, bit=%d\tmapped = %d sfr=%d fix=%d\n",
-                               reg->address,REG_BANK(reg),reg->isBitField, reg->isMapped,
-                               pic16_finalMapping[ reg->address ].isSFR, reg->isFixed);
+                       fprintf(stderr, "addr = 0x%03x, bit=%d\tfix=%d\n",
+                               reg->address,reg->isBitField, reg->isFixed);
                }
 #endif
 
                /* we can be 99% that within a pBlock, between two consequtive
                 * refernces to the same register, the extra banksel is needless */
+        
+        
+               /* now make some tests to make sure that instruction needs bank switch */
 
-               if((reg && !isACCESS_BANK(reg) && (isBankInstruction(pc) == -1))
-                       && (!isPCI_LIT(pc))
-                       && (PCI(pc)->op != POC_CALL)
-
-                       && ( ((pic16_options.opt_banksel>0)
-                               && (!prevreg || (prevreg && !pic16_areRegsSame(reg, prevreg))))
-                           || (!pic16_options.opt_banksel)
-                          )
-                                  )
-                          {
-                 /* Examine the instruction before this one to make sure it is
-                  * not a skip type instruction */
-                       pcprev = findPrevpCode(pc->prev, PC_OPCODE);
-
-                       /* FIXME: if previous is SKIP pCode, we should move the BANKSEL
-                        * before SKIP, but we have to check if the SKIP uses BANKSEL, etc... */
-                       if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) {
-                               prevreg = reg;
-                               if(!pic16_options.no_banksel)
-                                       insertBankSwitch(0, pc);
-                       }
+               /* if not no register exists, and if not a bit opcode goto loop */
+               if(!reg) {
+                       if(!(PCI(pc)->pcop && PCI(pc)->pcop->type == PO_GPR_BIT))goto loop;
                }
-
-       pcprev = pc;
-
-      }
-
-      pc = pc->next;
-  }while (pc);
-
-#if 0
-  if(pcprev && cur_bank) {
-
-    int pos = 1;  /* Assume that the bank switch instruction(s)
-                  * are inserted after this instruction */
-
-    if((PCI(pcprev)->op == POC_RETLW) || 
-       (PCI(pcprev)->op == POC_RETURN) || 
-       (PCI(pcprev)->op == POC_RETFIE)) {
-
-      /* oops, a RETURN - we need to switch banks *before* the RETURN */
-
-      pos = 0;
-
-    } 
-           
-    /* Brute force - make sure that we point to bank 0 at the
-     * end of each flow block */
-
-//    insertBankSwitch(pos, pcprev, 0);
-/*
-    new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(0));
-    pic16_pCodeInsertAfter(pcprev, new_pc);
-*/
-    cur_bank = 0;
-    //fprintf(stderr, "Brute force switch\n");
-  }
-#endif
-
+                
+               if(isPCI_SKIP(pc)) {
+//                     fprintf(stderr, "instruction is SKIP instruction\n");
+               }
+               if((reg && isACCESS_BANK(reg)) || !isBankInstruction(pc))goto loop;
+
+               if(isPCI_LIT(pc))goto loop;
+        
+               if(PCI(pc)->op == POC_CALL)goto loop;
+
+               /* Examine the instruction before this one to make sure it is
+                * not a skip type instruction */
+               pcprev = findPrevpCode(pc->prev, PC_OPCODE);
+
+               /* FIXME: if previous is SKIP pCode, we should move the BANKSEL
+                * before SKIP, but we have to check if the SKIP uses BANKSEL, etc... */
+               flag = 0;
+               if(pcprev && isPCI_SKIP(pcprev))flag=2; //goto loop;
+                
+               prevreg = reg;
+               insertBankSwitch(flag, pc);
+               pcprev = pc;
+
+//             fprintf(stderr, "BANK SWITCH inserted\n");
+               
+loop:
+               pc = pc->next;
+       } while (pc);
 }
 
 
+
 static void pBlockDestruct(pBlock *pb)
 {
 
@@ -6663,9 +6781,12 @@ void pic16_AnalyzeBanking(void)
 
        if(!the_pFile)return;
 
-       for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-//             fprintf(stderr, "%s:%d: Fix register banking in pb= 0x%p\n", __FILE__, __LINE__, pb);
-               pic16_FixRegisterBanking(pb);
+       
+       if(!pic16_options.no_banksel) {
+               for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+//                     fprintf(stderr, "%s:%d: Fix register banking in pb= 0x%p\n", __FILE__, __LINE__, pb);
+                       pic16_FixRegisterBanking(pb);
+               }
        }
 
 }