* src/pic/pcode.c (get_op_from_instruction): fix concatenation of string literals...
[fw/sdcc] / src / pic / pcode.c
index 7c2bc0a0604aabc87d717e3f3ba7818c91003f1a..b6763d85c9dbc04ad96526cb2a8a89a1e91f380c 100644 (file)
@@ -77,13 +77,14 @@ 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);
 extern void RegsUnMapLiveRanges(void);
 extern void BuildFlowTree(pBlock *pb);
 extern void pCodeRegOptimizeRegUsage(int level);
+extern int picIsInitialized(void);
 
 /****************************************************************/
 /*                      Forward declarations                    */
@@ -135,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
@@ -156,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
@@ -177,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
@@ -198,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
@@ -219,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
@@ -240,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
@@ -261,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
@@ -282,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
@@ -303,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
@@ -324,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
@@ -345,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
@@ -366,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
@@ -387,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
@@ -408,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
@@ -429,11 +444,34 @@ 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
 };
 
+pCodeInstruction pciCLRWDT = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, 
+   //   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_CLRWDT,
+  "CLRWDT",
+  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
+  POC_NOP,
+  PCC_NONE, // inCond
+  PCC_NONE  // outCond
+};
+
 pCodeInstruction pciDECF = {
   {PC_OPCODE, NULL, NULL, 0, NULL, 
    //   genericAnalyze,
@@ -450,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
@@ -471,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
@@ -492,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
@@ -513,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
@@ -534,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
@@ -555,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
@@ -576,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
@@ -597,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
@@ -618,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
@@ -639,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
@@ -660,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
@@ -681,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
@@ -702,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
@@ -723,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
@@ -744,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
@@ -751,7 +804,6 @@ pCodeInstruction pciMOVWF = {
 
 pCodeInstruction pciMOVLW = {
   {PC_OPCODE, NULL, NULL, 0, NULL, 
-   //   genericAnalyze,
    genericDestruct,
    genericPrint},
   POC_MOVLW,
@@ -765,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
@@ -785,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
@@ -806,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)
@@ -827,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
@@ -848,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
@@ -869,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
@@ -890,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
@@ -911,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
@@ -932,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
@@ -953,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
@@ -974,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
@@ -995,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
@@ -1016,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
@@ -1037,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
@@ -1058,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
@@ -1079,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
@@ -1100,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
@@ -1121,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
@@ -1295,6 +1365,7 @@ void pic14initMnemonics(void)
   pic14Mnemonics[POC_COMFW] = &pciCOMFW;
   pic14Mnemonics[POC_CLRF] = &pciCLRF;
   pic14Mnemonics[POC_CLRW] = &pciCLRW;
+  pic14Mnemonics[POC_CLRWDT] = &pciCLRWDT;
   pic14Mnemonics[POC_DECF] = &pciDECF;
   pic14Mnemonics[POC_DECFW] = &pciDECFW;
   pic14Mnemonics[POC_DECFSZ] = &pciDECFSZ;
@@ -1358,7 +1429,7 @@ int getpCode(char *mnem,unsigned dest)
   while(pci) {
 
     if(STRCASECMP(pci->mnemonic, mnem) == 0) {
-      if((pci->num_ops <= 1) || (pci->isModReg == dest))
+      if((pci->num_ops <= 1) || (pci->isModReg == dest) || (pci->isBitInst))
        return(pci->op);
     }
 
@@ -1516,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" ))) {
@@ -1908,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);
 
 }
@@ -1984,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;
 }
 
@@ -2083,6 +2155,9 @@ pCodeOp *newpCodeOpBit(char *s, int bit, int inBitSpace)
   PCORB(pcop)->bit = bit;
   PCORB(pcop)->inBitSpace = inBitSpace;
 
+  /* pCodeOpBit is derived from pCodeOpReg. We need to init this too */
+  PCOR(pcop)->r = NULL;
+  PCOR(pcop)->rIdx = 0;
   return pcop;
 }
 
@@ -2110,7 +2185,6 @@ pCodeOp *newpCodeOpReg(int rIdx)
 
     if(PCOR(pcop)->r)
       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
-    //fprintf(stderr, "newpcodeOpReg - rIdx = %d\n", PCOR(pcop)->r->rIdx);
   }
 
   pcop->type = PCOR(pcop)->r->pc_type;
@@ -2155,6 +2229,13 @@ pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type)
     pcop = newpCodeOpReg(-1);
     break;
 
+  case PO_GPR_REGISTER:
+    if(name)
+      pcop = newpCodeOpRegFromStr(name);
+    else
+      pcop = newpCodeOpReg(-1);
+    break;
+
   default:
     pcop = Safe_calloc(1,sizeof(pCodeOp) );
     pcop->type = type;
@@ -2463,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;
@@ -2505,7 +2590,10 @@ static char *get_op_from_instruction( pCodeInstruction *pcc)
   if(pcc )
     return get_op(pcc->pcop,NULL,0);
   
+  /* gcc 3.2:  warning: concatenation of string literals with __FUNCTION__ is deprecated 
   return ("ERROR Null: "__FUNCTION__);
+  */
+  return ("ERROR Null: get_op_from_instruction");
 
 }
 
@@ -2684,8 +2772,13 @@ static void genericPrint(FILE *of, pCode *pc)
     break;
 
   case PC_FLOW:
-    if(debug_verbose)
-      fprintf(of,";<>Start of new flow, seq=%d\n",pc->seq);
+    if(debug_verbose) {
+      fprintf(of,";<>Start of new flow, seq=0x%x",pc->seq);
+      if(PCFL(pc)->ancestor)
+       fprintf(of," ancestor = 0x%x", PCODE(PCFL(pc)->ancestor)->seq);
+      fprintf(of,"\n");
+
+    }
     break;
 
   case PC_CSOURCE:
@@ -3345,14 +3438,22 @@ void BuildFlow(pBlock *pb)
       InsertpFlow(pc, &pflow);
       seq = 0;
 
-    } else if (checkLabel(pc)) { //(PCI_HAS_LABEL(pc)) {
+    } else if (checkLabel(pc)) { 
 
       /* This instruction marks the beginning of a
        * new flow segment */
 
       pc->seq = 0;
-      seq = 1; 
-      InsertpFlow(findPrevInstruction(pc->prev), &pflow);
+      seq = 1;
+
+      /* If the previous pCode is not a flow object, then 
+       * insert a new flow object. (This check prevents 
+       * two consecutive flow objects from being insert in
+       * the case where a skip instruction preceeds an
+       * instruction containing a label.) */
+
+      if(last_pci && (PCI(last_pci)->pcflow == PCFL(pflow)))
+       InsertpFlow(findPrevInstruction(pc->prev), &pflow);
 
       PCI(pc)->pcflow = PCFL(pflow);
       
@@ -3586,8 +3687,15 @@ void LinkFlow_pCode(pCodeInstruction *from, pCodeInstruction *to)
 
 }
 
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*
+ * void LinkFlow(pBlock *pb)
+ *
+ * In BuildFlow, the PIC code has been partitioned into contiguous
+ * non-branching segments. In LinkFlow, we determine the execution
+ * order of these segments. For example, if one of the segments ends
+ * with a skip, then we know that there are two possible flow segments
+ * to which control may be passed.
+ *-----------------------------------------------------------------*/
 void LinkFlow(pBlock *pb)
 {
   pCode *pc=NULL;
@@ -3628,7 +3736,7 @@ void LinkFlow(pBlock *pb)
       //pc->print(stderr,pc);
 
       if(!(pcol && isPCOLAB(pcol))) {
-       if((PCI(pc)->op != POC_RETLW) && (PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL)) {
+       if((PCI(pc)->op != POC_RETLW) && (PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL) && (PCI(pc)->op != POC_RETFIE) ) {
          pc->print(stderr,pc);
          fprintf(stderr, "ERROR: %s, branch instruction doesn't have label\n",__FUNCTION__);
        }
@@ -3638,7 +3746,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;
     }
@@ -3662,6 +3772,8 @@ void LinkFlow(pBlock *pb)
     
   }
 }
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
@@ -3770,7 +3882,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;
 
@@ -3783,7 +3895,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 */
 
@@ -3813,7 +3933,6 @@ void FixRegisterBankingInFlow(pCodeFlow *pcfl, int cur_bank)
 
   while(isPCinFlow(pc,PCODE(pcfl))) {
 
-
     reg = getRegFromInstruction(pc);
 #if 0
     if(reg) {
@@ -3823,46 +3942,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);
-         */
 
        }
 
@@ -4208,6 +4322,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)) {
@@ -4218,9 +4334,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);
 
@@ -4440,11 +4566,10 @@ void FixRegisterBanking(pBlock *pb)
 {
   pCode *pc=NULL;
   pCode *pcprev=NULL;
-  pCode *new_pc;
 
   int cur_bank;
   regs *reg;
-  //  return;
+
   if(!pb)
     return;
 
@@ -4468,63 +4593,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)
 {
 
@@ -4645,10 +4858,10 @@ void AnalyzeFlow(int level)
    * In this phase, the individual flow blocks are examined
    * to determine their order of excution.
    */
-  /*
+
   for(pb = the_pFile->pbHead; pb; pb = pb->next)
     BuildFlowTree(pb);
-  */
+
 
   /* Phase x - Flow Analysis - Used Banks
    *
@@ -4709,6 +4922,15 @@ void AnalyzeBanking(void)
 {
   pBlock  *pb;
 
+  if(!picIsInitialized()) {
+    fprintf(stderr,"Temporary ERROR: at the moment you have to use\n");
+    fprintf(stderr,"an include file create by inc2h.pl. See SDCC source:\n");
+    fprintf(stderr,"support/scripts/inc2h.pl\n");
+    fprintf(stderr,"this is a nuisance bug that will be fixed shortly\n");
+
+    exit(1);
+  }
+
   /* Phase x - Flow Analysis - Used Banks
    *
    * In this phase, the individual flow blocks are examined