2004-01-16 Vangelis Rokas <vrokas@otenet.gr>
[fw/sdcc] / src / pic16 / pcode.c
index 12fed71666aeaa101d5e83b80d260164623f87c5..b05aaf59a9d30bc4572edf641485f1dee8877b5e 100644 (file)
@@ -1,6 +1,7 @@
 /*-------------------------------------------------------------------------
 
-   pcode.c - post code generation
+  pcode.c - post code generation
+
    Written By -  Scott Dattalo scott@dattalo.com
    Ported to PIC16 By -  Martin Dubuc m.dubuc@rogers.com
 
    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 -------------------------------------------------------------------------*/
 
-
 #include <stdio.h>
 
 #include "common.h"   // Include everything in the SDCC src directory
 #include "newalloc.h"
 
 
+#include "main.h"
 #include "pcode.h"
 #include "pcodeflow.h"
 #include "ralloc.h"
@@ -52,15 +53,26 @@ static peepCommand peepCommands[] = {
 
 
 // Eventually this will go into device dependent files:
-pCodeOpReg pic16_pc_status    = {{PO_STATUS,  "_STATUS"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_status    = {{PO_STATUS,  "STATUS"}, -1, NULL,0,NULL};
 pCodeOpReg pic16_pc_indf0     = {{PO_INDF0,   "INDF0"}, -1, NULL,0,NULL};
 pCodeOpReg pic16_pc_fsr0      = {{PO_FSR0,    "FSR0"}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_intcon    = {{PO_INTCON,  ""}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_intcon    = {{PO_INTCON,  "INTCON"}, -1, NULL,0,NULL};
 pCodeOpReg pic16_pc_pcl       = {{PO_PCL,     "PCL"}, -1, NULL,0,NULL};
-pCodeOpReg pic16_pc_pclath    = {{PO_PCLATH,  "_PCLATH"}, -1, NULL,0,NULL};
+pCodeOpReg pic16_pc_pclath    = {{PO_PCLATH,  "PCLATH"}, -1, NULL,0,NULL};
 pCodeOpReg pic16_pc_wreg      = {{PO_WREG,    "WREG"}, -1, NULL,0,NULL};
 pCodeOpReg pic16_pc_bsr       = {{PO_BSR,     "BSR"}, -1, NULL,0,NULL};
 
+pCodeOpReg pic16_pc_fsr1l      = {{PO_FSR0,    "FSR1L"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_fsr1h      = {{PO_FSR0,    "FSR1H"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_fsr2l      = {{PO_FSR0,    "FSR2L"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_fsr2h      = {{PO_FSR0,    "FSR2H"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_postinc1   = {{PO_FSR0,    "POSTINC1"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_preinc1    = {{PO_FSR0,    "PREINC1"}, -1, NULL, 0, NULL};
+
+pCodeOpReg pic16_pc_plusw2     = {{PO_FSR0,    "PLUSW2"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_preinc2    = {{PO_FSR0,    "PREINC1"}, -1, NULL, 0, NULL};
+pCodeOpReg pic16_pc_postdec1   = {{PO_FSR0,    "POSTDEV1"}, -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};
@@ -71,8 +83,6 @@ static int mnemonics_initialized = 0;
 static hTab *pic16MnemonicsHash = NULL;
 static hTab *pic16pCodePeepCommandsHash = NULL;
 
-
-
 static pFile *the_pFile = NULL;
 static pBlock *pb_dead_pcodes = NULL;
 
@@ -81,7 +91,9 @@ static int peepOptimizing = 1;        /* run the peephole optimizer if nonzero *
 static int functionInlining = 1;      /* inline functions if nonzero */
 int pic16_debug_verbose = 0;                /* Set true to inundate .asm file */
 
-static int GpCodeSequenceNumber = 1;
+int pic16_pcode_verbose = 0;
+
+//static int GpCodeSequenceNumber = 1;
 static int GpcFlowSeq = 1;
 
 extern void pic16_RemoveUnusedRegisters(void);
@@ -89,11 +101,8 @@ extern void pic16_RegsUnMapLiveRanges(void);
 extern void pic16_BuildFlowTree(pBlock *pb);
 extern void pic16_pCodeRegOptimizeRegUsage(int level);
 extern int pic16_picIsInitialized(void);
-#if !OPT_DISABLE_PIC
-// From pic/pcode.c:
 extern void SAFE_snprintf(char **str, size_t *size, const char *format, ...);
 extern int mnem2key(char const *mnem);
-#endif // OPT_DISABLE_PIC
 
 /****************************************************************/
 /*                      Forward declarations                    */
@@ -114,7 +123,7 @@ static void pCodePrintLabel(FILE *of, pCode *pc);
 static void pCodePrintFunction(FILE *of, pCode *pc);
 static void pCodeOpPrint(FILE *of, pCodeOp *pcop);
 static char *pic16_get_op_from_instruction( pCodeInstruction *pcc);
-char *pic16_get_op( pCodeOp *pcop,char *buff,int buf_size);
+char *pic16_get_op(pCodeOp *pcop,char *buff,size_t buf_size);
 int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd);
 int pic16_pCodePeepMatchRule(pCode *pc);
 static void pBlockStats(FILE *of, pBlock *pb);
@@ -148,9 +157,12 @@ pCodeInstruction pic16_pciADDWF = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_REGISTER | PCC_Z) // outCond
+  (PCC_REGISTER | PCC_Z), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciADDFW = {
@@ -172,9 +184,12 @@ pCodeInstruction pic16_pciADDFW = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_W | PCC_Z) // outCond
+  (PCC_W | PCC_Z), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciADDWFC = { // mdubuc - New
@@ -196,9 +211,12 @@ pCodeInstruction pic16_pciADDWFC = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
-  (PCC_REGISTER | PCC_Z) // outCond
+  (PCC_REGISTER | PCC_Z), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciADDFWC = {
@@ -220,9 +238,12 @@ pCodeInstruction pic16_pciADDFWC = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
-  (PCC_W | PCC_Z) // outCond
+  (PCC_W | PCC_Z), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciADDLW = {
@@ -244,9 +265,12 @@ pCodeInstruction pic16_pciADDLW = {
   1,    // literal operand
   0,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_LITERAL),   // inCond
-  (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciANDLW = {
@@ -268,9 +292,12 @@ pCodeInstruction pic16_pciANDLW = {
   1,    // literal operand
   0,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_LITERAL),   // inCond
-  (PCC_W | PCC_Z | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciANDWF = {
@@ -292,9 +319,12 @@ pCodeInstruction pic16_pciANDWF = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_REGISTER | PCC_Z | PCC_N) // outCond
+  (PCC_REGISTER | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciANDFW = {
@@ -316,6 +346,8 @@ pCodeInstruction pic16_pciANDFW = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
   (PCC_W | PCC_Z) // outCond
@@ -340,9 +372,12 @@ pCodeInstruction pic16_pciBC = { // mdubuc - New
   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_REL_ADDR | PCC_C),   // inCond
-  PCC_NONE    // outCond
+  PCC_NONE,    // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBCF = {
@@ -364,9 +399,12 @@ pCodeInstruction pic16_pciBCF = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,    // second literal operand
   POC_BSF,
   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
-  PCC_REGISTER // outCond
+  PCC_REGISTER, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBN = { // mdubuc - New
@@ -388,9 +426,12 @@ pCodeInstruction pic16_pciBN = { // mdubuc - New
   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_REL_ADDR | PCC_N),   // inCond
-  PCC_NONE    // outCond
+  PCC_NONE   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBNC = { // mdubuc - New
@@ -412,9 +453,12 @@ pCodeInstruction pic16_pciBNC = { // mdubuc - New
   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_REL_ADDR | PCC_C),   // inCond
-  PCC_NONE    // outCond
+  PCC_NONE   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBNN = { // mdubuc - New
@@ -436,9 +480,12 @@ pCodeInstruction pic16_pciBNN = { // mdubuc - New
   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_REL_ADDR | PCC_N),   // inCond
-  PCC_NONE    // outCond
+  PCC_NONE   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBNOV = { // mdubuc - New
@@ -460,9 +507,12 @@ pCodeInstruction pic16_pciBNOV = { // mdubuc - New
   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_REL_ADDR | PCC_OV),   // inCond
-  PCC_NONE    // outCond
+  PCC_NONE   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBNZ = { // mdubuc - New
@@ -484,9 +534,12 @@ pCodeInstruction pic16_pciBNZ = { // mdubuc - New
   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_REL_ADDR | PCC_Z),   // inCond
-  PCC_NONE    // outCond
+  PCC_NONE   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBOV = { // mdubuc - New
@@ -508,9 +561,12 @@ pCodeInstruction pic16_pciBOV = { // mdubuc - New
   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_REL_ADDR | PCC_OV),   // inCond
-  PCC_NONE  // outCond
+  PCC_NONE , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBRA = { // mdubuc - New
@@ -532,9 +588,12 @@ pCodeInstruction pic16_pciBRA = { // mdubuc - New
   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_REL_ADDR,   // inCond
-  PCC_NONE    // outCond
+  PCC_NONE   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBSF = {
@@ -556,9 +615,12 @@ pCodeInstruction pic16_pciBSF = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,    // second literal operand
   POC_BCF,
   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
-  (PCC_REGISTER | PCC_EXAMINE_PCOP) // outCond
+  (PCC_REGISTER | PCC_EXAMINE_PCOP), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBTFSC = {
@@ -580,9 +642,12 @@ pCodeInstruction pic16_pciBTFSC = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,    // second literal operand
   POC_BTFSS,
   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
-  PCC_EXAMINE_PCOP // outCond
+  PCC_EXAMINE_PCOP, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBTFSS = {
@@ -604,9 +669,12 @@ pCodeInstruction pic16_pciBTFSS = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,    // second literal operand
   POC_BTFSC,
   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
-  PCC_EXAMINE_PCOP // outCond
+  PCC_EXAMINE_PCOP, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBTG = { // mdubuc - New
@@ -628,9 +696,12 @@ pCodeInstruction pic16_pciBTG = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
-  (PCC_REGISTER | PCC_EXAMINE_PCOP) // outCond
+  (PCC_REGISTER | PCC_EXAMINE_PCOP), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciBZ = { // mdubuc - New
@@ -652,9 +723,12 @@ pCodeInstruction pic16_pciBZ = { // mdubuc - New
   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_Z,   // inCond
-  PCC_NONE // outCond
+  PCC_NONE, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciCALL = {
@@ -676,9 +750,12 @@ pCodeInstruction pic16_pciCALL = {
   0,    // literal operand
   0,    // RAM access bit
   1,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_NONE, // inCond
-  PCC_NONE  // outCond
+  PCC_NONE , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciCOMF = {
@@ -700,9 +777,12 @@ pCodeInstruction pic16_pciCOMF = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,  // inCond
-  PCC_REGISTER   // outCond
+  PCC_REGISTER  , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciCOMFW = {
@@ -724,9 +804,12 @@ pCodeInstruction pic16_pciCOMFW = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,  // inCond
-  PCC_W   // outCond
+  PCC_W  , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciCLRF = {
@@ -748,9 +831,12 @@ pCodeInstruction pic16_pciCLRF = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER, // inCond
-  PCC_REGISTER  // outCond
+  PCC_REGISTER , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciCLRWDT = {
@@ -772,9 +858,12 @@ pCodeInstruction pic16_pciCLRWDT = {
   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
+  PCC_NONE , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciCPFSEQ = { // mdubuc - New
@@ -796,9 +885,12 @@ pCodeInstruction pic16_pciCPFSEQ = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER), // inCond
-  PCC_NONE  // outCond
+  PCC_NONE , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciCPFSGT = { // mdubuc - New
@@ -820,9 +912,12 @@ pCodeInstruction pic16_pciCPFSGT = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER), // inCond
-  PCC_NONE  // outCond
+  PCC_NONE , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciCPFSLT = { // mdubuc - New
@@ -844,9 +939,12 @@ pCodeInstruction pic16_pciCPFSLT = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER), // inCond
-  PCC_NONE  // outCond
+  PCC_NONE , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciDAW = {
@@ -868,9 +966,12 @@ pCodeInstruction pic16_pciDAW = {
   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_W, // inCond
-  (PCC_W | PCC_C) // outCond
+  (PCC_W | PCC_C), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciDCFSNZ = { // mdubuc - New
@@ -892,9 +993,12 @@ pCodeInstruction pic16_pciDCFSNZ = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER, // inCond
-  PCC_REGISTER  // outCond
+  PCC_REGISTER , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciDCFSNZW = { // mdubuc - New
@@ -916,9 +1020,12 @@ pCodeInstruction pic16_pciDCFSNZW = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER, // inCond
-  PCC_W  // outCond
+  PCC_W , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciDECF = {
@@ -940,9 +1047,12 @@ pCodeInstruction pic16_pciDECF = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_REGISTER    // outCond
+  PCC_REGISTER   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciDECFW = {
@@ -964,9 +1074,12 @@ pCodeInstruction pic16_pciDECFW = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_W    // outCond
+  PCC_W   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciDECFSZ = {
@@ -988,9 +1101,12 @@ pCodeInstruction pic16_pciDECFSZ = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_REGISTER    // outCond
+  PCC_REGISTER   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciDECFSZW = {
@@ -1012,9 +1128,12 @@ pCodeInstruction pic16_pciDECFSZW = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_W           // outCond
+  PCC_W          , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciGOTO = {
@@ -1036,9 +1155,12 @@ pCodeInstruction pic16_pciGOTO = {
   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_REL_ADDR,   // inCond
-  PCC_NONE    // outCond
+  PCC_NONE   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciINCF = {
@@ -1060,9 +1182,12 @@ pCodeInstruction pic16_pciINCF = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  (PCC_REGISTER | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N) // outCond
+  (PCC_REGISTER | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciINCFW = {
@@ -1084,9 +1209,12 @@ pCodeInstruction pic16_pciINCFW = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_W    // outCond
+  PCC_W   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciINCFSZ = {
@@ -1108,9 +1236,12 @@ pCodeInstruction pic16_pciINCFSZ = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_REGISTER    // outCond
+  PCC_REGISTER   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciINCFSZW = {
@@ -1132,9 +1263,12 @@ pCodeInstruction pic16_pciINCFSZW = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_W           // outCond
+  PCC_W          , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciINFSNZ = { // mdubuc - New
@@ -1156,9 +1290,12 @@ pCodeInstruction pic16_pciINFSNZ = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_REGISTER    // outCond
+  PCC_REGISTER   , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciIORWF = {
@@ -1180,9 +1317,12 @@ pCodeInstruction pic16_pciIORWF = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_REGISTER | PCC_Z | PCC_N) // outCond
+  (PCC_REGISTER | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciIORFW = {
@@ -1204,9 +1344,12 @@ pCodeInstruction pic16_pciIORFW = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_W | PCC_Z | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciIORLW = {
@@ -1228,9 +1371,12 @@ pCodeInstruction pic16_pciIORLW = {
   1,    // literal operand
   0,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_LITERAL),   // inCond
-  (PCC_W | PCC_Z | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciLFSR = { // mdubuc - New
@@ -1252,10 +1398,12 @@ pCodeInstruction pic16_pciLFSR = { // mdubuc - New
   1,    // literal operand
   0,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  1,   // second literal operand
   POC_NOP,
-  (PCC_REGISTER | PCC_LITERAL), // mdubuc - Should we use a special syntax for
-                                // f (identifies FSRx)?
-  PCC_REGISTER // outCond
+  (PCC_REGISTER | PCC_LITERAL),
+  PCC_REGISTER, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciMOVF = {
@@ -1277,9 +1425,12 @@ pCodeInstruction pic16_pciMOVF = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  (PCC_Z | PCC_N) // outCond
+  (PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciMOVFW = {
@@ -1301,9 +1452,12 @@ pCodeInstruction pic16_pciMOVFW = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  (PCC_W | PCC_Z) // outCond
+  (PCC_W | PCC_Z), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciMOVFF = { // mdubuc - New
@@ -1325,9 +1479,12 @@ pCodeInstruction pic16_pciMOVFF = { // mdubuc - New
   0,    // literal operand
   0,    // RAM access bit
   0,    // fast call/return mode select bit
+  1,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_REGISTER2 // outCond
+  PCC_REGISTER2, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciMOVLB = { // mdubuc - New
@@ -1348,9 +1505,12 @@ pCodeInstruction pic16_pciMOVLB = { // mdubuc - New
   1,    // 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 | PCC_LITERAL),   // inCond
-  PCC_REGISTER // outCond - BSR
+  PCC_REGISTER, // outCond - BSR
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciMOVLW = {
@@ -1371,9 +1531,12 @@ pCodeInstruction pic16_pciMOVLW = {
   1,    // 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 | PCC_LITERAL),   // inCond
-  PCC_W // outCond
+  PCC_W, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciMOVWF = {
@@ -1395,9 +1558,12 @@ pCodeInstruction pic16_pciMOVWF = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_W // outCond
+  PCC_W, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciMULLW = { // mdubuc - New
@@ -1418,9 +1584,12 @@ pCodeInstruction pic16_pciMULLW = { // mdubuc - New
   1,    // literal operand
   0,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_LITERAL),   // inCond
-  PCC_REGISTER // outCond - PROD
+  PCC_REGISTER, // outCond - PROD
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciMULWF = { // mdubuc - New
@@ -1441,9 +1610,12 @@ pCodeInstruction pic16_pciMULWF = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  PCC_REGISTER // outCond - PROD
+  PCC_REGISTER, // outCond - PROD
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciNEGF = { // mdubuc - New
@@ -1464,9 +1636,12 @@ pCodeInstruction pic16_pciNEGF = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER, // inCond
-  (PCC_REGISTER | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+  (PCC_REGISTER | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciNOP = {
@@ -1487,9 +1662,12 @@ pCodeInstruction pic16_pciNOP = {
   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
+  PCC_NONE, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciPOP = { // mdubuc - New
@@ -1510,9 +1688,12 @@ pCodeInstruction pic16_pciPOP = { // mdubuc - New
   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
+  PCC_NONE  , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciPUSH = {
@@ -1533,9 +1714,12 @@ pCodeInstruction pic16_pciPUSH = {
   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
+  PCC_NONE  , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciRCALL = { // mdubuc - New
@@ -1556,9 +1740,12 @@ pCodeInstruction pic16_pciRCALL = { // mdubuc - New
   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_REL_ADDR,  // inCond
-  PCC_NONE   // outCond
+  PCC_NONE  , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciRETFIE = {
@@ -1580,9 +1767,12 @@ pCodeInstruction pic16_pciRETFIE = {
   0,    // literal operand
   0,    // RAM access bit
   1,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_NONE,   // inCond
-  PCC_NONE    // outCond (not true... affects the GIE bit too)
+  PCC_NONE,    // outCond (not true... affects the GIE bit too)
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciRETLW = {
@@ -1604,9 +1794,12 @@ pCodeInstruction pic16_pciRETLW = {
   1,    // literal operand
   0,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_LITERAL,   // inCond
-  PCC_W // outCond
+  PCC_W, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciRETURN = {
@@ -1628,9 +1821,12 @@ pCodeInstruction pic16_pciRETURN = {
   0,    // literal operand
   0,    // RAM access bit
   1,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_NONE,   // inCond
-  PCC_NONE // outCond
+  PCC_NONE, // outCond
+  PCI_MAGIC
 };
 pCodeInstruction pic16_pciRLCF = { // mdubuc - New
   {PC_OPCODE, NULL, NULL, 0, NULL, 
@@ -1651,9 +1847,12 @@ pCodeInstruction pic16_pciRLCF = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_C | PCC_REGISTER),   // inCond
-  (PCC_REGISTER | PCC_C | PCC_Z | PCC_N) // outCond
+  (PCC_REGISTER | PCC_C | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciRLCFW = { // mdubuc - New
@@ -1675,9 +1874,12 @@ pCodeInstruction pic16_pciRLCFW = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_C | PCC_REGISTER),   // inCond
-  (PCC_W | PCC_C | PCC_Z | PCC_N) // outCond
+  (PCC_W | PCC_C | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciRLNCF = { // mdubuc - New
@@ -1699,9 +1901,12 @@ pCodeInstruction pic16_pciRLNCF = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  (PCC_REGISTER | PCC_Z | PCC_N) // outCond
+  (PCC_REGISTER | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 pCodeInstruction pic16_pciRLNCFW = { // mdubuc - New
   {PC_OPCODE, NULL, NULL, 0, NULL, 
@@ -1722,9 +1927,12 @@ pCodeInstruction pic16_pciRLNCFW = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  (PCC_W | PCC_Z | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 pCodeInstruction pic16_pciRRCF = { // mdubuc - New
   {PC_OPCODE, NULL, NULL, 0, NULL, 
@@ -1745,9 +1953,12 @@ pCodeInstruction pic16_pciRRCF = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_C | PCC_REGISTER),   // inCond
-  (PCC_REGISTER | PCC_C | PCC_Z | PCC_N) // outCond
+  (PCC_REGISTER | PCC_C | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 pCodeInstruction pic16_pciRRCFW = { // mdubuc - New
   {PC_OPCODE, NULL, NULL, 0, NULL, 
@@ -1768,9 +1979,12 @@ pCodeInstruction pic16_pciRRCFW = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_C | PCC_REGISTER),   // inCond
-  (PCC_W | PCC_C | PCC_Z | PCC_N) // outCond
+  (PCC_W | PCC_C | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 pCodeInstruction pic16_pciRRNCF = { // mdubuc - New
   {PC_OPCODE, NULL, NULL, 0, NULL, 
@@ -1791,9 +2005,12 @@ pCodeInstruction pic16_pciRRNCF = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  (PCC_REGISTER | PCC_Z | PCC_N) // outCond
+  (PCC_REGISTER | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciRRNCFW = { // mdubuc - New
@@ -1815,9 +2032,12 @@ pCodeInstruction pic16_pciRRNCFW = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  (PCC_W | PCC_Z | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSETF = { // mdubuc - New
@@ -1839,9 +2059,12 @@ pCodeInstruction pic16_pciSETF = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,  // inCond
-  PCC_REGISTER   // outCond
+  PCC_REGISTER  , // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSUBLW = {
@@ -1863,9 +2086,12 @@ pCodeInstruction pic16_pciSUBLW = {
   1,    // literal operand
   0,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_LITERAL),   // inCond
-  (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N) // outCond
+  (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSUBFWB = {
@@ -1887,9 +2113,12 @@ pCodeInstruction pic16_pciSUBFWB = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
-  (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N) // outCond
+  (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSUBWF = {
@@ -1911,9 +2140,12 @@ pCodeInstruction pic16_pciSUBWF = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_REGISTER | PCC_Z) // outCond
+  (PCC_REGISTER | PCC_Z), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSUBFW = {
@@ -1935,9 +2167,12 @@ pCodeInstruction pic16_pciSUBFW = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_W | PCC_Z | PCC_OV | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSUBFWB_D1 = { // mdubuc - New
@@ -1959,9 +2194,12 @@ pCodeInstruction pic16_pciSUBFWB_D1 = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
-  (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+  (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSUBFWB_D0 = { // mdubuc - New
@@ -1983,9 +2221,12 @@ pCodeInstruction pic16_pciSUBFWB_D0 = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
-  (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSUBWFB_D1 = { // mdubuc - New
@@ -2007,9 +2248,12 @@ pCodeInstruction pic16_pciSUBWFB_D1 = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
-  (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+  (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSUBWFB_D0 = { // mdubuc - New
@@ -2031,9 +2275,12 @@ pCodeInstruction pic16_pciSUBWFB_D0 = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
-  (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSWAPF = {
@@ -2055,9 +2302,12 @@ pCodeInstruction pic16_pciSWAPF = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_REGISTER),   // inCond
-  (PCC_REGISTER) // outCond
+  (PCC_REGISTER), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciSWAPFW = {
@@ -2079,33 +2329,12 @@ pCodeInstruction pic16_pciSWAPFW = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_REGISTER),   // inCond
-  (PCC_W) // outCond
-};
-
-// mdubuc - Remove TRIS
-
-pCodeInstruction pic16_pciTRIS = {
-  {PC_OPCODE, NULL, NULL, 0, NULL, 
-   //   genericAnalyze,
-   genericDestruct,
-   genericPrint},
-  POC_TRIS,
-  "TRIS",
-  NULL, // from branch
-  NULL, // to branch
-  NULL, // label
-  NULL, // operand
-  NULL, // flow block
-  NULL, // C source 
-  1,    // num ops
-  0,0,  // dest, bit instruction
-  0,0,  // branch, skip
-  0,    // literal operand
-  POC_NOP,
-  PCC_NONE,   // inCond
-  PCC_REGISTER // outCond
+  (PCC_W), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciTSTFSZ = { // mdubuc - New
@@ -2127,9 +2356,12 @@ pCodeInstruction pic16_pciTSTFSZ = { // mdubuc - New
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   PCC_REGISTER,   // inCond
-  PCC_NONE // outCond
+  PCC_NONE, // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciXORWF = {
@@ -2151,9 +2383,12 @@ pCodeInstruction pic16_pciXORWF = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_REGISTER | PCC_Z | PCC_N) // outCond
+  (PCC_REGISTER | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciXORFW = {
@@ -2175,9 +2410,12 @@ pCodeInstruction pic16_pciXORFW = {
   0,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_REGISTER),   // inCond
-  (PCC_W | PCC_Z | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 pCodeInstruction pic16_pciXORLW = {
@@ -2199,18 +2437,20 @@ pCodeInstruction pic16_pciXORLW = {
   1,    // literal operand
   1,    // RAM access bit
   0,    // fast call/return mode select bit
+  0,   // second memory operand
+  0,   // second literal operand
   POC_NOP,
   (PCC_W | PCC_LITERAL),   // inCond
-  (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_N) // outCond
+  (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_N), // outCond
+  PCI_MAGIC
 };
 
 
 #define MAX_PIC16MNEMONICS 100
 pCodeInstruction *pic16Mnemonics[MAX_PIC16MNEMONICS];
 
+//#define USE_VSNPRINTF
 #if OPT_DISABLE_PIC
-/* This definition needs to be part of configure.in */
-// #define USE_VSNPRINTF
 
 #ifdef USE_VSNPRINTF
   // Alas, vsnprintf is not ANSI standard, and does not exist
@@ -2247,8 +2487,7 @@ void SAFE_snprintf(char **str, size_t *size, const  char  *format, ...)
 
 }
 
-#else  //  USE_VSNPRINTF
-
+#else
 // This version is *not* safe, despite the name.
 
 void SAFE_snprintf(char **str, size_t *size, const  char  *format, ...)
@@ -2268,7 +2507,7 @@ void SAFE_snprintf(char **str, size_t *size, const  char  *format, ...)
   len = strlen(buffer);
   if(len > *size) {
     fprintf(stderr,"WARNING, it looks like %s has overflowed\n",__FUNCTION__);
-    fprintf(stderr,"len = %d is > str size %d\n",len,*size);
+    fprintf(stderr,"len = %d is > str size %d\n",len, (int) *size);
   }
 
   strcpy(*str, buffer);
@@ -2278,9 +2517,7 @@ void SAFE_snprintf(char **str, size_t *size, const  char  *format, ...)
 }
 
 #endif    //  USE_VSNPRINTF
-    
-#endif // OPT_DISABLE_PIC
-
+#endif
 
 extern  void pic16_initStack(int base_address, int size);
 extern regs *pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias);
@@ -2291,39 +2528,60 @@ void  pic16_pCodeInitRegisters(void)
 {
   static int initialized=0;
 
-  if(initialized)
-    return;
-  initialized = 1;
-
-  pic16_initStack(0xfff, 8);
-  pic16_init_pic(port->processor);
-
-  pic16_pc_status.r = pic16_allocProcessorRegister(IDX_STATUS,"_STATUS", PO_STATUS, 0x80);
-  pic16_pc_pcl.r = pic16_allocProcessorRegister(IDX_PCL,"PCL", PO_PCL, 0x80);
-  pic16_pc_pclath.r = pic16_allocProcessorRegister(IDX_PCLATH,"_PCLATH", PO_PCLATH, 0x80);
-  pic16_pc_fsr0.r = pic16_allocProcessorRegister(IDX_FSR0,"FSR0", PO_FSR0, 0x80);
-  pic16_pc_indf0.r = pic16_allocProcessorRegister(IDX_INDF0,"INDF0", PO_INDF0, 0x80);
-  pic16_pc_intcon.r = pic16_allocProcessorRegister(IDX_INTCON,"INTCON", PO_INTCON, 0x80);
-  pic16_pc_wreg.r = pic16_allocProcessorRegister(IDX_WREG,"WREG", PO_WREG, 0x80);
-
-  pic16_pc_status.rIdx = IDX_STATUS;
-  pic16_pc_fsr0.rIdx = IDX_FSR0;
-  pic16_pc_indf0.rIdx = IDX_INDF0;
-  pic16_pc_intcon.rIdx = IDX_INTCON;
-  pic16_pc_pcl.rIdx = IDX_PCL;
-  pic16_pc_pclath.rIdx = IDX_PCLATH;
-  pic16_pc_wreg.rIdx = IDX_WREG;
-
-  pic16_pc_kzero.r = pic16_allocInternalRegister(IDX_KZ,"KZ",PO_GPR_REGISTER,0);
-  pic16_pc_ssave.r = pic16_allocInternalRegister(IDX_SSAVE,"SSAVE", PO_GPR_REGISTER, 0x80);
-  pic16_pc_wsave.r = pic16_allocInternalRegister(IDX_WSAVE,"WSAVE", PO_GPR_REGISTER, 0);
-
-  pic16_pc_kzero.rIdx = IDX_KZ;
-  pic16_pc_wsave.rIdx = IDX_WSAVE;
-  pic16_pc_ssave.rIdx = IDX_SSAVE;
-
-  /* probably should put this in a separate initialization routine */
-  pb_dead_pcodes = newpBlock();
+       if(initialized)
+               return;
+       
+       initialized = 1;
+
+       pic16_initStack(0xfff, 8);
+       pic16_init_pic(port->processor);
+
+       pic16_pc_status.r = pic16_allocProcessorRegister(IDX_STATUS,"STATUS", PO_STATUS, 0x80);
+       pic16_pc_pcl.r = pic16_allocProcessorRegister(IDX_PCL,"PCL", PO_PCL, 0x80);
+       pic16_pc_pclath.r = pic16_allocProcessorRegister(IDX_PCLATH,"PCLATH", PO_PCLATH, 0x80);
+       pic16_pc_fsr0.r = pic16_allocProcessorRegister(IDX_FSR0,"FSR0", PO_FSR0, 0x80);
+       pic16_pc_indf0.r = pic16_allocProcessorRegister(IDX_INDF0,"INDF0", PO_INDF0, 0x80);
+       pic16_pc_intcon.r = pic16_allocProcessorRegister(IDX_INTCON,"INTCON", PO_INTCON, 0x80);
+       pic16_pc_wreg.r = pic16_allocProcessorRegister(IDX_WREG,"WREG", PO_WREG, 0x80);
+
+       pic16_pc_fsr1l.r = pic16_allocProcessorRegister(IDX_FSR1L, "FSR1L", PO_FSR0, 0x80);
+       pic16_pc_fsr1h.r = pic16_allocProcessorRegister(IDX_FSR1H, "FSR1H", PO_FSR0, 0x80);
+       pic16_pc_fsr2l.r = pic16_allocProcessorRegister(IDX_FSR2L, "FSR2L", PO_FSR0, 0x80);
+       pic16_pc_fsr2h.r = pic16_allocProcessorRegister(IDX_FSR2H, "FSR2H", PO_FSR0, 0x80);
+       pic16_pc_postinc1.r = pic16_allocProcessorRegister(IDX_POSTINC1, "POSTINC1", PO_FSR0, 0x80);
+       pic16_pc_postdec1.r = pic16_allocProcessorRegister(IDX_POSTDEC1, "POSTDEC1", PO_FSR0, 0x80);
+       pic16_pc_preinc1.r = pic16_allocProcessorRegister(IDX_PREINC1, "PREINC1", PO_FSR0, 0x80);
+       
+       pic16_pc_preinc2.r = pic16_allocProcessorRegister(IDX_PREINC2, "PREINC2", PO_FSR0, 0x80);
+       pic16_pc_plusw2.r = pic16_allocProcessorRegister(IDX_PLUSW2, "PLUSW2", PO_FSR0, 0x80);
+       
+       pic16_pc_status.rIdx = IDX_STATUS;
+       pic16_pc_fsr0.rIdx = IDX_FSR0;
+       pic16_pc_indf0.rIdx = IDX_INDF0;
+       pic16_pc_intcon.rIdx = IDX_INTCON;
+       pic16_pc_pcl.rIdx = IDX_PCL;
+       pic16_pc_pclath.rIdx = IDX_PCLATH;
+       pic16_pc_wreg.rIdx = IDX_WREG;
+       pic16_pc_fsr1l.rIdx = IDX_FSR1L;
+       pic16_pc_fsr1h.rIdx = IDX_FSR1H;
+       pic16_pc_fsr2l.rIdx = IDX_FSR2L;
+       pic16_pc_fsr2h.rIdx = IDX_FSR2H;
+       pic16_pc_postinc1.rIdx = IDX_POSTINC1;
+       pic16_pc_postdec1.rIdx = IDX_POSTDEC1;
+       pic16_pc_preinc1.rIdx = IDX_PREINC1;
+       pic16_pc_preinc2.rIdx = IDX_PREINC2;
+       pic16_pc_plusw2.rIdx = IDX_PLUSW2;
+       
+       pic16_pc_kzero.r = pic16_allocInternalRegister(IDX_KZ,"KZ",PO_GPR_REGISTER,0);
+       pic16_pc_ssave.r = pic16_allocInternalRegister(IDX_SSAVE,"SSAVE", PO_GPR_REGISTER, 0x80);
+       pic16_pc_wsave.r = pic16_allocInternalRegister(IDX_WSAVE,"WSAVE", PO_GPR_REGISTER, 0);
+       
+       pic16_pc_kzero.rIdx = IDX_KZ;
+       pic16_pc_wsave.rIdx = IDX_WSAVE;
+       pic16_pc_ssave.rIdx = IDX_SSAVE;
+
+       /* probably should put this in a separate initialization routine */
+       pb_dead_pcodes = newpBlock();
 
 }
 
@@ -2350,7 +2608,7 @@ int mnem2key(char const *mnem)
   return (key & 0x1f);
 
 }
-#endif // OPT_DISABLE_PIC
+#endif
 
 void pic16initMnemonics(void)
 {
@@ -2449,7 +2707,6 @@ void pic16initMnemonics(void)
   pic16Mnemonics[POC_SUBFWB_D1] = &pic16_pciSUBFWB_D1;
   pic16Mnemonics[POC_SWAPF] = &pic16_pciSWAPF;
   pic16Mnemonics[POC_SWAPFW] = &pic16_pciSWAPFW;
-  pic16Mnemonics[POC_TRIS] = &pic16_pciTRIS;
   pic16Mnemonics[POC_TSTFSZ] = &pic16_pciTSTFSZ;
   pic16Mnemonics[POC_XORLW] = &pic16_pciXORLW;
   pic16Mnemonics[POC_XORWF] = &pic16_pciXORWF;
@@ -2484,9 +2741,13 @@ int pic16_getpCode(char *mnem,unsigned dest)
   while(pci) {
 
     if(STRCASECMP(pci->mnemonic, mnem) == 0) {
-      if((pci->num_ops <= 1) || (pci->isModReg == dest) || (pci->isBitInst) ||
-         (pci->num_ops <= 2 && pci->isAccess) ||
-         (pci->num_ops <= 2 && pci->isFastCall))
+      if((pci->num_ops <= 1)
+       || (pci->isModReg == dest)
+       || (pci->isBitInst)
+       || (pci->num_ops <= 2 && pci->isAccess)
+       || (pci->num_ops <= 2 && pci->isFastCall)
+       || (pci->num_ops <= 2 && pci->is2MemOp)
+       || (pci->num_ops <= 2 && pci->is2LitOp) )
        return(pci->op);
     }
 
@@ -2571,6 +2832,14 @@ void pic16_pBlockConvert2ISR(pBlock *pb)
   pb->dbName = 'I';
 }
 
+void pic16_pBlockConvert2Absolute(pBlock *pb)
+{
+       if(!pb)return;
+       if(pb->cmemmap)pb->cmemmap = NULL;
+       
+       pb->dbName = 'A';
+}
+  
 /*-----------------------------------------------------------------*/
 /* pic16_movepBlock2Head - given the dbname of a pBlock, move all  */
 /*                   instances to the front of the doubly linked   */
@@ -2581,6 +2850,11 @@ void pic16_movepBlock2Head(char dbName)
 {
   pBlock *pb;
 
+
+  /* this can happen in sources without code,
+   * only variable definitions */
+  if(!the_pFile)return;
+
   pb = the_pFile->pbHead;
 
   while(pb) {
@@ -2619,15 +2893,16 @@ void pic16_copypCode(FILE *of, char dbName)
 {
   pBlock *pb;
 
-  if(!of || !the_pFile)
-    return;
+       if(!of || !the_pFile)
+               return;
 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-    if(getpBlock_dbName(pb) == dbName) {
-      pBlockStats(of,pb);
-      pic16_printpBlock(of,pb);
-    }
-  }
+       for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+               if(getpBlock_dbName(pb) == dbName) {
+//                     fprintf(stderr, "%s:%d: output of pb= 0x%p\n", __FILE__, __LINE__, pb);
+                       pBlockStats(of,pb);
+                       pic16_printpBlock(of,pb);
+               }
+       }
 
 }
 void pic16_pcode_test(void)
@@ -2644,7 +2919,7 @@ void pic16_pcode_test(void)
     char buffer[100];
 
     /* create the file name */
-    strcpy(buffer,srcFileName);
+    strcpy(buffer,dstFileName);
     strcat(buffer,".p");
 
     if( !(pFile = fopen(buffer, "w" ))) {
@@ -2858,7 +3133,6 @@ pCode *pic16_newpCodeFunction(char *mod,char *f)
   pCodeFunction *pcf;
 
   pcf = Safe_calloc(1,sizeof(pCodeFunction));
-  //_ALLOC(pcf,sizeof(pCodeFunction));
 
   pcf->pc.type = PC_FUNCTION;
   pcf->pc.prev = pcf->pc.next = NULL;
@@ -2872,14 +3146,12 @@ pCode *pic16_newpCodeFunction(char *mod,char *f)
   pcf->ncalled = 0;
 
   if(mod) {
-    //_ALLOC_ATOMIC(pcf->modname,strlen(mod)+1);
     pcf->modname = Safe_calloc(1,strlen(mod)+1);
     strcpy(pcf->modname,mod);
   } else
     pcf->modname = NULL;
 
   if(f) {
-    //_ALLOC_ATOMIC(pcf->fname,strlen(f)+1);
     pcf->fname = Safe_calloc(1,strlen(f)+1);
     strcpy(pcf->fname,f);
   } else
@@ -2961,7 +3233,7 @@ pCodeFlowLink *pic16_newpCodeFlowLink(pCodeFlow *pcflow)
 }
 
 /*-----------------------------------------------------------------*/
-/* pic16_newpCodeCSource - create a new pCode Source Symbol              */
+/* pic16_newpCodeCSource - create a new pCode Source Symbol        */
 /*-----------------------------------------------------------------*/
 
 pCode *pic16_newpCodeCSource(int ln, char *f, char *l)
@@ -2992,6 +3264,51 @@ pCode *pic16_newpCodeCSource(int ln, char *f, char *l)
   return ( (pCode *)pccs);
 
 }
+
+
+/*******************************************************************/
+/* pic16_newpCodeAsmDir - create a new pCode Assembler Directive   */
+/*                     added by VR 6-Jun-2003                     */
+/*******************************************************************/
+
+pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...)
+{
+  pCodeAsmDir *pcad;
+  va_list ap;
+  char buffer[512];
+  char *lbp=buffer;
+  
+       pcad = Safe_calloc(1, sizeof(pCodeAsmDir));
+       pcad->pc.type = PC_ASMDIR;
+       pcad->pc.prev = pcad->pc.next = NULL;
+       pcad->pc.pb = NULL;
+       
+       pcad->pc.destruct = genericDestruct;
+       pcad->pc.print = genericPrint;
+
+       if(asdir && *asdir) {
+               
+               while(isspace(*asdir))asdir++;  // strip any white space from the beginning
+               
+               pcad->directive = Safe_strdup( asdir );
+       }
+       
+       va_start(ap, argfmt);
+       
+       memset(buffer, 0, sizeof(buffer));
+       if(argfmt && *argfmt)
+               vsprintf(buffer, argfmt, ap);
+       
+       va_end(ap);
+       
+       while(isspace(*lbp))lbp++;
+       
+       if(lbp && *lbp)
+               pcad->arg = Safe_strdup( lbp );
+
+  return ((pCode *)pcad);
+}
+
 /*-----------------------------------------------------------------*/
 /* pCodeLabelDestruct - free memory used by a label.               */
 /*-----------------------------------------------------------------*/
@@ -3036,7 +3353,6 @@ pCode *pic16_newpCodeLabel(char *name, int key)
   if(s)
     pcl->label = Safe_strdup(s);
 
-  //fprintf(stderr,"pic16_newpCodeLabel: key=%d, name=%s\n",key, ((s)?s:""));
   return ( (pCode *)pcl);
 
 }
@@ -3141,31 +3457,58 @@ pCodeOp *pic16_newpCodeOpLit(int lit)
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space)
+pCodeOp *pic16_newpCodeOpLit2(int lit, pCodeOp *arg2)
 {
+  char *s = buffer, tbuf[256], *tb=tbuf;
   pCodeOp *pcop;
 
-  pcop = Safe_calloc(1,sizeof(pCodeOpImmd) );
-  pcop->type = PO_IMMEDIATE;
-  if(name) {
-    regs *r = pic16_dirregWithName(name);
-    pcop->name = Safe_strdup(name);
-    PCOI(pcop)->r = r;
-    if(r) {
-      //fprintf(stderr, " pic16_newpCodeOpImmd reg %s exists\n",name);
-      PCOI(pcop)->rIdx = r->rIdx;
-    } else {
-      //fprintf(stderr, " pic16_newpCodeOpImmd reg %s doesn't exist\n",name);
-      PCOI(pcop)->rIdx = -1;
-    }
-    //fprintf(stderr,"%s %s %d\n",__FUNCTION__,name,offset);
-  } else {
-    pcop->name = NULL;
+
+  tb = pic16_get_op(arg2, NULL, 0);
+  pcop = Safe_calloc(1,sizeof(pCodeOpLit2) );
+  pcop->type = PO_LITERAL;
+
+  pcop->name = NULL;
+  if(lit>=0) {
+    sprintf(s,"0x%02x, %s",lit, tb);
+    if(s)
+      pcop->name = Safe_strdup(s);
   }
 
-  PCOI(pcop)->index = index;
-  PCOI(pcop)->offset = offset;
-  PCOI(pcop)->_const = code_space;
+  ((pCodeOpLit2 *)pcop)->lit = lit;
+  ((pCodeOpLit2 *)pcop)->arg2 = arg2;
+
+  return pcop;
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space)
+{
+  pCodeOp *pcop;
+
+       pcop = Safe_calloc(1,sizeof(pCodeOpImmd) );
+       pcop->type = PO_IMMEDIATE;
+       if(name) {
+               regs *r = pic16_dirregWithName(name);
+               pcop->name = Safe_strdup(name);
+               PCOI(pcop)->r = r;
+               
+               if(r) {
+                       fprintf(stderr, "%s:%d %s reg %s exists\n",__FILE__, __LINE__, __FUNCTION__, name);
+                       PCOI(pcop)->rIdx = r->rIdx;
+               } else {
+//                     fprintf(stderr, "%s:%d %s reg %s doesn't exist\n",
+//                             __FILE__, __LINE__, __FUNCTION__, name);
+                       PCOI(pcop)->rIdx = -1;
+               }
+//                     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;
 }
@@ -3242,6 +3585,11 @@ pCodeOp *pic16_newpCodeOpReg(int rIdx)
 
     if(PCOR(pcop)->r)
       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
+    else {
+       fprintf(stderr, "%s:%d Could not find a free GPR register\n",
+               __FUNCTION__, __LINE__);
+       exit(-1);
+    }
   }
 
   pcop->type = PCOR(pcop)->r->pc_type;
@@ -3252,12 +3600,18 @@ pCodeOp *pic16_newpCodeOpReg(int rIdx)
 pCodeOp *pic16_newpCodeOpRegFromStr(char *name)
 {
   pCodeOp *pcop;
+  regs *r;
 
-  pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-  PCOR(pcop)->r = pic16_allocRegByName(name, 1);
-  PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
-  pcop->type = PCOR(pcop)->r->pc_type;
-  pcop->name = PCOR(pcop)->r->name;
+       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+       PCOR(pcop)->r = r = pic16_allocRegByName(name, 1);
+       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
+       pcop->type = PCOR(pcop)->r->pc_type;
+       pcop->name = PCOR(pcop)->r->name;
+
+       if(pic16_pcode_verbose) {
+               fprintf(stderr, "%s:%d %s allocates register %s rIdx:0x%02x\n",
+                       __FILE__, __LINE__, __FUNCTION__, r->name, r->rIdx);
+       }
 
   return pcop;
 }
@@ -3334,6 +3688,7 @@ void pic16_pCodeConstString(char *name, char *value)
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
+#if 0
 static void pCodeReadCodeTable(void)
 {
   pBlock *pb;
@@ -3356,7 +3711,7 @@ static void pCodeReadCodeTable(void)
 
 
 }
-
+#endif
 /*-----------------------------------------------------------------*/
 /* pic16_addpCode2pBlock - place the pCode into the pBlock linked list   */
 /*-----------------------------------------------------------------*/
@@ -3465,15 +3820,36 @@ void pic16_printpBlock(FILE *of, pBlock *pb)
 {
   pCode *pc;
 
-  if(!pb)
-    return;
+       if(!pb)return;
 
-  if(!of)
-    of = stderr;
+       if(!of)of=stderr;
 
-  for(pc = pb->pcHead; pc; pc = pc->next)
-    printpCode(of,pc);
+#if 0
+       if(pb->dbName == 'A') {
+         absSym *ab;
+
+               PCF(pb->pcHead)->
+               for(ab=setFirstItem(absSymSet); ab; ab=setNextItem(absSymSet))
+                       if(strcmp(ab->name, 
+//             fprintf(of, "%s\tcode\t%d"
+       }
+#endif
 
+       for(pc = pb->pcHead; pc; pc = pc->next) {
+               if(isPCF(pc) && PCF(pc)->fname) {
+                       fprintf(of, "S_%s_%s\tcode", PCF(pc)->modname, PCF(pc)->fname);
+                       if(pb->dbName == 'A') {
+                         absSym *ab;
+                               for(ab=setFirstItem(absSymSet); ab; ab=setNextItem(absSymSet))
+                                       if(strcmp(ab->name, PCF(pc)->fname)) {
+                                               fprintf(of, "\t0X%06X", ab->address);
+                                               break;
+                                       }
+                       }
+                       fprintf(of, "\n");
+               }
+               printpCode(of,pc);
+       }
 }
 
 /*-----------------------------------------------------------------*/
@@ -3516,6 +3892,12 @@ static void genericDestruct(pCode *pc)
     regs *reg = pic16_getRegFromInstruction(pc);
     if(reg)
       deleteSetItem (&(reg->reglives.usedpCodes),pc);
+
+       if(PCI(pc)->is2MemOp) {
+               reg = pic16_getRegFromInstruction2(pc);
+               if(reg)
+                       deleteSetItem(&(reg->reglives.usedpCodes), pc);
+       }
   }
 
   /* Instead of deleting the memory used by this pCode, mark
@@ -3533,23 +3915,142 @@ static void genericDestruct(pCode *pc)
 }
 
 
+
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-static void pBlockRegs(FILE *of, pBlock *pb)
+/* modifiers for constant immediate */
+const char *immdmod[3]={"LOW", "HIGH", "UPPER"};
+
+char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size)
 {
+  regs *r;
+  static char b[50];
+  char *s;
+  int use_buffer = 1;    // copy the string to the passed buffer pointer
 
-  regs  *r;
+  if(!buffer) {
+    buffer = b;
+    size = sizeof(b);
+    use_buffer = 0;     // Don't bother copying the string to the buffer.
+  } 
 
-  r = setFirstItem(pb->tregisters);
-  while (r) {
-    r = setNextItem(pb->tregisters);
+  if(pcop) {
+    switch(pcop->type) {
+    case PO_INDF0:
+    case PO_FSR0:
+      if(use_buffer) {
+       SAFE_snprintf(&buffer,&size,"%s",PCOR(pcop)->r->name);
+       return buffer;
+      }
+      return PCOR(pcop)->r->name;
+      break;
+    case PO_GPR_TEMP:
+      r = pic16_regWithIdx(PCOR(pcop)->r->rIdx);
+
+      if(use_buffer) {
+       SAFE_snprintf(&buffer,&size,"%s",r->name);
+       return buffer;
+      }
+
+      return r->name;
+
+
+    case PO_IMMEDIATE:
+       s = buffer;
+
+       if(PCOI(pcop)->offset && PCOI(pcop)->offset<4) {
+               if(PCOI(pcop)->index) {
+                       SAFE_snprintf(&s,&size, "%s(%s + %d)",
+                               immdmod[ PCOI(pcop)->offset ],
+                               pcop->name,
+                               PCOI(pcop)->index);
+               } else {
+                       SAFE_snprintf(&s,&size,"%s(%s)",
+                               immdmod[ PCOI(pcop)->offset ],
+                               pcop->name);
+               }
+       } else {
+               if(PCOI(pcop)->index) {
+                       SAFE_snprintf(&s,&size, "%s(%s + %d)",
+                               immdmod[ 0 ],
+                               pcop->name,
+                               PCOI(pcop)->index);
+               } else {
+                       SAFE_snprintf(&s,&size, "%s(%s)",
+                               immdmod[ 0 ],
+                               pcop->name);
+               }
+       }
+               
+#if 0
+       if(PCOI(pcop)->_const) {
+               if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) {
+                       if(PCOI(pcop)->index) {
+                               SAFE_snprintf(&s,&size,"%s(%s + %d)",
+                                       immdmod[ PCOI(pcop)->offset ],
+                                       pcop->name,
+                                       PCOI(pcop)->index);
+                       } else {
+                               SAFE_snprintf(&s,&size,"%s(%s)",
+                                       immdmod[ PCOI(pcop)->offset ],
+                                       pcop->name);
+                       }
+
+               } else {
+                       if(PCOI(pcop)->index)
+                               SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index);
+                       else
+                               SAFE_snprintf(&s,&size,"LOW(%s)",pcop->name);
+               }
+       } else {
+               if( PCOI(pcop)->index) { // && PCOI(pcc->pcop)->offset<4) 
+                       SAFE_snprintf(&s,&size,"(%s + %d)",
+                               pcop->name,
+                               PCOI(pcop)->index );
+               } 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);
+               }
+       }
+#endif
+
+       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  (pcop->name) {
+       if(use_buffer) {
+         SAFE_snprintf(&buffer,&size,"%s",pcop->name);
+         return buffer;
+       }
+       return pcop->name;
+      }
+
+    }
   }
-}
 
+  return "NO operand";
+
+}
 
 /*-----------------------------------------------------------------*/
+/* pic16_get_op2 - variant to support two memory operand commands  */
 /*-----------------------------------------------------------------*/
-char *pic16_get_op(pCodeOp *pcop,char *buffer, int size)
+char *pic16_get_op2(pCodeOp *pcop,char *buffer, size_t size)
 {
   regs *r;
   static char b[50];
@@ -3562,18 +4063,24 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, int size)
     use_buffer = 0;     // Don't bother copying the string to the buffer.
   } 
 
+#if 0
+       fprintf(stderr, "%s:%d second operand %s is %d\tPO_DIR(%d) PO_GPR_TEMP(%d) PO_IMMEDIATE(%d) PO_INDF0(%d) PO_FSR0(%d)\n",
+               __FUNCTION__, __LINE__, PCOR(PCOR2(pcop)->pcop2)->r->name, PCOR2(pcop)->pcop2->type,
+               PO_DIR, PO_GPR_TEMP, PO_IMMEDIATE, PO_INDF0, PO_FSR0);
+#endif
+
   if(pcop) {
-    switch(pcop->type) {
+    switch(PCOR2(pcop)->pcop2->type) {
     case PO_INDF0:
     case PO_FSR0:
       if(use_buffer) {
-       SAFE_snprintf(&buffer,&size,"%s",PCOR(pcop)->r->name);
+       SAFE_snprintf(&buffer,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name);
        return buffer;
       }
-      return PCOR(pcop)->r->name;
+      return PCOR(PCOR2(pcop)->pcop2)->r->name;
       break;
     case PO_GPR_TEMP:
-      r = pic16_regWithIdx(PCOR(pcop)->r->rIdx);
+      r = pic16_regWithIdx(PCOR(PCOR2(pcop)->pcop2)->r->rIdx);
 
       if(use_buffer) {
        SAFE_snprintf(&buffer,&size,"%s",r->name);
@@ -3584,6 +4091,8 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, int size)
 
 
     case PO_IMMEDIATE:
+       break;
+#if 0
       s = buffer;
 
       if(PCOI(pcop)->_const) {
@@ -3610,28 +4119,33 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, int size)
       }
 
       return buffer;
+#endif
 
     case PO_DIR:
       s = buffer;
       //size = sizeof(buffer);
-      if( PCOR(pcop)->instance) {
-       SAFE_snprintf(&s,&size,"(%s + %d)",
-                     pcop->name,
-                     PCOR(pcop)->instance );
+      if( PCOR(PCOR2(pcop)->pcop2)->instance) {
+               SAFE_snprintf(&s,&size,"(%s + %d)",
+                       PCOR(PCOR2(pcop)->pcop2)->r->name,
+                       PCOR(PCOR2(pcop)->pcop2)->instance );
+       }
        //fprintf(stderr,"PO_DIR %s\n",buffer);
-      } else
-       SAFE_snprintf(&s,&size,"%s",pcop->name);
+       else
+       SAFE_snprintf(&s,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name);
       return buffer;
 
     default:
-      if  (pcop->name) {
+#if 0
+      if  (PCOR2(pcop)->r1->name) {
        if(use_buffer) {
-         SAFE_snprintf(&buffer,&size,"%s",pcop->name);
+         SAFE_snprintf(&buffer,&size,"%s",PCOR2(pcop)->r1->name);
          return buffer;
        }
-       return pcop->name;
+       return PCOR2(pcop)->r1->name;
       }
-
+#else
+      break;
+#endif
     }
   }
 
@@ -3646,8 +4160,11 @@ static char *pic16_get_op_from_instruction( pCodeInstruction *pcc)
 
   if(pcc )
     return pic16_get_op(pcc->pcop,NULL,0);
-  
-  return ("ERROR Null: "__FUNCTION__);
+
+  /* gcc 3.2:  warning: concatenation of string literals with __FUNCTION__ is deprecated 
+   *   return ("ERROR Null: "__FUNCTION__);
+   */
+  return ("ERROR Null: pic16_get_op_from_instruction");
 
 }
 
@@ -3660,19 +4177,40 @@ static void pCodeOpPrint(FILE *of, pCodeOp *pcop)
 }
 
 /*-----------------------------------------------------------------*/
+/* pic16_pCode2str - convert a pCode instruction to string               */
 /*-----------------------------------------------------------------*/
-static char *pCode2str(char *str, int size, pCode *pc)
+static char *pic16_pCode2str(char *str, size_t size, pCode *pc)
 {
   char *s = str;
+  regs *r;
+
+#if 0
+       if(isPCI(pc) && (PCI(pc)->pci_magic != PCI_MAGIC)) {
+               fprintf(stderr, "%s:%d: pCodeInstruction initialization error in instruction %s, magic is %x (defaut: %x)\n",
+                       __FILE__, __LINE__, PCI(pc)->mnemonic, PCI(pc)->pci_magic, PCI_MAGIC);
+               exit(-1);
+       }
+#endif
 
   switch(pc->type) {
 
   case PC_OPCODE:
-
     SAFE_snprintf(&s,&size, "\t%s\t", PCI(pc)->mnemonic);
 
     if( (PCI(pc)->num_ops >= 1) && (PCI(pc)->pcop)) {
 
+       if(PCI(pc)->is2MemOp) {
+               SAFE_snprintf(&s,&size, "%s, %s", 
+               pic16_get_op(PCOP(PCI(pc)->pcop), NULL, 0),
+               pic16_get_op2(PCOP(PCI(pc)->pcop), NULL, 0));
+               break;
+       }
+
+       if(PCI(pc)->is2LitOp) {
+               SAFE_snprintf(&s,&size, "%s", PCOP(PCI(pc)->pcop)->name);
+               break;
+       }
+
       if(PCI(pc)->isBitInst) {
        if(PCI(pc)->pcop->type == PO_GPR_BIT) {
          if( (((pCodeOpRegBit *)(PCI(pc)->pcop))->inBitSpace) )
@@ -3698,8 +4236,16 @@ static char *pCode2str(char *str, int size, pCode *pc)
        }else {
          SAFE_snprintf(&s,&size,"%s",pic16_get_op_from_instruction(PCI(pc)));
 
-         if( PCI(pc)->num_ops == 3)
-           SAFE_snprintf(&s,&size,",%c", ( (PCI(pc)->isModReg) ? 'F':'W'));
+               if( PCI(pc)->num_ops == 3 || ((PCI(pc)->num_ops == 2) && (PCI(pc)->isAccess))) {
+                       if(PCI(pc)->num_ops == 3)
+                               SAFE_snprintf(&s,&size,", %c", ( (PCI(pc)->isModReg) ? 'F':'W'));
+
+                       r = pic16_getRegFromInstruction(pc);
+//                     fprintf(stderr, "%s:%d reg = %p\tname= %s, accessBank= %d\n",
+//                                     __FUNCTION__, __LINE__, r, (r)?r->name:"<null>", (r)?r->accessBank:-1);
+
+                       if(r && !r->accessBank)SAFE_snprintf(&s,&size,", %s", "B");
+         }
        }
       }
 
@@ -3729,8 +4275,11 @@ static char *pCode2str(char *str, int size, pCode *pc)
     SAFE_snprintf(&s,&size,";\t--FLOW change\n");
     break;
   case PC_CSOURCE:
-    SAFE_snprintf(&s,&size,";#CSRC\t%s %d\n; %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
+    SAFE_snprintf(&s,&size,";#CSRC\t%s %d\t%s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
     break;
+  case PC_ASMDIR:
+       SAFE_snprintf(&s,&size,"\t%s\t%s\n", PCAD(pc)->directive, PCAD(pc)->arg?PCAD(pc)->arg:"");
+       break;
 
   case PC_BAD:
     SAFE_snprintf(&s,&size,";A bad pCode is being used\n");
@@ -3775,7 +4324,7 @@ static void genericPrint(FILE *of, pCode *pc)
     {
       char str[256];
       
-      pCode2str(str, 256, pc);
+      pic16_pCode2str(str, 256, pc);
 
       fprintf(of,"%s",str);
 
@@ -3783,37 +4332,12 @@ static void genericPrint(FILE *of, pCode *pc)
       if(pic16_debug_verbose) {
        fprintf(of, "\t;key=%03x",pc->seq);
        if(PCI(pc)->pcflow)
-         fprintf(of,",flow seq=%03x",PCI(pc)->pcflow->pc.seq);
-      }
-    }
-#if 0
-    {
-      pBranch *dpb = pc->to;   // debug
-      while(dpb) {
-       switch ( dpb->pc->type) {
-       case PC_OPCODE:
-         fprintf(of, "\t;%s", PCI(dpb->pc)->mnemonic);
-         break;
-       case PC_LABEL:
-         fprintf(of, "\t;label %d", PCL(dpb->pc)->key);
-         break;
-       case PC_FUNCTION:
-         fprintf(of, "\t;function %s", ( (PCF(dpb->pc)->fname) ? (PCF(dpb->pc)->fname) : "[END]"));
-         break;
-       case PC_FLOW:
-         fprintf(of, "\t;flow");
-         break;
-       case PC_COMMENT:
-       case PC_WILD:
-         break;
-       }
-       dpb = dpb->next;
+         fprintf(of,", flow seq=%03x",PCI(pc)->pcflow->pc.seq);
       }
     }
-#endif
-    fprintf(of,"\n");
+    fprintf(of, "\n");
     break;
-
+      
   case PC_WILD:
     fprintf(of,";\tWild opcode: id=%d\n",PCW(pc)->id);
     if(PCW(pc)->pci.label)
@@ -3836,8 +4360,20 @@ static void genericPrint(FILE *of, pCode *pc)
     break;
 
   case PC_CSOURCE:
-    fprintf(of,";#CSRC\t%s %d\n;  %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
+    fprintf(of,";#CSRC\t%s %d\t\t%s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
     break;
+  case PC_ASMDIR:
+       {
+         pBranch *pbl = PCAD(pc)->label;
+               while(pbl && pbl->pc) {
+                       if(pbl->pc->type == PC_LABEL)
+                               pCodePrintLabel(of, pbl->pc);
+                       pbl = pbl->next;
+               }
+       }
+       fprintf(of, "\t%s\t%s\n", PCAD(pc)->directive, PCAD(pc)->arg?PCAD(pc)->arg:"");
+       break;
+       
   case PC_LABEL:
   default:
     fprintf(of,"unknown pCode type %d\n",pc->type);
@@ -3855,27 +4391,42 @@ static void pCodePrintFunction(FILE *of, pCode *pc)
   if(!pc || !of)
     return;
 
+#if 0
   if( ((pCodeFunction *)pc)->modname) 
     fprintf(of,"F_%s",((pCodeFunction *)pc)->modname);
+#endif
 
   if(PCF(pc)->fname) {
     pBranch *exits = PCF(pc)->to;
     int i=0;
-    fprintf(of,"%s\t;Function start\n",PCF(pc)->fname);
+    fprintf(of,"%s", PCF(pc)->fname);
+    
+//     if(pic16_pcode_verbose)
+               fprintf(of, "\t;Function start");
+    
+    fprintf(of, "\n");
+    
     while(exits) {
       i++;
       exits = exits->next;
     }
     //if(i) i--;
-    fprintf(of,"; %d exit point%c\n",i, ((i==1) ? ' ':'s'));
+
+       if(pic16_pcode_verbose)
+               fprintf(of,"; %d exit point%c\n",i, ((i==1) ? ' ':'s'));
     
-  }else {
-    if((PCF(pc)->from && 
-       PCF(pc)->from->pc->type == PC_FUNCTION &&
-       PCF(PCF(pc)->from->pc)->fname) )
-      fprintf(of,"; exit point of %s\n",PCF(PCF(pc)->from->pc)->fname);
-    else
-      fprintf(of,"; exit point [can't find entry point]\n");
+  } else {
+       if((PCF(pc)->from && 
+               PCF(pc)->from->pc->type == PC_FUNCTION &&
+               PCF(PCF(pc)->from->pc)->fname) ) {
+
+               if(pic16_pcode_verbose)
+                       fprintf(of,"; exit point of %s\n",PCF(PCF(pc)->from->pc)->fname);
+       } else {
+               if(pic16_pcode_verbose)
+                       fprintf(of,"; exit point [can't find entry point]\n");
+       }
+       fprintf(of, "\n");
   }
 }
 /*-----------------------------------------------------------------*/
@@ -3889,7 +4440,7 @@ static void pCodePrintLabel(FILE *of, pCode *pc)
     return;
 
   if(PCL(pc)->label) 
-    fprintf(of,"%s\n",PCL(pc)->label);
+    fprintf(of,"%s:\n",PCL(pc)->label);
   else if (PCL(pc)->key >=0) 
     fprintf(of,"_%05d_DS_:\n",PCL(pc)->key);
   else
@@ -4151,7 +4702,7 @@ static pCode * findLabelinpBlock(pBlock *pb,pCodeOpLabel *pcop_label)
     
   return NULL;
 }
-
+#if 0
 /*-----------------------------------------------------------------*/
 /* findLabel - Search the pCode for a particular label             */
 /*-----------------------------------------------------------------*/
@@ -4171,7 +4722,7 @@ static pCode * findLabel(pCodeOpLabel *pcop_label)
   fprintf(stderr,"Couldn't find label %s", pcop_label->pcop.name);
   return NULL;
 }
-
+#endif
 /*-----------------------------------------------------------------*/
 /* pic16_findNextpCode - given a pCode, find the next of type 'pct'      */
 /*                 in the linked list                              */
@@ -4236,7 +4787,7 @@ pCode * pic16_findPrevInstruction(pCode *pci)
 {
   return findPrevpCode(pci, PC_OPCODE);
 }
-
+#if 0
 /*-----------------------------------------------------------------*/
 /* findFunctionEnd - given a pCode find the end of the function    */
 /*                   that contains it                              */
@@ -4254,7 +4805,7 @@ static pCode * findFunctionEnd(pCode *pc)
   fprintf(stderr,"Couldn't find function end\n");
   return NULL;
 }
-
+#endif
 #if 0
 /*-----------------------------------------------------------------*/
 /* AnalyzeLabel - if the pCode is a label, then merge it with the  */
@@ -4314,7 +4865,7 @@ regs * pic16_getRegFromInstruction(pCode *pc)
 
   case PO_BIT:
   case PO_GPR_TEMP:
-    //fprintf(stderr, "pic16_getRegFromInstruction - bit or temp\n");
+//     fprintf(stderr, "pic16_getRegFromInstruction - bit or temp\n");
     return PCOR(PCI(pc)->pcop)->r;
 
   case PO_IMMEDIATE:
@@ -4329,7 +4880,7 @@ regs * pic16_getRegFromInstruction(pCode *pc)
     return PCOR(PCI(pc)->pcop)->r;
 
   case PO_DIR:
-    //fprintf(stderr, "pic16_getRegFromInstruction - dir\n");
+//     fprintf(stderr, "pic16_getRegFromInstruction - dir\n");
     return PCOR(PCI(pc)->pcop)->r;
   case PO_LITERAL:
     //fprintf(stderr, "pic16_getRegFromInstruction - literal\n");
@@ -4345,10 +4896,77 @@ regs * pic16_getRegFromInstruction(pCode *pc)
 
 }
 
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-
-static void AnalyzepBlock(pBlock *pb)
+/*-------------------------------------------------------------------------------*/
+/* pic16_getRegFromInstruction2 - variant to support two memory operand commands */
+/*-------------------------------------------------------------------------------*/
+regs * pic16_getRegFromInstruction2(pCode *pc)
+{
+
+  if(!pc                   || 
+     !isPCI(pc)            ||
+     !PCI(pc)->pcop        ||
+     PCI(pc)->num_ops == 0 ||
+     (PCI(pc)->num_ops == 1))          // accept only 2 operand commands
+    return NULL;
+
+
+/*
+ * operands supported in MOVFF:
+ *  PO_INF0/PO_FSR0
+ *  PO_GPR_TEMP
+ *  PO_IMMEDIATE
+ *  PO_DIR
+ *
+ */
+  switch(PCI(pc)->pcop->type) {
+  case PO_INDF0:
+  case PO_FSR0:
+    return PCOR(PCOR2(PCI(pc)->pcop)->pcop2)->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");
+    return PCOR(PCOR2(PCI(pc)->pcop)->pcop2)->r;
+
+  case PO_IMMEDIATE:
+       break;
+#if 0
+    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;
+#endif
+
+  case PO_GPR_BIT:
+       break;
+//    return PCOR2(PCI(pc)->pcop)->r;
+
+  case PO_DIR:
+    //fprintf(stderr, "pic16_getRegFromInstruction - dir\n");
+    return PCOR(PCOR2(PCI(pc)->pcop)->pcop2)->r;
+
+  case PO_LITERAL:
+       break;
+    //fprintf(stderr, "pic16_getRegFromInstruction - literal\n");
+
+  default:
+    //fprintf(stderr, "pic16_getRegFromInstruction - unknown reg type %d\n",PCI(pc)->pcop->type);
+    //genericPrint(stderr, pc);
+    break;
+  }
+
+  return NULL;
+
+}
+
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
+
+static void AnalyzepBlock(pBlock *pb)
 {
   pCode *pc;
 
@@ -4557,7 +5175,7 @@ static void unBuildFlow(pBlock *pb)
 
 
 }
-
+#if 0
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 static void dumpCond(int cond)
@@ -4588,7 +5206,9 @@ static void dumpCond(int cond)
       fprintf(stderr, "  %s\n",pcc_str[i]);
 
 }
+#endif
 
+#if 0
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 static void FlowStats(pCodeFlow *pcflow)
@@ -4615,7 +5235,7 @@ static void FlowStats(pCodeFlow *pcflow)
   dumpCond(pcflow->outCond);
 
 }
-
+#endif
 /*-----------------------------------------------------------------*
  * int isBankInstruction(pCode *pc) - examine the pCode *pc to determine
  *    if it affects the banking bits. 
@@ -4756,9 +5376,14 @@ static 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) && (PCI(pc)->op != POC_RETFIE) ) {
-         pc->print(stderr,pc);
-         fprintf(stderr, "ERROR: %s, branch instruction doesn't have label\n",__FUNCTION__);
+       if((PCI(pc)->op != POC_RETLW)
+               && (PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL) && (PCI(pc)->op != POC_RETFIE) ) {
+       
+               /* continue if label is '$' which assembler knows how to parse */
+               if(((PCI(pc)->pcop->type == PO_STR) && !strcmp(PCI(pc)->pcop->name, "$")))continue;
+
+               pc->print(stderr,pc);
+               fprintf(stderr, "ERROR: %s, branch instruction doesn't have label\n",__FUNCTION__);
        }
        continue;
       }
@@ -4812,194 +5437,73 @@ int pic16_isPCinFlow(pCode *pc, pCode *pcflow)
   return 0;
 }
 
-/*-----------------------------------------------------------------*/
-/* BanksUsedFlow - Identify which banks are used in flow 2.        */
-/*-----------------------------------------------------------------*/
-static void BanksUsedFlow2(pCode *pcflow)
-{
-  pCode *pc=NULL;
-
-  int bank = -1;
-  bool RegUsed = 0;
-
-  regs *reg;
-
-  if(!isPCFL(pcflow)) {
-    fprintf(stderr, "BanksUsed - pcflow is not a flow object ");
-    return;
-  }
-
-  pc = pic16_findNextInstruction(pcflow->next);
-
-  PCFL(pcflow)->lastBank = -1;
-
-  while(pic16_isPCinFlow(pc,pcflow)) {
-
-    int bank_selected = isBankInstruction(pc);
-
-    //if(PCI(pc)->pcflow) 
-    //fprintf(stderr,"BanksUsedFlow2, looking at seq %d\n",PCI(pc)->pcflow->pc.seq);
-
-    if(bank_selected >= 0) {
-      //fprintf(stderr,"BanksUsed - mucking with bank %d\n",bank_selected);
-
-      /* This instruction is modifying banking bits before accessing registers */
-      if(!RegUsed)
-       PCFL(pcflow)->firstBank = -1;
-
-      if(PCFL(pcflow)->lastBank == -1)
-       PCFL(pcflow)->lastBank = 0;
-
-      bank = 1 << bank_selected;
-      PCFL(pcflow)->lastBank |= bank;
-                                
-
-    } else { 
-      reg = pic16_getRegFromInstruction(pc);
-
-      if(reg && !pic16_isREGinBank(reg, bank)) {
-       int allbanks = pic16_REGallBanks(reg);
-       if(bank == -1)
-         PCFL(pcflow)->firstBank = allbanks;
-
-       PCFL(pcflow)->lastBank = allbanks;
-
-       bank = allbanks;
-      }
-      RegUsed = 1;
-    }
-
-    pc = pic16_findNextInstruction(pc->next);
-  }
-
-//  fprintf(stderr,"BanksUsedFlow2 flow seq=%3d, first bank = 0x%03x, Last bank 0x%03x\n",
-//       pcflow->seq,PCFL(pcflow)->firstBank,PCFL(pcflow)->lastBank);
-
-
-
-}
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-static void BanksUsedFlow(pBlock *pb)
-{
-  pCode *pcflow;
-
-
-  //pb->pcHead->print(stderr, pb->pcHead);
-
-  pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW);
-  //pcflow->print(stderr,pcflow);
-
-  for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
-       pcflow != NULL;
-       pcflow = pic16_findNextpCode(pcflow->next, PC_FLOW) ) {
 
-    BanksUsedFlow2(pcflow);
-  }
 
-}
 
 
 /*-----------------------------------------------------------------*/
+/* insertBankSwitch - inserts a bank switch statement in the assembly listing */
 /*-----------------------------------------------------------------*/
 static void insertBankSwitch(int position, pCode *pc, int bsr)
 {
   pCode *new_pc;
+  regs *reg;
 
   if(!pc)
     return;
 
-  new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(bsr));
-
-  if(position) {
-    /* insert the bank switch after this pc instruction */
-    pCode *pcnext = pic16_findNextInstruction(pc);
-    pic16_pCodeInsertAfter(pc, new_pc);
-    if(pcnext)
-      pc = pcnext;
-
-  } else
-    pic16_pCodeInsertAfter(pc->prev, new_pc);
-
-  /* Move the label, if there is one */
-
-  if(PCI(pc)->label) {
-    PCI(new_pc)->label = PCI(pc)->label;
-    PCI(pc)->label = NULL;
-  }
-
-  /* The new instruction has the same pcflow block */
-  PCI(new_pc)->pcflow = PCI(pc)->pcflow;
-
-}
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-static void FixRegisterBankingInFlow(pCodeFlow *pcfl, int cur_bank)
-{
-  pCode *pc=NULL;
-  pCode *pcprev=NULL;
-  pCode *new_pc;
-
-  regs *reg;
+/*
+ * if bsr == -1 then do not insert a MOVLB instruction, but rather
+ * insert a BANKSEL assembler directive for the symbol used by
+ * the pCode. This will allow the linker to setup the correct
+ * bank at linking time
+ */
 
-  if(!pcfl)
-    return;
+       if(!pic16_options.gen_banksel || bsr != -1) {
+//             new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(bsr));
+               return;
+       } else {
+               /* emit the BANKSEL [symbol] */
 
-  pc = pic16_findNextInstruction(pcfl->pc.next);
+               /* FIXME */
+               /* IMPORTANT: The following code does not check if a symbol is
+                * split in multiple banks. This should be corrected. - VR 6/6/2003 */
 
-  while(pic16_isPCinFlow(pc,PCODE(pcfl))) {
+               reg = pic16_getRegFromInstruction(pc);
+               if(!reg)return;
+               new_pc = pic16_newpCodeAsmDir("BANKSEL", "%s", reg->name);
+               
+               position = 0;           // position is always before (sanity check!)
+       }
 
-    reg = pic16_getRegFromInstruction(pc);
 #if 0
-    if(reg) {
-      fprintf(stderr, "  %s  ",reg->name);
-      fprintf(stderr, "addr = 0x%03x, bank = %d\n",reg->address,REG_BANK(reg));
-
-    }
+       fprintf(stderr, "%s:%d: inserting bank switch\tbank = %d\n", __FUNCTION__, __LINE__, bsr);
+       pc->print(stderr, pc);
 #endif
 
-    if( ( (reg && !isACCESS_BANK(reg) && REG_BANK(reg)!=cur_bank) || 
-         ((PCI(pc)->op == POC_CALL) && (cur_bank != 0) ) ) &&
-       (!isPCI_LIT(pc)) ){
+       if(position) {
+               /* insert the bank switch after this pc instruction */
+               pCode *pcnext = pic16_findNextInstruction(pc);
+               pic16_pCodeInsertAfter(pc, new_pc);
+               if(pcnext)
+                       pc = pcnext;
 
-      /* 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 reg_bank;
+       } else
+               pic16_pCodeInsertAfter(pc->prev, new_pc);
 
-       reg_bank =  (reg) ? REG_BANK(reg) : 0;
+  /* Move the label, if there is one */
 
-       
-        if (cur_bank != reg_bank) {
-         //fprintf(stderr, "Cool! can switch banks\n");
-         cur_bank = reg_bank;
-         insertBankSwitch(0, pc, cur_bank);
+       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)->label = PCI(pc)->label;
+               PCI(pc)->label = NULL;
        }
 
-      } else {
-       //fprintf(stderr, "Bummer can't switch banks\n");
-       ;
-      }
-    }
-
-    pcprev = pc;
-    pc = pic16_findNextInstruction(pc->next);
-
-  }
-
-  if(pcprev && cur_bank) {
-    /* Brute force - make sure that we point to bank 0 at the
-     * end of each flow block */
-    new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(0));
-    pic16_pCodeInsertAfter(pcprev, new_pc);
-      cur_bank = 0;
-    //fprintf(stderr, "Brute force switch\n");
-  }
-
+//  fprintf(stderr, "BankSwitch has been inserted\n");
 }
 
+
 /*-----------------------------------------------------------------*/
 /*int compareBankFlow - compare the banking requirements between   */
 /*  flow objects. */
@@ -5050,154 +5554,8 @@ static int compareBankFlow(pCodeFlow *pcflow, pCodeFlowLink *pcflowLink, int toO
   return 1;
 
 }
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-static void FixBankFlow(pBlock *pb)
-{
-  pCode *pc=NULL;
-  pCode *pcflow;
-  pCodeFlowLink *pcfl;
-
-  pCode *pcflow_max_To=NULL;
-  pCode *pcflow_max_From=NULL;
-  int max_ToConflicts=0;
-  int max_FromConflicts=0;
-
-  //fprintf(stderr,"Fix Bank flow \n");
-  pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW);
-
-
-  /*
-    First loop through all of the flow objects in this pcode block
-    and fix the ones that have banking conflicts between the 
-    entry and exit.
-  */
-
-  //fprintf(stderr, "FixBankFlow - Phase 1\n");
-
-  for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
-       pcflow != NULL;
-       pcflow = pic16_findNextpCode(pcflow->next, PC_FLOW) ) {
-
-    if(!isPCFL(pcflow)) {
-      fprintf(stderr, "FixBankFlow - pcflow is not a flow object ");
-      continue;
-    }
-
-    if(PCFL(pcflow)->firstBank != PCFL(pcflow)->lastBank  &&
-       PCFL(pcflow)->firstBank >= 0 &&
-       PCFL(pcflow)->lastBank >= 0 ) {
-
-      int cur_bank = (PCFL(pcflow)->firstBank < PCFL(pcflow)->lastBank) ?
-       PCFL(pcflow)->firstBank : PCFL(pcflow)->lastBank;
-
-      FixRegisterBankingInFlow(PCFL(pcflow),cur_bank);
-      BanksUsedFlow2(pcflow);
-
-    }
-  }
-
-  //fprintf(stderr, "FixBankFlow - Phase 2\n");
-
-  for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
-       pcflow != NULL;
-       pcflow = pic16_findNextpCode(pcflow->next, PC_FLOW) ) {
-
-    int nFlows;
-    int nConflicts;
-
-    if(!isPCFL(pcflow)) {
-      fprintf(stderr, "FixBankFlow - pcflow is not a flow object ");
-      continue;
-    }
-
-    PCFL(pcflow)->FromConflicts = 0;
-    PCFL(pcflow)->ToConflicts = 0;
-
-    nFlows = 0;
-    nConflicts = 0;
-
-    //fprintf(stderr, " FixBankFlow flow seq %d\n",pcflow->seq);
-    pcfl = setFirstItem(PCFL(pcflow)->from);
-    while (pcfl) {
-
-      pc = PCODE(pcfl->pcflow);
-
-      if(!isPCFL(pc)) {
-       fprintf(stderr,"oops dumpflow - to is not a pcflow\n");
-       pc->print(stderr,pc);
-      }
-
-      nConflicts += compareBankFlow(PCFL(pcflow), pcfl, 0);
-      nFlows++;
-
-      pcfl=setNextItem(PCFL(pcflow)->from);
-    }
-
-    if((nFlows >= 2) && nConflicts && (PCFL(pcflow)->firstBank>0)) {
-      //fprintf(stderr, " From conflicts flow seq %d, nflows %d ,nconflicts %d\n",pcflow->seq,nFlows, nConflicts);
-
-      FixRegisterBankingInFlow(PCFL(pcflow),0);
-      BanksUsedFlow2(pcflow);
-
-      continue;  /* Don't need to check the flow from here - it's already been fixed */
-
-    }
-
-    nFlows = 0;
-    nConflicts = 0;
-
-    pcfl = setFirstItem(PCFL(pcflow)->to);
-    while (pcfl) {
-
-      pc = PCODE(pcfl->pcflow);
-      if(!isPCFL(pc)) {
-       fprintf(stderr,"oops dumpflow - to is not a pcflow\n");
-       pc->print(stderr,pc);
-      }
-
-      nConflicts += compareBankFlow(PCFL(pcflow), pcfl, 1);
-      nFlows++;
-
-      pcfl=setNextItem(PCFL(pcflow)->to);
-    }
-
-    if((nFlows >= 2) && nConflicts &&(nConflicts != nFlows) && (PCFL(pcflow)->lastBank>0)) {
-      //fprintf(stderr, " To conflicts flow seq %d, nflows %d ,nconflicts %d\n",pcflow->seq,nFlows, nConflicts);
-
-      FixRegisterBankingInFlow(PCFL(pcflow),0);
-      BanksUsedFlow2(pcflow);
-    }
-  }
-
-  /*
-    Loop through the flow objects again and find the ones with the 
-    maximum conflicts
-  */
-
-  for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
-       pcflow != NULL;
-       pcflow = pic16_findNextpCode(pcflow->next, PC_FLOW) ) {
-
-    if(PCFL(pcflow)->ToConflicts > max_ToConflicts)
-      pcflow_max_To = pcflow;
-
-    if(PCFL(pcflow)->FromConflicts > max_FromConflicts)
-      pcflow_max_From = pcflow;
-  }
-/*
-  if(pcflow_max_To)
-    fprintf(stderr,"compare flow Max To conflicts: seq %d conflicts %d\n",
-           PCFL(pcflow_max_To)->pc.seq,
-           PCFL(pcflow_max_To)->ToConflicts);
-
-  if(pcflow_max_From)
-    fprintf(stderr,"compare flow Max From conflicts: seq %d conflicts %d\n",
-           PCFL(pcflow_max_From)->pc.seq,
-           PCFL(pcflow_max_From)->FromConflicts);
-*/
-}
 
+#if 0
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 static void DumpFlow(pBlock *pb)
@@ -5252,7 +5610,7 @@ static void DumpFlow(pBlock *pb)
   }
 
 }
-
+#endif
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
 static int OptimizepBlock(pBlock *pb)
@@ -5452,14 +5810,15 @@ void pic16_pBlockMergeLabels(pBlock *pb)
 
     if(pc->type == PC_LABEL) {
 
-      //fprintf(stderr," checking merging label %s\n",PCL(pc)->label);
-      //fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key);
+//     fprintf(stderr," checking merging label %s\n",PCL(pc)->label);
+//     fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key);
+
       if((pcnext = pic16_findNextInstruction(pc) )) {
 
        // Unlink the pCode label from it's pCode chain
        pic16_unlinkpCode(pc);
        
-       //fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key);
+//     fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key);
        // And link it into the instruction's pBranch labels. (Note, since
        // it's possible to have multiple labels associated with one instruction
        // we must provide a means to accomodate the additional labels. Thus
@@ -5467,12 +5826,13 @@ void pic16_pBlockMergeLabels(pBlock *pb)
        // opposed to being a single member of the pCodeInstruction.)
 
        //_ALLOC(pbr,sizeof(pBranch));
+#if 1
        pbr = Safe_calloc(1,sizeof(pBranch));
        pbr->pc = pc;
        pbr->next = NULL;
 
        PCI(pcnext)->label = pic16_pBranchAppend(PCI(pcnext)->label,pbr);
-
+#endif
       } else {
        fprintf(stderr, "WARNING: couldn't associate label %s with an instruction\n",PCL(pc)->label);
       }
@@ -5536,104 +5896,94 @@ pCodeOp *pic16_popCopyGPR2Bit(pCodeOp *pc, int bitval)
         (pcop->type == PO_LITERAL) ||
         (pcop->type == PO_STR) ))
     PCOR(pcop)->r = PCOR(pc)->r;  /* This is dangerous... */
+    PCOR(pcop)->r->wasUsed = 1;
 
   return pcop;
 }
 
 
-
-#if 0
-/*-----------------------------------------------------------------*/
-/*-----------------------------------------------------------------*/
-int InstructionRegBank(pCode *pc)
+/*----------------------------------------------------------------------*
+ * pic16_areRegsSame - check to see if the names of two registers match *
+ *----------------------------------------------------------------------*/
+int pic16_areRegsSame(regs *r1, regs *r2)
 {
-  regs *reg;
-
-  if( (reg = pic16_getRegFromInstruction(pc)) == NULL)
-    return -1;
-
-  return REG_BANK(reg);
+       if(!strcmp(r1->name, r2->name))return 1;
 
+  return 0;
 }
-#endif
+
 
 /*-----------------------------------------------------------------*/
 /*-----------------------------------------------------------------*/
-static void FixRegisterBanking(pBlock *pb)
+static void pic16_FixRegisterBanking(pBlock *pb)
 {
   pCode *pc=NULL;
   pCode *pcprev=NULL;
+  regs *reg, *prevreg;
 
-  int cur_bank;
-  regs *reg;
+       if(!pb)
+               return;
 
-  if(!pb)
-    return;
+       pc = pic16_findNextpCode(pb->pcHead, PC_OPCODE);
+       if(!pc)
+               return;
 
-  //pc = pic16_findNextpCode(pb->pcHead, PC_FLOW);
-  pc = pic16_findNextpCode(pb->pcHead, PC_OPCODE);
-  if(!pc)
-    return;
-  /* loop through all of the flow blocks with in one pblock */
+       /* loop through all of the flow blocks with in one pblock */
 
-  //fprintf(stderr,"Register banking\n");
-  cur_bank = 0;
+//     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 */
 
-    //    do {
-      if(isPCI(pc)) {
-       //genericPrint(stderr, pc);
+      if(isPCI(pc) && !PCI(pc)->is2MemOp) {
+               reg = pic16_getRegFromInstruction(pc);
 
-       reg = pic16_getRegFromInstruction(pc);
 #if 0
-       if(reg) {
-         fprintf(stderr, "  %s  ",reg->name);
-         fprintf(stderr, "addr = 0x%03x, bank = %d, bit=%d\n",
-                 reg->address,REG_BANK(reg),reg->isBitField);
-
-       }
+               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);
+               }
 #endif
 
-       if( ( (reg && !isACCESS_BANK(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 reg_bank;
-
-           reg_bank =  (reg) ? REG_BANK(reg) : 0;
-         
-            if (cur_bank != reg_bank) {
-             cur_bank = reg_bank;
-             insertBankSwitch(0, pc, cur_bank);
-           }
-
-         }else {
-           //fprintf(stderr, "Bummer can't switch banks\n");
-           ;
-         }
-       }
+               /* we can be 99% that within a pBlock, between two consequtive
+                * refernces to the same register, the extra banksel is needless */
+
+               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;
+                               insertBankSwitch(0, pc, (pic16_options.gen_banksel)?-1:0);
+                       }
+               }
 
        pcprev = pc;
 
       }
 
       pc = pc->next;
-      // } while(pc && !(isPCFL(pc))); 
-
-
   }while (pc);
 
+#if 0
   if(pcprev && cur_bank) {
 
     int pos = 1;  /* Assume that the bank switch instruction(s)
@@ -5652,7 +6002,7 @@ static void FixRegisterBanking(pBlock *pb)
     /* Brute force - make sure that we point to bank 0 at the
      * end of each flow block */
 
-    insertBankSwitch(pos, pcprev, 0);
+//    insertBankSwitch(pos, pcprev, 0);
 /*
     new_pc = pic16_newpCode(POC_MOVLB, pic16_newpCodeOpLit(0));
     pic16_pCodeInsertAfter(pcprev, new_pc);
@@ -5660,45 +6010,9 @@ static void FixRegisterBanking(pBlock *pb)
     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
 
-
+}
 
 
 static void pBlockDestruct(pBlock *pb)
@@ -5767,24 +6081,27 @@ static void mergepBlocks(char dbName)
 static void AnalyzeFlow(int level)
 {
   static int times_called=0;
-
   pBlock *pb;
 
-  if(!the_pFile)
-    return;
+       if(!the_pFile) {
+
+               /* remove unused allocated registers before exiting */
+               pic16_RemoveUnusedRegisters();
+       
+         return;
+       }
 
 
   /* if this is not the first time this function has been called,
      then clean up old flow information */
-  if(times_called++) {
-    for(pb = the_pFile->pbHead; pb; pb = pb->next)
-      unBuildFlow(pb);
-
-    pic16_RegsUnMapLiveRanges();
+       if(times_called++) {
+               for(pb = the_pFile->pbHead; pb; pb = pb->next)
+                       unBuildFlow(pb);
 
-  }
+               pic16_RegsUnMapLiveRanges();
+       }
 
-  GpcFlowSeq = 1;
+       GpcFlowSeq = 1;
 
   /* Phase 2 - Flow Analysis - Register Banking
    *
@@ -5792,8 +6109,10 @@ static void AnalyzeFlow(int level)
    * and register banking is fixed.
    */
 
-  //for(pb = the_pFile->pbHead; pb; pb = pb->next)
-  //FixRegisterBanking(pb);
+#if 0
+       for(pb = the_pFile->pbHead; pb; pb = pb->next)
+               pic16_FixRegisterBanking(pb);
+#endif
 
   /* Phase 2 - Flow Analysis
    *
@@ -5803,8 +6122,8 @@ static void AnalyzeFlow(int level)
    * a call or goto or whatever).
    */
 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-    pic16_BuildFlow(pb);
+       for(pb = the_pFile->pbHead; pb; pb = pb->next)
+               pic16_BuildFlow(pb);
 
 
   /* Phase 2 - Flow Analysis - linking flow blocks
@@ -5813,17 +6132,17 @@ static void AnalyzeFlow(int level)
    * to determine their order of excution.
    */
 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-    LinkFlow(pb);
+       for(pb = the_pFile->pbHead; pb; pb = pb->next)
+               LinkFlow(pb);
 
   /* Phase 3 - Flow Analysis - Flow Tree
    *
    * In this phase, the individual flow blocks are examined
-   * to determine their order of excution.
+   * to determine their order of execution.
    */
 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-    pic16_BuildFlowTree(pb);
+       for(pb = the_pFile->pbHead; pb; pb = pb->next)
+               pic16_BuildFlowTree(pb);
 
 
   /* Phase x - Flow Analysis - Used Banks
@@ -5832,49 +6151,62 @@ static void AnalyzeFlow(int level)
    * to determine the Register Banks they use
    */
 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-    FixBankFlow(pb);
+#if 0
+       for(pb = the_pFile->pbHead; pb; pb = pb->next)
+               FixBankFlow(pb);
+#endif
 
 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-    pic16_pCodeRegMapLiveRanges(pb);
+       for(pb = the_pFile->pbHead; pb; pb = pb->next)
+               pic16_pCodeRegMapLiveRanges(pb);
 
-  pic16_RemoveUnusedRegisters();
+       pic16_RemoveUnusedRegisters();
 
   //  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-  pic16_pCodeRegOptimizeRegUsage(level);
+       pic16_pCodeRegOptimizeRegUsage(level);
 
-  OptimizepCode('*');
 
+       if(!options.nopeep)
+               OptimizepCode('*');
+
+
+#if 0
+       for(pb = the_pFile->pbHead; pb; pb = pb->next)
+               DumpFlow(pb);
+#endif
 
-/*
-  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-    DumpFlow(pb);
-*/
   /* debug stuff */ 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-    pCode *pcflow;
-    for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
-        (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL;
-        pcflow = pcflow->next) {
+       for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+         pCode *pcflow;
+               for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
+                       (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL;
+                       pcflow = pcflow->next) {
+
+                       FillFlow(PCFL(pcflow));
+               }
+       }
 
-      FillFlow(PCFL(pcflow));
-    }
-  }
+#if 0
+       for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+         pCode *pcflow;
 
-/*
-  for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-    pCode *pcflow;
-    for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
-        (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL;
-        pcflow = pcflow->next) {
+               for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
+                       (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL;
+                       pcflow = pcflow->next) {
 
-      FlowStats(PCFL(pcflow));
-    }
-  }
-*/
+                       FlowStats(PCFL(pcflow));
+               }
+       }
+#endif
 }
 
+/* VR -- no need to analyze banking in flow, but left here :
+ *     1. because it may be used in the future for other purposes
+ *     2. because if omitted we'll miss some optimization done here
+ *
+ * Perhaps I should rename it to something else
+ */
+
 /*-----------------------------------------------------------------*/
 /* pic16_AnalyzeBanking - Called after the memory addresses have been    */
 /*                  assigned to the registers.                     */
@@ -5885,28 +6217,36 @@ void pic16_AnalyzeBanking(void)
 {
   pBlock  *pb;
 
-  if(!pic16_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");
+       if(!pic16_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);
-  }
+               /* I think it took a long long time to fix this bug! ;-) -- VR */
 
-  /* Phase x - Flow Analysis - Used Banks
-   *
-   * In this phase, the individual flow blocks are examined
-   * to determine the Register Banks they use
-   */
+               exit(1);
+       }
 
-  AnalyzeFlow(0);
-  AnalyzeFlow(1);
 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-    BanksUsedFlow(pb);
-  for(pb = the_pFile->pbHead; pb; pb = pb->next)
-    FixRegisterBanking(pb);
+       /* Phase x - Flow Analysis - Used Banks
+        *
+        * In this phase, the individual flow blocks are examined
+        * to determine the Register Banks they use
+        */
+
+       AnalyzeFlow(0);
+       AnalyzeFlow(1);
+
+//     for(pb = the_pFile->pbHead; pb; pb = pb->next)
+//             BanksUsedFlow(pb);
+
+       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);
+       }
 
 }
 
@@ -6049,7 +6389,9 @@ void pic16_AnalyzepCode(char dbName)
       }
     }
 
-    changes = OptimizepCode(dbName);
+       if(!options.nopeep)
+               changes = OptimizepCode(dbName);
+       else changes = 0;
 
   } while(changes && (i++ < MAX_PASSES));
 
@@ -6106,7 +6448,9 @@ static void MarkUsedRegisters(set *regset)
   regs *r1,*r2;
 
   for(r1=setFirstItem(regset); r1; r1=setNextItem(regset)) {
+//     fprintf(stderr, "marking register = %s\t", r1->name);
     r2 = pic16_regWithIdx(r1->rIdx);
+//     fprintf(stderr, "to register = %s\n", r2->name);
     r2->isFree = 0;
     r2->wasUsed = 1;
   }
@@ -6118,6 +6462,8 @@ static void pBlockStats(FILE *of, pBlock *pb)
   pCode *pc;
   regs  *r;
 
+       if(!pic16_pcode_verbose)return;
+       
   fprintf(of,";***\n;  pBlock Stats: dbName = %c\n;***\n",getpBlock_dbName(pb));
 
   // for now just print the first element of each set
@@ -6418,7 +6764,7 @@ static void InlineFunction(pBlock *pb)
 
       pBranch *pbr;
 
-      if(pcn && isPCF(pcn) && (PCF(pcn)->ncalled == 1)) {
+      if(pcn && isPCF(pcn) && (PCF(pcn)->ncalled == 0)) {              /* change 0 to 1 to enable inlining */
        
        //fprintf(stderr,"Cool can inline:\n");
        //pcn->print(stderr,pcn);