new option -o
[fw/sdcc] / src / pic / pcode.c
index 3dcb4748ae08af43ea1155c28713a7cf4faaa34f..b9d3418c087769256160f047c06e8c8d70721728 100644 (file)
@@ -77,7 +77,7 @@ static int peepOptimizing = 1;        /* run the peephole optimizer if nonzero *
 static int functionInlining = 1;      /* inline functions if nonzero */
 int debug_verbose = 0;                /* Set true to inundate .asm file */
 
-static int GpCodeSequenceNumber = 1;
+// static int GpCodeSequenceNumber = 1;
 int GpcFlowSeq = 1;
 
 extern void RemoveUnusedRegisters(void);
@@ -136,6 +136,7 @@ pCodeInstruction pciADDWF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z) // outCond
@@ -157,6 +158,7 @@ pCodeInstruction pciADDFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z) // outCond
@@ -178,6 +180,7 @@ pCodeInstruction pciADDLW = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  1,    // literal operand
   POC_NOP,
   (PCC_W | PCC_LITERAL),   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
@@ -199,6 +202,7 @@ pCodeInstruction pciANDLW = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  1,    // literal operand
   POC_NOP,
   (PCC_W | PCC_LITERAL),   // inCond
   (PCC_W | PCC_Z) // outCond
@@ -220,6 +224,7 @@ pCodeInstruction pciANDWF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z) // outCond
@@ -241,6 +246,7 @@ pCodeInstruction pciANDFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z) // outCond
@@ -262,6 +268,7 @@ pCodeInstruction pciBCF = {
   2,    // num ops
   1,1,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_BSF,
   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
   PCC_REGISTER // outCond
@@ -283,6 +290,7 @@ pCodeInstruction pciBSF = {
   2,    // num ops
   1,1,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_BCF,
   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
   (PCC_REGISTER | PCC_EXAMINE_PCOP) // outCond
@@ -304,6 +312,7 @@ pCodeInstruction pciBTFSC = {
   2,    // num ops
   0,1,  // dest, bit instruction
   1,1,  // branch, skip
+  0,    // literal operand
   POC_BTFSS,
   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
   PCC_EXAMINE_PCOP // outCond
@@ -325,6 +334,7 @@ pCodeInstruction pciBTFSS = {
   2,    // num ops
   0,1,  // dest, bit instruction
   1,1,  // branch, skip
+  0,    // literal operand
   POC_BTFSC,
   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
   PCC_EXAMINE_PCOP // outCond
@@ -346,6 +356,7 @@ pCodeInstruction pciCALL = {
   1,    // num ops
   0,0,  // dest, bit instruction
   1,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_NONE, // inCond
   PCC_NONE  // outCond
@@ -367,6 +378,7 @@ pCodeInstruction pciCOMF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_REGISTER,  // inCond
   PCC_REGISTER   // outCond
@@ -388,6 +400,7 @@ pCodeInstruction pciCOMFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_REGISTER,  // inCond
   PCC_W   // outCond
@@ -409,6 +422,7 @@ pCodeInstruction pciCLRF = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_NONE, // inCond
   PCC_REGISTER  // outCond
@@ -430,6 +444,7 @@ pCodeInstruction pciCLRW = {
   0,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_NONE, // inCond
   PCC_W  // outCond
@@ -451,6 +466,7 @@ pCodeInstruction pciCLRWDT = {
   0,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_NONE, // inCond
   PCC_NONE  // outCond
@@ -472,6 +488,7 @@ pCodeInstruction pciDECF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_REGISTER    // outCond
@@ -493,6 +510,7 @@ pCodeInstruction pciDECFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_W    // outCond
@@ -514,6 +532,7 @@ pCodeInstruction pciDECFSZ = {
   2,    // num ops
   1,0,  // dest, bit instruction
   1,1,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_REGISTER    // outCond
@@ -535,6 +554,7 @@ pCodeInstruction pciDECFSZW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   1,1,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_W           // outCond
@@ -556,6 +576,7 @@ pCodeInstruction pciGOTO = {
   1,    // num ops
   0,0,  // dest, bit instruction
   1,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_NONE,   // inCond
   PCC_NONE    // outCond
@@ -577,6 +598,7 @@ pCodeInstruction pciINCF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_REGISTER    // outCond
@@ -598,6 +620,7 @@ pCodeInstruction pciINCFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_W    // outCond
@@ -619,6 +642,7 @@ pCodeInstruction pciINCFSZ = {
   2,    // num ops
   1,0,  // dest, bit instruction
   1,1,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_REGISTER    // outCond
@@ -640,6 +664,7 @@ pCodeInstruction pciINCFSZW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   1,1,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_W           // outCond
@@ -661,6 +686,7 @@ pCodeInstruction pciIORWF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z) // outCond
@@ -682,6 +708,7 @@ pCodeInstruction pciIORFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z) // outCond
@@ -703,6 +730,7 @@ pCodeInstruction pciIORLW = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  1,    // literal operand
   POC_NOP,
   (PCC_W | PCC_LITERAL),   // inCond
   (PCC_W | PCC_Z) // outCond
@@ -724,6 +752,7 @@ pCodeInstruction pciMOVF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_Z // outCond
@@ -745,6 +774,7 @@ pCodeInstruction pciMOVFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
   (PCC_W | PCC_Z) // outCond
@@ -766,6 +796,7 @@ pCodeInstruction pciMOVWF = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_W,   // inCond
   PCC_REGISTER // outCond
@@ -773,7 +804,6 @@ pCodeInstruction pciMOVWF = {
 
 pCodeInstruction pciMOVLW = {
   {PC_OPCODE, NULL, NULL, 0, NULL, 
-   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_MOVLW,
@@ -787,6 +817,7 @@ pCodeInstruction pciMOVLW = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  1,    // literal operand
   POC_NOP,
   (PCC_NONE | PCC_LITERAL),   // inCond
   PCC_W // outCond
@@ -807,6 +838,7 @@ pCodeInstruction pciNOP = {
   0,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_NONE,   // inCond
   PCC_NONE // outCond
@@ -828,6 +860,7 @@ pCodeInstruction pciRETFIE = {
   0,    // num ops
   0,0,  // dest, bit instruction
   1,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_NONE,   // inCond
   PCC_NONE // outCond (not true... affects the GIE bit too)
@@ -849,6 +882,7 @@ pCodeInstruction pciRETLW = {
   1,    // num ops
   0,0,  // dest, bit instruction
   1,0,  // branch, skip
+  1,    // literal operand
   POC_NOP,
   PCC_LITERAL,   // inCond
   PCC_W // outCond
@@ -870,6 +904,7 @@ pCodeInstruction pciRETURN = {
   0,    // num ops
   0,0,  // dest, bit instruction
   1,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_NONE,   // inCond
   PCC_NONE // outCond
@@ -891,6 +926,7 @@ pCodeInstruction pciRLF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   (PCC_C | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond
@@ -912,6 +948,7 @@ pCodeInstruction pciRLFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   (PCC_C | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
@@ -933,6 +970,7 @@ pCodeInstruction pciRRF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   (PCC_C | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond
@@ -954,6 +992,7 @@ pCodeInstruction pciRRFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   (PCC_C | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
@@ -975,6 +1014,7 @@ pCodeInstruction pciSUBWF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z) // outCond
@@ -996,6 +1036,7 @@ pCodeInstruction pciSUBFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z) // outCond
@@ -1017,6 +1058,7 @@ pCodeInstruction pciSUBLW = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  1,    // literal operand
   POC_NOP,
   (PCC_W | PCC_LITERAL),   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
@@ -1038,6 +1080,7 @@ pCodeInstruction pciSWAPF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   (PCC_REGISTER),   // inCond
   (PCC_REGISTER) // outCond
@@ -1059,6 +1102,7 @@ pCodeInstruction pciSWAPFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   (PCC_REGISTER),   // inCond
   (PCC_W) // outCond
@@ -1080,6 +1124,7 @@ pCodeInstruction pciTRIS = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   PCC_NONE,   // inCond
   PCC_REGISTER // outCond
@@ -1101,6 +1146,7 @@ pCodeInstruction pciXORWF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z) // outCond
@@ -1122,6 +1168,7 @@ pCodeInstruction pciXORFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  0,    // literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z) // outCond
@@ -1143,6 +1190,7 @@ pCodeInstruction pciXORLW = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  1,    // literal operand
   POC_NOP,
   (PCC_W | PCC_LITERAL),   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
@@ -1539,7 +1587,7 @@ void pcode_test(void)
     char buffer[100];
 
     /* create the file name */
-    strcpy(buffer,srcFileName);
+    strcpy(buffer,dstFileName);
     strcat(buffer,".p");
 
     if( !(pFile = fopen(buffer, "w" ))) {
@@ -1931,7 +1979,7 @@ pCode *newpCodeLabel(char *name, int key)
   if(s)
     pcl->label = Safe_strdup(s);
 
-
+  //fprintf(stderr,"newpCodeLabel: key=%d, name=%s\n",key, ((s)?s:""));
   return ( (pCode *)pcl);
 
 }
@@ -2007,6 +2055,7 @@ pCodeOp *newpCodeOpLabel(char *name, int key)
 
   ((pCodeOpLabel *)pcop)->key = key;
 
+  //fprintf(stderr,"newpCodeOpLabel: key=%d, name=%s\n",key,((s)?s:""));
   return pcop;
 }
 
@@ -2495,8 +2544,12 @@ char *get_op(pCodeOp *pcop,char *buffer, int size)
          SAFE_snprintf(&s,&size,"(%s + %d)",
                        pcop->name,
                        PCOI(pcop)->index );
-       } else
-         SAFE_snprintf(&s,&size,"%s",pcop->name);
+       } else {
+         if(PCOI(pcop)->offset)
+           SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset);
+         else
+           SAFE_snprintf(&s,&size,"%s",pcop->name);
+       }
       }
 
       return buffer;
@@ -3690,7 +3743,9 @@ void LinkFlow(pBlock *pb)
       if( (pct = findLabelinpBlock(pb,pcol)) != NULL)
        LinkFlow_pCode(PCI(pc),PCI(pct));
       else
-       fprintf(stderr, "ERROR: %s, couldn't find label\n",__FUNCTION__);
+       fprintf(stderr, "ERROR: %s, couldn't find label. key=%d,lab=%s\n",
+               __FUNCTION__,pcol->key,((PCOP(pcol)->name)?PCOP(pcol)->name:"-"));
+  //fprintf(stderr,"newpCodeOpLabel: key=%d, name=%s\n",key,((s)?s:""));
 
       continue;
     }
@@ -3824,7 +3879,7 @@ void BanksUsedFlow(pBlock *pb)
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-void insertBankSwitch(pCode *pc, int Set_Clear, int RP_BankBit)
+void insertBankSwitch(int position, pCode *pc, int Set_Clear, int RP_BankBit)
 {
   pCode *new_pc;
 
@@ -3837,7 +3892,15 @@ void insertBankSwitch(pCode *pc, int Set_Clear, int RP_BankBit)
     new_pc = newpCode((Set_Clear ? POC_BSF : POC_BCF),
                      popCopyGPR2Bit(PCOP(&pc_status),RP_BankBit));
 
-  pCodeInsertAfter(pc->prev, new_pc);
+  if(position) {
+    /* insert the bank switch after this pc instruction */
+    pCode *pcnext = findNextInstruction(pc);
+    pCodeInsertAfter(pc, new_pc);
+    if(pcnext)
+      pc = pcnext;
+
+  } else
+    pCodeInsertAfter(pc->prev, new_pc);
 
   /* Move the label, if there is one */
 
@@ -3867,7 +3930,6 @@ void FixRegisterBankingInFlow(pCodeFlow *pcfl, int cur_bank)
 
   while(isPCinFlow(pc,PCODE(pcfl))) {
 
-
     reg = getRegFromInstruction(pc);
 #if 0
     if(reg) {
@@ -3877,46 +3939,41 @@ void FixRegisterBankingInFlow(pCodeFlow *pcfl, int cur_bank)
     }
 #endif
 
-    if(reg && REG_BANK(reg)!=cur_bank) {
+    if( ( (reg && REG_BANK(reg)!=cur_bank) || 
+         ((PCI(pc)->op == POC_CALL) && (cur_bank != 0) ) ) &&
+       (!isPCI_LIT(pc)) ){
+
       /* Examine the instruction before this one to make sure it is
        * not a skip type instruction */
       pcprev = findPrevpCode(pc->prev, PC_OPCODE);
+
       if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) {
-       int b = cur_bank ^ REG_BANK(reg);
+       int b;
+       int reg_bank;
+
+       reg_bank =  (reg) ? REG_BANK(reg) : 0;
+         
+       b = cur_bank ^ reg_bank;
 
        //fprintf(stderr, "Cool! can switch banks\n");
-       cur_bank = REG_BANK(reg);
+       cur_bank = reg_bank;
        switch(b & 3) {
        case 0:
          break;
        case 1:
-         insertBankSwitch(pc, cur_bank&1, PIC_RP0_BIT);
+         insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT);
          break;
        case 2:
-         insertBankSwitch(pc, cur_bank&2, PIC_RP1_BIT);
-         insertBankSwitch(pc, cur_bank&2, PIC_RP1_BIT);
+         insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT);
+         insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT);
          break;
        case 3:
          if(cur_bank & 3) {
-           insertBankSwitch(pc, cur_bank&1, PIC_RP0_BIT);
-           insertBankSwitch(pc, cur_bank&2, PIC_RP1_BIT);
+           insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT);
+           insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT);
          } else
-           insertBankSwitch(pc, -1, -1);
+           insertBankSwitch(0, pc, -1, -1);
          break;
-         /*
-           new_pc = newpCode(((cur_bank&1) ? POC_BSF : POC_BCF),
-           popCopyGPR2Bit(PCOP(&pc_status),PIC_RP0_BIT));
-           pCodeInsertAfter(pc->prev, new_pc);
-           if(PCI(pc)->label) { 
-           PCI(new_pc)->label = PCI(pc)->label;
-           PCI(pc)->label = NULL;
-           }
-         */
-         /*
-           new_pc = newpCode(((cur_bank&1) ? POC_BCF : POC_BSF),
-           popCopyGPR2Bit(PCOP(&pc_status),PIC_RP0_BIT));
-           pCodeInsertAfter(pc, new_pc);
-         */
 
        }
 
@@ -4262,6 +4319,8 @@ pCode * findInstructionUsingLabel(pCodeLabel *pcl, pCode *pcs)
 void exchangeLabels(pCodeLabel *pcl, pCode *pc)
 {
 
+  char *s=NULL;
+
   if(isPCI(pc) && 
      (PCI(pc)->pcop) && 
      (PCI(pc)->pcop->type == PO_LABEL)) {
@@ -4272,9 +4331,19 @@ void exchangeLabels(pCodeLabel *pcl, pCode *pc)
     if(pcol->pcop.name)
       free(pcol->pcop.name);
 
-    sprintf(buffer,"_%05d_DS_",pcl->key);
-
-    pcol->pcop.name = Safe_strdup(buffer);
+    /* If the key is negative, then we (probably) have a label to
+     * a function and the name is already defined */
+       
+    if(pcl->key>0)
+      sprintf(s=buffer,"_%05d_DS_",pcl->key);
+    else 
+      s = pcl->label;
+
+    //sprintf(buffer,"_%05d_DS_",pcl->key);
+    if(!s) {
+      fprintf(stderr, "ERROR %s:%d function label is null\n",__FUNCTION__,__LINE__);
+    }
+    pcol->pcop.name = Safe_strdup(s);
     pcol->key = pcl->key;
     //pc->print(stderr,pc);
 
@@ -4494,11 +4563,10 @@ void FixRegisterBanking(pBlock *pb)
 {
   pCode *pc=NULL;
   pCode *pcprev=NULL;
-  pCode *new_pc;
 
   int cur_bank;
   regs *reg;
-  //  return;
+
   if(!pb)
     return;
 
@@ -4522,63 +4590,151 @@ void FixRegisterBanking(pBlock *pb)
        //genericPrint(stderr, pc);
 
        reg = getRegFromInstruction(pc);
-       #if 0
+#if 0
        if(reg) {
          fprintf(stderr, "  %s  ",reg->name);
-         fprintf(stderr, "addr = 0x%03x, bank = %d\n",reg->address,REG_BANK(reg));
+         fprintf(stderr, "addr = 0x%03x, bank = %d, bit=%d\n",
+                 reg->address,REG_BANK(reg),reg->isBitField);
 
        }
-       #endif
-       if(reg && REG_BANK(reg)!=cur_bank) {
+#endif
+
+       if( ( (reg && REG_BANK(reg)!=cur_bank) || 
+             ((PCI(pc)->op == POC_CALL) && (cur_bank != 0) ) ) &&
+           (!isPCI_LIT(pc)) ){
+
+
          /* Examine the instruction before this one to make sure it is
           * not a skip type instruction */
          pcprev = findPrevpCode(pc->prev, PC_OPCODE);
-         if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) {
-           int b = cur_bank ^ REG_BANK(reg);
 
-           //fprintf(stderr, "Cool! can switch banks\n");
-           cur_bank = REG_BANK(reg);
-           if(b & 1) {
-             new_pc = newpCode(((cur_bank&1) ? POC_BSF : POC_BCF),
-                               popCopyGPR2Bit(PCOP(&pc_status),PIC_RP0_BIT));
-             pCodeInsertAfter(pc->prev, new_pc);
-             if(PCI(pc)->label) { 
-               PCI(new_pc)->label = PCI(pc)->label;
-               PCI(pc)->label = NULL;
-             }
-             /*
-               new_pc = newpCode(((cur_bank&1) ? POC_BCF : POC_BSF),
-               popCopyGPR2Bit(PCOP(&pc_status),PIC_RP0_BIT));
-               pCodeInsertAfter(pc, new_pc);
-             */
+         if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) {
+           int b;
+           int reg_bank;
+
+           reg_bank =  (reg) ? REG_BANK(reg) : 0;
+         
+           b = cur_bank ^ reg_bank;
+
+           cur_bank = reg_bank;
+           switch(b & 3) {
+           case 0:
+             break;
+           case 1:
+             insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT);
+             break;
+           case 2:
+             insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT);
+             insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT);
+             break;
+           case 3:
+             if(cur_bank & 3) {
+               insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT);
+               insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT);
+             } else
+               insertBankSwitch(0, pc, -1, -1);
+             break;
 
            }
 
-         } else {
+         }else {
            //fprintf(stderr, "Bummer can't switch banks\n");
            ;
          }
        }
+
+       pcprev = pc;
+
       }
 
-      pcprev = pc;
       pc = pc->next;
       // } while(pc && !(isPCFL(pc))); 
 
 
   }while (pc);
 
-    if(pcprev && cur_bank) {
-      /* Brute force - make sure that we point to bank 0 at the
-       * end of each flow block */
-      new_pc = newpCode(POC_BCF,
-                       popCopyGPR2Bit(PCOP(&pc_status),PIC_RP0_BIT));
-      pCodeInsertAfter(pcprev, new_pc);
-      cur_bank = 0;
+  if(pcprev && cur_bank) {
+
+    int pos = 1;  /* Assume that the bank swithc 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 */
+
+    switch(cur_bank & 3) {
+    case 0:
+      break;
+    case 1:
+      insertBankSwitch(pos, pcprev, 0, PIC_RP0_BIT);
+      break;
+    case 2:
+      insertBankSwitch(pos, pcprev, 0, PIC_RP1_BIT);
+      insertBankSwitch(pos, pcprev, 0, PIC_RP1_BIT);
+      break;
+    case 3:
+      insertBankSwitch(pos, pcprev, -1, -1);
+      break;
+
     }
+/*
+    new_pc = newpCode(POC_BCF,
+                     popCopyGPR2Bit(PCOP(&pc_status),PIC_RP0_BIT));
+    pCodeInsertAfter(pcprev, new_pc);
+*/
+    cur_bank = 0;
+    //fprintf(stderr, "Brute force switch\n");
+  }
 
 }
 
+
+
+
+#if 0
+       if(reg && REG_BANK(reg)!=cur_bank) {
+         //fprintf(stderr,"need to switch banks\n");
+         /* Examine the instruction before this one to make sure it is
+          * not a skip type instruction */
+         pcprev = findPrevpCode(pc->prev, PC_OPCODE);
+         if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) {
+           int b = cur_bank ^ REG_BANK(reg);
+
+           cur_bank = REG_BANK(reg);
+
+           switch(b & 3) {
+           case 0:
+             break;
+           case 1:
+             insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT);
+             break;
+           case 2:
+             insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT);
+             insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT);
+             break;
+           case 3:
+             if(cur_bank & 3) {
+               insertBankSwitch(0, pc, cur_bank&1, PIC_RP0_BIT);
+               insertBankSwitch(0, pc, cur_bank&2, PIC_RP1_BIT);
+             } else
+               insertBankSwitch(0, pc, -1, -1);
+             break;
+
+           }
+#endif
+
+
+
+
 void pBlockDestruct(pBlock *pb)
 {