Numerous bug fixes in PIC Port (pointers, shifting, bank selection,...)
[fw/sdcc] / src / pic / pcode.c
index f2177942d87b22a6137d0572d0835d63bbbfcfad..2e1e2b584dca3ebad25c8718a0fd3994306ff8c3 100644 (file)
 #define STRCASECMP strcasecmp
 #endif
 
+/****************************************************************/
+/****************************************************************/
+
+peepCommand peepCommands[] = {
+
+  {NOTBITSKIP, "_NOTBITSKIP_"},
+  {BITSKIP, "_BITSKIP_"},
+  {INVERTBITSKIP, "_INVERTBITSKIP_"},
+
+  {-1, NULL}
+};
+
+
 
 // Eventually this will go into device dependent files:
 pCodeOpReg pc_status    = {{PO_STATUS,  "STATUS"}, -1, NULL,0,NULL};
@@ -45,24 +58,26 @@ pCodeOpReg pc_pcl       = {{PO_PCL,     "PCL"}, -1, NULL,0,NULL};
 pCodeOpReg pc_pclath    = {{PO_PCLATH,  "PCLATH"}, -1, NULL,0,NULL};
 
 pCodeOpReg pc_kzero     = {{PO_GPR_REGISTER,  "KZ"}, -1, NULL,0,NULL};
-pCodeOpReg pc_wsave     = {{PO_GPR_REGISTER,  "W_SAVE"}, -1, NULL,0,NULL};
-pCodeOpReg pc_ssave     = {{PO_GPR_REGISTER,  "STATUS_SAVE"}, -1, NULL,0,NULL};
+pCodeOpReg pc_wsave     = {{PO_GPR_REGISTER,  "WSAVE"}, -1, NULL,0,NULL};
+pCodeOpReg pc_ssave     = {{PO_GPR_REGISTER,  "SSAVE"}, -1, NULL,0,NULL};
 
 static int mnemonics_initialized = 0;
 
 
 static hTab *pic14MnemonicsHash = NULL;
+static hTab *pic14pCodePeepCommandsHash = NULL;
 
 
 
 static pFile *the_pFile = NULL;
-static int peepOptimizing = 0;
+static int peepOptimizing = 1;
 static int GpCodeSequenceNumber = 1;
 static int GpcFlowSeq = 1;
 
 #define isPCI(x)        ((PCODE(x)->type == PC_OPCODE))
 #define isPCI_BRANCH(x) ((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isBranch)
 #define isPCI_SKIP(x)   ((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isSkip)
+#define isPCI_BITSKIP(x)((PCODE(x)->type == PC_OPCODE) &&  PCI(x)->isSkip && PCI(x)->isBitInst)
 #define isPCFL(x)       ((PCODE(x)->type == PC_FLOW))
 #define isPCF(x)        ((PCODE(x)->type == PC_FUNCTION))
 #define isCALL(x)       ((isPCI(x)) && (PCI(x)->op == POC_CALL))
@@ -86,7 +101,8 @@ static void genericPrint(FILE *of,pCode *pc);
 static void pCodePrintLabel(FILE *of, pCode *pc);
 static void pCodePrintFunction(FILE *of, pCode *pc);
 static void pCodeOpPrint(FILE *of, pCodeOp *pcop);
-static char *get_op( pCodeInstruction *pcc);
+static char *get_op_from_instruction( pCodeInstruction *pcc);
+char *get_op( pCodeOp *pcop);
 int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd);
 int pCodePeepMatchRule(pCode *pc);
 void pBlockStats(FILE *of, pBlock *pb);
@@ -107,6 +123,7 @@ pCodeInstruction pciADDWF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z) // outCond
 };
@@ -116,7 +133,7 @@ pCodeInstruction pciADDFW = {
    //   genericAnalyze,
    genericDestruct,
    genericPrint},
-  POC_ADDWF,
+  POC_ADDFW,
   "ADDWF",
   NULL, // from branch
   NULL, // to branch
@@ -126,6 +143,7 @@ pCodeInstruction pciADDFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z) // outCond
 };
@@ -145,6 +163,7 @@ pCodeInstruction pciADDLW = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_W,   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
 };
@@ -164,6 +183,7 @@ pCodeInstruction pciANDLW = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_W,   // inCond
   (PCC_W | PCC_Z) // outCond
 };
@@ -183,6 +203,7 @@ pCodeInstruction pciANDWF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z) // outCond
 };
@@ -192,7 +213,7 @@ pCodeInstruction pciANDFW = {
    //   genericAnalyze,
    genericDestruct,
    genericPrint},
-  POC_ANDWF,
+  POC_ANDFW,
   "ANDWF",
   NULL, // from branch
   NULL, // to branch
@@ -202,6 +223,7 @@ pCodeInstruction pciANDFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z) // outCond
 };
@@ -221,6 +243,7 @@ pCodeInstruction pciBCF = {
   2,    // num ops
   1,1,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_BSF,
   PCC_REGISTER,   // inCond
   PCC_REGISTER // outCond
 };
@@ -240,6 +263,7 @@ pCodeInstruction pciBSF = {
   2,    // num ops
   1,1,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_BCF,
   PCC_REGISTER,   // inCond
   PCC_REGISTER // outCond
 };
@@ -259,6 +283,7 @@ pCodeInstruction pciBTFSC = {
   2,    // num ops
   0,1,  // dest, bit instruction
   1,1,  // branch, skip
+  POC_BTFSS,
   PCC_REGISTER,   // inCond
   PCC_NONE // outCond
 };
@@ -278,6 +303,7 @@ pCodeInstruction pciBTFSS = {
   2,    // num ops
   0,1,  // dest, bit instruction
   1,1,  // branch, skip
+  POC_BTFSC,
   PCC_REGISTER,   // inCond
   PCC_NONE // outCond
 };
@@ -297,6 +323,7 @@ pCodeInstruction pciCALL = {
   1,    // num ops
   0,0,  // dest, bit instruction
   1,0,  // branch, skip
+  POC_NOP,
   PCC_NONE, // inCond
   PCC_NONE  // outCond
 };
@@ -316,6 +343,7 @@ pCodeInstruction pciCOMF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_REGISTER,  // inCond
   PCC_REGISTER   // outCond
 };
@@ -335,6 +363,7 @@ pCodeInstruction pciCOMFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_REGISTER,  // inCond
   PCC_W   // outCond
 };
@@ -354,6 +383,7 @@ pCodeInstruction pciCLRF = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_REGISTER, // inCond
   PCC_REGISTER  // outCond
 };
@@ -373,6 +403,7 @@ pCodeInstruction pciCLRW = {
   0,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_W, // inCond
   PCC_W  // outCond
 };
@@ -392,6 +423,7 @@ pCodeInstruction pciDECF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_REGISTER    // outCond
 };
@@ -411,6 +443,7 @@ pCodeInstruction pciDECFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_W    // outCond
 };
@@ -430,6 +463,7 @@ pCodeInstruction pciDECFSZ = {
   2,    // num ops
   1,0,  // dest, bit instruction
   1,1,  // branch, skip
+  POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_REGISTER    // outCond
 };
@@ -449,6 +483,7 @@ pCodeInstruction pciDECFSZW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   1,1,  // branch, skip
+  POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_W           // outCond
 };
@@ -468,11 +503,11 @@ pCodeInstruction pciGOTO = {
   1,    // num ops
   0,0,  // dest, bit instruction
   1,0,  // branch, skip
+  POC_NOP,
   PCC_NONE,   // inCond
   PCC_NONE    // outCond
 };
 
-
 pCodeInstruction pciINCF = {
   {PC_OPCODE, NULL, NULL, 0, NULL, 
    //   genericAnalyze,
@@ -488,6 +523,7 @@ pCodeInstruction pciINCF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_REGISTER    // outCond
 };
@@ -507,6 +543,7 @@ pCodeInstruction pciINCFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_W    // outCond
 };
@@ -526,6 +563,7 @@ pCodeInstruction pciINCFSZ = {
   2,    // num ops
   1,0,  // dest, bit instruction
   1,1,  // branch, skip
+  POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_REGISTER    // outCond
 };
@@ -545,6 +583,7 @@ pCodeInstruction pciINCFSZW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   1,1,  // branch, skip
+  POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_W           // outCond
 };
@@ -564,6 +603,7 @@ pCodeInstruction pciIORWF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z) // outCond
 };
@@ -573,7 +613,7 @@ pCodeInstruction pciIORFW = {
    //   genericAnalyze,
    genericDestruct,
    genericPrint},
-  POC_IORWF,
+  POC_IORFW,
   "IORWF",
   NULL, // from branch
   NULL, // to branch
@@ -583,6 +623,7 @@ pCodeInstruction pciIORFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z) // outCond
 };
@@ -602,6 +643,7 @@ pCodeInstruction pciIORLW = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_W,   // inCond
   (PCC_W | PCC_Z) // outCond
 };
@@ -621,6 +663,7 @@ pCodeInstruction pciMOVF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_REGISTER,   // inCond
   PCC_Z // outCond
 };
@@ -640,6 +683,7 @@ pCodeInstruction pciMOVFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_REGISTER,   // inCond
   (PCC_W | PCC_Z) // outCond
 };
@@ -659,6 +703,7 @@ pCodeInstruction pciMOVWF = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_W,   // inCond
   PCC_REGISTER // outCond
 };
@@ -678,6 +723,7 @@ pCodeInstruction pciMOVLW = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_NONE,   // inCond
   PCC_W // outCond
 };
@@ -696,6 +742,7 @@ pCodeInstruction pciNOP = {
   0,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_NONE,   // inCond
   PCC_NONE // outCond
 };
@@ -715,6 +762,7 @@ pCodeInstruction pciRETFIE = {
   0,    // num ops
   0,0,  // dest, bit instruction
   1,0,  // branch, skip
+  POC_NOP,
   PCC_NONE,   // inCond
   PCC_NONE // outCond (not true... affects the GIE bit too)
 };
@@ -734,6 +782,7 @@ pCodeInstruction pciRETLW = {
   1,    // num ops
   0,0,  // dest, bit instruction
   1,0,  // branch, skip
+  POC_NOP,
   PCC_NONE,   // inCond
   PCC_W // outCond
 };
@@ -753,6 +802,7 @@ pCodeInstruction pciRETURN = {
   0,    // num ops
   0,0,  // dest, bit instruction
   1,0,  // branch, skip
+  POC_NOP,
   PCC_NONE,   // inCond
   PCC_NONE // outCond
 };
@@ -772,6 +822,7 @@ pCodeInstruction pciRLF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   (PCC_C | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond
 };
@@ -791,6 +842,7 @@ pCodeInstruction pciRLFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   (PCC_C | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
 };
@@ -810,6 +862,7 @@ pCodeInstruction pciRRF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   (PCC_C | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond
 };
@@ -829,6 +882,7 @@ pCodeInstruction pciRRFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   (PCC_C | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
 };
@@ -848,6 +902,7 @@ pCodeInstruction pciSUBWF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z) // outCond
 };
@@ -857,7 +912,7 @@ pCodeInstruction pciSUBFW = {
    //   genericAnalyze,
    genericDestruct,
    genericPrint},
-  POC_SUBWF,
+  POC_SUBFW,
   "SUBWF",
   NULL, // from branch
   NULL, // to branch
@@ -867,6 +922,7 @@ pCodeInstruction pciSUBFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z) // outCond
 };
@@ -886,6 +942,7 @@ pCodeInstruction pciSUBLW = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_W,   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
 };
@@ -905,6 +962,7 @@ pCodeInstruction pciSWAPF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   (PCC_REGISTER),   // inCond
   (PCC_REGISTER) // outCond
 };
@@ -924,6 +982,7 @@ pCodeInstruction pciSWAPFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   (PCC_REGISTER),   // inCond
   (PCC_W) // outCond
 };
@@ -943,6 +1002,7 @@ pCodeInstruction pciTRIS = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_NONE,   // inCond
   PCC_REGISTER // outCond
 };
@@ -962,6 +1022,7 @@ pCodeInstruction pciXORWF = {
   2,    // num ops
   1,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_REGISTER | PCC_Z) // outCond
 };
@@ -971,7 +1032,7 @@ pCodeInstruction pciXORFW = {
    //   genericAnalyze,
    genericDestruct,
    genericPrint},
-  POC_XORWF,
+  POC_XORFW,
   "XORWF",
   NULL, // from branch
   NULL, // to branch
@@ -981,6 +1042,7 @@ pCodeInstruction pciXORFW = {
   2,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z) // outCond
 };
@@ -1000,6 +1062,7 @@ pCodeInstruction pciXORLW = {
   1,    // num ops
   0,0,  // dest, bit instruction
   0,0,  // branch, skip
+  POC_NOP,
   PCC_W,   // inCond
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
 };
@@ -1080,13 +1143,13 @@ void SAFE_snprintf(char **str, size_t *size, const  char  *format, ...)
 extern  void initStack(int base_address, int size);
 extern regs *allocProcessorRegister(int rIdx, char * name, short po_type, int alias);
 extern regs *allocInternalRegister(int rIdx, char * name, short po_type, int alias);
-extern void init_pic(void);
+extern void init_pic(char *);
 
 void  pCodeInitRegisters(void)
 {
 
   initStack(0x38, 8);
-  init_pic();
+  init_pic(port->processor);
 
   pc_status.r = allocProcessorRegister(IDX_STATUS,"STATUS", PO_STATUS, 0x80);
   pc_pcl.r = allocProcessorRegister(IDX_PCL,"PCL", PO_PCL, 0x80);
@@ -1145,6 +1208,9 @@ void pic14initMnemonics(void)
   if(mnemonics_initialized)
     return;
 
+//FIXME - probably should NULL out the array before making the assignments
+//since we check the array contents below this initialization.
+
   pic14Mnemonics[POC_ADDLW] = &pciADDLW;
   pic14Mnemonics[POC_ADDWF] = &pciADDWF;
   pic14Mnemonics[POC_ADDFW] = &pciADDFW;
@@ -1207,6 +1273,8 @@ void pic14initMnemonics(void)
   mnemonics_initialized = 1;
 }
 
+int getpCodePeepCommand(char *cmd);
+
 int getpCode(char *mnem,unsigned dest)
 {
 
@@ -1232,6 +1300,59 @@ int getpCode(char *mnem,unsigned dest)
   return -1;
 }
 
+/*-----------------------------------------------------------------*
+ * pic14initpCodePeepCommands
+ *
+ *-----------------------------------------------------------------*/
+void pic14initpCodePeepCommands(void)
+{
+
+  int key, i;
+  peepCommand *pcmd;
+
+  i = 0;
+  do {
+    hTabAddItem(&pic14pCodePeepCommandsHash, 
+               mnem2key(peepCommands[i].cmd), &peepCommands[i]);
+    i++;
+  } while (peepCommands[i].cmd);
+
+  pcmd = hTabFirstItem(pic14pCodePeepCommandsHash, &key);
+
+  while(pcmd) {
+    //fprintf(stderr, "peep command %s  key %d\n",pcmd->cmd,pcmd->id);
+    pcmd = hTabNextItem(pic14pCodePeepCommandsHash, &key);
+  }
+
+}
+
+/*-----------------------------------------------------------------
+ *
+ *
+ *-----------------------------------------------------------------*/
+
+int getpCodePeepCommand(char *cmd)
+{
+
+  peepCommand *pcmd;
+  int key = mnem2key(cmd);
+
+
+  pcmd = hTabFirstItemWK(pic14pCodePeepCommandsHash, key);
+
+  while(pcmd) {
+    // fprintf(stderr," comparing %s to %s\n",pcmd->cmd,cmd);
+    if(STRCASECMP(pcmd->cmd, cmd) == 0) {
+      return pcmd->id;
+    }
+
+    pcmd = hTabNextItemWK (pic14pCodePeepCommandsHash);
+  
+  }
+
+  return -1;
+}
+
 char getpBlock_dbName(pBlock *pb)
 {
   if(!pb)
@@ -1463,8 +1584,42 @@ pCode *newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_la
   pcw->operand = optional_operand;
   pcw->label   = optional_label;
 
+  pcw->mustBeBitSkipInst = 0;
+  pcw->mustNotBeBitSkipInst = 0;
+  pcw->invertBitSkipInst = 0;
+
   return ( (pCode *)pcw);
   
+}
+
+ /*-----------------------------------------------------------------*/
+/* newPcodeInlineP - create a new pCode from a char string           */
+/*-----------------------------------------------------------------*/
+
+
+pCode *newpCodeInlineP(char *cP)
+{
+
+  pCodeComment *pcc ;
+    
+  pcc = Safe_calloc(1,sizeof(pCodeComment));
+
+  pcc->pc.type = PC_INLINE;
+  pcc->pc.prev = pcc->pc.next = NULL;
+  //pcc->pc.from = pcc->pc.to = pcc->pc.label = NULL;
+  pcc->pc.pb = NULL;
+
+  //  pcc->pc.analyze = genericAnalyze;
+  pcc->pc.destruct = genericDestruct;
+  pcc->pc.print = genericPrint;
+
+  if(cP)
+    pcc->comment = Safe_strdup(cP);
+  else
+    pcc->comment = NULL;
+
+  return ( (pCode *)pcc);
+
 }
 
 /*-----------------------------------------------------------------*/
@@ -1718,34 +1873,36 @@ pCodeOp *newpCodeOpLit(int lit)
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-pCodeOp *newpCodeOpImmd(char *name, int offset)
+pCodeOp *newpCodeOpImmd(char *name, int offset, int index, int code_space)
 {
   pCodeOp *pcop;
 
-
   pcop = Safe_calloc(1,sizeof(pCodeOpImmd) );
   pcop->type = PO_IMMEDIATE;
   if(name) {
     pcop->name = Safe_strdup(name);
+    //fprintf(stderr,"%s %s %d\n",__FUNCTION__,name,offset);
   } else {
     pcop->name = NULL;
   }
 
 
+  PCOI(pcop)->index = index;
   PCOI(pcop)->offset = offset;
+  PCOI(pcop)->_const = code_space;
 
   return pcop;
 }
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype)
+pCodeOp *newpCodeOpWild(int id, pCodeWildBlock *pcwb, pCodeOp *subtype)
 {
   char *s = buffer;
   pCodeOp *pcop;
 
 
-  if(!pcp || !subtype) {
+  if(!pcwb || !subtype) {
     fprintf(stderr, "Wild opcode declaration error: %s-%d\n",__FILE__,__LINE__);
     exit(1);
   }
@@ -1756,7 +1913,7 @@ pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype)
   pcop->name = Safe_strdup(s);
 
   PCOW(pcop)->id = id;
-  PCOW(pcop)->pcp = pcp;
+  PCOW(pcop)->pcwb = pcwb;
   PCOW(pcop)->subtype = subtype;
   PCOW(pcop)->matched = NULL;
 
@@ -1782,6 +1939,14 @@ pCodeOp *newpCodeOpBit(char *s, int bit, int inBitSpace)
   return pcop;
 }
 
+/*-----------------------------------------------------------------*
+ * pCodeOp *newpCodeOpReg(int rIdx) - allocate a new register
+ *
+ * If rIdx >=0 then a specific register from the set of registers
+ * will be selected. If rIdx <0, then a new register will be searched
+ * for.
+ *-----------------------------------------------------------------*/
+
 pCodeOp *newpCodeOpReg(int rIdx)
 {
   pCodeOp *pcop;
@@ -1789,18 +1954,29 @@ pCodeOp *newpCodeOpReg(int rIdx)
   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
 
   pcop->name = NULL;
-  PCOR(pcop)->rIdx = rIdx;
-  PCOR(pcop)->r = pic14_regWithIdx(rIdx);
+
+  if(rIdx >= 0) {
+    PCOR(pcop)->rIdx = rIdx;
+    PCOR(pcop)->r = pic14_regWithIdx(rIdx);
+  } else {
+    PCOR(pcop)->r = pic14_findFreeReg(REG_GPR);
+
+    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;
 
   return pcop;
 }
+
 pCodeOp *newpCodeOpRegFromStr(char *name)
 {
   pCodeOp *pcop;
 
   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-  PCOR(pcop)->r = allocRegByName(name);
+  PCOR(pcop)->r = allocRegByName(name, 1);
   PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
   pcop->type = PCOR(pcop)->r->pc_type;
   pcop->name = PCOR(pcop)->r->name;
@@ -1828,6 +2004,9 @@ pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type)
   case PO_LABEL:
     pcop = newpCodeOpLabel(NULL,-1);
     break;
+  case PO_GPR_TEMP:
+    pcop = newpCodeOpReg(-1);
+    break;
 
   default:
     pcop = Safe_calloc(1,sizeof(pCodeOp) );
@@ -2015,28 +2194,28 @@ void pBlockRegs(FILE *of, pBlock *pb)
 }
 
 
-static char *get_op( pCodeInstruction *pcc)
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+char *get_op(pCodeOp *pcop)
 {
   regs *r;
   static char buffer[50];
   char *s;
   int size;
 
-  if(pcc && pcc->pcop) {
 
-
-    switch(pcc->pcop->type) {
+  if(pcop) {
+    switch(pcop->type) {
     case PO_INDF:
     case PO_FSR:
       //fprintf(stderr,"get_op getting register name rIdx=%d\n",PCOR(pcc->pcop)->rIdx);
       //r = pic14_regWithIdx(PCOR(pcc->pcop)->rIdx);
       //return r->name;
-      return PCOR(pcc->pcop)->r->name;
+      return PCOR(pcop)->r->name;
       break;
     case PO_GPR_TEMP:
-      r = pic14_regWithIdx(PCOR(pcc->pcop)->r->rIdx);
+      r = pic14_regWithIdx(PCOR(pcop)->r->rIdx);
       //fprintf(stderr,"getop: getting %s\nfrom:\n",r->name); //pcc->pcop->name);
-      pBlockRegs(stderr,pcc->pc.pb);
       return r->name;
 
       //    case PO_GPR_BIT:
@@ -2044,24 +2223,61 @@ static char *get_op( pCodeInstruction *pcc)
     case PO_IMMEDIATE:
       s = buffer;
       size = sizeof(buffer);
-      if( PCOI(pcc->pcop)->offset && PCOI(pcc->pcop)->offset<4) {
-       SAFE_snprintf(&s,&size,"((%s >> %d)&0xff)",
-                     pcc->pcop->name,
-                     8 * PCOI(pcc->pcop)->offset );
-      } else
-       SAFE_snprintf(&s,&size,"LOW(%s)",pcc->pcop->name);
-
+      //fprintf(stderr,"PO_IMMEDIATE name = %s  offset = %d\n",pcc->pcop->name,PCOI(pcc->pcop)->offset);
+      if(PCOI(pcop)->_const) {
+
+       if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) {
+         SAFE_snprintf(&s,&size,"(((%s+%d) >> %d)&0xff)",
+                       pcop->name,
+                       PCOI(pcop)->index,
+                       8 * PCOI(pcop)->offset );
+       } else
+         SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index);
+      } else {
       
+       if( PCOI(pcop)->index) { // && PCOI(pcc->pcop)->offset<4) {
+         SAFE_snprintf(&s,&size,"(%s + %d)",
+                       pcop->name,
+                       PCOI(pcop)->index );
+       } else
+         SAFE_snprintf(&s,&size,"%s",pcop->name);
+      }
+
+      return buffer;
+
+    case PO_DIR:
+      s = buffer;
+      size = sizeof(buffer);
+      if( PCOR(pcop)->instance) {
+       SAFE_snprintf(&s,&size,"(%s + %d)",
+                     pcop->name,
+                     PCOR(pcop)->instance );
+       //fprintf(stderr,"PO_DIR %s\n",buffer);
+      } else
+       SAFE_snprintf(&s,&size,"%s",pcop->name);
       return buffer;
 
     default:
-      if  (pcc->pcop->name)
-       return pcc->pcop->name;
+      if  (pcop->name)
+       return pcop->name;
 
     }
   }
 
   return "NO operand";
+
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+static char *get_op_from_instruction( pCodeInstruction *pcc)
+{
+
+  if(pcc )
+    return get_op(pcc->pcop);
+  
+  return ("ERROR Null: "__FUNCTION__);
+
 }
 
 /*-----------------------------------------------------------------*/
@@ -2091,23 +2307,23 @@ char *pCode2str(char *str, int size, pCode *pc)
                          PCI(pc)->pcop->name ,
                          PCI(pc)->pcop->name );
          else
-           SAFE_snprintf(&s,&size,"%s,%d", get_op(PCI(pc)), 
+           SAFE_snprintf(&s,&size,"%s,%d", get_op_from_instruction(PCI(pc)), 
                          (((pCodeOpRegBit *)(PCI(pc)->pcop))->bit ));
        } else if(PCI(pc)->pcop->type == PO_GPR_BIT) {
-         SAFE_snprintf(&s,&size,"%s,%d", get_op(PCI(pc)),PCORB(PCI(pc)->pcop)->bit);
+         SAFE_snprintf(&s,&size,"%s,%d", get_op_from_instruction(PCI(pc)),PCORB(PCI(pc)->pcop)->bit);
        }else
-         SAFE_snprintf(&s,&size,"%s,0 ; ?bug", get_op(PCI(pc)));
+         SAFE_snprintf(&s,&size,"%s,0 ; ?bug", get_op_from_instruction(PCI(pc)));
        //PCI(pc)->pcop->t.bit );
       } else {
 
        if(PCI(pc)->pcop->type == PO_GPR_BIT) {
          if( PCI(pc)->num_ops == 2)
-           SAFE_snprintf(&s,&size,"(%s >> 3),%c",get_op(PCI(pc)),((PCI(pc)->isModReg) ? 'F':'W'));
+           SAFE_snprintf(&s,&size,"(%s >> 3),%c",get_op_from_instruction(PCI(pc)),((PCI(pc)->isModReg) ? 'F':'W'));
          else
-           SAFE_snprintf(&s,&size,"(1 << (%s & 7))",get_op(PCI(pc)));
+           SAFE_snprintf(&s,&size,"(1 << (%s & 7))",get_op_from_instruction(PCI(pc)));
 
        }else {
-         SAFE_snprintf(&s,&size,"%s",get_op(PCI(pc)));
+         SAFE_snprintf(&s,&size,"%s",get_op_from_instruction(PCI(pc)));
 
          if( PCI(pc)->num_ops == 2)
            SAFE_snprintf(&s,&size,",%c", ( (PCI(pc)->isModReg) ? 'F':'W'));
@@ -2122,6 +2338,11 @@ char *pCode2str(char *str, int size, pCode *pc)
     SAFE_snprintf(&s,&size,";%s", ((pCodeComment *)pc)->comment);
     break;
 
+  case PC_INLINE:
+    /* assuming that inline code ends with a \n */
+    SAFE_snprintf(&s,&size,"%s", ((pCodeComment *)pc)->comment);
+    break;
+
   case PC_LABEL:
     SAFE_snprintf(&s,&size,";label=%s, key=%d\n",PCL(pc)->label,PCL(pc)->key);
     break;
@@ -2154,6 +2375,10 @@ static void genericPrint(FILE *of, pCode *pc)
     fprintf(of,";%s\n", ((pCodeComment *)pc)->comment);
     break;
 
+  case PC_INLINE:
+    fprintf(of,"%s\n", ((pCodeComment *)pc)->comment);
+     break;
+
   case PC_OPCODE:
     // If the opcode has a label, print that first
     {
@@ -2658,27 +2883,26 @@ regs * getRegFromInstruction(pCode *pc)
 
   case PO_BIT:
   case PO_GPR_TEMP:
-    fprintf(stderr, "getRegFromInstruction - bit or temp\n");
+    //fprintf(stderr, "getRegFromInstruction - bit or temp\n");
     return PCOR(PCI(pc)->pcop)->r;
 
   case PO_IMMEDIATE:
-    fprintf(stderr, "getRegFromInstruction - immediate\n");
+    //fprintf(stderr, "getRegFromInstruction - immediate\n");
     return NULL; // PCOR(PCI(pc)->pcop)->r;
 
   case PO_GPR_BIT:
     return PCOR(PCI(pc)->pcop)->r;
 
   case PO_DIR:
-    fprintf(stderr, "getRegFromInstruction - dir\n");
-    //return NULL; PCOR(PCI(pc)->pcop)->r;
+    //fprintf(stderr, "getRegFromInstruction - dir\n");
     return PCOR(PCI(pc)->pcop)->r;
   case PO_LITERAL:
-    fprintf(stderr, "getRegFromInstruction - literal\n");
+    //fprintf(stderr, "getRegFromInstruction - literal\n");
     break;
 
   default:
-    fprintf(stderr, "getRegFromInstruction - unknown reg type %d\n",PCI(pc)->pcop->type);
-    genericPrint(stderr, pc);
+    //fprintf(stderr, "getRegFromInstruction - unknown reg type %d\n",PCI(pc)->pcop->type);
+    //genericPrint(stderr, pc);
     break;
   }
 
@@ -3163,8 +3387,9 @@ void OptimizepCode(char dbName)
 }
 
 /*-----------------------------------------------------------------*/
-/* popCopy - copy a pcode operator                                 */
+/* popCopyGPR2Bit - copy a pcode operator                          */
 /*-----------------------------------------------------------------*/
+
 pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
 {
   pCodeOp *pcop;
@@ -3206,7 +3431,7 @@ void FixRegisterBanking(pBlock *pb)
 
   int cur_bank;
   regs *reg;
-  return;
+  //  return;
   if(!pb)
     return;
 
@@ -3215,7 +3440,7 @@ void FixRegisterBanking(pBlock *pb)
     return;
   /* loop through all of the flow blocks with in one pblock */
 
-  //  fprintf(stderr,"Register banking\n");
+  //fprintf(stderr,"Register banking\n");
   cur_bank = 0;
   do {
     /* at this point, pc should point to a PC_FLOW object */
@@ -3226,21 +3451,21 @@ void FixRegisterBanking(pBlock *pb)
 
     do {
       if(isPCI(pc)) {
-    genericPrint(stderr, pc);
+       //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));
 
        }
-       //#endif
+       #endif
        if(reg && REG_BANK(reg)!=cur_bank) {
          /* Examine the instruction before this one to make sure it is
           * not a skip type instruction */
          pcprev = findPrevpCode(pc->prev, PC_OPCODE);
-         if(pcprev && !isPCI_SKIP(pcprev)) {
+         if(!pcprev || (pcprev && !isPCI_SKIP(pcprev))) {
            int b = cur_bank ^ REG_BANK(reg);
 
            //fprintf(stderr, "Cool! can switch banks\n");
@@ -3261,8 +3486,10 @@ void FixRegisterBanking(pBlock *pb)
 
            }
 
-         } else
-           fprintf(stderr, "Bummer can't switch banks\n");
+         } else {
+           //fprintf(stderr, "Bummer can't switch banks\n");
+           ;
+         }
        }
       }
 
@@ -3437,7 +3664,7 @@ void buildCallTree(void    )
        if (PCF(pc)->fname) {
 
          if(STRCASECMP(PCF(pc)->fname, "_main") == 0) {
-           fprintf(stderr," found main \n");
+           //fprintf(stderr," found main \n");
            pb->cmemmap = NULL;  /* FIXME do we need to free ? */
            pb->dbName = 'M';
          }
@@ -3618,7 +3845,7 @@ void pBlockStats(FILE *of, pBlock *pb)
 
     while(pc) {
       if(pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL) {
-       fprintf(of,";   %s\n",get_op(PCI(pc)));
+       fprintf(of,";   %s\n",get_op_from_instruction(PCI(pc)));
       }
       pc = setNextItem(pb->function_calls);
     }
@@ -3679,7 +3906,7 @@ set *register_usage(pBlock *pb)
   for( ; pc; pc = setNextItem(pb->function_calls)) {
 
     if(pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL) {
-      char *dest = get_op(PCI(pc));
+      char *dest = get_op_from_instruction(PCI(pc));
 
       pcn = findFunction(dest);
       if(pcn) 
@@ -3801,7 +4028,7 @@ void pct2(FILE *of,pBlock *pb,int indent)
   for( ; pc; pc = setNextItem(pb->function_calls)) {
 
     if(pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL) {
-      char *dest = get_op(PCI(pc));
+      char *dest = get_op_from_instruction(PCI(pc));
 
       pcn = findFunction(dest);
       if(pcn) 
@@ -3923,7 +4150,7 @@ void printCallTree(FILE *of)
       while(pc->next && !ispCodeFunction(pc->next)) {
        pc = pc->next;
        if(pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL)
-         fprintf(of,"\t%s\n",get_op(PCI(pc)));
+         fprintf(of,"\t%s\n",get_op_from_instruction(PCI(pc)));
       }
     }