Large cummulative patch for pic16 port.
[fw/sdcc] / src / pic16 / pcode.c
1 /*-------------------------------------------------------------------------
2
3   pcode.c - post code generation
4
5    Written By -  Scott Dattalo scott@dattalo.com
6    Ported to PIC16 By -  Martin Dubuc m.dubuc@rogers.com
7
8    This program is free software; you can redistribute it and/or modify it
9    under the terms of the GNU General Public License as published by the
10    Free Software Foundation; either version 2, or (at your option) any
11    later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 -------------------------------------------------------------------------*/
22
23 #include <stdio.h>
24
25 #include "common.h"   // Include everything in the SDCC src directory
26 #include "newalloc.h"
27
28
29 #include "main.h"
30 #include "pcode.h"
31 #include "pcodeflow.h"
32 #include "ralloc.h"
33 #include "device.h"
34
35 #if defined(__BORLANDC__) || defined(_MSC_VER)
36 #define STRCASECMP stricmp
37 #else
38 #define STRCASECMP strcasecmp
39 #endif
40
41 /****************************************************************/
42 /****************************************************************/
43
44 static peepCommand peepCommands[] = {
45
46   {NOTBITSKIP, "_NOTBITSKIP_"},
47   {BITSKIP, "_BITSKIP_"},
48   {INVERTBITSKIP, "_INVERTBITSKIP_"},
49
50   {-1, NULL}
51 };
52
53
54
55 // Eventually this will go into device dependent files:
56 pCodeOpReg pic16_pc_status    = {{PO_STATUS,  "STATUS"}, -1, NULL,0,NULL};
57 pCodeOpReg pic16_pc_intcon    = {{PO_INTCON,  "INTCON"}, -1, NULL,0,NULL};
58 pCodeOpReg pic16_pc_pcl       = {{PO_PCL,     "PCL"}, -1, NULL,0,NULL};
59 pCodeOpReg pic16_pc_pclath    = {{PO_PCLATH,  "PCLATH"}, -1, NULL,0,NULL};
60 pCodeOpReg pic16_pc_pclatu    = {{PO_PCLATU,  "PCLATU"}, -1, NULL,0,NULL}; // patch 14
61 pCodeOpReg pic16_pc_wreg      = {{PO_WREG,    "WREG"}, -1, NULL,0,NULL};
62 pCodeOpReg pic16_pc_bsr       = {{PO_BSR,     "BSR"}, -1, NULL,0,NULL};
63
64 pCodeOpReg pic16_pc_tosl      = {{PO_SFR_REGISTER,   "TOSL"}, -1, NULL,0,NULL}; // patch 14
65 pCodeOpReg pic16_pc_tosh      = {{PO_SFR_REGISTER,   "TOSH"}, -1, NULL,0,NULL}; //
66 pCodeOpReg pic16_pc_tosu      = {{PO_SFR_REGISTER,   "TOSU"}, -1, NULL,0,NULL}; // patch 14
67
68 pCodeOpReg pic16_pc_tblptrl   = {{PO_SFR_REGISTER,   "TBLPTRL"}, -1, NULL,0,NULL}; // patch 15
69 pCodeOpReg pic16_pc_tblptrh   = {{PO_SFR_REGISTER,   "TBLPTRH"}, -1, NULL,0,NULL}; //
70 pCodeOpReg pic16_pc_tblptru   = {{PO_SFR_REGISTER,   "TBLPTRU"}, -1, NULL,0,NULL}; //
71 pCodeOpReg pic16_pc_tablat    = {{PO_SFR_REGISTER,   "TABLAT"}, -1, NULL,0,NULL};  // patch 15
72
73 //pCodeOpReg pic16_pc_fsr0      = {{PO_FSR0,    "FSR0"}, -1, NULL,0,NULL}; //deprecated !
74
75 pCodeOpReg pic16_pc_fsr0l       = {{PO_FSR0,    "FSR0L"}, -1, NULL, 0, NULL};
76 pCodeOpReg pic16_pc_fsr0h       = {{PO_FSR0,    "FSR0H"}, -1, NULL, 0, NULL};
77 pCodeOpReg pic16_pc_fsr1l       = {{PO_FSR0,    "FSR1L"}, -1, NULL, 0, NULL};
78 pCodeOpReg pic16_pc_fsr1h       = {{PO_FSR0,    "FSR1H"}, -1, NULL, 0, NULL};
79 pCodeOpReg pic16_pc_fsr2l       = {{PO_FSR0,    "FSR2L"}, -1, NULL, 0, NULL};
80 pCodeOpReg pic16_pc_fsr2h       = {{PO_FSR0,    "FSR2H"}, -1, NULL, 0, NULL};
81
82 pCodeOpReg pic16_pc_indf0       = {{PO_INDF0,   "INDF0"}, -1, NULL,0,NULL};
83 pCodeOpReg pic16_pc_postinc0    = {{PO_INDF0,   "POSTINC0"}, -1, NULL, 0, NULL};
84 pCodeOpReg pic16_pc_postdec0    = {{PO_INDF0,   "POSTDEC0"}, -1, NULL, 0, NULL};
85 pCodeOpReg pic16_pc_preinc0     = {{PO_INDF0,   "PREINC0"}, -1, NULL, 0, NULL};
86 pCodeOpReg pic16_pc_plusw0      = {{PO_INDF0,   "PLUSW0"}, -1, NULL, 0, NULL};
87
88 pCodeOpReg pic16_pc_indf1       = {{PO_INDF0,   "INDF1"}, -1, NULL,0,NULL};
89 pCodeOpReg pic16_pc_postinc1    = {{PO_INDF0,   "POSTINC1"}, -1, NULL, 0, NULL};
90 pCodeOpReg pic16_pc_postdec1    = {{PO_INDF0,   "POSTDEC1"}, -1, NULL, 0, NULL};
91 pCodeOpReg pic16_pc_preinc1     = {{PO_INDF0,   "PREINC1"}, -1, NULL, 0, NULL};
92 pCodeOpReg pic16_pc_plusw1      = {{PO_INDF0,   "PLUSW1"}, -1, NULL, 0, NULL};
93
94 pCodeOpReg pic16_pc_indf2       = {{PO_INDF0,   "INDF2"}, -1, NULL,0,NULL};
95 pCodeOpReg pic16_pc_postinc2    = {{PO_INDF0,   "POSTINC2"}, -1, NULL, 0, NULL};
96 pCodeOpReg pic16_pc_postdec2    = {{PO_INDF0,   "POSTDEC2"}, -1, NULL, 0, NULL};
97 pCodeOpReg pic16_pc_preinc2     = {{PO_INDF0,   "PREINC2"}, -1, NULL, 0, NULL};
98 pCodeOpReg pic16_pc_plusw2      = {{PO_INDF0,   "PLUSW2"}, -1, NULL, 0, NULL};
99
100 pCodeOpReg pic16_pc_prodl       = {{PO_PRODL, "PRODL"}, -1, NULL, 0, NULL};
101 pCodeOpReg pic16_pc_prodh       = {{PO_PRODH, "PRODH"}, -1, NULL, 0, NULL};
102
103 /* EEPROM registers */
104 pCodeOpReg pic16_pc_eecon1      = {{PO_SFR_REGISTER, "EECON1"}, -1, NULL, 0, NULL};
105 pCodeOpReg pic16_pc_eecon2      = {{PO_SFR_REGISTER, "EECON2"}, -1, NULL, 0, NULL};
106 pCodeOpReg pic16_pc_eedata      = {{PO_SFR_REGISTER, "EEDATA"}, -1, NULL, 0, NULL};
107 pCodeOpReg pic16_pc_eeadr       = {{PO_SFR_REGISTER, "EEADR"}, -1, NULL, 0, NULL};
108
109
110
111 pCodeOpReg pic16_pc_kzero     = {{PO_GPR_REGISTER,  "KZ"}, -1, NULL,0,NULL};
112 pCodeOpReg pic16_pc_wsave     = {{PO_GPR_REGISTER,  "WSAVE"}, -1, NULL,0,NULL};
113 pCodeOpReg pic16_pc_ssave     = {{PO_GPR_REGISTER,  "SSAVE"}, -1, NULL,0,NULL};
114
115 pCodeOpReg pic16_pc_gpsimio   = {{PO_GPR_REGISTER, "GPSIMIO"}, -1, NULL, 0, NULL};
116 pCodeOpReg pic16_pc_gpsimio2  = {{PO_GPR_REGISTER, "GPSIMIO2"}, -1, NULL, 0, NULL};
117
118 char *OPT_TYPE_STR[] = { "begin", "end" };
119 char *LR_TYPE_STR[] = { "entry begin", "entry end", "exit begin", "exit end" };
120
121
122 static int mnemonics_initialized = 0;
123
124
125 static hTab *pic16MnemonicsHash = NULL;
126 static hTab *pic16pCodePeepCommandsHash = NULL;
127
128 static pFile *the_pFile = NULL;
129 static pBlock *pb_dead_pcodes = NULL;
130
131 /* Hardcoded flags to change the behavior of the PIC port */
132 static int peepOptimizing = 1;        /* run the peephole optimizer if nonzero */
133 static int functionInlining = 1;      /* inline functions if nonzero */
134 int pic16_debug_verbose = 0;                /* Set true to inundate .asm file */
135
136 int pic16_pcode_verbose = 0;
137
138 //static int GpCodeSequenceNumber = 1;
139 static int GpcFlowSeq = 1;
140
141 extern void pic16_RemoveUnusedRegisters(void);
142 extern void pic16_RegsUnMapLiveRanges(void);
143 extern void pic16_BuildFlowTree(pBlock *pb);
144 extern void pic16_pCodeRegOptimizeRegUsage(int level);
145 extern int pic16_picIsInitialized(void);
146 extern void SAFE_snprintf(char **str, size_t *size, const char *format, ...);
147 extern int mnem2key(char const *mnem);
148
149 /****************************************************************/
150 /*                      Forward declarations                    */
151 /****************************************************************/
152
153 void pic16_unlinkpCode(pCode *pc);
154 #if 0
155 static void genericAnalyze(pCode *pc);
156 static void AnalyzeGOTO(pCode *pc);
157 static void AnalyzeSKIP(pCode *pc);
158 static void AnalyzeRETURN(pCode *pc);
159 #endif
160
161 static void genericDestruct(pCode *pc);
162 static void genericPrint(FILE *of,pCode *pc);
163
164 static void pCodePrintLabel(FILE *of, pCode *pc);
165 static void pCodePrintFunction(FILE *of, pCode *pc);
166 static void pCodeOpPrint(FILE *of, pCodeOp *pcop);
167 static char *pic16_get_op_from_instruction( pCodeInstruction *pcc);
168 char *pic16_get_op(pCodeOp *pcop,char *buff,size_t buf_size);
169 int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd);
170 int pic16_pCodePeepMatchRule(pCode *pc);
171 static void pBlockStats(FILE *of, pBlock *pb);
172 static pBlock *newpBlock(void);
173 extern void pic16_pCodeInsertAfter(pCode *pc1, pCode *pc2);
174 extern pCodeOp *pic16_popCopyReg(pCodeOpReg *pc);
175 pCodeOp *pic16_popCopyGPR2Bit(pCodeOp *pc, int bitval);
176 void pic16_pCodeRegMapLiveRanges(pBlock *pb);
177 void OptimizeLocalRegs(void);
178 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst);
179
180 char *dumpPicOptype(PIC_OPTYPE type);
181
182 pCodeOp *pic16_popGetLit2(int, pCodeOp *);
183 pCodeOp *pic16_popGetLit(int);
184 pCodeOp *pic16_popGetWithString(char *);
185 extern int inWparamList(char *s);
186
187
188 /****************************************************************/
189 /*                    PIC Instructions                          */
190 /****************************************************************/
191
192 pCodeInstruction pic16_pciADDWF = {
193   {PC_OPCODE, NULL, NULL, 0, NULL, 
194    //   genericAnalyze,
195    genericDestruct,
196    genericPrint},
197   POC_ADDWF,
198   "ADDWF",
199   2,
200   NULL, // from branch
201   NULL, // to branch
202   NULL, // label
203   NULL, // operand
204   NULL, // flow block
205   NULL, // C source 
206   3,    // num ops
207   1,0,  // dest, bit instruction
208   0,0,  // branch, skip
209   0,    // literal operand
210   1,    // RAM access bit
211   0,    // fast call/return mode select bit
212   0,    // second memory operand
213   0,    // second literal operand
214   POC_NOP,
215   (PCC_W | PCC_REGISTER),   // inCond
216   (PCC_REGISTER | PCC_Z), // outCond
217   PCI_MAGIC
218 };
219
220 pCodeInstruction pic16_pciADDFW = {
221   {PC_OPCODE, NULL, NULL, 0, NULL, 
222    //   genericAnalyze,
223    genericDestruct,
224    genericPrint},
225   POC_ADDFW,
226   "ADDWF",
227   2,
228   NULL, // from branch
229   NULL, // to branch
230   NULL, // label
231   NULL, // operand
232   NULL, // flow block
233   NULL, // C source 
234   3,    // num ops
235   0,0,  // dest, bit instruction
236   0,0,  // branch, skip
237   0,    // literal operand
238   1,    // RAM access bit
239   0,    // fast call/return mode select bit
240   0,    // second memory operand
241   0,    // second literal operand
242   POC_NOP,
243   (PCC_W | PCC_REGISTER),   // inCond
244   (PCC_W | PCC_Z), // outCond
245   PCI_MAGIC
246 };
247
248 pCodeInstruction pic16_pciADDWFC = { // mdubuc - New
249   {PC_OPCODE, NULL, NULL, 0, NULL, 
250    //   genericAnalyze,
251    genericDestruct,
252    genericPrint},
253   POC_ADDWFC,
254   "ADDWFC",
255   2,
256   NULL, // from branch
257   NULL, // to branch
258   NULL, // label
259   NULL, // operand
260   NULL, // flow block
261   NULL, // C source 
262   3,    // num ops
263   1,0,  // dest, bit instruction
264   0,0,  // branch, skip
265   0,    // literal operand
266   1,    // RAM access bit
267   0,    // fast call/return mode select bit
268   0,    // second memory operand
269   0,    // second literal operand
270   POC_NOP,
271   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
272   (PCC_REGISTER | PCC_Z), // outCond
273   PCI_MAGIC
274 };
275
276 pCodeInstruction pic16_pciADDFWC = {
277   {PC_OPCODE, NULL, NULL, 0, NULL, 
278    //   genericAnalyze,
279    genericDestruct,
280    genericPrint},
281   POC_ADDFWC,
282   "ADDWFC",
283   2,
284   NULL, // from branch
285   NULL, // to branch
286   NULL, // label
287   NULL, // operand
288   NULL, // flow block
289   NULL, // C source 
290   3,    // num ops
291   0,0,  // dest, bit instruction
292   0,0,  // branch, skip
293   0,    // literal operand
294   1,    // RAM access bit
295   0,    // fast call/return mode select bit
296   0,    // second memory operand
297   0,    // second literal operand
298   POC_NOP,
299   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
300   (PCC_W | PCC_Z), // outCond
301   PCI_MAGIC
302 };
303
304 pCodeInstruction pic16_pciADDLW = {
305   {PC_OPCODE, NULL, NULL, 0, NULL, 
306    //   genericAnalyze,
307    genericDestruct,
308    genericPrint},
309   POC_ADDLW,
310   "ADDLW",
311   2,
312   NULL, // from branch
313   NULL, // to branch
314   NULL, // label
315   NULL, // operand
316   NULL, // flow block
317   NULL, // C source 
318   1,    // num ops
319   0,0,  // dest, bit instruction
320   0,0,  // branch, skip
321   1,    // literal operand
322   0,    // RAM access bit
323   0,    // fast call/return mode select bit
324   0,    // second memory operand
325   0,    // second literal operand
326   POC_NOP,
327   (PCC_W | PCC_LITERAL),   // inCond
328   (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
329   PCI_MAGIC
330 };
331
332 pCodeInstruction pic16_pciANDLW = {
333   {PC_OPCODE, NULL, NULL, 0, NULL, 
334    //   genericAnalyze,
335    genericDestruct,
336    genericPrint},
337   POC_ANDLW,
338   "ANDLW",
339   2,
340   NULL, // from branch
341   NULL, // to branch
342   NULL, // label
343   NULL, // operand
344   NULL, // flow block
345   NULL, // C source 
346   1,    // num ops
347   0,0,  // dest, bit instruction
348   0,0,  // branch, skip
349   1,    // literal operand
350   0,    // RAM access bit
351   0,    // fast call/return mode select bit
352   0,    // second memory operand
353   0,    // second literal operand
354   POC_NOP,
355   (PCC_W | PCC_LITERAL),   // inCond
356   (PCC_W | PCC_Z | PCC_N), // outCond
357   PCI_MAGIC
358 };
359
360 pCodeInstruction pic16_pciANDWF = {
361   {PC_OPCODE, NULL, NULL, 0, NULL, 
362    //   genericAnalyze,
363    genericDestruct,
364    genericPrint},
365   POC_ANDWF,
366   "ANDWF",
367   2,
368   NULL, // from branch
369   NULL, // to branch
370   NULL, // label
371   NULL, // operand
372   NULL, // flow block
373   NULL, // C source 
374   3,    // num ops
375   1,0,  // dest, bit instruction
376   0,0,  // branch, skip
377   0,    // literal operand
378   1,    // RAM access bit
379   0,    // fast call/return mode select bit
380   0,    // second memory operand
381   0,    // second literal operand
382   POC_NOP,
383   (PCC_W | PCC_REGISTER),   // inCond
384   (PCC_REGISTER | PCC_Z | PCC_N), // outCond
385   PCI_MAGIC
386 };
387
388 pCodeInstruction pic16_pciANDFW = {
389   {PC_OPCODE, NULL, NULL, 0, NULL, 
390    //   genericAnalyze,
391    genericDestruct,
392    genericPrint},
393   POC_ANDFW,
394   "ANDWF",
395   2,
396   NULL, // from branch
397   NULL, // to branch
398   NULL, // label
399   NULL, // operand
400   NULL, // flow block
401   NULL, // C source 
402   3,    // num ops
403   0,0,  // dest, bit instruction
404   0,0,  // branch, skip
405   0,    // literal operand
406   1,    // RAM access bit
407   0,    // fast call/return mode select bit
408   0,    // second memory operand
409   0,    // second literal operand
410   POC_NOP,
411   (PCC_W | PCC_REGISTER),   // inCond
412   (PCC_W | PCC_Z) // outCond
413 };
414
415 pCodeInstruction pic16_pciBC = { // mdubuc - New
416   {PC_OPCODE, NULL, NULL, 0, NULL, 
417    //   genericAnalyze,
418    genericDestruct,
419    genericPrint},
420   POC_BC,
421   "BC",
422   2,
423   NULL, // from branch
424   NULL, // to branch
425   NULL, // label
426   NULL, // operand
427   NULL, // flow block
428   NULL, // C source 
429   1,    // num ops
430   0,0,  // dest, bit instruction
431   1,0,  // branch, skip
432   0,    // literal operand
433   0,    // RAM access bit
434   0,    // fast call/return mode select bit
435   0,    // second memory operand
436   0,    // second literal operand
437   POC_NOP,
438   (PCC_REL_ADDR | PCC_C),   // inCond
439   PCC_NONE,    // outCond
440   PCI_MAGIC
441 };
442
443 pCodeInstruction pic16_pciBCF = {
444   {PC_OPCODE, NULL, NULL, 0, NULL, 
445    //   genericAnalyze,
446    genericDestruct,
447    genericPrint},
448   POC_BCF,
449   "BCF",
450   2,
451   NULL, // from branch
452   NULL, // to branch
453   NULL, // label
454   NULL, // operand
455   NULL, // flow block
456   NULL, // C source 
457   3,    // num ops
458   1,1,  // dest, bit instruction
459   0,0,  // branch, skip
460   0,    // literal operand
461   1,    // RAM access bit
462   0,    // fast call/return mode select bit
463   0,    // second memory operand
464   0,    // second literal operand
465   POC_BSF,
466   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
467   PCC_REGISTER, // outCond
468   PCI_MAGIC
469 };
470
471 pCodeInstruction pic16_pciBN = { // mdubuc - New
472   {PC_OPCODE, NULL, NULL, 0, NULL, 
473    //   genericAnalyze,
474    genericDestruct,
475    genericPrint},
476   POC_BN,
477   "BN",
478   2,
479   NULL, // from branch
480   NULL, // to branch
481   NULL, // label
482   NULL, // operand
483   NULL, // flow block
484   NULL, // C source 
485   1,    // num ops
486   0,0,  // dest, bit instruction
487   1,0,  // branch, skip
488   0,    // literal operand
489   0,    // RAM access bit
490   0,    // fast call/return mode select bit
491   0,    // second memory operand
492   0,    // second literal operand
493   POC_NOP,
494   (PCC_REL_ADDR | PCC_N),   // inCond
495   PCC_NONE   , // outCond
496   PCI_MAGIC
497 };
498
499 pCodeInstruction pic16_pciBNC = { // mdubuc - New
500   {PC_OPCODE, NULL, NULL, 0, NULL, 
501    //   genericAnalyze,
502    genericDestruct,
503    genericPrint},
504   POC_BNC,
505   "BNC",
506   2,
507   NULL, // from branch
508   NULL, // to branch
509   NULL, // label
510   NULL, // operand
511   NULL, // flow block
512   NULL, // C source 
513   1,    // num ops
514   0,0,  // dest, bit instruction
515   1,0,  // branch, skip
516   0,    // literal operand
517   0,    // RAM access bit
518   0,    // fast call/return mode select bit
519   0,    // second memory operand
520   0,    // second literal operand
521   POC_NOP,
522   (PCC_REL_ADDR | PCC_C),   // inCond
523   PCC_NONE   , // outCond
524   PCI_MAGIC
525 };
526
527 pCodeInstruction pic16_pciBNN = { // mdubuc - New
528   {PC_OPCODE, NULL, NULL, 0, NULL, 
529    //   genericAnalyze,
530    genericDestruct,
531    genericPrint},
532   POC_BNN,
533   "BNN",
534   2,
535   NULL, // from branch
536   NULL, // to branch
537   NULL, // label
538   NULL, // operand
539   NULL, // flow block
540   NULL, // C source 
541   1,    // num ops
542   0,0,  // dest, bit instruction
543   1,0,  // branch, skip
544   0,    // literal operand
545   0,    // RAM access bit
546   0,    // fast call/return mode select bit
547   0,    // second memory operand
548   0,    // second literal operand
549   POC_NOP,
550   (PCC_REL_ADDR | PCC_N),   // inCond
551   PCC_NONE   , // outCond
552   PCI_MAGIC
553 };
554
555 pCodeInstruction pic16_pciBNOV = { // mdubuc - New
556   {PC_OPCODE, NULL, NULL, 0, NULL, 
557    //   genericAnalyze,
558    genericDestruct,
559    genericPrint},
560   POC_BNOV,
561   "BNOV",
562   2,
563   NULL, // from branch
564   NULL, // to branch
565   NULL, // label
566   NULL, // operand
567   NULL, // flow block
568   NULL, // C source 
569   1,    // num ops
570   0,0,  // dest, bit instruction
571   1,0,  // branch, skip
572   0,    // literal operand
573   0,    // RAM access bit
574   0,    // fast call/return mode select bit
575   0,    // second memory operand
576   0,    // second literal operand
577   POC_NOP,
578   (PCC_REL_ADDR | PCC_OV),   // inCond
579   PCC_NONE   , // outCond
580   PCI_MAGIC
581 };
582
583 pCodeInstruction pic16_pciBNZ = { // mdubuc - New
584   {PC_OPCODE, NULL, NULL, 0, NULL, 
585    //   genericAnalyze,
586    genericDestruct,
587    genericPrint},
588   POC_BNZ,
589   "BNZ",
590   2,
591   NULL, // from branch
592   NULL, // to branch
593   NULL, // label
594   NULL, // operand
595   NULL, // flow block
596   NULL, // C source 
597   1,    // num ops
598   0,0,  // dest, bit instruction
599   1,0,  // branch, skip
600   0,    // literal operand
601   0,    // RAM access bit
602   0,    // fast call/return mode select bit
603   0,    // second memory operand
604   0,    // second literal operand
605   POC_NOP,
606   (PCC_REL_ADDR | PCC_Z),   // inCond
607   PCC_NONE   , // outCond
608   PCI_MAGIC
609 };
610
611 pCodeInstruction pic16_pciBOV = { // mdubuc - New
612   {PC_OPCODE, NULL, NULL, 0, NULL, 
613    //   genericAnalyze,
614    genericDestruct,
615    genericPrint},
616   POC_BOV,
617   "BOV",
618   2,
619   NULL, // from branch
620   NULL, // to branch
621   NULL, // label
622   NULL, // operand
623   NULL, // flow block
624   NULL, // C source 
625   1,    // num ops
626   0,0,  // dest, bit instruction
627   1,0,  // branch, skip
628   0,    // literal operand
629   0,    // RAM access bit
630   0,    // fast call/return mode select bit
631   0,    // second memory operand
632   0,    // second literal operand
633   POC_NOP,
634   (PCC_REL_ADDR | PCC_OV),   // inCond
635   PCC_NONE , // outCond
636   PCI_MAGIC
637 };
638
639 pCodeInstruction pic16_pciBRA = { // mdubuc - New
640   {PC_OPCODE, NULL, NULL, 0, NULL, 
641    //   genericAnalyze,
642    genericDestruct,
643    genericPrint},
644   POC_BRA,
645   "BRA",
646   2,
647   NULL, // from branch
648   NULL, // to branch
649   NULL, // label
650   NULL, // operand
651   NULL, // flow block
652   NULL, // C source 
653   1,    // num ops
654   0,0,  // dest, bit instruction
655   1,0,  // branch, skip
656   0,    // literal operand
657   0,    // RAM access bit
658   0,    // fast call/return mode select bit
659   0,    // second memory operand
660   0,    // second literal operand
661   POC_NOP,
662   PCC_REL_ADDR,   // inCond
663   PCC_NONE   , // outCond
664   PCI_MAGIC
665 };
666
667 pCodeInstruction pic16_pciBSF = {
668   {PC_OPCODE, NULL, NULL, 0, NULL, 
669    //   genericAnalyze,
670    genericDestruct,
671    genericPrint},
672   POC_BSF,
673   "BSF",
674   2,
675   NULL, // from branch
676   NULL, // to branch
677   NULL, // label
678   NULL, // operand
679   NULL, // flow block
680   NULL, // C source 
681   3,    // num ops
682   1,1,  // dest, bit instruction
683   0,0,  // branch, skip
684   0,    // literal operand
685   1,    // RAM access bit
686   0,    // fast call/return mode select bit
687   0,    // second memory operand
688   0,    // second literal operand
689   POC_BCF,
690   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
691   (PCC_REGISTER | PCC_EXAMINE_PCOP), // outCond
692   PCI_MAGIC
693 };
694
695 pCodeInstruction pic16_pciBTFSC = {
696   {PC_OPCODE, NULL, NULL, 0, NULL, 
697    //   AnalyzeSKIP,
698    genericDestruct,
699    genericPrint},
700   POC_BTFSC,
701   "BTFSC",
702   2,
703   NULL, // from branch
704   NULL, // to branch
705   NULL, // label
706   NULL, // operand
707   NULL, // flow block
708   NULL, // C source 
709   3,    // num ops
710   0,1,  // dest, bit instruction
711   1,1,  // branch, skip
712   0,    // literal operand
713   1,    // RAM access bit
714   0,    // fast call/return mode select bit
715   0,    // second memory operand
716   0,    // second literal operand
717   POC_BTFSS,
718   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
719   PCC_EXAMINE_PCOP, // outCond
720   PCI_MAGIC
721 };
722
723 pCodeInstruction pic16_pciBTFSS = {
724   {PC_OPCODE, NULL, NULL, 0, NULL, 
725    //   AnalyzeSKIP,
726    genericDestruct,
727    genericPrint},
728   POC_BTFSS,
729   "BTFSS",
730   2,
731   NULL, // from branch
732   NULL, // to branch
733   NULL, // label
734   NULL, // operand
735   NULL, // flow block
736   NULL, // C source 
737   3,    // num ops
738   0,1,  // dest, bit instruction
739   1,1,  // branch, skip
740   0,    // literal operand
741   1,    // RAM access bit
742   0,    // fast call/return mode select bit
743   0,    // second memory operand
744   0,    // second literal operand
745   POC_BTFSC,
746   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
747   PCC_EXAMINE_PCOP, // outCond
748   PCI_MAGIC
749 };
750
751 pCodeInstruction pic16_pciBTG = { // mdubuc - New
752   {PC_OPCODE, NULL, NULL, 0, NULL, 
753    //   genericAnalyze,
754    genericDestruct,
755    genericPrint},
756   POC_BTG,
757   "BTG",
758   2,
759   NULL, // from branch
760   NULL, // to branch
761   NULL, // label
762   NULL, // operand
763   NULL, // flow block
764   NULL, // C source 
765   3,    // num ops
766   0,1,  // dest, bit instruction
767   0,0,  // branch, skip
768   0,    // literal operand
769   1,    // RAM access bit
770   0,    // fast call/return mode select bit
771   0,    // second memory operand
772   0,    // second literal operand
773   POC_NOP,
774   (PCC_REGISTER | PCC_EXAMINE_PCOP),   // inCond
775   (PCC_REGISTER | PCC_EXAMINE_PCOP), // outCond
776   PCI_MAGIC
777 };
778
779 pCodeInstruction pic16_pciBZ = { // mdubuc - New
780   {PC_OPCODE, NULL, NULL, 0, NULL, 
781    //   genericAnalyze,
782    genericDestruct,
783    genericPrint},
784   POC_BZ,
785   "BZ",
786   2,
787   NULL, // from branch
788   NULL, // to branch
789   NULL, // label
790   NULL, // operand
791   NULL, // flow block
792   NULL, // C source 
793   1,    // num ops
794   0,0,  // dest, bit instruction
795   1,0,  // branch, skip
796   0,    // literal operand
797   0,    // RAM access bit
798   0,    // fast call/return mode select bit
799   0,    // second memory operand
800   0,    // second literal operand
801   POC_NOP,
802   PCC_Z,   // inCond
803   PCC_NONE, // outCond
804   PCI_MAGIC
805 };
806
807 pCodeInstruction pic16_pciCALL = {
808   {PC_OPCODE, NULL, NULL, 0, NULL, 
809    //   genericAnalyze,
810    genericDestruct,
811    genericPrint},
812   POC_CALL,
813   "CALL",
814   4,
815   NULL, // from branch
816   NULL, // to branch
817   NULL, // label
818   NULL, // operand
819   NULL, // flow block
820   NULL, // C source 
821   2,    // num ops
822   0,0,  // dest, bit instruction
823   1,0,  // branch, skip
824   0,    // literal operand
825   0,    // RAM access bit
826   1,    // fast call/return mode select bit
827   0,    // second memory operand
828   0,    // second literal operand
829   POC_NOP,
830   PCC_NONE, // inCond
831   PCC_NONE, // outCond
832   PCI_MAGIC
833 };
834
835 pCodeInstruction pic16_pciCOMF = {
836   {PC_OPCODE, NULL, NULL, 0, NULL, 
837    //   genericAnalyze,
838    genericDestruct,
839    genericPrint},
840   POC_COMF,
841   "COMF",
842   2,
843   NULL, // from branch
844   NULL, // to branch
845   NULL, // label
846   NULL, // operand
847   NULL, // flow block
848   NULL, // C source 
849   3,    // num ops
850   1,0,  // dest, bit instruction
851   0,0,  // branch, skip
852   0,    // literal operand
853   1,    // RAM access bit
854   0,    // fast call/return mode select bit
855   0,    // second memory operand
856   0,    // second literal operand
857   POC_NOP,
858   PCC_REGISTER,  // inCond
859   PCC_REGISTER  , // outCond
860   PCI_MAGIC
861 };
862
863 pCodeInstruction pic16_pciCOMFW = {
864   {PC_OPCODE, NULL, NULL, 0, NULL, 
865    //   genericAnalyze,
866    genericDestruct,
867    genericPrint},
868   POC_COMFW,
869   "COMF",
870   2,
871   NULL, // from branch
872   NULL, // to branch
873   NULL, // label
874   NULL, // operand
875   NULL, // flow block
876   NULL, // C source 
877   3,    // num ops
878   0,0,  // dest, bit instruction
879   0,0,  // branch, skip
880   0,    // literal operand
881   1,    // RAM access bit
882   0,    // fast call/return mode select bit
883   0,    // second memory operand
884   0,    // second literal operand
885   POC_NOP,
886   PCC_REGISTER,  // inCond
887   PCC_W  , // outCond
888   PCI_MAGIC
889 };
890
891 pCodeInstruction pic16_pciCLRF = {
892   {PC_OPCODE, NULL, NULL, 0, NULL, 
893    //   genericAnalyze,
894    genericDestruct,
895    genericPrint},
896   POC_CLRF,
897   "CLRF",
898   2,
899   NULL, // from branch
900   NULL, // to branch
901   NULL, // label
902   NULL, // operand
903   NULL, // flow block
904   NULL, // C source 
905   2,    // num ops
906   0,0,  // dest, bit instruction
907   0,0,  // branch, skip
908   0,    // literal operand
909   1,    // RAM access bit
910   0,    // fast call/return mode select bit
911   0,    // second memory operand
912   0,    // second literal operand
913   POC_NOP,
914   PCC_REGISTER, // inCond
915   PCC_REGISTER , // outCond
916   PCI_MAGIC
917 };
918
919 pCodeInstruction pic16_pciCLRWDT = {
920   {PC_OPCODE, NULL, NULL, 0, NULL, 
921    //   genericAnalyze,
922    genericDestruct,
923    genericPrint},
924   POC_CLRWDT,
925   "CLRWDT",
926   2,
927   NULL, // from branch
928   NULL, // to branch
929   NULL, // label
930   NULL, // operand
931   NULL, // flow block
932   NULL, // C source 
933   0,    // num ops
934   0,0,  // dest, bit instruction
935   0,0,  // branch, skip
936   0,    // literal operand
937   0,    // RAM access bit
938   0,    // fast call/return mode select bit
939   0,    // second memory operand
940   0,    // second literal operand
941   POC_NOP,
942   PCC_NONE, // inCond
943   PCC_NONE , // outCond
944   PCI_MAGIC
945 };
946
947 pCodeInstruction pic16_pciCPFSEQ = { // mdubuc - New
948   {PC_OPCODE, NULL, NULL, 0, NULL, 
949    //   genericAnalyze,
950    genericDestruct,
951    genericPrint},
952   POC_CPFSEQ,
953   "CPFSEQ",
954   2,
955   NULL, // from branch
956   NULL, // to branch
957   NULL, // label
958   NULL, // operand
959   NULL, // flow block
960   NULL, // C source 
961   2,    // num ops
962   0,0,  // dest, bit instruction
963   1,1,  // branch, skip
964   0,    // literal operand
965   1,    // RAM access bit
966   0,    // fast call/return mode select bit
967   0,    // second memory operand
968   0,    // second literal operand
969   POC_NOP,
970   (PCC_W | PCC_REGISTER), // inCond
971   PCC_NONE , // outCond
972   PCI_MAGIC
973 };
974
975 pCodeInstruction pic16_pciCPFSGT = { // mdubuc - New
976   {PC_OPCODE, NULL, NULL, 0, NULL, 
977    //   genericAnalyze,
978    genericDestruct,
979    genericPrint},
980   POC_CPFSGT,
981   "CPFSGT",
982   2,
983   NULL, // from branch
984   NULL, // to branch
985   NULL, // label
986   NULL, // operand
987   NULL, // flow block
988   NULL, // C source 
989   2,    // num ops
990   0,0,  // dest, bit instruction
991   1,1,  // branch, skip
992   0,    // literal operand
993   1,    // RAM access bit
994   0,    // fast call/return mode select bit
995   0,    // second memory operand
996   0,    // second literal operand
997   POC_NOP,
998   (PCC_W | PCC_REGISTER), // inCond
999   PCC_NONE , // outCond
1000   PCI_MAGIC
1001 };
1002
1003 pCodeInstruction pic16_pciCPFSLT = { // mdubuc - New
1004   {PC_OPCODE, NULL, NULL, 0, NULL, 
1005    //   genericAnalyze,
1006    genericDestruct,
1007    genericPrint},
1008   POC_CPFSLT,
1009   "CPFSLT",
1010   2,
1011   NULL, // from branch
1012   NULL, // to branch
1013   NULL, // label
1014   NULL, // operand
1015   NULL, // flow block
1016   NULL, // C source 
1017   2,    // num ops
1018   1,0,  // dest, bit instruction
1019   1,1,  // branch, skip
1020   0,    // literal operand
1021   1,    // RAM access bit
1022   0,    // fast call/return mode select bit
1023   0,    // second memory operand
1024   0,    // second literal operand
1025   POC_NOP,
1026   (PCC_W | PCC_REGISTER), // inCond
1027   PCC_NONE , // outCond
1028   PCI_MAGIC
1029 };
1030
1031 pCodeInstruction pic16_pciDAW = {
1032   {PC_OPCODE, NULL, NULL, 0, NULL, 
1033    //   genericAnalyze,
1034    genericDestruct,
1035    genericPrint},
1036   POC_DAW,
1037   "DAW",
1038   2,
1039   NULL, // from branch
1040   NULL, // to branch
1041   NULL, // label
1042   NULL, // operand
1043   NULL, // flow block
1044   NULL, // C source 
1045   0,    // num ops
1046   0,0,  // dest, bit instruction
1047   0,0,  // branch, skip
1048   0,    // literal operand
1049   0,    // RAM access bit
1050   0,    // fast call/return mode select bit
1051   0,    // second memory operand
1052   0,    // second literal operand
1053   POC_NOP,
1054   PCC_W, // inCond
1055   (PCC_W | PCC_C), // outCond
1056   PCI_MAGIC
1057 };
1058
1059 pCodeInstruction pic16_pciDCFSNZ = { // mdubuc - New
1060   {PC_OPCODE, NULL, NULL, 0, NULL, 
1061    //   genericAnalyze,
1062    genericDestruct,
1063    genericPrint},
1064   POC_DCFSNZ,
1065   "DCFSNZ",
1066   2,
1067   NULL, // from branch
1068   NULL, // to branch
1069   NULL, // label
1070   NULL, // operand
1071   NULL, // flow block
1072   NULL, // C source 
1073   3,    // num ops
1074   1,0,  // dest, bit instruction
1075   1,1,  // branch, skip
1076   0,    // literal operand
1077   1,    // RAM access bit
1078   0,    // fast call/return mode select bit
1079   0,    // second memory operand
1080   0,    // second literal operand
1081   POC_NOP,
1082   PCC_REGISTER, // inCond
1083   PCC_REGISTER , // outCond
1084   PCI_MAGIC
1085 };
1086
1087 pCodeInstruction pic16_pciDCFSNZW = { // mdubuc - New
1088   {PC_OPCODE, NULL, NULL, 0, NULL, 
1089    //   genericAnalyze,
1090    genericDestruct,
1091    genericPrint},
1092   POC_DCFSNZW,
1093   "DCFSNZ",
1094   2,
1095   NULL, // from branch
1096   NULL, // to branch
1097   NULL, // label
1098   NULL, // operand
1099   NULL, // flow block
1100   NULL, // C source 
1101   3,    // num ops
1102   0,0,  // dest, bit instruction
1103   1,1,  // branch, skip
1104   0,    // literal operand
1105   1,    // RAM access bit
1106   0,    // fast call/return mode select bit
1107   0,    // second memory operand
1108   0,    // second literal operand
1109   POC_NOP,
1110   PCC_REGISTER, // inCond
1111   PCC_W , // outCond
1112   PCI_MAGIC
1113 };
1114
1115 pCodeInstruction pic16_pciDECF = {
1116   {PC_OPCODE, NULL, NULL, 0, NULL, 
1117    //   genericAnalyze,
1118    genericDestruct,
1119    genericPrint},
1120   POC_DECF,
1121   "DECF",
1122   2,
1123   NULL, // from branch
1124   NULL, // to branch
1125   NULL, // label
1126   NULL, // operand
1127   NULL, // flow block
1128   NULL, // C source 
1129   3,    // num ops
1130   1,0,  // dest, bit instruction
1131   0,0,  // branch, skip
1132   0,    // literal operand
1133   1,    // RAM access bit
1134   0,    // fast call/return mode select bit
1135   0,    // second memory operand
1136   0,    // second literal operand
1137   POC_NOP,
1138   PCC_REGISTER,   // inCond
1139   PCC_REGISTER   , // outCond
1140   PCI_MAGIC
1141 };
1142
1143 pCodeInstruction pic16_pciDECFW = {
1144   {PC_OPCODE, NULL, NULL, 0, NULL, 
1145    //   genericAnalyze,
1146    genericDestruct,
1147    genericPrint},
1148   POC_DECFW,
1149   "DECF",
1150   2,
1151   NULL, // from branch
1152   NULL, // to branch
1153   NULL, // label
1154   NULL, // operand
1155   NULL, // flow block
1156   NULL, // C source 
1157   3,    // num ops
1158   0,0,  // dest, bit instruction
1159   0,0,  // branch, skip
1160   0,    // literal operand
1161   1,    // RAM access bit
1162   0,    // fast call/return mode select bit
1163   0,    // second memory operand
1164   0,    // second literal operand
1165   POC_NOP,
1166   PCC_REGISTER,   // inCond
1167   PCC_W   , // outCond
1168   PCI_MAGIC
1169 };
1170
1171 pCodeInstruction pic16_pciDECFSZ = {
1172   {PC_OPCODE, NULL, NULL, 0, NULL, 
1173    //   AnalyzeSKIP,
1174    genericDestruct,
1175    genericPrint},
1176   POC_DECFSZ,
1177   "DECFSZ",
1178   2,
1179   NULL, // from branch
1180   NULL, // to branch
1181   NULL, // label
1182   NULL, // operand
1183   NULL, // flow block
1184   NULL, // C source 
1185   3,    // num ops
1186   1,0,  // dest, bit instruction
1187   1,1,  // branch, skip
1188   0,    // literal operand
1189   1,    // RAM access bit
1190   0,    // fast call/return mode select bit
1191   0,    // second memory operand
1192   0,    // second literal operand
1193   POC_NOP,
1194   PCC_REGISTER,   // inCond
1195   PCC_REGISTER   , // outCond
1196   PCI_MAGIC
1197 };
1198
1199 pCodeInstruction pic16_pciDECFSZW = {
1200   {PC_OPCODE, NULL, NULL, 0, NULL, 
1201    //   AnalyzeSKIP,
1202    genericDestruct,
1203    genericPrint},
1204   POC_DECFSZW,
1205   "DECFSZ",
1206   2,
1207   NULL, // from branch
1208   NULL, // to branch
1209   NULL, // label
1210   NULL, // operand
1211   NULL, // flow block
1212   NULL, // C source 
1213   3,    // num ops
1214   0,0,  // dest, bit instruction
1215   1,1,  // branch, skip
1216   0,    // literal operand
1217   1,    // RAM access bit
1218   0,    // fast call/return mode select bit
1219   0,    // second memory operand
1220   0,    // second literal operand
1221   POC_NOP,
1222   PCC_REGISTER,   // inCond
1223   PCC_W          , // outCond
1224   PCI_MAGIC
1225 };
1226
1227 pCodeInstruction pic16_pciGOTO = {
1228   {PC_OPCODE, NULL, NULL, 0, NULL, 
1229    //   AnalyzeGOTO,
1230    genericDestruct,
1231    genericPrint},
1232   POC_GOTO,
1233   "GOTO",
1234   4,
1235   NULL, // from branch
1236   NULL, // to branch
1237   NULL, // label
1238   NULL, // operand
1239   NULL, // flow block
1240   NULL, // C source 
1241   1,    // num ops
1242   0,0,  // dest, bit instruction
1243   1,0,  // branch, skip
1244   0,    // literal operand
1245   0,    // RAM access bit
1246   0,    // fast call/return mode select bit
1247   0,    // second memory operand
1248   0,    // second literal operand
1249   POC_NOP,
1250   PCC_REL_ADDR,   // inCond
1251   PCC_NONE   , // outCond
1252   PCI_MAGIC
1253 };
1254
1255 pCodeInstruction pic16_pciINCF = {
1256   {PC_OPCODE, NULL, NULL, 0, NULL, 
1257    //   genericAnalyze,
1258    genericDestruct,
1259    genericPrint},
1260   POC_INCF,
1261   "INCF",
1262   2,
1263   NULL, // from branch
1264   NULL, // to branch
1265   NULL, // label
1266   NULL, // operand
1267   NULL, // flow block
1268   NULL, // C source 
1269   3,    // num ops
1270   1,0,  // dest, bit instruction
1271   0,0,  // branch, skip
1272   0,    // literal operand
1273   1,    // RAM access bit
1274   0,    // fast call/return mode select bit
1275   0,    // second memory operand
1276   0,    // second literal operand
1277   POC_NOP,
1278   PCC_REGISTER,   // inCond
1279   (PCC_REGISTER | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond
1280   PCI_MAGIC
1281 };
1282
1283 pCodeInstruction pic16_pciINCFW = {
1284   {PC_OPCODE, NULL, NULL, 0, NULL, 
1285    //   genericAnalyze,
1286    genericDestruct,
1287    genericPrint},
1288   POC_INCFW,
1289   "INCF",
1290   2,
1291   NULL, // from branch
1292   NULL, // to branch
1293   NULL, // label
1294   NULL, // operand
1295   NULL, // flow block
1296   NULL, // C source 
1297   3,    // num ops
1298   0,0,  // dest, bit instruction
1299   0,0,  // branch, skip
1300   0,    // literal operand
1301   1,    // RAM access bit
1302   0,    // fast call/return mode select bit
1303   0,    // second memory operand
1304   0,    // second literal operand
1305   POC_NOP,
1306   PCC_REGISTER,   // inCond
1307   PCC_W   , // outCond
1308   PCI_MAGIC
1309 };
1310
1311 pCodeInstruction pic16_pciINCFSZ = {
1312   {PC_OPCODE, NULL, NULL, 0, NULL, 
1313    //   AnalyzeSKIP,
1314    genericDestruct,
1315    genericPrint},
1316   POC_INCFSZ,
1317   "INCFSZ",
1318   2,
1319   NULL, // from branch
1320   NULL, // to branch
1321   NULL, // label
1322   NULL, // operand
1323   NULL, // flow block
1324   NULL, // C source 
1325   3,    // num ops
1326   1,0,  // dest, bit instruction
1327   1,1,  // branch, skip
1328   0,    // literal operand
1329   1,    // RAM access bit
1330   0,    // fast call/return mode select bit
1331   0,    // second memory operand
1332   0,    // second literal operand
1333   POC_INFSNZ,
1334   PCC_REGISTER,   // inCond
1335   PCC_REGISTER   , // outCond
1336   PCI_MAGIC
1337 };
1338
1339 pCodeInstruction pic16_pciINCFSZW = {
1340   {PC_OPCODE, NULL, NULL, 0, NULL, 
1341    //   AnalyzeSKIP,
1342    genericDestruct,
1343    genericPrint},
1344   POC_INCFSZW,
1345   "INCFSZ",
1346   2,
1347   NULL, // from branch
1348   NULL, // to branch
1349   NULL, // label
1350   NULL, // operand
1351   NULL, // flow block
1352   NULL, // C source 
1353   3,    // num ops
1354   0,0,  // dest, bit instruction
1355   1,1,  // branch, skip
1356   0,    // literal operand
1357   1,    // RAM access bit
1358   0,    // fast call/return mode select bit
1359   0,    // second memory operand
1360   0,    // second literal operand
1361   POC_INFSNZW,
1362   PCC_REGISTER,   // inCond
1363   PCC_W          , // outCond
1364   PCI_MAGIC
1365 };
1366
1367 pCodeInstruction pic16_pciINFSNZ = { // mdubuc - New
1368   {PC_OPCODE, NULL, NULL, 0, NULL, 
1369    //   AnalyzeSKIP,
1370    genericDestruct,
1371    genericPrint},
1372   POC_INFSNZ,
1373   "INFSNZ",
1374   2,
1375   NULL, // from branch
1376   NULL, // to branch
1377   NULL, // label
1378   NULL, // operand
1379   NULL, // flow block
1380   NULL, // C source 
1381   3,    // num ops
1382   1,0,  // dest, bit instruction
1383   1,1,  // branch, skip
1384   0,    // literal operand
1385   1,    // RAM access bit
1386   0,    // fast call/return mode select bit
1387   0,    // second memory operand
1388   0,    // second literal operand
1389   POC_INCFSZ,
1390   PCC_REGISTER,   // inCond
1391   PCC_REGISTER   , // outCond
1392   PCI_MAGIC
1393 };
1394
1395 pCodeInstruction pic16_pciINFSNZW = { // vrokas - New
1396   {PC_OPCODE, NULL, NULL, 0, NULL, 
1397    //   AnalyzeSKIP,
1398    genericDestruct,
1399    genericPrint},
1400   POC_INFSNZW,
1401   "INFSNZ",
1402   2,
1403   NULL, // from branch
1404   NULL, // to branch
1405   NULL, // label
1406   NULL, // operand
1407   NULL, // flow block
1408   NULL, // C source 
1409   3,    // num ops
1410   0,0,  // dest, bit instruction
1411   1,1,  // branch, skip
1412   0,    // literal operand
1413   1,    // RAM access bit
1414   0,    // fast call/return mode select bit
1415   0,    // second memory operand
1416   0,    // second literal operand
1417   POC_INCFSZW,
1418   PCC_REGISTER,   // inCond
1419   PCC_W          , // outCond
1420   PCI_MAGIC
1421 };
1422
1423 pCodeInstruction pic16_pciIORWF = {
1424   {PC_OPCODE, NULL, NULL, 0, NULL, 
1425    //   genericAnalyze,
1426    genericDestruct,
1427    genericPrint},
1428   POC_IORWF,
1429   "IORWF",
1430   2,
1431   NULL, // from branch
1432   NULL, // to branch
1433   NULL, // label
1434   NULL, // operand
1435   NULL, // flow block
1436   NULL, // C source 
1437   3,    // num ops
1438   1,0,  // dest, bit instruction
1439   0,0,  // branch, skip
1440   0,    // literal operand
1441   1,    // RAM access bit
1442   0,    // fast call/return mode select bit
1443   0,    // second memory operand
1444   0,    // second literal operand
1445   POC_NOP,
1446   (PCC_W | PCC_REGISTER),   // inCond
1447   (PCC_REGISTER | PCC_Z | PCC_N), // outCond
1448   PCI_MAGIC
1449 };
1450
1451 pCodeInstruction pic16_pciIORFW = {
1452   {PC_OPCODE, NULL, NULL, 0, NULL, 
1453    //   genericAnalyze,
1454    genericDestruct,
1455    genericPrint},
1456   POC_IORFW,
1457   "IORWF",
1458   2,
1459   NULL, // from branch
1460   NULL, // to branch
1461   NULL, // label
1462   NULL, // operand
1463   NULL, // flow block
1464   NULL, // C source 
1465   3,    // num ops
1466   0,0,  // dest, bit instruction
1467   0,0,  // branch, skip
1468   0,    // literal operand
1469   1,    // RAM access bit
1470   0,    // fast call/return mode select bit
1471   0,    // second memory operand
1472   0,    // second literal operand
1473   POC_NOP,
1474   (PCC_W | PCC_REGISTER),   // inCond
1475   (PCC_W | PCC_Z | PCC_N), // outCond
1476   PCI_MAGIC
1477 };
1478
1479 pCodeInstruction pic16_pciIORLW = {
1480   {PC_OPCODE, NULL, NULL, 0, NULL, 
1481    //   genericAnalyze,
1482    genericDestruct,
1483    genericPrint},
1484   POC_IORLW,
1485   "IORLW",
1486   2,
1487   NULL, // from branch
1488   NULL, // to branch
1489   NULL, // label
1490   NULL, // operand
1491   NULL, // flow block
1492   NULL, // C source 
1493   1,    // num ops
1494   0,0,  // dest, bit instruction
1495   0,0,  // branch, skip
1496   1,    // literal operand
1497   0,    // RAM access bit
1498   0,    // fast call/return mode select bit
1499   0,    // second memory operand
1500   0,    // second literal operand
1501   POC_NOP,
1502   (PCC_W | PCC_LITERAL),   // inCond
1503   (PCC_W | PCC_Z | PCC_N), // outCond
1504   PCI_MAGIC
1505 };
1506
1507 pCodeInstruction pic16_pciLFSR = { // mdubuc - New
1508   {PC_OPCODE, NULL, NULL, 0, NULL, 
1509    //   genericAnalyze,
1510    genericDestruct,
1511    genericPrint},
1512   POC_LFSR,
1513   "LFSR",
1514   4,
1515   NULL, // from branch
1516   NULL, // to branch
1517   NULL, // label
1518   NULL, // operand
1519   NULL, // flow block
1520   NULL, // C source 
1521   2,    // num ops
1522   0,0,  // dest, bit instruction
1523   0,0,  // branch, skip
1524   1,    // literal operand
1525   0,    // RAM access bit
1526   0,    // fast call/return mode select bit
1527   0,    // second memory operand
1528   1,    // second literal operand
1529   POC_NOP,
1530   (PCC_REGISTER | PCC_LITERAL),
1531   PCC_REGISTER, // outCond
1532   PCI_MAGIC
1533 };
1534
1535 pCodeInstruction pic16_pciMOVF = {
1536   {PC_OPCODE, NULL, NULL, 0, NULL, 
1537    //   genericAnalyze,
1538    genericDestruct,
1539    genericPrint},
1540   POC_MOVF,
1541   "MOVF",
1542   2,
1543   NULL, // from branch
1544   NULL, // to branch
1545   NULL, // label
1546   NULL, // operand
1547   NULL, // flow block
1548   NULL, // C source 
1549   3,    // num ops
1550   1,0,  // dest, bit instruction
1551   0,0,  // branch, skip
1552   0,    // literal operand
1553   1,    // RAM access bit
1554   0,    // fast call/return mode select bit
1555   0,    // second memory operand
1556   0,    // second literal operand
1557   POC_NOP,
1558   PCC_REGISTER,   // inCond
1559   (PCC_Z | PCC_N), // outCond
1560   PCI_MAGIC
1561 };
1562
1563 pCodeInstruction pic16_pciMOVFW = {
1564   {PC_OPCODE, NULL, NULL, 0, NULL, 
1565    //   genericAnalyze,
1566    genericDestruct,
1567    genericPrint},
1568   POC_MOVFW,
1569   "MOVF",
1570   2,
1571   NULL, // from branch
1572   NULL, // to branch
1573   NULL, // label
1574   NULL, // operand
1575   NULL, // flow block
1576   NULL, // C source 
1577   3,    // num ops
1578   0,0,  // dest, bit instruction
1579   0,0,  // branch, skip
1580   0,    // literal operand
1581   1,    // RAM access bit
1582   0,    // fast call/return mode select bit
1583   0,    // second memory operand
1584   0,    // second literal operand
1585   POC_NOP,
1586   PCC_REGISTER,   // inCond
1587   (PCC_W | PCC_Z), // outCond
1588   PCI_MAGIC
1589 };
1590
1591 pCodeInstruction pic16_pciMOVFF = { // mdubuc - New
1592   {PC_OPCODE, NULL, NULL, 0, NULL, 
1593    //   genericAnalyze,
1594    genericDestruct,
1595    genericPrint},
1596   POC_MOVFF,
1597   "MOVFF",
1598   4,
1599   NULL, // from branch
1600   NULL, // to branch
1601   NULL, // label
1602   NULL, // operand
1603   NULL, // flow block
1604   NULL, // C source 
1605   2,    // num ops
1606   0,0,  // dest, bit instruction
1607   0,0,  // branch, skip
1608   0,    // literal operand
1609   0,    // RAM access bit
1610   0,    // fast call/return mode select bit
1611   1,    // second memory operand
1612   0,    // second literal operand
1613   POC_NOP,
1614   PCC_REGISTER,   // inCond
1615   PCC_REGISTER, // outCond
1616   PCI_MAGIC
1617 };
1618
1619 pCodeInstruction pic16_pciMOVLB = { // mdubuc - New
1620   {PC_OPCODE, NULL, NULL, 0, NULL, 
1621    genericDestruct,
1622    genericPrint},
1623   POC_MOVLB,
1624   "MOVLB",
1625   2,
1626   NULL, // from branch
1627   NULL, // to branch
1628   NULL, // label
1629   NULL, // operand
1630   NULL, // flow block
1631   NULL, // C source 
1632   1,    // num ops
1633   0,0,  // dest, bit instruction
1634   0,0,  // branch, skip
1635   1,    // literal operand
1636   0,    // RAM access bit
1637   0,    // fast call/return mode select bit
1638   0,    // second memory operand
1639   0,    // second literal operand
1640   POC_NOP,
1641   (PCC_NONE | PCC_LITERAL),   // inCond
1642   PCC_REGISTER, // outCond - BSR
1643   PCI_MAGIC
1644 };
1645
1646 pCodeInstruction pic16_pciMOVLW = {
1647   {PC_OPCODE, NULL, NULL, 0, NULL, 
1648    genericDestruct,
1649    genericPrint},
1650   POC_MOVLW,
1651   "MOVLW",
1652   2,
1653   NULL, // from branch
1654   NULL, // to branch
1655   NULL, // label
1656   NULL, // operand
1657   NULL, // flow block
1658   NULL, // C source 
1659   1,    // num ops
1660   0,0,  // dest, bit instruction
1661   0,0,  // branch, skip
1662   1,    // literal operand
1663   0,    // RAM access bit
1664   0,    // fast call/return mode select bit
1665   0,    // second memory operand
1666   0,    // second literal operand
1667   POC_NOP,
1668   (PCC_NONE | PCC_LITERAL),   // inCond
1669   PCC_W, // outCond
1670   PCI_MAGIC
1671 };
1672
1673 pCodeInstruction pic16_pciMOVWF = {
1674   {PC_OPCODE, NULL, NULL, 0, NULL, 
1675    //   genericAnalyze,
1676    genericDestruct,
1677    genericPrint},
1678   POC_MOVWF,
1679   "MOVWF",
1680   2,
1681   NULL, // from branch
1682   NULL, // to branch
1683   NULL, // label
1684   NULL, // operand
1685   NULL, // flow block
1686   NULL, // C source 
1687   2,    // num ops
1688   0,0,  // dest, bit instruction
1689   0,0,  // branch, skip
1690   0,    // literal operand
1691   1,    // RAM access bit
1692   0,    // fast call/return mode select bit
1693   0,    // second memory operand
1694   0,    // second literal operand
1695   POC_NOP,
1696   PCC_REGISTER,   // inCond
1697   PCC_W, // outCond
1698   PCI_MAGIC
1699 };
1700
1701 pCodeInstruction pic16_pciMULLW = { // mdubuc - New
1702   {PC_OPCODE, NULL, NULL, 0, NULL, 
1703    genericDestruct,
1704    genericPrint},
1705   POC_MULLW,
1706   "MULLW",
1707   2,
1708   NULL, // from branch
1709   NULL, // to branch
1710   NULL, // label
1711   NULL, // operand
1712   NULL, // flow block
1713   NULL, // C source 
1714   1,    // num ops
1715   0,0,  // dest, bit instruction
1716   0,0,  // branch, skip
1717   1,    // literal operand
1718   0,    // RAM access bit
1719   0,    // fast call/return mode select bit
1720   0,    // second memory operand
1721   0,    // second literal operand
1722   POC_NOP,
1723   (PCC_W | PCC_LITERAL),   // inCond
1724   PCC_REGISTER, // outCond - PROD
1725   PCI_MAGIC
1726 };
1727
1728 pCodeInstruction pic16_pciMULWF = { // mdubuc - New
1729   {PC_OPCODE, NULL, NULL, 0, NULL, 
1730    genericDestruct,
1731    genericPrint},
1732   POC_MULWF,
1733   "MULWF",
1734   2,
1735   NULL, // from branch
1736   NULL, // to branch
1737   NULL, // label
1738   NULL, // operand
1739   NULL, // flow block
1740   NULL, // C source 
1741   2,    // num ops
1742   0,0,  // dest, bit instruction
1743   0,0,  // branch, skip
1744   0,    // literal operand
1745   1,    // RAM access bit
1746   0,    // fast call/return mode select bit
1747   0,    // second memory operand
1748   0,    // second literal operand
1749   POC_NOP,
1750   (PCC_W | PCC_REGISTER),   // inCond
1751   PCC_REGISTER, // outCond - PROD
1752   PCI_MAGIC
1753 };
1754
1755 pCodeInstruction pic16_pciNEGF = { // mdubuc - New
1756   {PC_OPCODE, NULL, NULL, 0, NULL, 
1757    genericDestruct,
1758    genericPrint},
1759   POC_NEGF,
1760   "NEGF",
1761   2,
1762   NULL, // from branch
1763   NULL, // to branch
1764   NULL, // label
1765   NULL, // operand
1766   NULL, // flow block
1767   NULL, // C source 
1768   2,    // num ops
1769   0,0,  // dest, bit instruction
1770   0,0,  // branch, skip
1771   0,    // literal operand
1772   1,    // RAM access bit
1773   0,    // fast call/return mode select bit
1774   0,    // second memory operand
1775   0,    // second literal operand
1776   POC_NOP,
1777   PCC_REGISTER, // inCond
1778   (PCC_REGISTER | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
1779   PCI_MAGIC
1780 };
1781
1782 pCodeInstruction pic16_pciNOP = {
1783   {PC_OPCODE, NULL, NULL, 0, NULL, 
1784    genericDestruct,
1785    genericPrint},
1786   POC_NOP,
1787   "NOP",
1788   2,
1789   NULL, // from branch
1790   NULL, // to branch
1791   NULL, // label
1792   NULL, // operand
1793   NULL, // flow block
1794   NULL, // C source 
1795   0,    // num ops
1796   0,0,  // dest, bit instruction
1797   0,0,  // branch, skip
1798   0,    // literal operand
1799   0,    // RAM access bit
1800   0,    // fast call/return mode select bit
1801   0,    // second memory operand
1802   0,    // second literal operand
1803   POC_NOP,
1804   PCC_NONE,   // inCond
1805   PCC_NONE, // outCond
1806   PCI_MAGIC
1807 };
1808
1809 pCodeInstruction pic16_pciPOP = { // mdubuc - New
1810   {PC_OPCODE, NULL, NULL, 0, NULL, 
1811    genericDestruct,
1812    genericPrint},
1813   POC_POP,
1814   "POP",
1815   2,
1816   NULL, // from branch
1817   NULL, // to branch
1818   NULL, // label
1819   NULL, // operand
1820   NULL, // flow block
1821   NULL, // C source 
1822   0,    // num ops
1823   0,0,  // dest, bit instruction
1824   0,0,  // branch, skip
1825   0,    // literal operand
1826   0,    // RAM access bit
1827   0,    // fast call/return mode select bit
1828   0,    // second memory operand
1829   0,    // second literal operand
1830   POC_NOP,
1831   PCC_NONE,  // inCond
1832   PCC_NONE  , // outCond
1833   PCI_MAGIC
1834 };
1835
1836 pCodeInstruction pic16_pciPUSH = {
1837   {PC_OPCODE, NULL, NULL, 0, NULL, 
1838    genericDestruct,
1839    genericPrint},
1840   POC_PUSH,
1841   "PUSH",
1842   2,
1843   NULL, // from branch
1844   NULL, // to branch
1845   NULL, // label
1846   NULL, // operand
1847   NULL, // flow block
1848   NULL, // C source 
1849   0,    // num ops
1850   0,0,  // dest, bit instruction
1851   0,0,  // branch, skip
1852   0,    // literal operand
1853   0,    // RAM access bit
1854   0,    // fast call/return mode select bit
1855   0,    // second memory operand
1856   0,    // second literal operand
1857   POC_NOP,
1858   PCC_NONE,  // inCond
1859   PCC_NONE  , // outCond
1860   PCI_MAGIC
1861 };
1862
1863 pCodeInstruction pic16_pciRCALL = { // mdubuc - New
1864   {PC_OPCODE, NULL, NULL, 0, NULL, 
1865    genericDestruct,
1866    genericPrint},
1867   POC_RCALL,
1868   "RCALL",
1869   2,
1870   NULL, // from branch
1871   NULL, // to branch
1872   NULL, // label
1873   NULL, // operand
1874   NULL, // flow block
1875   NULL, // C source 
1876   1,    // num ops
1877   0,0,  // dest, bit instruction
1878   0,0,  // branch, skip
1879   0,    // literal operand
1880   0,    // RAM access bit
1881   0,    // fast call/return mode select bit
1882   0,    // second memory operand
1883   0,    // second literal operand
1884   POC_NOP,
1885   PCC_REL_ADDR,  // inCond
1886   PCC_NONE  , // outCond
1887   PCI_MAGIC
1888 };
1889
1890 pCodeInstruction pic16_pciRETFIE = {
1891   {PC_OPCODE, NULL, NULL, 0, NULL, 
1892    //   AnalyzeRETURN,
1893    genericDestruct,
1894    genericPrint},
1895   POC_RETFIE,
1896   "RETFIE",
1897   2,
1898   NULL, // from branch
1899   NULL, // to branch
1900   NULL, // label
1901   NULL, // operand
1902   NULL, // flow block
1903   NULL, // C source 
1904   1,    // num ops
1905   0,0,  // dest, bit instruction
1906   1,0,  // branch, skip
1907   0,    // literal operand
1908   0,    // RAM access bit
1909   1,    // fast call/return mode select bit
1910   0,    // second memory operand
1911   0,    // second literal operand
1912   POC_NOP,
1913   PCC_NONE,   // inCond
1914   PCC_NONE,    // outCond (not true... affects the GIE bit too)
1915   PCI_MAGIC
1916 };
1917
1918 pCodeInstruction pic16_pciRETLW = {
1919   {PC_OPCODE, NULL, NULL, 0, NULL, 
1920    //   AnalyzeRETURN,
1921    genericDestruct,
1922    genericPrint},
1923   POC_RETLW,
1924   "RETLW",
1925   2,
1926   NULL, // from branch
1927   NULL, // to branch
1928   NULL, // label
1929   NULL, // operand
1930   NULL, // flow block
1931   NULL, // C source 
1932   1,    // num ops
1933   0,0,  // dest, bit instruction
1934   1,0,  // branch, skip
1935   1,    // literal operand
1936   0,    // RAM access bit
1937   0,    // fast call/return mode select bit
1938   0,    // second memory operand
1939   0,    // second literal operand
1940   POC_NOP,
1941   PCC_LITERAL,   // inCond
1942   PCC_W, // outCond
1943   PCI_MAGIC
1944 };
1945
1946 pCodeInstruction pic16_pciRETURN = {
1947   {PC_OPCODE, NULL, NULL, 0, NULL, 
1948    //   AnalyzeRETURN,
1949    genericDestruct,
1950    genericPrint},
1951   POC_RETURN,
1952   "RETURN",
1953   2,
1954   NULL, // from branch
1955   NULL, // to branch
1956   NULL, // label
1957   NULL, // operand
1958   NULL, // flow block
1959   NULL, // C source 
1960   1,    // num ops
1961   0,0,  // dest, bit instruction
1962   1,0,  // branch, skip
1963   0,    // literal operand
1964   0,    // RAM access bit
1965   1,    // fast call/return mode select bit
1966   0,    // second memory operand
1967   0,    // second literal operand
1968   POC_NOP,
1969   PCC_NONE,   // inCond
1970   PCC_NONE, // outCond
1971   PCI_MAGIC
1972 };
1973 pCodeInstruction pic16_pciRLCF = { // mdubuc - New
1974   {PC_OPCODE, NULL, NULL, 0, NULL, 
1975    //   genericAnalyze,
1976    genericDestruct,
1977    genericPrint},
1978   POC_RLCF,
1979   "RLCF",
1980   2,
1981   NULL, // from branch
1982   NULL, // to branch
1983   NULL, // label
1984   NULL, // operand
1985   NULL, // flow block
1986   NULL, // C source 
1987   3,    // num ops
1988   1,0,  // dest, bit instruction
1989   0,0,  // branch, skip
1990   0,    // literal operand
1991   1,    // RAM access bit
1992   0,    // fast call/return mode select bit
1993   0,    // second memory operand
1994   0,    // second literal operand
1995   POC_NOP,
1996   (PCC_C | PCC_REGISTER),   // inCond
1997   (PCC_REGISTER | PCC_C | PCC_Z | PCC_N), // outCond
1998   PCI_MAGIC
1999 };
2000
2001 pCodeInstruction pic16_pciRLCFW = { // mdubuc - New
2002   {PC_OPCODE, NULL, NULL, 0, NULL, 
2003    //   genericAnalyze,
2004    genericDestruct,
2005    genericPrint},
2006   POC_RLCFW,
2007   "RLCF",
2008   2,
2009   NULL, // from branch
2010   NULL, // to branch
2011   NULL, // label
2012   NULL, // operand
2013   NULL, // flow block
2014   NULL, // C source 
2015   3,    // num ops
2016   0,0,  // dest, bit instruction
2017   0,0,  // branch, skip
2018   0,    // literal operand
2019   1,    // RAM access bit
2020   0,    // fast call/return mode select bit
2021   0,    // second memory operand
2022   0,    // second literal operand
2023   POC_NOP,
2024   (PCC_C | PCC_REGISTER),   // inCond
2025   (PCC_W | PCC_C | PCC_Z | PCC_N), // outCond
2026   PCI_MAGIC
2027 };
2028
2029 pCodeInstruction pic16_pciRLNCF = { // mdubuc - New
2030   {PC_OPCODE, NULL, NULL, 0, NULL, 
2031    //   genericAnalyze,
2032    genericDestruct,
2033    genericPrint},
2034   POC_RLNCF,
2035   "RLNCF",
2036   2,
2037   NULL, // from branch
2038   NULL, // to branch
2039   NULL, // label
2040   NULL, // operand
2041   NULL, // flow block
2042   NULL, // C source 
2043   3,    // num ops
2044   1,0,  // dest, bit instruction
2045   0,0,  // branch, skip
2046   0,    // literal operand
2047   1,    // RAM access bit
2048   0,    // fast call/return mode select bit
2049   0,    // second memory operand
2050   0,    // second literal operand
2051   POC_NOP,
2052   PCC_REGISTER,   // inCond
2053   (PCC_REGISTER | PCC_Z | PCC_N), // outCond
2054   PCI_MAGIC
2055 };
2056 pCodeInstruction pic16_pciRLNCFW = { // mdubuc - New
2057   {PC_OPCODE, NULL, NULL, 0, NULL, 
2058    //   genericAnalyze,
2059    genericDestruct,
2060    genericPrint},
2061   POC_RLNCFW,
2062   "RLNCF",
2063   2,
2064   NULL, // from branch
2065   NULL, // to branch
2066   NULL, // label
2067   NULL, // operand
2068   NULL, // flow block
2069   NULL, // C source 
2070   3,    // num ops
2071   0,0,  // dest, bit instruction
2072   0,0,  // branch, skip
2073   0,    // literal operand
2074   1,    // RAM access bit
2075   0,    // fast call/return mode select bit
2076   0,    // second memory operand
2077   0,    // second literal operand
2078   POC_NOP,
2079   PCC_REGISTER,   // inCond
2080   (PCC_W | PCC_Z | PCC_N), // outCond
2081   PCI_MAGIC
2082 };
2083 pCodeInstruction pic16_pciRRCF = { // mdubuc - New
2084   {PC_OPCODE, NULL, NULL, 0, NULL, 
2085    //   genericAnalyze,
2086    genericDestruct,
2087    genericPrint},
2088   POC_RRCF,
2089   "RRCF",
2090   2,
2091   NULL, // from branch
2092   NULL, // to branch
2093   NULL, // label
2094   NULL, // operand
2095   NULL, // flow block
2096   NULL, // C source 
2097   3,    // num ops
2098   1,0,  // dest, bit instruction
2099   0,0,  // branch, skip
2100   0,    // literal operand
2101   1,    // RAM access bit
2102   0,    // fast call/return mode select bit
2103   0,    // second memory operand
2104   0,    // second literal operand
2105   POC_NOP,
2106   (PCC_C | PCC_REGISTER),   // inCond
2107   (PCC_REGISTER | PCC_C | PCC_Z | PCC_N), // outCond
2108   PCI_MAGIC
2109 };
2110 pCodeInstruction pic16_pciRRCFW = { // mdubuc - New
2111   {PC_OPCODE, NULL, NULL, 0, NULL, 
2112    //   genericAnalyze,
2113    genericDestruct,
2114    genericPrint},
2115   POC_RRCFW,
2116   "RRCF",
2117   2,
2118   NULL, // from branch
2119   NULL, // to branch
2120   NULL, // label
2121   NULL, // operand
2122   NULL, // flow block
2123   NULL, // C source 
2124   3,    // num ops
2125   0,0,  // dest, bit instruction
2126   0,0,  // branch, skip
2127   0,    // literal operand
2128   1,    // RAM access bit
2129   0,    // fast call/return mode select bit
2130   0,    // second memory operand
2131   0,    // second literal operand
2132   POC_NOP,
2133   (PCC_C | PCC_REGISTER),   // inCond
2134   (PCC_W | PCC_C | PCC_Z | PCC_N), // outCond
2135   PCI_MAGIC
2136 };
2137 pCodeInstruction pic16_pciRRNCF = { // mdubuc - New
2138   {PC_OPCODE, NULL, NULL, 0, NULL, 
2139    //   genericAnalyze,
2140    genericDestruct,
2141    genericPrint},
2142   POC_RRNCF,
2143   "RRNCF",
2144   2,
2145   NULL, // from branch
2146   NULL, // to branch
2147   NULL, // label
2148   NULL, // operand
2149   NULL, // flow block
2150   NULL, // C source 
2151   3,    // num ops
2152   1,0,  // dest, bit instruction
2153   0,0,  // branch, skip
2154   0,    // literal operand
2155   1,    // RAM access bit
2156   0,    // fast call/return mode select bit
2157   0,    // second memory operand
2158   0,    // second literal operand
2159   POC_NOP,
2160   PCC_REGISTER,   // inCond
2161   (PCC_REGISTER | PCC_Z | PCC_N), // outCond
2162   PCI_MAGIC
2163 };
2164
2165 pCodeInstruction pic16_pciRRNCFW = { // mdubuc - New
2166   {PC_OPCODE, NULL, NULL, 0, NULL, 
2167    //   genericAnalyze,
2168    genericDestruct,
2169    genericPrint},
2170   POC_RRNCFW,
2171   "RRNCF",
2172   2,
2173   NULL, // from branch
2174   NULL, // to branch
2175   NULL, // label
2176   NULL, // operand
2177   NULL, // flow block
2178   NULL, // C source 
2179   3,    // num ops
2180   0,0,  // dest, bit instruction
2181   0,0,  // branch, skip
2182   0,    // literal operand
2183   1,    // RAM access bit
2184   0,    // fast call/return mode select bit
2185   0,    // second memory operand
2186   0,    // second literal operand
2187   POC_NOP,
2188   PCC_REGISTER,   // inCond
2189   (PCC_W | PCC_Z | PCC_N), // outCond
2190   PCI_MAGIC
2191 };
2192
2193 pCodeInstruction pic16_pciSETF = { // mdubuc - New
2194   {PC_OPCODE, NULL, NULL, 0, NULL, 
2195    //   genericAnalyze,
2196    genericDestruct,
2197    genericPrint},
2198   POC_SETF,
2199   "SETF",
2200   2,
2201   NULL, // from branch
2202   NULL, // to branch
2203   NULL, // label
2204   NULL, // operand
2205   NULL, // flow block
2206   NULL, // C source 
2207   2,    // num ops
2208   0,0,  // dest, bit instruction
2209   0,0,  // branch, skip
2210   0,    // literal operand
2211   1,    // RAM access bit
2212   0,    // fast call/return mode select bit
2213   0,    // second memory operand
2214   0,    // second literal operand
2215   POC_NOP,
2216   PCC_REGISTER,  // inCond
2217   PCC_REGISTER  , // outCond
2218   PCI_MAGIC
2219 };
2220
2221 pCodeInstruction pic16_pciSUBLW = {
2222   {PC_OPCODE, NULL, NULL, 0, NULL, 
2223    //   genericAnalyze,
2224    genericDestruct,
2225    genericPrint},
2226   POC_SUBLW,
2227   "SUBLW",
2228   2,
2229   NULL, // from branch
2230   NULL, // to branch
2231   NULL, // label
2232   NULL, // operand
2233   NULL, // flow block
2234   NULL, // C source 
2235   1,    // num ops
2236   0,0,  // dest, bit instruction
2237   0,0,  // branch, skip
2238   1,    // literal operand
2239   0,    // RAM access bit
2240   0,    // fast call/return mode select bit
2241   0,    // second memory operand
2242   0,    // second literal operand
2243   POC_NOP,
2244   (PCC_W | PCC_LITERAL),   // inCond
2245   (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond
2246   PCI_MAGIC
2247 };
2248
2249 pCodeInstruction pic16_pciSUBFWB = {
2250   {PC_OPCODE, NULL, NULL, 0, NULL, 
2251    //   genericAnalyze,
2252    genericDestruct,
2253    genericPrint},
2254   POC_SUBFWB,
2255   "SUBFWB",
2256   2,
2257   NULL, // from branch
2258   NULL, // to branch
2259   NULL, // label
2260   NULL, // operand
2261   NULL, // flow block
2262   NULL, // C source 
2263   3,    // num ops
2264   1,0,  // dest, bit instruction
2265   0,0,  // branch, skip
2266   0,    // literal operand
2267   1,    // RAM access bit
2268   0,    // fast call/return mode select bit
2269   0,    // second memory operand
2270   0,    // second literal operand
2271   POC_NOP,
2272   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
2273   (PCC_W | PCC_C | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond
2274   PCI_MAGIC
2275 };
2276
2277 pCodeInstruction pic16_pciSUBWF = {
2278   {PC_OPCODE, NULL, NULL, 0, NULL, 
2279    //   genericAnalyze,
2280    genericDestruct,
2281    genericPrint},
2282   POC_SUBWF,
2283   "SUBWF",
2284   2,
2285   NULL, // from branch
2286   NULL, // to branch
2287   NULL, // label
2288   NULL, // operand
2289   NULL, // flow block
2290   NULL, // C source 
2291   3,    // num ops
2292   1,0,  // dest, bit instruction
2293   0,0,  // branch, skip
2294   0,    // literal operand
2295   1,    // RAM access bit
2296   0,    // fast call/return mode select bit
2297   0,    // second memory operand
2298   0,    // second literal operand
2299   POC_NOP,
2300   (PCC_W | PCC_REGISTER),   // inCond
2301   (PCC_REGISTER | PCC_Z), // outCond
2302   PCI_MAGIC
2303 };
2304
2305 pCodeInstruction pic16_pciSUBFW = {
2306   {PC_OPCODE, NULL, NULL, 0, NULL, 
2307    //   genericAnalyze,
2308    genericDestruct,
2309    genericPrint},
2310   POC_SUBFW,
2311   "SUBWF",
2312   2,
2313   NULL, // from branch
2314   NULL, // to branch
2315   NULL, // label
2316   NULL, // operand
2317   NULL, // flow block
2318   NULL, // C source 
2319   3,    // num ops
2320   0,0,  // dest, bit instruction
2321   0,0,  // branch, skip
2322   0,    // literal operand
2323   1,    // RAM access bit
2324   0,    // fast call/return mode select bit
2325   0,    // second memory operand
2326   0,    // second literal operand
2327   POC_NOP,
2328   (PCC_W | PCC_REGISTER),   // inCond
2329   (PCC_W | PCC_Z | PCC_OV | PCC_N), // outCond
2330   PCI_MAGIC
2331 };
2332
2333 pCodeInstruction pic16_pciSUBFWB_D1 = { // mdubuc - New
2334   {PC_OPCODE, NULL, NULL, 0, NULL, 
2335    //   genericAnalyze,
2336    genericDestruct,
2337    genericPrint},
2338   POC_SUBFWB_D1,
2339   "SUBFWB",
2340   2,
2341   NULL, // from branch
2342   NULL, // to branch
2343   NULL, // label
2344   NULL, // operand
2345   NULL, // flow block
2346   NULL, // C source 
2347   3,    // num ops
2348   1,0,  // dest, bit instruction
2349   0,0,  // branch, skip
2350   0,    // literal operand
2351   1,    // RAM access bit
2352   0,    // fast call/return mode select bit
2353   0,    // second memory operand
2354   0,    // second literal operand
2355   POC_NOP,
2356   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
2357   (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
2358   PCI_MAGIC
2359 };
2360
2361 pCodeInstruction pic16_pciSUBFWB_D0 = { // mdubuc - New
2362   {PC_OPCODE, NULL, NULL, 0, NULL, 
2363    //   genericAnalyze,
2364    genericDestruct,
2365    genericPrint},
2366   POC_SUBFWB_D0,
2367   "SUBFWB",
2368   2,
2369   NULL, // from branch
2370   NULL, // to branch
2371   NULL, // label
2372   NULL, // operand
2373   NULL, // flow block
2374   NULL, // C source 
2375   3,    // num ops
2376   0,0,  // dest, bit instruction
2377   0,0,  // branch, skip
2378   0,    // literal operand
2379   1,    // RAM access bit
2380   0,    // fast call/return mode select bit
2381   0,    // second memory operand
2382   0,    // second literal operand
2383   POC_NOP,
2384   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
2385   (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
2386   PCI_MAGIC
2387 };
2388
2389 pCodeInstruction pic16_pciSUBWFB_D1 = { // mdubuc - New
2390   {PC_OPCODE, NULL, NULL, 0, NULL, 
2391    //   genericAnalyze,
2392    genericDestruct,
2393    genericPrint},
2394   POC_SUBWFB_D1,
2395   "SUBWFB",
2396   2,
2397   NULL, // from branch
2398   NULL, // to branch
2399   NULL, // label
2400   NULL, // operand
2401   NULL, // flow block
2402   NULL, // C source 
2403   3,    // num ops
2404   1,0,  // dest, bit instruction
2405   0,0,  // branch, skip
2406   0,    // literal operand
2407   1,    // RAM access bit
2408   0,    // fast call/return mode select bit
2409   0,    // second memory operand
2410   0,    // second literal operand
2411   POC_NOP,
2412   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
2413   (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
2414   PCI_MAGIC
2415 };
2416
2417 pCodeInstruction pic16_pciSUBWFB_D0 = { // mdubuc - New
2418   {PC_OPCODE, NULL, NULL, 0, NULL, 
2419    //   genericAnalyze,
2420    genericDestruct,
2421    genericPrint},
2422   POC_SUBWFB_D0,
2423   "SUBWFB",
2424   2,
2425   NULL, // from branch
2426   NULL, // to branch
2427   NULL, // label
2428   NULL, // operand
2429   NULL, // flow block
2430   NULL, // C source 
2431   3,    // num ops
2432   0,0,  // dest, bit instruction
2433   0,0,  // branch, skip
2434   0,    // literal operand
2435   1,    // RAM access bit
2436   0,    // fast call/return mode select bit
2437   0,    // second memory operand
2438   0,    // second literal operand
2439   POC_NOP,
2440   (PCC_W | PCC_REGISTER | PCC_C),   // inCond
2441   (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_OV | PCC_N), // outCond
2442   PCI_MAGIC
2443 };
2444
2445 pCodeInstruction pic16_pciSWAPF = {
2446   {PC_OPCODE, NULL, NULL, 0, NULL, 
2447    //   genericAnalyze,
2448    genericDestruct,
2449    genericPrint},
2450   POC_SWAPF,
2451   "SWAPF",
2452   2,
2453   NULL, // from branch
2454   NULL, // to branch
2455   NULL, // label
2456   NULL, // operand
2457   NULL, // flow block
2458   NULL, // C source 
2459   3,    // num ops
2460   1,0,  // dest, bit instruction
2461   0,0,  // branch, skip
2462   0,    // literal operand
2463   1,    // RAM access bit
2464   0,    // fast call/return mode select bit
2465   0,    // second memory operand
2466   0,    // second literal operand
2467   POC_NOP,
2468   (PCC_REGISTER),   // inCond
2469   (PCC_REGISTER), // outCond
2470   PCI_MAGIC
2471 };
2472
2473 pCodeInstruction pic16_pciSWAPFW = {
2474   {PC_OPCODE, NULL, NULL, 0, NULL, 
2475    //   genericAnalyze,
2476    genericDestruct,
2477    genericPrint},
2478   POC_SWAPFW,
2479   "SWAPF",
2480   2,
2481   NULL, // from branch
2482   NULL, // to branch
2483   NULL, // label
2484   NULL, // operand
2485   NULL, // flow block
2486   NULL, // C source 
2487   3,    // num ops
2488   0,0,  // dest, bit instruction
2489   0,0,  // branch, skip
2490   0,    // literal operand
2491   1,    // RAM access bit
2492   0,    // fast call/return mode select bit
2493   0,    // second memory operand
2494   0,    // second literal operand
2495   POC_NOP,
2496   (PCC_REGISTER),   // inCond
2497   (PCC_W), // outCond
2498   PCI_MAGIC
2499 };
2500
2501 pCodeInstruction pic16_pciTBLRD = {     // patch 15
2502   {PC_OPCODE, NULL, NULL, 0, NULL, 
2503    genericDestruct,
2504    genericPrint},
2505   POC_TBLRD,
2506   "TBLRD*",
2507   2,
2508   NULL, // from branch
2509   NULL, // to branch
2510   NULL, // label
2511   NULL, // operand
2512   NULL, // flow block
2513   NULL, // C source 
2514   0,    // num ops
2515   0,0,  // dest, bit instruction
2516   0,0,  // branch, skip
2517   0,    // literal operand
2518   0,    // RAM access bit
2519   0,    // fast call/return mode select bit
2520   0,    // second memory operand
2521   0,    // second literal operand
2522   POC_NOP,
2523   PCC_NONE,  // inCond
2524   PCC_NONE  , // outCond
2525   PCI_MAGIC
2526 };
2527
2528 pCodeInstruction pic16_pciTBLRD_POSTINC = {     // patch 15
2529   {PC_OPCODE, NULL, NULL, 0, NULL, 
2530    genericDestruct,
2531    genericPrint},
2532   POC_TBLRD_POSTINC,
2533   "TBLRD*+",
2534   2,
2535   NULL, // from branch
2536   NULL, // to branch
2537   NULL, // label
2538   NULL, // operand
2539   NULL, // flow block
2540   NULL, // C source 
2541   0,    // num ops
2542   0,0,  // dest, bit instruction
2543   0,0,  // branch, skip
2544   0,    // literal operand
2545   0,    // RAM access bit
2546   0,    // fast call/return mode select bit
2547   0,    // second memory operand
2548   0,    // second literal operand
2549   POC_NOP,
2550   PCC_NONE,  // inCond
2551   PCC_NONE  , // outCond
2552   PCI_MAGIC
2553 };
2554
2555 pCodeInstruction pic16_pciTBLRD_POSTDEC = {     // patch 15
2556   {PC_OPCODE, NULL, NULL, 0, NULL, 
2557    genericDestruct,
2558    genericPrint},
2559   POC_TBLRD_POSTDEC,
2560   "TBLRD*-",
2561   2,
2562   NULL, // from branch
2563   NULL, // to branch
2564   NULL, // label
2565   NULL, // operand
2566   NULL, // flow block
2567   NULL, // C source 
2568   0,    // num ops
2569   0,0,  // dest, bit instruction
2570   0,0,  // branch, skip
2571   0,    // literal operand
2572   0,    // RAM access bit
2573   0,    // fast call/return mode select bit
2574   0,    // second memory operand
2575   0,    // second literal operand
2576   POC_NOP,
2577   PCC_NONE,  // inCond
2578   PCC_NONE  , // outCond
2579   PCI_MAGIC
2580 };
2581
2582 pCodeInstruction pic16_pciTBLRD_PREINC = {      // patch 15
2583   {PC_OPCODE, NULL, NULL, 0, NULL, 
2584    genericDestruct,
2585    genericPrint},
2586   POC_TBLRD_PREINC,
2587   "TBLRD+*",
2588   2,
2589   NULL, // from branch
2590   NULL, // to branch
2591   NULL, // label
2592   NULL, // operand
2593   NULL, // flow block
2594   NULL, // C source 
2595   0,    // num ops
2596   0,0,  // dest, bit instruction
2597   0,0,  // branch, skip
2598   0,    // literal operand
2599   0,    // RAM access bit
2600   0,    // fast call/return mode select bit
2601   0,    // second memory operand
2602   0,    // second literal operand
2603   POC_NOP,
2604   PCC_NONE,  // inCond
2605   PCC_NONE  , // outCond
2606   PCI_MAGIC
2607 };
2608
2609 pCodeInstruction pic16_pciTBLWT = {     // patch 15
2610   {PC_OPCODE, NULL, NULL, 0, NULL, 
2611    genericDestruct,
2612    genericPrint},
2613   POC_TBLWT,
2614   "TBLWT*",
2615   2,
2616   NULL, // from branch
2617   NULL, // to branch
2618   NULL, // label
2619   NULL, // operand
2620   NULL, // flow block
2621   NULL, // C source 
2622   0,    // num ops
2623   0,0,  // dest, bit instruction
2624   0,0,  // branch, skip
2625   0,    // literal operand
2626   0,    // RAM access bit
2627   0,    // fast call/return mode select bit
2628   0,    // second memory operand
2629   0,    // second literal operand
2630   POC_NOP,
2631   PCC_NONE,  // inCond
2632   PCC_NONE  , // outCond
2633   PCI_MAGIC
2634 };
2635
2636 pCodeInstruction pic16_pciTBLWT_POSTINC = {     // patch 15
2637   {PC_OPCODE, NULL, NULL, 0, NULL, 
2638    genericDestruct,
2639    genericPrint},
2640   POC_TBLWT_POSTINC,
2641   "TBLWT*+",
2642   2,
2643   NULL, // from branch
2644   NULL, // to branch
2645   NULL, // label
2646   NULL, // operand
2647   NULL, // flow block
2648   NULL, // C source 
2649   0,    // num ops
2650   0,0,  // dest, bit instruction
2651   0,0,  // branch, skip
2652   0,    // literal operand
2653   0,    // RAM access bit
2654   0,    // fast call/return mode select bit
2655   0,    // second memory operand
2656   0,    // second literal operand
2657   POC_NOP,
2658   PCC_NONE,  // inCond
2659   PCC_NONE  , // outCond
2660   PCI_MAGIC
2661 };
2662
2663 pCodeInstruction pic16_pciTBLWT_POSTDEC = {     // patch 15
2664   {PC_OPCODE, NULL, NULL, 0, NULL, 
2665    genericDestruct,
2666    genericPrint},
2667   POC_TBLWT_POSTDEC,
2668   "TBLWT*-",
2669   2,
2670   NULL, // from branch
2671   NULL, // to branch
2672   NULL, // label
2673   NULL, // operand
2674   NULL, // flow block
2675   NULL, // C source 
2676   0,    // num ops
2677   0,0,  // dest, bit instruction
2678   0,0,  // branch, skip
2679   0,    // literal operand
2680   0,    // RAM access bit
2681   0,    // fast call/return mode select bit
2682   0,    // second memory operand
2683   0,    // second literal operand
2684   POC_NOP,
2685   PCC_NONE,  // inCond
2686   PCC_NONE  , // outCond
2687   PCI_MAGIC
2688 };
2689
2690 pCodeInstruction pic16_pciTBLWT_PREINC = {      // patch 15
2691   {PC_OPCODE, NULL, NULL, 0, NULL, 
2692    genericDestruct,
2693    genericPrint},
2694   POC_TBLWT_PREINC,
2695   "TBLWT+*",
2696   2,
2697   NULL, // from branch
2698   NULL, // to branch
2699   NULL, // label
2700   NULL, // operand
2701   NULL, // flow block
2702   NULL, // C source 
2703   0,    // num ops
2704   0,0,  // dest, bit instruction
2705   0,0,  // branch, skip
2706   0,    // literal operand
2707   0,    // RAM access bit
2708   0,    // fast call/return mode select bit
2709   0,    // second memory operand
2710   0,    // second literal operand
2711   POC_NOP,
2712   PCC_NONE,  // inCond
2713   PCC_NONE  , // outCond
2714   PCI_MAGIC
2715 };
2716
2717 pCodeInstruction pic16_pciTSTFSZ = { // mdubuc - New
2718   {PC_OPCODE, NULL, NULL, 0, NULL, 
2719    //   genericAnalyze,
2720    genericDestruct,
2721    genericPrint},
2722   POC_TSTFSZ,
2723   "TSTFSZ",
2724   2,
2725   NULL, // from branch
2726   NULL, // to branch
2727   NULL, // label
2728   NULL, // operand
2729   NULL, // flow block
2730   NULL, // C source 
2731   2,    // num ops
2732   0,0,  // dest, bit instruction
2733   1,1,  // branch, skip
2734   0,    // literal operand
2735   1,    // RAM access bit
2736   0,    // fast call/return mode select bit
2737   0,    // second memory operand
2738   0,    // second literal operand
2739   POC_NOP,
2740   PCC_REGISTER,   // inCond
2741   PCC_NONE, // outCond
2742   PCI_MAGIC
2743 };
2744
2745 pCodeInstruction pic16_pciXORWF = {
2746   {PC_OPCODE, NULL, NULL, 0, NULL, 
2747    //   genericAnalyze,
2748    genericDestruct,
2749    genericPrint},
2750   POC_XORWF,
2751   "XORWF",
2752   2,
2753   NULL, // from branch
2754   NULL, // to branch
2755   NULL, // label
2756   NULL, // operand
2757   NULL, // flow block
2758   NULL, // C source 
2759   3,    // num ops
2760   1,0,  // dest, bit instruction
2761   0,0,  // branch, skip
2762   0,    // literal operand
2763   1,    // RAM access bit
2764   0,    // fast call/return mode select bit
2765   0,    // second memory operand
2766   0,    // second literal operand
2767   POC_NOP,
2768   (PCC_W | PCC_REGISTER),   // inCond
2769   (PCC_REGISTER | PCC_Z | PCC_N), // outCond
2770   PCI_MAGIC
2771 };
2772
2773 pCodeInstruction pic16_pciXORFW = {
2774   {PC_OPCODE, NULL, NULL, 0, NULL, 
2775    //   genericAnalyze,
2776    genericDestruct,
2777    genericPrint},
2778   POC_XORFW,
2779   "XORWF",
2780   2,
2781   NULL, // from branch
2782   NULL, // to branch
2783   NULL, // label
2784   NULL, // operand
2785   NULL, // flow block
2786   NULL, // C source 
2787   3,    // num ops
2788   0,0,  // dest, bit instruction
2789   0,0,  // branch, skip
2790   0,    // literal operand
2791   1,    // RAM access bit
2792   0,    // fast call/return mode select bit
2793   0,    // second memory operand
2794   0,    // second literal operand
2795   POC_NOP,
2796   (PCC_W | PCC_REGISTER),   // inCond
2797   (PCC_W | PCC_Z | PCC_N), // outCond
2798   PCI_MAGIC
2799 };
2800
2801 pCodeInstruction pic16_pciXORLW = {
2802   {PC_OPCODE, NULL, NULL, 0, NULL, 
2803    //   genericAnalyze,
2804    genericDestruct,
2805    genericPrint},
2806   POC_XORLW,
2807   "XORLW",
2808   2,
2809   NULL, // from branch
2810   NULL, // to branch
2811   NULL, // label
2812   NULL, // operand
2813   NULL, // flow block
2814   NULL, // C source 
2815   1,    // num ops
2816   0,0,  // dest, bit instruction
2817   0,0,  // branch, skip
2818   1,    // literal operand
2819   1,    // RAM access bit
2820   0,    // fast call/return mode select bit
2821   0,    // second memory operand
2822   0,    // second literal operand
2823   POC_NOP,
2824   (PCC_W | PCC_LITERAL),   // inCond
2825   (PCC_W | PCC_Z | PCC_C | PCC_DC | PCC_N), // outCond
2826   PCI_MAGIC
2827 };
2828
2829
2830 pCodeInstruction pic16_pciBANKSEL = {
2831   {PC_OPCODE, NULL, NULL, 0, NULL, 
2832    genericDestruct,
2833    genericPrint},
2834   POC_BANKSEL,
2835   "BANKSEL",
2836   2,
2837   NULL, // from branch
2838   NULL, // to branch
2839   NULL, // label
2840   NULL, // operand
2841   NULL, // flow block
2842   NULL, // C source 
2843   0,    // num ops
2844   0,0,  // dest, bit instruction
2845   0,0,  // branch, skip
2846   0,    // literal operand
2847   0,    // RAM access bit
2848   0,    // fast call/return mode select bit
2849   0,    // second memory operand
2850   0,    // second literal operand
2851   POC_NOP,
2852   PCC_NONE,   // inCond
2853   PCC_NONE, // outCond
2854   PCI_MAGIC
2855 };
2856
2857
2858 #define MAX_PIC16MNEMONICS 100
2859 pCodeInstruction *pic16Mnemonics[MAX_PIC16MNEMONICS];
2860
2861 //#define USE_VSNPRINTF
2862 #if OPT_DISABLE_PIC
2863
2864 #ifdef USE_VSNPRINTF
2865   // Alas, vsnprintf is not ANSI standard, and does not exist
2866   // on Solaris (and probably other non-Gnu flavored Unixes).
2867
2868 /*-----------------------------------------------------------------*/
2869 /* SAFE_snprintf - like snprintf except the string pointer is      */
2870 /*                 after the string has been printed to. This is   */
2871 /*                 useful for printing to string as though if it   */
2872 /*                 were a stream.                                  */
2873 /*-----------------------------------------------------------------*/
2874 void SAFE_snprintf(char **str, size_t *size, const  char  *format, ...)
2875 {
2876   va_list val;
2877   int len;
2878
2879   if(!str || !*str)
2880     return;
2881
2882   va_start(val, format);
2883
2884   vsnprintf(*str, *size, format, val);
2885
2886   va_end (val);
2887
2888   len = strlen(*str);
2889   if(len > *size) {
2890     fprintf(stderr,"WARNING, it looks like %s has overflowed\n",__FUNCTION__);
2891     fprintf(stderr,"len = %d is > str size %d\n",len,*size);
2892   }
2893
2894   *str += len;
2895   *size -= len;
2896
2897 }
2898
2899 #else
2900 // This version is *not* safe, despite the name.
2901
2902 void SAFE_snprintf(char **str, size_t *size, const  char  *format, ...)
2903 {
2904   va_list val;
2905   int len;
2906   static char buffer[1024]; /* grossly conservative, but still not inherently safe */
2907
2908   if(!str || !*str)
2909     return;
2910
2911   va_start(val, format);
2912
2913   vsprintf(buffer, format, val);
2914   va_end (val);
2915
2916   len = strlen(buffer);
2917   if(len > *size) {
2918     fprintf(stderr,"WARNING, it looks like %s has overflowed\n",__FUNCTION__);
2919     fprintf(stderr,"len = %d is > str size %d\n",len, (int) *size);
2920   }
2921
2922   strcpy(*str, buffer);
2923   *str += len;
2924   *size -= len;
2925
2926 }
2927
2928 #endif    //  USE_VSNPRINTF
2929 #endif
2930
2931 extern set *externs;
2932 extern  void pic16_initStack(int base_address, int size);
2933 extern regs *pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias);
2934 extern regs *pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias);
2935 extern void pic16_init_pic(char *);
2936
2937 void  pic16_pCodeInitRegisters(void)
2938 {
2939   static int initialized=0;
2940
2941         if(initialized)
2942                 return;
2943         
2944         initialized = 1;
2945
2946 //      pic16_initStack(0xfff, 8);
2947         pic16_init_pic(port->processor);
2948
2949         pic16_pc_status.r = pic16_allocProcessorRegister(IDX_STATUS,"STATUS", PO_STATUS, 0x80);
2950         pic16_pc_pcl.r = pic16_allocProcessorRegister(IDX_PCL,"PCL", PO_PCL, 0x80);
2951         pic16_pc_pclath.r = pic16_allocProcessorRegister(IDX_PCLATH,"PCLATH", PO_PCLATH, 0x80);
2952         pic16_pc_pclatu.r = pic16_allocProcessorRegister(IDX_PCLATU,"PCLATU", PO_PCLATU, 0x80);
2953         pic16_pc_intcon.r = pic16_allocProcessorRegister(IDX_INTCON,"INTCON", PO_INTCON, 0x80);
2954         pic16_pc_wreg.r = pic16_allocProcessorRegister(IDX_WREG,"WREG", PO_WREG, 0x80);
2955         pic16_pc_bsr.r = pic16_allocProcessorRegister(IDX_BSR,"BSR", PO_BSR, 0x80);
2956
2957         pic16_pc_tosl.r = pic16_allocProcessorRegister(IDX_TOSL,"TOSL", PO_SFR_REGISTER, 0x80);
2958         pic16_pc_tosh.r = pic16_allocProcessorRegister(IDX_TOSH,"TOSH", PO_SFR_REGISTER, 0x80);
2959         pic16_pc_tosu.r = pic16_allocProcessorRegister(IDX_TOSU,"TOSU", PO_SFR_REGISTER, 0x80);
2960
2961         pic16_pc_tblptrl.r = pic16_allocProcessorRegister(IDX_TBLPTRL,"TBLPTRL", PO_SFR_REGISTER, 0x80);
2962         pic16_pc_tblptrh.r = pic16_allocProcessorRegister(IDX_TBLPTRH,"TBLPTRH", PO_SFR_REGISTER, 0x80);
2963         pic16_pc_tblptru.r = pic16_allocProcessorRegister(IDX_TBLPTRU,"TBLPTRU", PO_SFR_REGISTER, 0x80);
2964         pic16_pc_tablat.r = pic16_allocProcessorRegister(IDX_TABLAT,"TABLAT", PO_SFR_REGISTER, 0x80);
2965
2966         pic16_pc_fsr0l.r = pic16_allocProcessorRegister(IDX_FSR0L, "FSR0L", PO_FSR0, 0x80);
2967         pic16_pc_fsr0h.r = pic16_allocProcessorRegister(IDX_FSR0H, "FSR0H", PO_FSR0, 0x80);
2968         pic16_pc_fsr1l.r = pic16_allocProcessorRegister(IDX_FSR1L, "FSR1L", PO_FSR0, 0x80);
2969         pic16_pc_fsr1h.r = pic16_allocProcessorRegister(IDX_FSR1H, "FSR1H", PO_FSR0, 0x80);
2970         pic16_pc_fsr2l.r = pic16_allocProcessorRegister(IDX_FSR2L, "FSR2L", PO_FSR0, 0x80);
2971         pic16_pc_fsr2h.r = pic16_allocProcessorRegister(IDX_FSR2H, "FSR2H", PO_FSR0, 0x80);
2972
2973         pic16_pc_indf0.r = pic16_allocProcessorRegister(IDX_INDF0,"INDF0", PO_INDF0, 0x80);
2974         pic16_pc_postinc0.r = pic16_allocProcessorRegister(IDX_POSTINC0, "POSTINC0", PO_INDF0, 0x80);
2975         pic16_pc_postdec0.r = pic16_allocProcessorRegister(IDX_POSTDEC0, "POSTDEC0", PO_INDF0, 0x80);
2976         pic16_pc_preinc0.r = pic16_allocProcessorRegister(IDX_PREINC0, "PREINC0", PO_INDF0, 0x80);
2977         pic16_pc_plusw0.r = pic16_allocProcessorRegister(IDX_PLUSW0, "PLUSW0", PO_INDF0, 0x80);
2978         
2979         pic16_pc_indf1.r = pic16_allocProcessorRegister(IDX_INDF1,"INDF1", PO_INDF0, 0x80);
2980         pic16_pc_postinc1.r = pic16_allocProcessorRegister(IDX_POSTINC1, "POSTINC1", PO_INDF0, 0x80);
2981         pic16_pc_postdec1.r = pic16_allocProcessorRegister(IDX_POSTDEC1, "POSTDEC1", PO_INDF0, 0x80);
2982         pic16_pc_preinc1.r = pic16_allocProcessorRegister(IDX_PREINC1, "PREINC1", PO_INDF0, 0x80);
2983         pic16_pc_plusw1.r = pic16_allocProcessorRegister(IDX_PLUSW1, "PLUSW1", PO_INDF0, 0x80);
2984
2985         pic16_pc_indf2.r = pic16_allocProcessorRegister(IDX_INDF2,"INDF2", PO_INDF0, 0x80);
2986         pic16_pc_postinc2.r = pic16_allocProcessorRegister(IDX_POSTINC2, "POSTINC2", PO_INDF0, 0x80);
2987         pic16_pc_postdec2.r = pic16_allocProcessorRegister(IDX_POSTDEC2, "POSTDEC2", PO_INDF0, 0x80);
2988         pic16_pc_preinc2.r = pic16_allocProcessorRegister(IDX_PREINC2, "PREINC2", PO_INDF0, 0x80);
2989         pic16_pc_plusw2.r = pic16_allocProcessorRegister(IDX_PLUSW2, "PLUSW2", PO_INDF0, 0x80);
2990         
2991         pic16_pc_prodl.r = pic16_allocProcessorRegister(IDX_PRODL, "PRODL", PO_PRODL, 0x80);
2992         pic16_pc_prodh.r = pic16_allocProcessorRegister(IDX_PRODH, "PRODH", PO_PRODH, 0x80);
2993
2994
2995         pic16_pc_eecon1.r = pic16_allocProcessorRegister(IDX_EECON1, "EECON1", PO_SFR_REGISTER, 0x80);
2996         pic16_pc_eecon2.r = pic16_allocProcessorRegister(IDX_EECON2, "EECON2", PO_SFR_REGISTER, 0x80);
2997         pic16_pc_eedata.r = pic16_allocProcessorRegister(IDX_EEDATA, "EEDATA", PO_SFR_REGISTER, 0x80);
2998         pic16_pc_eeadr.r = pic16_allocProcessorRegister(IDX_EEADR, "EEADR", PO_SFR_REGISTER, 0x80);
2999
3000         
3001         pic16_pc_status.rIdx = IDX_STATUS;
3002         pic16_pc_intcon.rIdx = IDX_INTCON;
3003         pic16_pc_pcl.rIdx = IDX_PCL;
3004         pic16_pc_pclath.rIdx = IDX_PCLATH;
3005         pic16_pc_pclatu.rIdx = IDX_PCLATU;
3006         pic16_pc_wreg.rIdx = IDX_WREG;
3007         pic16_pc_bsr.rIdx = IDX_BSR;
3008
3009         pic16_pc_tosl.rIdx = IDX_TOSL;
3010         pic16_pc_tosh.rIdx = IDX_TOSH;
3011         pic16_pc_tosu.rIdx = IDX_TOSU;
3012
3013         pic16_pc_tblptrl.rIdx = IDX_TBLPTRL;
3014         pic16_pc_tblptrh.rIdx = IDX_TBLPTRH;
3015         pic16_pc_tblptru.rIdx = IDX_TBLPTRU;
3016         pic16_pc_tablat.rIdx = IDX_TABLAT;
3017
3018         pic16_pc_fsr0l.rIdx = IDX_FSR0L;
3019         pic16_pc_fsr0h.rIdx = IDX_FSR0H;
3020         pic16_pc_fsr1l.rIdx = IDX_FSR1L;
3021         pic16_pc_fsr1h.rIdx = IDX_FSR1H;
3022         pic16_pc_fsr2l.rIdx = IDX_FSR2L;
3023         pic16_pc_fsr2h.rIdx = IDX_FSR2H;
3024         pic16_pc_indf0.rIdx = IDX_INDF0;
3025         pic16_pc_postinc0.rIdx = IDX_POSTINC0;
3026         pic16_pc_postdec0.rIdx = IDX_POSTDEC0;
3027         pic16_pc_preinc0.rIdx = IDX_PREINC0;
3028         pic16_pc_plusw0.rIdx = IDX_PLUSW0;
3029         pic16_pc_indf1.rIdx = IDX_INDF1;
3030         pic16_pc_postinc1.rIdx = IDX_POSTINC1;
3031         pic16_pc_postdec1.rIdx = IDX_POSTDEC1;
3032         pic16_pc_preinc1.rIdx = IDX_PREINC1;
3033         pic16_pc_plusw1.rIdx = IDX_PLUSW1;
3034         pic16_pc_indf2.rIdx = IDX_INDF2;
3035         pic16_pc_postinc2.rIdx = IDX_POSTINC2;
3036         pic16_pc_postdec2.rIdx = IDX_POSTDEC2;
3037         pic16_pc_preinc2.rIdx = IDX_PREINC2;
3038         pic16_pc_plusw2.rIdx = IDX_PLUSW2;
3039         pic16_pc_prodl.rIdx = IDX_PRODL;
3040         pic16_pc_prodh.rIdx = IDX_PRODH;
3041         
3042         pic16_pc_kzero.r = pic16_allocInternalRegister(IDX_KZ,"KZ",PO_GPR_REGISTER,0);
3043         pic16_pc_ssave.r = pic16_allocInternalRegister(IDX_SSAVE,"SSAVE", PO_GPR_REGISTER, 0);
3044         pic16_pc_wsave.r = pic16_allocInternalRegister(IDX_WSAVE,"WSAVE", PO_GPR_REGISTER, 0);
3045         
3046         pic16_pc_kzero.rIdx = IDX_KZ;
3047         pic16_pc_wsave.rIdx = IDX_WSAVE;
3048         pic16_pc_ssave.rIdx = IDX_SSAVE;
3049
3050         pic16_pc_eecon1.rIdx = IDX_EECON1;
3051         pic16_pc_eecon2.rIdx = IDX_EECON2;
3052         pic16_pc_eedata.rIdx = IDX_EEDATA;
3053         pic16_pc_eeadr.rIdx = IDX_EEADR;
3054         
3055         
3056         pic16_pc_gpsimio.r = pic16_allocProcessorRegister(IDX_GPSIMIO, "GPSIMIO", PO_GPR_REGISTER, 0x80);
3057         pic16_pc_gpsimio2.r = pic16_allocProcessorRegister(IDX_GPSIMIO2, "GPSIMIO2", PO_GPR_REGISTER, 0x80);
3058
3059         pic16_pc_gpsimio.rIdx = IDX_GPSIMIO;
3060         pic16_pc_gpsimio2.rIdx = IDX_GPSIMIO2;
3061
3062         /* probably should put this in a separate initialization routine */
3063         pb_dead_pcodes = newpBlock();
3064
3065 }
3066
3067 #if OPT_DISABLE_PIC
3068 /*-----------------------------------------------------------------*/
3069 /*  mnem2key - convert a pic mnemonic into a hash key              */
3070 /*   (BTW - this spreads the mnemonics quite well)                 */
3071 /*                                                                 */
3072 /*-----------------------------------------------------------------*/
3073
3074 int mnem2key(char const *mnem)
3075 {
3076   int key = 0;
3077
3078   if(!mnem)
3079     return 0;
3080
3081   while(*mnem) {
3082
3083     key += toupper(*mnem++) +1;
3084
3085   }
3086
3087   return (key & 0x1f);
3088
3089 }
3090 #endif
3091
3092 void pic16initMnemonics(void)
3093 {
3094   int i = 0;
3095   int key;
3096   //  char *str;
3097   pCodeInstruction *pci;
3098
3099   if(mnemonics_initialized)
3100     return;
3101
3102   // NULL out the array before making the assignments
3103   // since we check the array contents below this initialization.
3104
3105   for (i = 0; i < MAX_PIC16MNEMONICS; i++) {
3106     pic16Mnemonics[i] = NULL;
3107   }
3108
3109   pic16Mnemonics[POC_ADDLW] = &pic16_pciADDLW;
3110   pic16Mnemonics[POC_ADDWF] = &pic16_pciADDWF;
3111   pic16Mnemonics[POC_ADDFW] = &pic16_pciADDFW;
3112   pic16Mnemonics[POC_ADDWFC] = &pic16_pciADDWFC;
3113   pic16Mnemonics[POC_ADDFWC] = &pic16_pciADDFWC;
3114   pic16Mnemonics[POC_ANDLW] = &pic16_pciANDLW;
3115   pic16Mnemonics[POC_ANDWF] = &pic16_pciANDWF;
3116   pic16Mnemonics[POC_ANDFW] = &pic16_pciANDFW;
3117   pic16Mnemonics[POC_BC] = &pic16_pciBC;
3118   pic16Mnemonics[POC_BCF] = &pic16_pciBCF;
3119   pic16Mnemonics[POC_BN] = &pic16_pciBN;
3120   pic16Mnemonics[POC_BNC] = &pic16_pciBNC;
3121   pic16Mnemonics[POC_BNN] = &pic16_pciBNN;
3122   pic16Mnemonics[POC_BNOV] = &pic16_pciBNOV;
3123   pic16Mnemonics[POC_BNZ] = &pic16_pciBNZ;
3124   pic16Mnemonics[POC_BOV] = &pic16_pciBOV;
3125   pic16Mnemonics[POC_BRA] = &pic16_pciBRA;
3126   pic16Mnemonics[POC_BSF] = &pic16_pciBSF;
3127   pic16Mnemonics[POC_BTFSC] = &pic16_pciBTFSC;
3128   pic16Mnemonics[POC_BTFSS] = &pic16_pciBTFSS;
3129   pic16Mnemonics[POC_BTG] = &pic16_pciBTG;
3130   pic16Mnemonics[POC_BZ] = &pic16_pciBZ;
3131   pic16Mnemonics[POC_CALL] = &pic16_pciCALL;
3132   pic16Mnemonics[POC_CLRF] = &pic16_pciCLRF;
3133   pic16Mnemonics[POC_CLRWDT] = &pic16_pciCLRWDT;
3134   pic16Mnemonics[POC_COMF] = &pic16_pciCOMF;
3135   pic16Mnemonics[POC_COMFW] = &pic16_pciCOMFW;
3136   pic16Mnemonics[POC_CPFSEQ] = &pic16_pciCPFSEQ;
3137   pic16Mnemonics[POC_CPFSGT] = &pic16_pciCPFSGT;
3138   pic16Mnemonics[POC_CPFSLT] = &pic16_pciCPFSLT;
3139   pic16Mnemonics[POC_DAW] = &pic16_pciDAW;
3140   pic16Mnemonics[POC_DCFSNZ] = &pic16_pciDCFSNZ;
3141   pic16Mnemonics[POC_DECF] = &pic16_pciDECF;
3142   pic16Mnemonics[POC_DECFW] = &pic16_pciDECFW;
3143   pic16Mnemonics[POC_DECFSZ] = &pic16_pciDECFSZ;
3144   pic16Mnemonics[POC_DECFSZW] = &pic16_pciDECFSZW;
3145   pic16Mnemonics[POC_GOTO] = &pic16_pciGOTO;
3146   pic16Mnemonics[POC_INCF] = &pic16_pciINCF;
3147   pic16Mnemonics[POC_INCFW] = &pic16_pciINCFW;
3148   pic16Mnemonics[POC_INCFSZ] = &pic16_pciINCFSZ;
3149   pic16Mnemonics[POC_INCFSZW] = &pic16_pciINCFSZW;
3150   pic16Mnemonics[POC_INFSNZ] = &pic16_pciINFSNZ;
3151   pic16Mnemonics[POC_INFSNZW] = &pic16_pciINFSNZW;
3152   pic16Mnemonics[POC_IORWF] = &pic16_pciIORWF;
3153   pic16Mnemonics[POC_IORFW] = &pic16_pciIORFW;
3154   pic16Mnemonics[POC_IORLW] = &pic16_pciIORLW;
3155   pic16Mnemonics[POC_LFSR] = &pic16_pciLFSR;
3156   pic16Mnemonics[POC_MOVF] = &pic16_pciMOVF;
3157   pic16Mnemonics[POC_MOVFW] = &pic16_pciMOVFW;
3158   pic16Mnemonics[POC_MOVFF] = &pic16_pciMOVFF;
3159   pic16Mnemonics[POC_MOVLB] = &pic16_pciMOVLB;
3160   pic16Mnemonics[POC_MOVLW] = &pic16_pciMOVLW;
3161   pic16Mnemonics[POC_MOVWF] = &pic16_pciMOVWF;
3162   pic16Mnemonics[POC_MULLW] = &pic16_pciMULLW;
3163   pic16Mnemonics[POC_MULWF] = &pic16_pciMULWF;
3164   pic16Mnemonics[POC_NEGF] = &pic16_pciNEGF;
3165   pic16Mnemonics[POC_NOP] = &pic16_pciNOP;
3166   pic16Mnemonics[POC_POP] = &pic16_pciPOP;
3167   pic16Mnemonics[POC_PUSH] = &pic16_pciPUSH;
3168   pic16Mnemonics[POC_RCALL] = &pic16_pciRCALL;
3169   pic16Mnemonics[POC_RETFIE] = &pic16_pciRETFIE;
3170   pic16Mnemonics[POC_RETLW] = &pic16_pciRETLW;
3171   pic16Mnemonics[POC_RETURN] = &pic16_pciRETURN;
3172   pic16Mnemonics[POC_RLCF] = &pic16_pciRLCF;
3173   pic16Mnemonics[POC_RLCFW] = &pic16_pciRLCFW;
3174   pic16Mnemonics[POC_RLNCF] = &pic16_pciRLNCF;
3175   pic16Mnemonics[POC_RLNCFW] = &pic16_pciRLNCFW;
3176   pic16Mnemonics[POC_RRCF] = &pic16_pciRRCF;
3177   pic16Mnemonics[POC_RRCFW] = &pic16_pciRRCFW;
3178   pic16Mnemonics[POC_RRNCF] = &pic16_pciRRNCF;
3179   pic16Mnemonics[POC_RRNCFW] = &pic16_pciRRNCFW;
3180   pic16Mnemonics[POC_SETF] = &pic16_pciSETF;
3181   pic16Mnemonics[POC_SUBLW] = &pic16_pciSUBLW;
3182   pic16Mnemonics[POC_SUBWF] = &pic16_pciSUBWF;
3183   pic16Mnemonics[POC_SUBFW] = &pic16_pciSUBFW;
3184   pic16Mnemonics[POC_SUBWFB_D0] = &pic16_pciSUBWFB_D0;
3185   pic16Mnemonics[POC_SUBWFB_D1] = &pic16_pciSUBWFB_D1;
3186   pic16Mnemonics[POC_SUBFWB_D0] = &pic16_pciSUBFWB_D0;
3187   pic16Mnemonics[POC_SUBFWB_D1] = &pic16_pciSUBFWB_D1;
3188   pic16Mnemonics[POC_SWAPF] = &pic16_pciSWAPF;
3189   pic16Mnemonics[POC_SWAPFW] = &pic16_pciSWAPFW;
3190   pic16Mnemonics[POC_TBLRD] = &pic16_pciTBLRD;
3191   pic16Mnemonics[POC_TBLRD_POSTINC] = &pic16_pciTBLRD_POSTINC;
3192   pic16Mnemonics[POC_TBLRD_POSTDEC] = &pic16_pciTBLRD_POSTDEC;
3193   pic16Mnemonics[POC_TBLRD_PREINC] = &pic16_pciTBLRD_PREINC;
3194   pic16Mnemonics[POC_TBLWT] = &pic16_pciTBLWT;
3195   pic16Mnemonics[POC_TBLWT_POSTINC] = &pic16_pciTBLWT_POSTINC;
3196   pic16Mnemonics[POC_TBLWT_POSTDEC] = &pic16_pciTBLWT_POSTDEC;
3197   pic16Mnemonics[POC_TBLWT_PREINC] = &pic16_pciTBLWT_PREINC;
3198   pic16Mnemonics[POC_TSTFSZ] = &pic16_pciTSTFSZ;
3199   pic16Mnemonics[POC_XORLW] = &pic16_pciXORLW;
3200   pic16Mnemonics[POC_XORWF] = &pic16_pciXORWF;
3201   pic16Mnemonics[POC_XORFW] = &pic16_pciXORFW;
3202   pic16Mnemonics[POC_BANKSEL] = &pic16_pciBANKSEL;
3203
3204   for(i=0; i<MAX_PIC16MNEMONICS; i++)
3205     if(pic16Mnemonics[i])
3206       hTabAddItem(&pic16MnemonicsHash, mnem2key(pic16Mnemonics[i]->mnemonic), pic16Mnemonics[i]);
3207   pci = hTabFirstItem(pic16MnemonicsHash, &key);
3208
3209   while(pci) {
3210     DFPRINTF((stderr, "element %d key %d, mnem %s\n",i++,key,pci->mnemonic));
3211     pci = hTabNextItem(pic16MnemonicsHash, &key);
3212   }
3213
3214   mnemonics_initialized = 1;
3215 }
3216
3217 int pic16_getpCodePeepCommand(char *cmd);
3218
3219 int pic16_getpCode(char *mnem,unsigned dest)
3220 {
3221
3222   pCodeInstruction *pci;
3223   int key = mnem2key(mnem);
3224
3225   if(!mnemonics_initialized)
3226     pic16initMnemonics();
3227
3228   pci = hTabFirstItemWK(pic16MnemonicsHash, key);
3229
3230   while(pci) {
3231
3232     if(STRCASECMP(pci->mnemonic, mnem) == 0) {
3233       if((pci->num_ops <= 1)
3234         || (pci->isModReg == dest)
3235         || (pci->isBitInst)
3236         || (pci->num_ops <= 2 && pci->isAccess)
3237         || (pci->num_ops <= 2 && pci->isFastCall)
3238         || (pci->num_ops <= 2 && pci->is2MemOp)
3239         || (pci->num_ops <= 2 && pci->is2LitOp) )
3240         return(pci->op);
3241     }
3242
3243     pci = hTabNextItemWK (pic16MnemonicsHash);
3244   
3245   }
3246
3247   return -1;
3248 }
3249
3250 /*-----------------------------------------------------------------*
3251  * pic16initpCodePeepCommands
3252  *
3253  *-----------------------------------------------------------------*/
3254 void pic16initpCodePeepCommands(void)
3255 {
3256
3257   int key, i;
3258   peepCommand *pcmd;
3259
3260   i = 0;
3261   do {
3262     hTabAddItem(&pic16pCodePeepCommandsHash, 
3263                 mnem2key(peepCommands[i].cmd), &peepCommands[i]);
3264     i++;
3265   } while (peepCommands[i].cmd);
3266
3267   pcmd = hTabFirstItem(pic16pCodePeepCommandsHash, &key);
3268
3269   while(pcmd) {
3270     //fprintf(stderr, "peep command %s  key %d\n",pcmd->cmd,pcmd->id);
3271     pcmd = hTabNextItem(pic16pCodePeepCommandsHash, &key);
3272   }
3273
3274 }
3275
3276 /*-----------------------------------------------------------------
3277  *
3278  *
3279  *-----------------------------------------------------------------*/
3280
3281 int pic16_getpCodePeepCommand(char *cmd)
3282 {
3283
3284   peepCommand *pcmd;
3285   int key = mnem2key(cmd);
3286
3287
3288   pcmd = hTabFirstItemWK(pic16pCodePeepCommandsHash, key);
3289
3290   while(pcmd) {
3291     // fprintf(stderr," comparing %s to %s\n",pcmd->cmd,cmd);
3292     if(STRCASECMP(pcmd->cmd, cmd) == 0) {
3293       return pcmd->id;
3294     }
3295
3296     pcmd = hTabNextItemWK (pic16pCodePeepCommandsHash);
3297   
3298   }
3299
3300   return -1;
3301 }
3302
3303 static char getpBlock_dbName(pBlock *pb)
3304 {
3305   if(!pb)
3306     return 0;
3307
3308   if(pb->cmemmap)
3309     return pb->cmemmap->dbName;
3310
3311   return pb->dbName;
3312 }
3313 void pic16_pBlockConvert2ISR(pBlock *pb)
3314 {
3315         if(!pb)return;
3316
3317         if(pb->cmemmap)pb->cmemmap = NULL;
3318
3319         pb->dbName = 'I';
3320
3321         if(pic16_pcode_verbose)
3322                 fprintf(stderr, "%s:%d converting to 'I'interrupt pBlock\n", __FILE__, __LINE__);
3323 }
3324
3325 void pic16_pBlockConvert2Absolute(pBlock *pb)
3326 {
3327         if(!pb)return;
3328         if(pb->cmemmap)pb->cmemmap = NULL;
3329         
3330         pb->dbName = 'A';
3331         
3332         if(pic16_pcode_verbose)
3333                 fprintf(stderr, "%s:%d converting to 'A'bsolute pBlock\n", __FILE__, __LINE__);
3334 }
3335   
3336 /*-----------------------------------------------------------------*/
3337 /* pic16_movepBlock2Head - given the dbname of a pBlock, move all  */
3338 /*                   instances to the front of the doubly linked   */
3339 /*                   list of pBlocks                               */
3340 /*-----------------------------------------------------------------*/
3341
3342 void pic16_movepBlock2Head(char dbName)
3343 {
3344   pBlock *pb;
3345
3346
3347   /* this can happen in sources without code,
3348    * only variable definitions */
3349   if(!the_pFile)return;
3350
3351   pb = the_pFile->pbHead;
3352
3353   while(pb) {
3354
3355     if(getpBlock_dbName(pb) == dbName) {
3356       pBlock *pbn = pb->next;
3357       pb->next = the_pFile->pbHead;
3358       the_pFile->pbHead->prev = pb;
3359       the_pFile->pbHead = pb;
3360
3361       if(pb->prev)
3362         pb->prev->next = pbn;
3363
3364       // If the pBlock that we just moved was the last
3365       // one in the link of all of the pBlocks, then we
3366       // need to point the tail to the block just before
3367       // the one we moved.
3368       // Note: if pb->next is NULL, then pb must have 
3369       // been the last pBlock in the chain.
3370
3371       if(pbn)
3372         pbn->prev = pb->prev;
3373       else
3374         the_pFile->pbTail = pb->prev;
3375
3376       pb = pbn;
3377
3378     } else
3379       pb = pb->next;
3380
3381   }
3382
3383 }
3384
3385 void pic16_copypCode(FILE *of, char dbName)
3386 {
3387   pBlock *pb;
3388
3389         if(!of || !the_pFile)
3390                 return;
3391
3392         for(pb = the_pFile->pbHead; pb; pb = pb->next) {
3393                 if(getpBlock_dbName(pb) == dbName) {
3394 //                      fprintf(stderr, "%s:%d: output of pb= 0x%p\n", __FILE__, __LINE__, pb);
3395                         pBlockStats(of,pb);
3396                         pic16_printpBlock(of,pb);
3397                 }
3398         }
3399
3400 }
3401 void pic16_pcode_test(void)
3402 {
3403
3404   DFPRINTF((stderr,"pcode is alive!\n"));
3405
3406   //initMnemonics();
3407
3408   if(the_pFile) {
3409
3410     pBlock *pb;
3411     FILE *pFile;
3412     char buffer[100];
3413
3414     /* create the file name */
3415     strcpy(buffer,dstFileName);
3416     strcat(buffer,".p");
3417
3418     if( !(pFile = fopen(buffer, "w" ))) {
3419       werror(E_FILE_OPEN_ERR,buffer);
3420       exit(1);
3421     }
3422
3423     fprintf(pFile,"pcode dump\n\n");
3424
3425     for(pb = the_pFile->pbHead; pb; pb = pb->next) {
3426       fprintf(pFile,"\n\tNew pBlock\n\n");
3427       if(pb->cmemmap)
3428         fprintf(pFile,"%s",pb->cmemmap->sname);
3429       else
3430         fprintf(pFile,"internal pblock");
3431
3432       fprintf(pFile,", dbName =%c\n",getpBlock_dbName(pb));
3433       pic16_printpBlock(pFile,pb);
3434     }
3435   }
3436 }
3437
3438
3439 unsigned long pic16_countInstructions(void)
3440 {
3441   pBlock *pb;
3442   pCode *pc;
3443   unsigned long isize=0;
3444
3445     if(!the_pFile)return -1;
3446     
3447     for(pb = the_pFile->pbHead; pb; pb = pb->next) {
3448       for(pc = pb->pcHead; pc; pc = pc->next) {
3449         if(isPCI(pc) || isPCAD(pc))isize += PCI(pc)->isize;
3450       }
3451     }
3452   return (isize);
3453 }
3454
3455
3456 /*-----------------------------------------------------------------*/
3457 /* int RegCond(pCodeOp *pcop) - if pcop points to the STATUS reg-  */
3458 /*      ister, RegCond will return the bit being referenced.       */
3459 /*                                                                 */
3460 /* fixme - why not just OR in the pcop bit field                   */
3461 /*-----------------------------------------------------------------*/
3462
3463 static int RegCond(pCodeOp *pcop)
3464 {
3465
3466   if(!pcop)
3467     return 0;
3468
3469   if(!pcop->name)return 0;
3470
3471   if(pcop->type == PO_GPR_BIT  && !strcmp(pcop->name, pic16_pc_status.pcop.name)) {
3472     switch(PCORB(pcop)->bit) {
3473     case PIC_C_BIT:
3474       return PCC_C;
3475     case PIC_DC_BIT:
3476         return PCC_DC;
3477     case PIC_Z_BIT:
3478       return PCC_Z;
3479     }
3480
3481   }
3482
3483   return 0;
3484 }
3485
3486 /*-----------------------------------------------------------------*/
3487 /* pic16_newpCode - create and return a newly initialized pCode          */
3488 /*                                                                 */
3489 /*  fixme - rename this                                            */
3490 /*                                                                 */
3491 /* The purpose of this routine is to create a new Instruction      */
3492 /* pCode. This is called by gen.c while the assembly code is being */
3493 /* generated.                                                      */
3494 /*                                                                 */
3495 /* Inouts:                                                         */
3496 /*  PIC_OPCODE op - the assembly instruction we wish to create.    */
3497 /*                  (note that the op is analogous to but not the  */
3498 /*                  same thing as the opcode of the instruction.)  */
3499 /*  pCdoeOp *pcop - pointer to the operand of the instruction.     */
3500 /*                                                                 */
3501 /* Outputs:                                                        */
3502 /*  a pointer to the new malloc'd pCode is returned.               */
3503 /*                                                                 */
3504 /*                                                                 */
3505 /*                                                                 */
3506 /*-----------------------------------------------------------------*/
3507 pCode *pic16_newpCode (PIC_OPCODE op, pCodeOp *pcop)
3508 {
3509   pCodeInstruction *pci ;
3510
3511   if(!mnemonics_initialized)
3512     pic16initMnemonics();
3513     
3514   pci = Safe_calloc(1, sizeof(pCodeInstruction));
3515
3516   if((op>=0) && (op < MAX_PIC16MNEMONICS) && pic16Mnemonics[op]) {
3517     memcpy(pci, pic16Mnemonics[op], sizeof(pCodeInstruction));
3518     pci->pcop = pcop;
3519
3520     if(pci->inCond & PCC_EXAMINE_PCOP)
3521       pci->inCond  |= RegCond(pcop);
3522
3523     if(pci->outCond & PCC_EXAMINE_PCOP)
3524       pci->outCond  |= RegCond(pcop);
3525
3526     pci->pc.prev = pci->pc.next = NULL;
3527     return (pCode *)pci;
3528   }
3529
3530   fprintf(stderr, "pCode mnemonic error %s,%d\n",__FUNCTION__,__LINE__);
3531   exit(1);
3532
3533   return NULL;
3534 }       
3535
3536 /*-----------------------------------------------------------------*/
3537 /* pic16_newpCodeWild - create a "wild" as in wild card pCode            */
3538 /*                                                                 */
3539 /* Wild pcodes are used during the peep hole optimizer to serve    */
3540 /* as place holders for any instruction. When a snippet of code is */
3541 /* compared to a peep hole rule, the wild card opcode will match   */
3542 /* any instruction. However, the optional operand and label are    */
3543 /* additional qualifiers that must also be matched before the      */
3544 /* line (of assembly code) is declared matched. Note that the      */
3545 /* operand may be wild too.                                        */
3546 /*                                                                 */
3547 /*   Note, a wild instruction is specified just like a wild var:   */
3548 /*      %4     ; A wild instruction,                               */
3549 /*  See the peeph.def file for additional examples                 */
3550 /*                                                                 */
3551 /*-----------------------------------------------------------------*/
3552
3553 pCode *pic16_newpCodeWild(int pCodeID, pCodeOp *optional_operand, pCodeOp *optional_label)
3554 {
3555
3556   pCodeWild *pcw;
3557     
3558   pcw = Safe_calloc(1,sizeof(pCodeWild));
3559
3560   pcw->pci.pc.type = PC_WILD;
3561   pcw->pci.pc.prev = pcw->pci.pc.next = NULL;
3562   pcw->pci.from = pcw->pci.to = pcw->pci.label = NULL;
3563   pcw->pci.pc.pb = NULL;
3564
3565   //  pcw->pci.pc.analyze = genericAnalyze;
3566   pcw->pci.pc.destruct = genericDestruct;
3567   pcw->pci.pc.print = genericPrint;
3568
3569   pcw->id = pCodeID;              // this is the 'n' in %n
3570   pcw->operand = optional_operand;
3571   pcw->label   = optional_label;
3572
3573   pcw->mustBeBitSkipInst = 0;
3574   pcw->mustNotBeBitSkipInst = 0;
3575   pcw->invertBitSkipInst = 0;
3576
3577   return ( (pCode *)pcw);
3578   
3579 }
3580
3581  /*-----------------------------------------------------------------*/
3582 /* newPcodeInlineP - create a new pCode from a char string           */
3583 /*-----------------------------------------------------------------*/
3584
3585
3586 pCode *pic16_newpCodeInlineP(char *cP)
3587 {
3588
3589   pCodeComment *pcc ;
3590     
3591   pcc = Safe_calloc(1,sizeof(pCodeComment));
3592
3593   pcc->pc.type = PC_INLINE;
3594   pcc->pc.prev = pcc->pc.next = NULL;
3595   //pcc->pc.from = pcc->pc.to = pcc->pc.label = NULL;
3596   pcc->pc.pb = NULL;
3597
3598   //  pcc->pc.analyze = genericAnalyze;
3599   pcc->pc.destruct = genericDestruct;
3600   pcc->pc.print = genericPrint;
3601
3602   if(cP)
3603     pcc->comment = Safe_strdup(cP);
3604   else
3605     pcc->comment = NULL;
3606
3607   return ( (pCode *)pcc);
3608
3609 }
3610
3611 /*-----------------------------------------------------------------*/
3612 /* newPcodeCharP - create a new pCode from a char string           */
3613 /*-----------------------------------------------------------------*/
3614
3615 pCode *pic16_newpCodeCharP(char *cP)
3616 {
3617
3618   pCodeComment *pcc ;
3619     
3620   pcc = Safe_calloc(1,sizeof(pCodeComment));
3621
3622   pcc->pc.type = PC_COMMENT;
3623   pcc->pc.prev = pcc->pc.next = NULL;
3624   //pcc->pc.from = pcc->pc.to = pcc->pc.label = NULL;
3625   pcc->pc.pb = NULL;
3626
3627   //  pcc->pc.analyze = genericAnalyze;
3628   pcc->pc.destruct = genericDestruct;
3629   pcc->pc.print = genericPrint;
3630
3631   if(cP)
3632     pcc->comment = Safe_strdup(cP);
3633   else
3634     pcc->comment = NULL;
3635
3636   return ( (pCode *)pcc);
3637
3638 }
3639
3640 /*-----------------------------------------------------------------*/
3641 /* pic16_newpCodeFunction -                                              */
3642 /*-----------------------------------------------------------------*/
3643
3644
3645 pCode *pic16_newpCodeFunction(char *mod,char *f)
3646 {
3647   pCodeFunction *pcf;
3648
3649   pcf = Safe_calloc(1,sizeof(pCodeFunction));
3650
3651   pcf->pc.type = PC_FUNCTION;
3652   pcf->pc.prev = pcf->pc.next = NULL;
3653   //pcf->pc.from = pcf->pc.to = pcf->pc.label = NULL;
3654   pcf->pc.pb = NULL;
3655
3656   //  pcf->pc.analyze = genericAnalyze;
3657   pcf->pc.destruct = genericDestruct;
3658   pcf->pc.print = pCodePrintFunction;
3659
3660   pcf->ncalled = 0;
3661   pcf->absblock = 0;
3662   
3663   if(mod) {
3664     pcf->modname = Safe_calloc(1,strlen(mod)+1);
3665     strcpy(pcf->modname,mod);
3666   } else
3667     pcf->modname = NULL;
3668
3669   if(f) {
3670     pcf->fname = Safe_calloc(1,strlen(f)+1);
3671     strcpy(pcf->fname,f);
3672   } else
3673     pcf->fname = NULL;
3674
3675   pcf->stackusage = 0;
3676
3677   return ( (pCode *)pcf);
3678 }
3679
3680 /*-----------------------------------------------------------------*/
3681 /* pic16_newpCodeFlow                                                    */
3682 /*-----------------------------------------------------------------*/
3683 static void destructpCodeFlow(pCode *pc)
3684 {
3685   if(!pc || !isPCFL(pc))
3686     return;
3687
3688 /*
3689   if(PCFL(pc)->from)
3690   if(PCFL(pc)->to)
3691 */
3692   pic16_unlinkpCode(pc);
3693
3694   deleteSet(&PCFL(pc)->registers);
3695   deleteSet(&PCFL(pc)->from);
3696   deleteSet(&PCFL(pc)->to);
3697
3698   /* Instead of deleting the memory used by this pCode, mark
3699    * the object as bad so that if there's a pointer to this pCode
3700    * dangling around somewhere then (hopefully) when the type is
3701    * checked we'll catch it.
3702    */
3703
3704   pc->type = PC_BAD;
3705   pic16_addpCode2pBlock(pb_dead_pcodes, pc);
3706
3707 //  free(pc);
3708
3709 }
3710
3711 pCode *pic16_newpCodeFlow(void )
3712 {
3713   pCodeFlow *pcflow;
3714
3715   //_ALLOC(pcflow,sizeof(pCodeFlow));
3716   pcflow = Safe_calloc(1,sizeof(pCodeFlow));
3717
3718   pcflow->pc.type = PC_FLOW;
3719   pcflow->pc.prev = pcflow->pc.next = NULL;
3720   pcflow->pc.pb = NULL;
3721
3722   //  pcflow->pc.analyze = genericAnalyze;
3723   pcflow->pc.destruct = destructpCodeFlow;
3724   pcflow->pc.print = genericPrint;
3725
3726   pcflow->pc.seq = GpcFlowSeq++;
3727
3728   pcflow->from = pcflow->to = NULL;
3729
3730   pcflow->inCond = PCC_NONE;
3731   pcflow->outCond = PCC_NONE;
3732
3733   pcflow->firstBank = -1;
3734   pcflow->lastBank = -1;
3735
3736   pcflow->FromConflicts = 0;
3737   pcflow->ToConflicts = 0;
3738
3739   pcflow->end = NULL;
3740
3741   pcflow->registers = newSet();
3742
3743   return ( (pCode *)pcflow);
3744
3745 }
3746
3747 /*-----------------------------------------------------------------*/
3748 /*-----------------------------------------------------------------*/
3749 pCodeFlowLink *pic16_newpCodeFlowLink(pCodeFlow *pcflow)
3750 {
3751   pCodeFlowLink *pcflowLink;
3752
3753   pcflowLink = Safe_calloc(1,sizeof(pCodeFlowLink));
3754
3755   pcflowLink->pcflow = pcflow;
3756   pcflowLink->bank_conflict = 0;
3757
3758   return pcflowLink;
3759 }
3760
3761 /*-----------------------------------------------------------------*/
3762 /* pic16_newpCodeCSource - create a new pCode Source Symbol        */
3763 /*-----------------------------------------------------------------*/
3764
3765 pCode *pic16_newpCodeCSource(int ln, char *f, char *l)
3766 {
3767
3768   pCodeCSource *pccs;
3769     
3770   pccs = Safe_calloc(1,sizeof(pCodeCSource));
3771
3772   pccs->pc.type = PC_CSOURCE;
3773   pccs->pc.prev = pccs->pc.next = NULL;
3774   pccs->pc.pb = NULL;
3775
3776   pccs->pc.destruct = genericDestruct;
3777   pccs->pc.print = genericPrint;
3778
3779   pccs->line_number = ln;
3780   if(l)
3781     pccs->line = Safe_strdup(l);
3782   else
3783     pccs->line = NULL;
3784
3785   if(f)
3786     pccs->file_name = Safe_strdup(f);
3787   else
3788     pccs->file_name = NULL;
3789
3790   return ( (pCode *)pccs);
3791
3792 }
3793
3794
3795 /*******************************************************************/
3796 /* pic16_newpCodeAsmDir - create a new pCode Assembler Directive   */
3797 /*                      added by VR 6-Jun-2003                     */
3798 /*******************************************************************/
3799
3800 pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...)
3801 {
3802   pCodeAsmDir *pcad;
3803   va_list ap;
3804   char buffer[512];
3805   char *lbp=buffer;
3806   
3807         pcad = Safe_calloc(1, sizeof(pCodeAsmDir));
3808         pcad->pci.pc.type = PC_ASMDIR;
3809         pcad->pci.pc.prev = pcad->pci.pc.next = NULL;
3810         pcad->pci.pc.pb = NULL;
3811         pcad->pci.isize = 2;
3812         pcad->pci.pc.destruct = genericDestruct;
3813         pcad->pci.pc.print = genericPrint;
3814
3815         if(asdir && *asdir) {
3816                 
3817                 while(isspace(*asdir))asdir++;  // strip any white space from the beginning
3818                 
3819                 pcad->directive = Safe_strdup( asdir );
3820         }
3821         
3822         va_start(ap, argfmt);
3823         
3824         memset(buffer, 0, sizeof(buffer));
3825         if(argfmt && *argfmt)
3826                 vsprintf(buffer, argfmt, ap);
3827         
3828         va_end(ap);
3829         
3830         while(isspace(*lbp))lbp++;
3831         
3832         if(lbp && *lbp)
3833                 pcad->arg = Safe_strdup( lbp );
3834
3835   return ((pCode *)pcad);
3836 }
3837
3838 /*-----------------------------------------------------------------*/
3839 /* pCodeLabelDestruct - free memory used by a label.               */
3840 /*-----------------------------------------------------------------*/
3841 static void pCodeLabelDestruct(pCode *pc)
3842 {
3843
3844   if(!pc)
3845     return;
3846
3847 //  if((pc->type == PC_LABEL) && PCL(pc)->label)
3848 //    free(PCL(pc)->label);
3849
3850   /* Instead of deleting the memory used by this pCode, mark
3851    * the object as bad so that if there's a pointer to this pCode
3852    * dangling around somewhere then (hopefully) when the type is
3853    * checked we'll catch it.
3854    */
3855
3856   pc->type = PC_BAD;
3857   pic16_addpCode2pBlock(pb_dead_pcodes, pc);
3858
3859 //  free(pc);
3860
3861 }
3862
3863 pCode *pic16_newpCodeLabel(char *name, int key)
3864 {
3865
3866   char *s = buffer;
3867   pCodeLabel *pcl;
3868     
3869   pcl = Safe_calloc(1,sizeof(pCodeLabel) );
3870
3871   pcl->pc.type = PC_LABEL;
3872   pcl->pc.prev = pcl->pc.next = NULL;
3873   //pcl->pc.from = pcl->pc.to = pcl->pc.label = NULL;
3874   pcl->pc.pb = NULL;
3875
3876   //  pcl->pc.analyze = genericAnalyze;
3877   pcl->pc.destruct = pCodeLabelDestruct;
3878   pcl->pc.print = pCodePrintLabel;
3879
3880   pcl->key = key;
3881   pcl->force = 0;
3882   
3883   pcl->label = NULL;
3884   if(key>0) {
3885     sprintf(s,"_%05d_DS_",key);
3886   } else
3887     s = name;
3888
3889   if(s)
3890     pcl->label = Safe_strdup(s);
3891
3892 //  if(pic16_pcode_verbose)
3893 //      fprintf(stderr, "%s:%d label name: %s\n", __FILE__, __LINE__, pcl->label);
3894
3895
3896   return ( (pCode *)pcl);
3897
3898 }
3899
3900 pCode *pic16_newpCodeLabelFORCE(char *name, int key)
3901 {
3902   pCodeLabel *pcl = (pCodeLabel *)pic16_newpCodeLabel(name, key);
3903   
3904         pcl->force = 1;
3905   
3906   return ( (pCode *)pcl );
3907 }
3908
3909 pCode *pic16_newpCodeInfo(INFO_TYPE type, pCodeOp *pcop)
3910 {
3911   pCodeInfo *pci;
3912
3913     pci = Safe_calloc(1, sizeof(pCodeInfo));
3914     pci->pci.pc.type = PC_INFO;
3915     pci->pci.pc.prev = pci->pci.pc.next = NULL;
3916     pci->pci.pc.pb = NULL;
3917     pci->pci.label = NULL;
3918         
3919     pci->pci.pc.destruct = genericDestruct;
3920     pci->pci.pc.print = genericPrint;
3921     
3922     pci->type = type;
3923     pci->oper1 = pcop;
3924   
3925   return ((pCode *)pci);
3926 }
3927
3928
3929 /*-----------------------------------------------------------------*/
3930 /* newpBlock - create and return a pointer to a new pBlock         */
3931 /*-----------------------------------------------------------------*/
3932 static pBlock *newpBlock(void)
3933 {
3934
3935   pBlock *PpB;
3936
3937   PpB = Safe_calloc(1,sizeof(pBlock) );
3938   PpB->next = PpB->prev = NULL;
3939
3940   PpB->function_entries = PpB->function_exits = PpB->function_calls = NULL;
3941   PpB->tregisters = NULL;
3942   PpB->visited = 0;
3943   PpB->FlowTree = NULL;
3944
3945   return PpB;
3946
3947 }
3948
3949 /*-----------------------------------------------------------------*/
3950 /* pic16_newpCodeChain - create a new chain of pCodes                    */
3951 /*-----------------------------------------------------------------*
3952  *
3953  *  This function will create a new pBlock and the pointer to the
3954  *  pCode that is passed in will be the first pCode in the block.
3955  *-----------------------------------------------------------------*/
3956
3957
3958 pBlock *pic16_newpCodeChain(memmap *cm,char c, pCode *pc)
3959 {
3960
3961   pBlock *pB  = newpBlock();
3962
3963   pB->pcHead  = pB->pcTail = pc;
3964   pB->cmemmap = cm;
3965   pB->dbName  = c;
3966
3967   return pB;
3968 }
3969
3970
3971
3972 /*-----------------------------------------------------------------*/
3973 /* pic16_newpCodeOpLabel - Create a new label given the key              */
3974 /*  Note, a negative key means that the label is part of wild card */
3975 /*  (and hence a wild card label) used in the pCodePeep            */
3976 /*   optimizations).                                               */
3977 /*-----------------------------------------------------------------*/
3978
3979 pCodeOp *pic16_newpCodeOpLabel(char *name, int key)
3980 {
3981   char *s=NULL;
3982   static int label_key=-1;
3983
3984   pCodeOp *pcop;
3985
3986   pcop = Safe_calloc(1,sizeof(pCodeOpLabel) );
3987   pcop->type = PO_LABEL;
3988
3989   pcop->name = NULL;
3990
3991   if(key>0)
3992     sprintf(s=buffer,"_%05d_DS_",key);
3993   else 
3994     s = name, key = label_key--;
3995
3996   if(s)
3997     pcop->name = Safe_strdup(s);
3998
3999   ((pCodeOpLabel *)pcop)->key = key;
4000
4001   //fprintf(stderr,"pic16_newpCodeOpLabel: key=%d, name=%s\n",key,((s)?s:""));
4002   return pcop;
4003 }
4004
4005 /*-----------------------------------------------------------------*/
4006 /*-----------------------------------------------------------------*/
4007 pCodeOp *pic16_newpCodeOpLit(int lit)
4008 {
4009   char *s = buffer;
4010   pCodeOp *pcop;
4011
4012
4013   pcop = Safe_calloc(1,sizeof(pCodeOpLit) );
4014   pcop->type = PO_LITERAL;
4015
4016   pcop->name = NULL;
4017 //  if(lit>=0)
4018     sprintf(s,"0x%02hhx",(char)(lit));
4019 //  else
4020 //    sprintf(s, "%i", lit);
4021   
4022   if(s)
4023     pcop->name = Safe_strdup(s);
4024
4025   ((pCodeOpLit *)pcop)->lit = lit;
4026
4027   return pcop;
4028 }
4029
4030 /*-----------------------------------------------------------------*/
4031 /*-----------------------------------------------------------------*/
4032 pCodeOp *pic16_newpCodeOpLit2(int lit, pCodeOp *arg2)
4033 {
4034   char *s = buffer, tbuf[256], *tb=tbuf;
4035   pCodeOp *pcop;
4036
4037
4038   tb = pic16_get_op(arg2, NULL, 0);
4039   pcop = Safe_calloc(1,sizeof(pCodeOpLit2) );
4040   pcop->type = PO_LITERAL;
4041
4042   pcop->name = NULL;
4043   if(lit>=0) {
4044     sprintf(s,"0x%02x, %s",lit, tb);
4045     if(s)
4046       pcop->name = Safe_strdup(s);
4047   }
4048
4049   ((pCodeOpLit2 *)pcop)->lit = lit;
4050   ((pCodeOpLit2 *)pcop)->arg2 = arg2;
4051
4052   return pcop;
4053 }
4054
4055 /*-----------------------------------------------------------------*/
4056 /*-----------------------------------------------------------------*/
4057 pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space)
4058 {
4059   pCodeOp *pcop;
4060
4061         pcop = Safe_calloc(1,sizeof(pCodeOpImmd) );
4062         pcop->type = PO_IMMEDIATE;
4063         if(name) {
4064                 regs *r = pic16_dirregWithName(name);
4065                 pcop->name = Safe_strdup(name);
4066                 PCOI(pcop)->r = r;
4067                 
4068                 if(r) {
4069 //                      fprintf(stderr, "%s:%d %s reg %s exists (r: %p)\n",__FILE__, __LINE__, __FUNCTION__, name, r);
4070                         PCOI(pcop)->rIdx = r->rIdx;
4071                 } else {
4072 //                      fprintf(stderr, "%s:%d %s reg %s doesn't exist\n", __FILE__, __LINE__, __FUNCTION__, name);
4073                         PCOI(pcop)->rIdx = -1;
4074                 }
4075 //                      fprintf(stderr,"%s %s %d\n",__FUNCTION__,name,offset);
4076         } else {
4077                 pcop->name = NULL;
4078         }
4079
4080         PCOI(pcop)->index = index;
4081         PCOI(pcop)->offset = offset;
4082         PCOI(pcop)->_const = code_space;
4083
4084   return pcop;
4085 }
4086
4087 /*-----------------------------------------------------------------*/
4088 /*-----------------------------------------------------------------*/
4089 pCodeOp *pic16_newpCodeOpWild(int id, pCodeWildBlock *pcwb, pCodeOp *subtype)
4090 {
4091   char *s = buffer;
4092   pCodeOp *pcop;
4093
4094
4095   if(!pcwb || !subtype) {
4096     fprintf(stderr, "Wild opcode declaration error: %s-%d\n",__FILE__,__LINE__);
4097     exit(1);
4098   }
4099
4100   pcop = Safe_calloc(1,sizeof(pCodeOpWild));
4101   pcop->type = PO_WILD;
4102   sprintf(s,"%%%d",id);
4103   pcop->name = Safe_strdup(s);
4104
4105   PCOW(pcop)->id = id;
4106   PCOW(pcop)->pcwb = pcwb;
4107   PCOW(pcop)->subtype = subtype;
4108   PCOW(pcop)->matched = NULL;
4109
4110   PCOW(pcop)->pcop2 = NULL;
4111   
4112   return pcop;
4113 }
4114
4115 /*-----------------------------------------------------------------*/
4116 /*-----------------------------------------------------------------*/
4117 pCodeOp *pic16_newpCodeOpWild2(int id, int id2, pCodeWildBlock *pcwb, pCodeOp *subtype, pCodeOp *subtype2)
4118 {
4119   char *s = buffer;
4120   pCodeOp *pcop;
4121
4122
4123         if(!pcwb || !subtype || !subtype2) {
4124                 fprintf(stderr, "Wild opcode declaration error: %s-%d\n",__FILE__,__LINE__);
4125                 exit(1);
4126         }
4127
4128         pcop = Safe_calloc(1,sizeof(pCodeOpWild));
4129         pcop->type = PO_WILD;
4130         sprintf(s,"%%%d",id);
4131         pcop->name = Safe_strdup(s);
4132
4133         PCOW(pcop)->id = id;
4134         PCOW(pcop)->pcwb = pcwb;
4135         PCOW(pcop)->subtype = subtype;
4136         PCOW(pcop)->matched = NULL;
4137
4138         PCOW(pcop)->pcop2 = Safe_calloc(1, sizeof(pCodeOpWild));
4139
4140         if(!subtype2->name) {
4141                 PCOW(pcop)->pcop2 = Safe_calloc(1, sizeof(pCodeOpWild));
4142                 PCOW2(pcop)->pcop.type = PO_WILD;
4143                 sprintf(s, "%%%d", id2);
4144                 PCOW2(pcop)->pcop.name = Safe_strdup(s);
4145                 PCOW2(pcop)->id = id2;
4146                 PCOW2(pcop)->subtype = subtype2;
4147
4148 //              fprintf(stderr, "%s:%d %s [wild,wild] for name: %s (%d)\tname2: %s (%d)\n", __FILE__, __LINE__, __FUNCTION__,
4149 //                              pcop->name, id, PCOW2(pcop)->pcop.name, id2);
4150         } else {
4151                 PCOW2(pcop)->pcop2 = pic16_pCodeOpCopy( subtype2 );
4152
4153 //              fprintf(stderr, "%s:%d %s [wild,str] for name: %s (%d)\tname2: %s (%d)\n", __FILE__, __LINE__, __FUNCTION__,
4154 //                              pcop->name, id, PCOW2(pcop)->pcop.name, id2);
4155         }
4156   
4157
4158
4159   return pcop;
4160 }
4161
4162
4163 /*-----------------------------------------------------------------*/
4164 /*-----------------------------------------------------------------*/
4165 pCodeOp *pic16_newpCodeOpBit(char *s, int bit, int inBitSpace, PIC_OPTYPE subt)
4166 {
4167   pCodeOp *pcop;
4168   
4169   pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) );
4170   pcop->type = PO_GPR_BIT;
4171   if(s)
4172     pcop->name = Safe_strdup(s);   
4173   else
4174     pcop->name = NULL;
4175
4176   PCORB(pcop)->bit = bit;
4177   PCORB(pcop)->inBitSpace = inBitSpace;
4178   PCORB(pcop)->subtype = subt;
4179
4180   /* pCodeOpBit is derived from pCodeOpReg. We need to init this too */
4181   PCOR(pcop)->r = pic16_regWithName(s); //NULL;
4182 //  fprintf(stderr, "%s:%d %s for reg: %s\treg= %p\n", __FILE__, __LINE__, __FUNCTION__, s, PCOR(pcop)->r);
4183 //  PCOR(pcop)->rIdx = 0;
4184   return pcop;
4185 }
4186
4187
4188 /*-----------------------------------------------------------------*
4189  * pCodeOp *pic16_newpCodeOpReg(int rIdx) - allocate a new register
4190  *
4191  * If rIdx >=0 then a specific register from the set of registers
4192  * will be selected. If rIdx <0, then a new register will be searched
4193  * for.
4194  *-----------------------------------------------------------------*/
4195
4196 pCodeOp *pic16_newpCodeOpReg(int rIdx)
4197 {
4198   pCodeOp *pcop;
4199
4200   pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
4201
4202   pcop->name = NULL;
4203
4204   if(rIdx >= 0) {
4205     PCOR(pcop)->rIdx = rIdx;
4206     PCOR(pcop)->r = pic16_regWithIdx(rIdx);
4207   } else {
4208     PCOR(pcop)->r = pic16_findFreeReg(REG_GPR);
4209
4210     if(PCOR(pcop)->r)
4211       PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
4212     else {
4213         fprintf(stderr, "%s:%d Could not find a free GPR register\n",
4214                 __FUNCTION__, __LINE__);
4215         exit(-1);
4216     }
4217   }
4218
4219   pcop->type = PCOR(pcop)->r->pc_type;
4220
4221   return pcop;
4222 }
4223
4224 pCodeOp *pic16_newpCodeOpRegFromStr(char *name)
4225 {
4226   pCodeOp *pcop;
4227   regs *r;
4228
4229         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
4230         PCOR(pcop)->r = r = pic16_allocRegByName(name, 1, NULL);
4231         PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx;
4232         pcop->type = PCOR(pcop)->r->pc_type;
4233         pcop->name = PCOR(pcop)->r->name;
4234
4235 //      if(pic16_pcode_verbose) {
4236 //              fprintf(stderr, "%s:%d %s allocates register %s rIdx:0x%02x\n",
4237 //                      __FILE__, __LINE__, __FUNCTION__, r->name, r->rIdx);
4238 //      }
4239
4240   return pcop;
4241 }
4242
4243 /*-----------------------------------------------------------------*/
4244 /*-----------------------------------------------------------------*/
4245 pCodeOp *pic16_newpCodeOpOpt(OPT_TYPE type, char *key)
4246 {
4247   pCodeOpOpt *pcop;
4248
4249         pcop = Safe_calloc(1, sizeof(pCodeOpOpt));
4250         
4251         pcop->type = type;
4252         pcop->key = Safe_strdup( key );
4253
4254   return (PCOP(pcop));
4255 }
4256
4257 /*-----------------------------------------------------------------*/
4258 /*-----------------------------------------------------------------*/
4259 pCodeOp *pic16_newpCodeOpLocalRegs(LR_TYPE type)
4260 {
4261   pCodeOpLocalReg *pcop;
4262
4263         pcop = Safe_calloc(1, sizeof(pCodeOpLocalReg));
4264         
4265         pcop->type = type;
4266
4267   return (PCOP(pcop));
4268 }
4269
4270
4271 /*-----------------------------------------------------------------*/
4272 /*-----------------------------------------------------------------*/
4273
4274 pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE type)
4275 {
4276   pCodeOp *pcop;
4277
4278   switch(type) {
4279   case PO_BIT:
4280   case PO_GPR_BIT:
4281     pcop = pic16_newpCodeOpBit(name, -1,0, type);
4282     break;
4283
4284   case PO_LITERAL:
4285     pcop = pic16_newpCodeOpLit(-1);
4286     break;
4287
4288   case PO_LABEL:
4289     pcop = pic16_newpCodeOpLabel(NULL,-1);
4290     break;
4291   case PO_GPR_TEMP:
4292     pcop = pic16_newpCodeOpReg(-1);
4293     break;
4294
4295   case PO_GPR_REGISTER:
4296     if(name)
4297       pcop = pic16_newpCodeOpRegFromStr(name);
4298     else
4299       pcop = pic16_newpCodeOpReg(-1);
4300     break;
4301
4302   default:
4303     pcop = Safe_calloc(1,sizeof(pCodeOp) );
4304     pcop->type = type;
4305     if(name)
4306       pcop->name = Safe_strdup(name);   
4307     else
4308       pcop->name = NULL;
4309   }
4310
4311   return pcop;
4312 }
4313
4314 #define DB_ITEMS_PER_LINE       8
4315
4316 typedef struct DBdata
4317   {
4318     int count;
4319     char buffer[256];
4320   } DBdata;
4321
4322 struct DBdata DBd;
4323 static int DBd_init = -1;
4324
4325 /*-----------------------------------------------------------------*/
4326 /*    Initialiase "DB" data buffer                                 */
4327 /*-----------------------------------------------------------------*/
4328 void pic16_initDB(void)
4329 {
4330         DBd_init = -1;
4331 }
4332
4333
4334 /*-----------------------------------------------------------------*/
4335 /*    Flush pending "DB" data to a pBlock                          */
4336 /*                                                                 */
4337 /* ptype - type of p pointer, 'f' file pointer, 'p' pBlock pointer */
4338 /*-----------------------------------------------------------------*/
4339 void pic16_flushDB(char ptype, void *p)
4340 {
4341         if (DBd.count>0) {
4342                 if(ptype == 'p')
4343                         pic16_addpCode2pBlock(((pBlock *)p),pic16_newpCodeAsmDir("DB", "%s", DBd.buffer));
4344                 else
4345                 if(ptype == 'f')
4346                         fprintf(((FILE *)p), "\tdb\t%s\n", DBd.buffer);
4347                 else {
4348                         /* sanity check */
4349                         fprintf(stderr, "PIC16 port error: could not emit initial value data\n");
4350                 }
4351
4352                 DBd.count = 0;
4353                 DBd.buffer[0] = '\0';
4354         }
4355 }
4356
4357
4358 /*-----------------------------------------------------------------*/
4359 /*    Add "DB" directives to a pBlock                              */
4360 /*-----------------------------------------------------------------*/
4361 void pic16_emitDB(char c, char ptype, void *p)
4362 {
4363   int l;
4364
4365         if (DBd_init<0) {
4366          // we need to initialize
4367                 DBd_init = 0;
4368                 DBd.count = 0;
4369                 DBd.buffer[0] = '\0';
4370         }
4371
4372         l = strlen(DBd.buffer);
4373         sprintf(DBd.buffer+l,"%s0x%02x", (DBd.count>0?", ":""), c & 0xff);
4374
4375 //      fprintf(stderr, "%s:%d DBbuffer: '%s'\n", __FILE__, __LINE__, DBd.buffer);
4376         
4377         DBd.count++;
4378         if (DBd.count>= DB_ITEMS_PER_LINE)
4379                 pic16_flushDB(ptype, p);
4380 }
4381
4382 void pic16_emitDS(char *s, char ptype, void *p)
4383 {
4384   int l;
4385
4386         if (DBd_init<0) {
4387          // we need to initialize
4388                 DBd_init = 0;
4389                 DBd.count = 0;
4390                 DBd.buffer[0] = '\0';
4391         }
4392
4393         l = strlen(DBd.buffer);
4394         sprintf(DBd.buffer+l,"%s%s", (DBd.count>0?", ":""), s);
4395
4396 //      fprintf(stderr, "%s:%d DBbuffer: '%s'\n", __FILE__, __LINE__, DBd.buffer);
4397
4398         DBd.count++;    //=strlen(s);
4399         if (DBd.count>=16)
4400                 pic16_flushDB(ptype, p);
4401 }
4402
4403
4404 /*-----------------------------------------------------------------*/
4405 /*-----------------------------------------------------------------*/
4406 void pic16_pCodeConstString(char *name, char *value)
4407 {
4408   pBlock *pb;
4409
4410   //  fprintf(stderr, " %s  %s  %s\n",__FUNCTION__,name,value);
4411
4412   if(!name || !value)
4413     return;
4414
4415   pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block"));
4416
4417   pic16_addpBlock(pb);
4418
4419 //  sprintf(buffer,"; %s = ", name);
4420 //  strcat(buffer, value);
4421 //  fputs(buffer, stderr);
4422
4423 //  pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(buffer));
4424   pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(name,-1));
4425
4426   do {
4427         pic16_emitDB(*value, 'p', (void *)pb);
4428   }while (*value++);
4429   pic16_flushDB('p', (void *)pb);
4430 }
4431
4432 /*-----------------------------------------------------------------*/
4433 /*-----------------------------------------------------------------*/
4434 #if 0
4435 static void pCodeReadCodeTable(void)
4436 {
4437   pBlock *pb;
4438
4439   fprintf(stderr, " %s\n",__FUNCTION__);
4440
4441   pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block"));
4442
4443   pic16_addpBlock(pb);
4444
4445   pic16_addpCode2pBlock(pb,pic16_newpCodeCharP("; ReadCodeTable - built in function"));
4446   pic16_addpCode2pBlock(pb,pic16_newpCodeCharP("; Inputs: temp1,temp2 = code pointer"));
4447   pic16_addpCode2pBlock(pb,pic16_newpCodeCharP("; Outpus: W (from RETLW at temp2:temp1)"));
4448   pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("ReadCodeTable:",-1));
4449
4450   pic16_addpCode2pBlock(pb,pic16_newpCode(POC_MOVFW,pic16_newpCodeOpRegFromStr("temp2")));
4451   pic16_addpCode2pBlock(pb,pic16_newpCode(POC_MOVWF,pic16_newpCodeOpRegFromStr("PCLATH")));
4452   pic16_addpCode2pBlock(pb,pic16_newpCode(POC_MOVFW,pic16_newpCodeOpRegFromStr("temp1")));
4453   pic16_addpCode2pBlock(pb,pic16_newpCode(POC_MOVWF,pic16_newpCodeOpRegFromStr("PCL")));
4454
4455
4456 }
4457 #endif
4458 /*-----------------------------------------------------------------*/
4459 /* pic16_addpCode2pBlock - place the pCode into the pBlock linked list   */
4460 /*-----------------------------------------------------------------*/
4461 void pic16_addpCode2pBlock(pBlock *pb, pCode *pc)
4462 {
4463
4464   if(!pc)
4465     return;
4466
4467   if(!pb->pcHead) {
4468     /* If this is the first pcode to be added to a block that
4469      * was initialized with a NULL pcode, then go ahead and
4470      * make this pcode the head and tail */
4471     pb->pcHead  = pb->pcTail = pc;
4472   } else {
4473     //    if(pb->pcTail)
4474     pb->pcTail->next = pc;
4475
4476     pc->prev = pb->pcTail;
4477     pc->pb = pb;
4478
4479     pb->pcTail = pc;
4480   }
4481 }
4482
4483 /*-----------------------------------------------------------------*/
4484 /* pic16_addpBlock - place a pBlock into the pFile                 */
4485 /*-----------------------------------------------------------------*/
4486 void pic16_addpBlock(pBlock *pb)
4487 {
4488   // fprintf(stderr," Adding pBlock: dbName =%c\n",getpBlock_dbName(pb));
4489
4490   if(!the_pFile) {
4491     /* First time called, we'll pass through here. */
4492     //_ALLOC(the_pFile,sizeof(pFile));
4493     the_pFile = Safe_calloc(1,sizeof(pFile));
4494     the_pFile->pbHead = the_pFile->pbTail = pb;
4495     the_pFile->functions = NULL;
4496     return;
4497   }
4498
4499   the_pFile->pbTail->next = pb;
4500   pb->prev = the_pFile->pbTail;
4501   pb->next = NULL;
4502   the_pFile->pbTail = pb;
4503 }
4504
4505 /*-----------------------------------------------------------------*/
4506 /* removepBlock - remove a pBlock from the pFile                   */
4507 /*-----------------------------------------------------------------*/
4508 static void removepBlock(pBlock *pb)
4509 {
4510   pBlock *pbs;
4511
4512   if(!the_pFile)
4513     return;
4514
4515
4516   //fprintf(stderr," Removing pBlock: dbName =%c\n",getpBlock_dbName(pb));
4517
4518   for(pbs = the_pFile->pbHead; pbs; pbs = pbs->next) {
4519     if(pbs == pb) {
4520
4521       if(pbs == the_pFile->pbHead)
4522         the_pFile->pbHead = pbs->next;
4523
4524       if (pbs == the_pFile->pbTail) 
4525         the_pFile->pbTail = pbs->prev;
4526
4527       if(pbs->next)
4528         pbs->next->prev = pbs->prev;
4529
4530       if(pbs->prev)
4531         pbs->prev->next = pbs->next;
4532
4533       return;
4534
4535     }
4536   }
4537
4538   fprintf(stderr, "Warning: call to %s:%s didn't find pBlock\n",__FILE__,__FUNCTION__);
4539
4540 }
4541
4542 /*-----------------------------------------------------------------*/
4543 /* printpCode - write the contents of a pCode to a file            */
4544 /*-----------------------------------------------------------------*/
4545 static void printpCode(FILE *of, pCode *pc)
4546 {
4547
4548   if(!pc || !of)
4549     return;
4550
4551   if(pc->print) {
4552     pc->print(of,pc);
4553     return;
4554   }
4555
4556   fprintf(of,"warning - unable to print pCode\n");
4557 }
4558
4559 /*-----------------------------------------------------------------*/
4560 /* pic16_printpBlock - write the contents of a pBlock to a file    */
4561 /*-----------------------------------------------------------------*/
4562 void pic16_printpBlock(FILE *of, pBlock *pb)
4563 {
4564   pCode *pc;
4565
4566         if(!pb)return;
4567
4568         if(!of)of=stderr;
4569
4570         for(pc = pb->pcHead; pc; pc = pc->next) {
4571                 if(isPCF(pc) && PCF(pc)->fname) {
4572                         fprintf(of, "S_%s_%s\tcode", PCF(pc)->modname, PCF(pc)->fname);
4573                         if(pb->dbName == 'A') {
4574                           absSym *ab;
4575                                 for(ab=setFirstItem(absSymSet); ab; ab=setNextItem(absSymSet)) {
4576 //                                      fprintf(stderr, "%s:%d testing %s <-> %s\n", __FILE__, __LINE__, PCF(pc)->fname, ab->name);
4577                                         if(!strcmp(ab->name, PCF(pc)->fname)) {
4578 //                                              fprintf(stderr, "%s:%d address = %x\n", __FILE__, __LINE__, ab->address);
4579                                                 fprintf(of, "\t0X%06X", ab->address);
4580                                                 break;
4581                                         }
4582                                 }
4583                         }
4584                         fprintf(of, "\n");
4585                 }
4586                 printpCode(of,pc);
4587         }
4588 }
4589
4590 /*-----------------------------------------------------------------*/
4591 /*                                                                 */
4592 /*       pCode processing                                          */
4593 /*                                                                 */
4594 /*                                                                 */
4595 /*                                                                 */
4596 /*-----------------------------------------------------------------*/
4597
4598 void pic16_unlinkpCode(pCode *pc)
4599 {
4600
4601
4602   if(pc) {
4603 #ifdef PCODE_DEBUG
4604     fprintf(stderr,"Unlinking: ");
4605     printpCode(stderr, pc);
4606 #endif
4607     if(pc->prev) 
4608       pc->prev->next = pc->next;
4609     if(pc->next)
4610       pc->next->prev = pc->prev;
4611
4612     pc->prev = pc->next = NULL;
4613   }
4614 }
4615
4616 /*-----------------------------------------------------------------*/
4617 /*-----------------------------------------------------------------*/
4618
4619 static void genericDestruct(pCode *pc)
4620 {
4621
4622   pic16_unlinkpCode(pc);
4623
4624   if(isPCI(pc)) {
4625     /* For instructions, tell the register (if there's one used)
4626      * that it's no longer needed */
4627     regs *reg = pic16_getRegFromInstruction(pc);
4628     if(reg)
4629       deleteSetItem (&(reg->reglives.usedpCodes),pc);
4630
4631         if(PCI(pc)->is2MemOp) {
4632                 reg = pic16_getRegFromInstruction2(pc);
4633                 if(reg)
4634                         deleteSetItem(&(reg->reglives.usedpCodes), pc);
4635         }
4636   }
4637
4638   /* Instead of deleting the memory used by this pCode, mark
4639    * the object as bad so that if there's a pointer to this pCode
4640    * dangling around somewhere then (hopefully) when the type is
4641    * checked we'll catch it.
4642    */
4643
4644   pc->type = PC_BAD;
4645   pic16_addpCode2pBlock(pb_dead_pcodes, pc);
4646
4647   //free(pc);
4648 }
4649
4650
4651 void DEBUGpic16_emitcode (char *inst,char *fmt, ...);
4652 /*-----------------------------------------------------------------*/
4653 /*-----------------------------------------------------------------*/
4654 /* modifiers for constant immediate */
4655 const char *immdmod[3]={"LOW", "HIGH", "UPPER"};
4656
4657 char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size)
4658 {
4659   regs *r;
4660   static char b[50];
4661   char *s;
4662   int use_buffer = 1;    // copy the string to the passed buffer pointer
4663
4664         if(!buffer) {
4665                 buffer = b;
4666                 size = sizeof(b);
4667                 use_buffer = 0;     // Don't bother copying the string to the buffer.
4668         } 
4669
4670         if(pcop) {
4671                 switch(pcop->type) {
4672                         case PO_W:
4673                         case PO_WREG:
4674                         case PO_PRODL:
4675                         case PO_PRODH:
4676                         case PO_INDF0:
4677                         case PO_FSR0:
4678                                 if(use_buffer) {
4679                                         SAFE_snprintf(&buffer,&size,"%s",PCOR(pcop)->r->name);
4680                                         return buffer;
4681                                 }
4682                                 return PCOR(pcop)->r->name;
4683                                 break;
4684                         case PO_GPR_TEMP:
4685                                 r = pic16_regWithIdx(PCOR(pcop)->r->rIdx);
4686                                 if(use_buffer) {
4687                                         SAFE_snprintf(&buffer,&size,"%s",r->name);
4688                                         return buffer;
4689                                 }
4690                                 return r->name;
4691
4692                         case PO_IMMEDIATE:
4693                                 s = buffer;
4694                                 if(PCOI(pcop)->offset && PCOI(pcop)->offset<4) {
4695                                         if(PCOI(pcop)->index) {
4696                                                 SAFE_snprintf(&s,&size, "%s(%s + %d)",
4697                                                         immdmod[ PCOI(pcop)->offset ],
4698                                                         pcop->name,
4699                                                         PCOI(pcop)->index);
4700                                         } else {
4701                                                 SAFE_snprintf(&s,&size,"%s(%s)",
4702                                                         immdmod[ PCOI(pcop)->offset ],
4703                                                         pcop->name);
4704                                         }
4705                                 } else {
4706                                         if(PCOI(pcop)->index) {
4707                                                 SAFE_snprintf(&s,&size, "%s(%s + %d)",
4708                                                         immdmod[ 0 ],
4709                                                         pcop->name,
4710                                                         PCOI(pcop)->index);
4711                                         } else {
4712                                                 SAFE_snprintf(&s,&size, "%s(%s)",
4713                                                         immdmod[ 0 ],
4714                                                         pcop->name);
4715                                         }
4716                                 }
4717                                 return buffer;
4718
4719                         case PO_GPR_REGISTER:
4720                         case PO_DIR:
4721                                 s = buffer;
4722 //                              size = sizeof(buffer);
4723                                 if( PCOR(pcop)->instance) {
4724                                         SAFE_snprintf(&s,&size,"(%s + %d)",
4725                                                 pcop->name,
4726                                                 PCOR(pcop)->instance );
4727                                 } else {
4728                                         SAFE_snprintf(&s,&size,"%s",pcop->name);
4729                                 }
4730                                 return buffer;
4731                         case PO_GPR_BIT:
4732                                 s = buffer;
4733                                 if(PCORB(pcop)->subtype == PO_GPR_TEMP) {
4734                                         SAFE_snprintf(&s, &size, "%s", pcop->name);
4735                                 } else {
4736                                         if(PCORB(pcop)->pcor.instance)
4737                                                 SAFE_snprintf(&s, &size, "(%s + %d)", pcop->name, PCORB(pcop)->pcor.instance);
4738                                         else
4739                                                 SAFE_snprintf(&s, &size, "%s", pcop->name);
4740                                 }
4741
4742                                 return (buffer);
4743                         default:
4744                                 if(pcop->name) {
4745                                         if(use_buffer) {
4746                                                 SAFE_snprintf(&buffer,&size,"%s",pcop->name);
4747                                                 return buffer;
4748                                         }
4749                                 return pcop->name;
4750                                 }
4751
4752                 }
4753         }
4754
4755   return "NO operand1";
4756 }
4757
4758 /*-----------------------------------------------------------------*/
4759 /* pic16_get_op2 - variant to support two memory operand commands  */
4760 /*-----------------------------------------------------------------*/
4761 char *pic16_get_op2(pCodeOp *pcop,char *buffer, size_t size)
4762 {
4763   regs *r;
4764   static char b[50];
4765   char *s;
4766   int use_buffer = 1;    // copy the string to the passed buffer pointer
4767
4768         if(!buffer) {
4769                 buffer = b;
4770                 size = sizeof(b);
4771                 use_buffer = 0;     // Don't bother copying the string to the buffer.
4772         } 
4773
4774 #if 0
4775         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",
4776                 __FUNCTION__, __LINE__, PCOR(PCOR2(pcop)->pcop2)->r->name, PCOR2(pcop)->pcop2->type,
4777                 PO_DIR, PO_GPR_TEMP, PO_IMMEDIATE, PO_INDF0, PO_FSR0);
4778 #endif
4779
4780         if(pcop) {
4781                 switch(PCOR2(pcop)->pcop2->type) {
4782                         case PO_W:
4783                         case PO_WREG:
4784                         case PO_PRODL:
4785                         case PO_PRODH:
4786                         case PO_INDF0:
4787                         case PO_FSR0:
4788                                 if(use_buffer) {
4789                                         SAFE_snprintf(&buffer,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name);
4790                                         return buffer;
4791                                 }
4792                                 return PCOR(PCOR2(pcop)->pcop2)->r->name;
4793                                 break;
4794                         case PO_GPR_TEMP:
4795                                 r = pic16_regWithIdx(PCOR(PCOR2(pcop)->pcop2)->r->rIdx);
4796
4797                                 if(use_buffer) {
4798                                         SAFE_snprintf(&buffer,&size,"%s",r->name);
4799                                         return buffer;
4800                                 }
4801                                 return r->name;
4802
4803                         case PO_IMMEDIATE:
4804                                         assert( 0 );
4805                                 break;
4806 #if 0
4807                                 s = buffer;
4808
4809                                 if(PCOI(pcop)->_const) {
4810                                         if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) {
4811                                                 SAFE_snprintf(&s,&size,"(((%s+%d) >> %d)&0xff)",
4812                                                         pcop->name,
4813                                                         PCOI(pcop)->index,
4814                                                         8 * PCOI(pcop)->offset );
4815                                         } else
4816                                                 SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index);
4817                                 } else {
4818                                         if( PCOI(pcop)->index) {
4819                                                 SAFE_snprintf(&s,&size,"(%s + %d)",
4820                                                         pcop->name,
4821                                                         PCOI(pcop)->index );
4822                                         } else {
4823                                                 if(PCOI(pcop)->offset)
4824                                                         SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset);
4825                                                 else
4826                                                         SAFE_snprintf(&s,&size,"%s",pcop->name);
4827                                         }
4828                                 }
4829                                 return buffer;
4830 #endif
4831                         case PO_DIR:
4832                                 s = buffer;
4833                                 if( PCOR(PCOR2(pcop)->pcop2)->instance) {
4834                                         SAFE_snprintf(&s,&size,"(%s + %d)",
4835                                                 PCOR(PCOR2(pcop)->pcop2)->r->name,
4836                                                 PCOR(PCOR2(pcop)->pcop2)->instance );
4837                                 } else {
4838                                         SAFE_snprintf(&s,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name);
4839                                 }
4840                                 return buffer;
4841
4842                         default:
4843                                 if(PCOR(PCOR2(pcop)->pcop2)->r->name) {
4844                                         if(use_buffer) {
4845                                                 SAFE_snprintf(&buffer,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name);
4846                                                 return buffer;
4847                                         }
4848                                         return PCOR(PCOR2(pcop)->pcop2)->r->name;
4849                                 }
4850                 }
4851         }
4852
4853   return "NO operand2";
4854 }
4855
4856 /*-----------------------------------------------------------------*/
4857 /*-----------------------------------------------------------------*/
4858 static char *pic16_get_op_from_instruction( pCodeInstruction *pcc)
4859 {
4860
4861   if(pcc )
4862     return pic16_get_op(pcc->pcop,NULL,0);
4863
4864   /* gcc 3.2:  warning: concatenation of string literals with __FUNCTION__ is deprecated 
4865    *   return ("ERROR Null: "__FUNCTION__);
4866    */
4867   return ("ERROR Null: pic16_get_op_from_instruction");
4868
4869 }
4870
4871 /*-----------------------------------------------------------------*/
4872 /*-----------------------------------------------------------------*/
4873 static void pCodeOpPrint(FILE *of, pCodeOp *pcop)
4874 {
4875
4876   fprintf(of,"pcodeopprint- not implemented\n");
4877 }
4878
4879 /*-----------------------------------------------------------------*/
4880 /* pic16_pCode2str - convert a pCode instruction to string               */
4881 /*-----------------------------------------------------------------*/
4882 char *pic16_pCode2str(char *str, size_t size, pCode *pc)
4883 {
4884   char *s = str;
4885   regs *r;
4886
4887 #if 0
4888         if(isPCI(pc) && (PCI(pc)->pci_magic != PCI_MAGIC)) {
4889                 fprintf(stderr, "%s:%d: pCodeInstruction initialization error in instruction %s, magic is %x (defaut: %x)\n",
4890                         __FILE__, __LINE__, PCI(pc)->mnemonic, PCI(pc)->pci_magic, PCI_MAGIC);
4891 //              exit(-1);
4892         }
4893 #endif
4894
4895   switch(pc->type) {
4896
4897   case PC_OPCODE:
4898     SAFE_snprintf(&s,&size, "\t%s\t", PCI(pc)->mnemonic);
4899
4900     if( (PCI(pc)->num_ops >= 1) && (PCI(pc)->pcop)) {
4901
4902         if(PCI(pc)->is2MemOp) {
4903                 SAFE_snprintf(&s,&size, "%s, %s", 
4904                 pic16_get_op(PCOP(PCI(pc)->pcop), NULL, 0),
4905                 pic16_get_op2(PCOP(PCI(pc)->pcop), NULL, 0));
4906                 break;
4907         }
4908
4909         if(PCI(pc)->is2LitOp) {
4910                 SAFE_snprintf(&s,&size, "%s", PCOP(PCI(pc)->pcop)->name);
4911                 break;
4912         }
4913
4914       if(PCI(pc)->isBitInst) {
4915         if(PCI(pc)->pcop->type != PO_GPR_BIT) {
4916           if( (((pCodeOpRegBit *)(PCI(pc)->pcop))->inBitSpace) )
4917             SAFE_snprintf(&s,&size,"(%s >> 3), (%s & 7)", 
4918                           PCI(pc)->pcop->name ,
4919                           PCI(pc)->pcop->name );
4920           else
4921             SAFE_snprintf(&s,&size,"%s,%d", pic16_get_op_from_instruction(PCI(pc)),
4922 //                        (((pCodeOpRegBit *)(PCI(pc)->pcop))->pcor.instance),
4923                           (((pCodeOpRegBit *)(PCI(pc)->pcop))->bit ));
4924                           
4925         } else if(PCI(pc)->pcop->type == PO_GPR_BIT) {
4926           SAFE_snprintf(&s,&size,"%s,%d", pic16_get_op_from_instruction(PCI(pc)),PCORB(PCI(pc)->pcop)->bit);
4927         }else
4928           SAFE_snprintf(&s,&size,"%s,0 ; ?bug", pic16_get_op_from_instruction(PCI(pc)));
4929         //PCI(pc)->pcop->t.bit );
4930       } else {
4931
4932         if(PCI(pc)->pcop->type == PO_GPR_BIT) {
4933           if( PCI(pc)->num_ops == 3)
4934             SAFE_snprintf(&s,&size,"(%s >> 3),%c",pic16_get_op_from_instruction(PCI(pc)),((PCI(pc)->isModReg) ? 'F':'W'));
4935           else
4936             SAFE_snprintf(&s,&size,"(1 << (%s & 7))",pic16_get_op_from_instruction(PCI(pc)));
4937
4938         }else {
4939           SAFE_snprintf(&s,&size,"%s", pic16_get_op_from_instruction(PCI(pc)));
4940
4941                 if( PCI(pc)->num_ops == 3 || ((PCI(pc)->num_ops == 2) && (PCI(pc)->isAccess))) {
4942                         if(PCI(pc)->num_ops == 3)
4943                                 SAFE_snprintf(&s,&size,", %c", ( (PCI(pc)->isModReg) ? 'F':'W'));
4944
4945                         r = pic16_getRegFromInstruction(pc);
4946 //                      fprintf(stderr, "%s:%d reg = %p\tname= %s, accessBank= %d\n",
4947 //                                      __FUNCTION__, __LINE__, r, (r)?r->name:"<null>", (r)?r->accessBank:-1);
4948
4949                         if(r && !r->accessBank)SAFE_snprintf(&s,&size,", %s", (!pic16_mplab_comp?"B":"BANKED"));
4950           }
4951         }
4952       }
4953
4954     }
4955     break;
4956
4957   case PC_COMMENT:
4958     /* assuming that comment ends with a \n */
4959     SAFE_snprintf(&s,&size,";%s", ((pCodeComment *)pc)->comment);
4960     break;
4961
4962   case PC_INFO:
4963     SAFE_snprintf(&s,&size,"; info ==>");
4964     switch(((pCodeInfo *)pc)->type) {
4965       case INF_OPTIMIZATION:
4966           SAFE_snprintf(&s,&size, " [optimization] %s\n", OPT_TYPE_STR[ PCOO(PCINF(pc)->oper1)->type ]);
4967           break;
4968       case INF_LOCALREGS:
4969           SAFE_snprintf(&s,&size, " [localregs] %s\n", LR_TYPE_STR[ PCOLR(PCINF(pc)->oper1)->type ]);
4970           break;
4971     }; break;
4972
4973   case PC_INLINE:
4974     /* assuming that inline code ends with a \n */
4975     SAFE_snprintf(&s,&size,"%s", ((pCodeComment *)pc)->comment);
4976     break;
4977
4978   case PC_LABEL:
4979     SAFE_snprintf(&s,&size,";label=%s, key=%d\n",PCL(pc)->label,PCL(pc)->key);
4980     break;
4981   case PC_FUNCTION:
4982     SAFE_snprintf(&s,&size,";modname=%s,function=%s: id=%d\n",PCF(pc)->modname,PCF(pc)->fname);
4983     break;
4984   case PC_WILD:
4985     SAFE_snprintf(&s,&size,";\tWild opcode: id=%d\n",PCW(pc)->id);
4986     break;
4987   case PC_FLOW:
4988     SAFE_snprintf(&s,&size,";\t--FLOW change\n");
4989     break;
4990   case PC_CSOURCE:
4991 //    SAFE_snprintf(&s,&size,";#CSRC\t%s %d\t%s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
4992       SAFE_snprintf(&s,&size,"%s\t.line\t%d; %s\t%s\n", ((pic16_mplab_comp || !options.debug)?";":""),
4993         PCCS(pc)->line_number, PCCS(pc)->file_name, PCCS(pc)->line);
4994     break;
4995   case PC_ASMDIR:
4996         if(PCAD(pc)->directive) {
4997                 SAFE_snprintf(&s,&size,"\t%s%s%s\n", PCAD(pc)->directive, PCAD(pc)->arg?"\t":"", PCAD(pc)->arg?PCAD(pc)->arg:"");
4998         } else
4999         if(PCAD(pc)->arg) {
5000                 /* special case to handle inline labels without a tab */
5001                 SAFE_snprintf(&s,&size,"%s\n", PCAD(pc)->arg);
5002         }
5003         break;
5004
5005   case PC_BAD:
5006     SAFE_snprintf(&s,&size,";A bad pCode is being used\n");
5007     break;
5008   }
5009
5010   return str;
5011
5012 }
5013
5014 /*-----------------------------------------------------------------*/
5015 /* genericPrint - the contents of a pCode to a file                */
5016 /*-----------------------------------------------------------------*/
5017 static void genericPrint(FILE *of, pCode *pc)
5018 {
5019
5020   if(!pc || !of)
5021     return;
5022
5023   switch(pc->type) {
5024   case PC_COMMENT:
5025 //    fputs(((pCodeComment *)pc)->comment, of);
5026     fprintf(of,"; %s\n", ((pCodeComment *)pc)->comment);
5027     break;
5028
5029   case PC_INFO:
5030     {
5031       pBranch *pbl = PCI(pc)->label;
5032       while(pbl && pbl->pc) {
5033         if(pbl->pc->type == PC_LABEL)
5034           pCodePrintLabel(of, pbl->pc);
5035         pbl = pbl->next;
5036       }
5037     }
5038           
5039     if(pic16_pcode_verbose) {
5040       fprintf(of, "; info ==>");
5041       switch(((pCodeInfo *)pc)->type) {
5042         case INF_OPTIMIZATION:
5043               fprintf(of, " [optimization] %s\n", OPT_TYPE_STR[ PCOO(PCINF(pc)->oper1)->type ]);
5044               break;
5045         case INF_LOCALREGS:
5046               fprintf(of, " [localregs] %s\n", LR_TYPE_STR[ PCOLR(PCINF(pc)->oper1)->type ]);
5047               break;
5048         }
5049     };
5050     
5051     break;
5052
5053   case PC_INLINE:
5054     fprintf(of,"%s\n", ((pCodeComment *)pc)->comment);
5055      break;
5056
5057   case PC_OPCODE:
5058     // If the opcode has a label, print that first
5059     {
5060       pBranch *pbl = PCI(pc)->label;
5061       while(pbl && pbl->pc) {
5062         if(pbl->pc->type == PC_LABEL)
5063           pCodePrintLabel(of, pbl->pc);
5064         pbl = pbl->next;
5065       }
5066     }
5067
5068     if(PCI(pc)->cline) 
5069       genericPrint(of,PCODE(PCI(pc)->cline));
5070
5071     {
5072       char str[256];
5073       
5074       pic16_pCode2str(str, 256, pc);
5075
5076       fprintf(of,"%s",str);
5077       /* Debug */
5078       if(pic16_debug_verbose) {
5079         fprintf(of, "\t;key=%03x",pc->seq);
5080         if(PCI(pc)->pcflow)
5081           fprintf(of,", flow seq=%03x",PCI(pc)->pcflow->pc.seq);
5082       }
5083     }
5084     fprintf(of, "\n");
5085     break;
5086       
5087   case PC_WILD:
5088     fprintf(of,";\tWild opcode: id=%d\n",PCW(pc)->id);
5089     if(PCW(pc)->pci.label)
5090       pCodePrintLabel(of, PCW(pc)->pci.label->pc);
5091
5092     if(PCW(pc)->operand) {
5093       fprintf(of,";\toperand  ");
5094       pCodeOpPrint(of,PCW(pc)->operand );
5095     }
5096     break;
5097
5098   case PC_FLOW:
5099     if(pic16_debug_verbose) {
5100       fprintf(of,";<>Start of new flow, seq=0x%x",pc->seq);
5101       if(PCFL(pc)->ancestor)
5102         fprintf(of," ancestor = 0x%x", PCODE(PCFL(pc)->ancestor)->seq);
5103       fprintf(of,"\n");
5104
5105     }
5106     break;
5107
5108   case PC_CSOURCE:
5109 //    fprintf(of,";#CSRC\t%s %d\t\t%s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line);
5110     fprintf(of,"%s\t.line\t%d; %s\t%s\n", ((pic16_mplab_comp || !options.debug)?";":""),
5111         PCCS(pc)->line_number, PCCS(pc)->file_name, PCCS(pc)->line);
5112          
5113     break;
5114
5115   case PC_ASMDIR:
5116         {
5117           pBranch *pbl = PCAD(pc)->pci.label;
5118                 while(pbl && pbl->pc) {
5119                         if(pbl->pc->type == PC_LABEL)
5120                                 pCodePrintLabel(of, pbl->pc);
5121                         pbl = pbl->next;
5122                 }
5123         }
5124         if(PCAD(pc)->directive) {
5125                 fprintf(of, "\t%s%s%s\n", PCAD(pc)->directive, PCAD(pc)->arg?"\t":"", PCAD(pc)->arg?PCAD(pc)->arg:"");
5126         } else
5127         if(PCAD(pc)->arg) {
5128                 /* special case to handle inline labels without tab */
5129                 fprintf(of, "%s\n", PCAD(pc)->arg);
5130         }
5131         break;
5132         
5133   case PC_LABEL:
5134   default:
5135     fprintf(of,"unknown pCode type %d\n",pc->type);
5136   }
5137
5138 }
5139
5140 /*-----------------------------------------------------------------*/
5141 /* pCodePrintFunction - prints function begin/end                  */
5142 /*-----------------------------------------------------------------*/
5143
5144 static void pCodePrintFunction(FILE *of, pCode *pc)
5145 {
5146
5147   if(!pc || !of)
5148     return;
5149
5150 #if 0
5151   if( ((pCodeFunction *)pc)->modname) 
5152     fprintf(of,"F_%s",((pCodeFunction *)pc)->modname);
5153 #endif
5154
5155   if(!PCF(pc)->absblock) {
5156       if(PCF(pc)->fname) {
5157       pBranch *exits = PCF(pc)->to;
5158       int i=0;
5159
5160       fprintf(of,"%s:", PCF(pc)->fname);
5161     
5162       if(pic16_pcode_verbose)
5163         fprintf(of, "\t;Function start");
5164     
5165       fprintf(of, "\n");
5166     
5167       while(exits) {
5168         i++;
5169         exits = exits->next;
5170       }
5171       //if(i) i--;
5172
5173       if(pic16_pcode_verbose)
5174         fprintf(of,"; %d exit point%c\n",i, ((i==1) ? ' ':'s'));
5175     
5176     } else {
5177         if((PCF(pc)->from && 
5178                 PCF(pc)->from->pc->type == PC_FUNCTION &&
5179                 PCF(PCF(pc)->from->pc)->fname) ) {
5180
5181                 if(pic16_pcode_verbose)
5182                         fprintf(of,"; exit point of %s\n",PCF(PCF(pc)->from->pc)->fname);
5183         } else {
5184                 if(pic16_pcode_verbose)
5185                         fprintf(of,"; exit point [can't find entry point]\n");
5186         }
5187         fprintf(of, "\n");
5188     }
5189   }
5190 }
5191 /*-----------------------------------------------------------------*/
5192 /* pCodePrintLabel - prints label                                  */
5193 /*-----------------------------------------------------------------*/
5194
5195 static void pCodePrintLabel(FILE *of, pCode *pc)
5196 {
5197
5198   if(!pc || !of)
5199     return;
5200
5201   if(PCL(pc)->label) 
5202     fprintf(of,"%s:\n",PCL(pc)->label);
5203   else if (PCL(pc)->key >=0) 
5204     fprintf(of,"_%05d_DS_:\n",PCL(pc)->key);
5205   else
5206     fprintf(of,";wild card label: id=%d\n",-PCL(pc)->key);
5207
5208 }
5209 /*-----------------------------------------------------------------*/
5210 /* unlinkpCodeFromBranch - Search for a label in a pBranch and     */
5211 /*                         remove it if it is found.               */
5212 /*-----------------------------------------------------------------*/
5213 static void unlinkpCodeFromBranch(pCode *pcl , pCode *pc)
5214 {
5215   pBranch *b, *bprev;
5216
5217
5218   bprev = NULL;
5219
5220   if(pcl->type == PC_OPCODE)
5221     b = PCI(pcl)->label;
5222   else {
5223     fprintf(stderr, "LINE %d. can't unlink from non opcode\n",__LINE__);
5224     exit(1);
5225
5226   }
5227
5228   //fprintf (stderr, "%s \n",__FUNCTION__);
5229   //pcl->print(stderr,pcl);
5230   //pc->print(stderr,pc);
5231   while(b) {
5232     if(b->pc == pc) {
5233       //fprintf (stderr, "found label\n");
5234       //pc->print(stderr, pc);
5235
5236       /* Found a label */
5237       if(bprev) {
5238         bprev->next = b->next;  /* Not first pCode in chain */
5239 //      free(b);
5240       } else {
5241         pc->destruct(pc);
5242         PCI(pcl)->label = b->next;   /* First pCode in chain */
5243 //      free(b);
5244       }
5245       return;  /* A label can't occur more than once */
5246     }
5247     bprev = b;
5248     b = b->next;
5249   }
5250
5251 }
5252
5253 /*-----------------------------------------------------------------*/
5254 /*-----------------------------------------------------------------*/
5255 pBranch * pic16_pBranchAppend(pBranch *h, pBranch *n)
5256 {
5257   pBranch *b;
5258
5259   if(!h)
5260     return n;
5261
5262   if(h == n)
5263     return n;
5264
5265   b = h;
5266   while(b->next)
5267     b = b->next;
5268
5269   b->next = n;
5270
5271   return h;
5272   
5273 }  
5274 /*-----------------------------------------------------------------*/
5275 /* pBranchLink - given two pcodes, this function will link them    */
5276 /*               together through their pBranches                  */
5277 /*-----------------------------------------------------------------*/
5278 static void pBranchLink(pCodeFunction *f, pCodeFunction *t)
5279 {
5280   pBranch *b;
5281
5282   // Declare a new branch object for the 'from' pCode.
5283
5284   //_ALLOC(b,sizeof(pBranch));
5285   b = Safe_calloc(1,sizeof(pBranch));
5286   b->pc = PCODE(t);             // The link to the 'to' pCode.
5287   b->next = NULL;
5288
5289   f->to = pic16_pBranchAppend(f->to,b);
5290
5291   // Now do the same for the 'to' pCode.
5292
5293   //_ALLOC(b,sizeof(pBranch));
5294   b = Safe_calloc(1,sizeof(pBranch));
5295   b->pc = PCODE(f);
5296   b->next = NULL;
5297
5298   t->from = pic16_pBranchAppend(t->from,b);
5299   
5300 }
5301
5302 #if 0
5303 /*-----------------------------------------------------------------*/
5304 /* pBranchFind - find the pBranch in a pBranch chain that contains */
5305 /*               a pCode                                           */
5306 /*-----------------------------------------------------------------*/
5307 static pBranch *pBranchFind(pBranch *pb,pCode *pc)
5308 {
5309   while(pb) {
5310
5311     if(pb->pc == pc)
5312       return pb;
5313
5314     pb = pb->next;
5315   }
5316
5317   return NULL;
5318 }
5319
5320 /*-----------------------------------------------------------------*/
5321 /* pic16_pCodeUnlink - Unlink the given pCode from its pCode chain.      */
5322 /*-----------------------------------------------------------------*/
5323 void pic16_pCodeUnlink(pCode *pc)
5324 {
5325   pBranch *pb1,*pb2;
5326   pCode *pc1;
5327
5328   if(!pc->prev || !pc->next) {
5329     fprintf(stderr,"unlinking bad pCode in %s:%d\n",__FILE__,__LINE__);
5330     exit(1);
5331   }
5332
5333   /* first remove the pCode from the chain */
5334   pc->prev->next = pc->next;
5335   pc->next->prev = pc->prev;
5336
5337   /* Now for the hard part... */
5338
5339   /* Remove the branches */
5340
5341   pb1 = PCI(pc)->from;
5342   while(pb1) {
5343     PCI(pc1) = pb1->pc;    /* Get the pCode that branches to the
5344                        * one we're unlinking */
5345
5346     /* search for the link back to this pCode (the one we're
5347      * unlinking) */
5348     if((pb2 = pBranchFind(PCI(pc1)->to,pc))) {
5349       pb2->pc = PCI(pc)->to->pc;  // make the replacement
5350
5351       /* if the pCode we're unlinking contains multiple 'to'
5352        * branches (e.g. this a skip instruction) then we need
5353        * to copy these extra branches to the chain. */
5354       if(PCI(pc)->to->next)
5355         pic16_pBranchAppend(pb2, PCI(pc)->to->next);
5356     }
5357     
5358     pb1 = pb1->next;
5359   }
5360
5361
5362 }
5363 #endif
5364 /*-----------------------------------------------------------------*/
5365 /*-----------------------------------------------------------------*/
5366 #if 0
5367 static void genericAnalyze(pCode *pc)
5368 {
5369   switch(pc->type) {
5370   case PC_WILD:
5371   case PC_COMMENT:
5372     return;
5373   case PC_LABEL:
5374   case PC_FUNCTION:
5375   case PC_OPCODE:
5376     {
5377       // Go through the pCodes that are in pCode chain and link
5378       // them together through the pBranches. Note, the pCodes
5379       // are linked together as a contiguous stream like the 
5380       // assembly source code lines. The linking here mimics this
5381       // except that comments are not linked in.
5382       // 
5383       pCode *npc = pc->next;
5384       while(npc) {
5385         if(npc->type == PC_OPCODE || npc->type == PC_LABEL) {
5386           pBranchLink(pc,npc);
5387           return;
5388         } else
5389           npc = npc->next;
5390       }
5391       /* reached the end of the pcode chain without finding
5392        * an instruction we could link to. */
5393     }
5394     break;
5395   case PC_FLOW:
5396     fprintf(stderr,"analyze PC_FLOW\n");
5397
5398     return;
5399   case PC_BAD:
5400     fprintf(stderr,,";A bad pCode is being used\n");
5401
5402   }
5403 }
5404 #endif
5405
5406 /*-----------------------------------------------------------------*/
5407 /*-----------------------------------------------------------------*/
5408 static int compareLabel(pCode *pc, pCodeOpLabel *pcop_label)
5409 {
5410   pBranch *pbr;
5411
5412   if(pc->type == PC_LABEL) {
5413     if( ((pCodeLabel *)pc)->key ==  pcop_label->key)
5414       return TRUE;
5415   }
5416   if((pc->type == PC_OPCODE)
5417         || (pc->type == PC_ASMDIR)
5418         ) {
5419     pbr = PCI(pc)->label;
5420     while(pbr) {
5421       if(pbr->pc->type == PC_LABEL) {
5422         if( ((pCodeLabel *)(pbr->pc))->key ==  pcop_label->key)
5423           return TRUE;
5424       }
5425       pbr = pbr->next;
5426     }
5427   }
5428
5429   return FALSE;
5430 }
5431
5432 /*-----------------------------------------------------------------*/
5433 /*-----------------------------------------------------------------*/
5434 static int checkLabel(pCode *pc)
5435 {
5436   pBranch *pbr;
5437
5438   if(pc && isPCI(pc)) {
5439     pbr = PCI(pc)->label;
5440     while(pbr) {
5441       if(isPCL(pbr->pc) && (PCL(pbr->pc)->key >= 0))
5442         return TRUE;
5443
5444       pbr = pbr->next;
5445     }
5446   }
5447
5448   return FALSE;
5449 }
5450
5451 /*-----------------------------------------------------------------*/
5452 /* findLabelinpBlock - Search the pCode for a particular label     */
5453 /*-----------------------------------------------------------------*/
5454 static pCode * findLabelinpBlock(pBlock *pb,pCodeOpLabel *pcop_label)
5455 {
5456   pCode  *pc;
5457
5458   if(!pb)
5459     return NULL;
5460
5461   for(pc = pb->pcHead; pc; pc = pc->next) 
5462     if(compareLabel(pc,pcop_label))
5463       return pc;
5464     
5465   return NULL;
5466 }
5467 #if 0
5468 /*-----------------------------------------------------------------*/
5469 /* findLabel - Search the pCode for a particular label             */
5470 /*-----------------------------------------------------------------*/
5471 static pCode * findLabel(pCodeOpLabel *pcop_label)
5472 {
5473   pBlock *pb;
5474   pCode  *pc;
5475
5476   if(!the_pFile)
5477     return NULL;
5478
5479   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
5480     if( (pc = findLabelinpBlock(pb,pcop_label)) != NULL)
5481       return pc;
5482   }
5483
5484   fprintf(stderr,"Couldn't find label %s", pcop_label->pcop.name);
5485   return NULL;
5486 }
5487 #endif
5488 /*-----------------------------------------------------------------*/
5489 /* pic16_findNextpCode - given a pCode, find the next of type 'pct'      */
5490 /*                 in the linked list                              */
5491 /*-----------------------------------------------------------------*/
5492 pCode * pic16_findNextpCode(pCode *pc, PC_TYPE pct)
5493 {
5494
5495   while(pc) {
5496     if(pc->type == pct)
5497       return pc;
5498
5499     pc = pc->next;
5500   }
5501
5502   return NULL;
5503 }
5504
5505 /*-----------------------------------------------------------------*/
5506 /* findPrevpCode - given a pCode, find the previous of type 'pct'  */
5507 /*                 in the linked list                              */
5508 /*-----------------------------------------------------------------*/
5509 static pCode * findPrevpCode(pCode *pc, PC_TYPE pct)
5510 {
5511
5512   while(pc) {
5513     if(pc->type == pct)
5514       return pc;
5515
5516     pc = pc->prev;
5517   }
5518
5519   return NULL;
5520 }
5521
5522
5523 //#define PCODE_DEBUG
5524 /*-----------------------------------------------------------------*/
5525 /* pic16_findNextInstruction - given a pCode, find the next instruction  */
5526 /*                       in the linked list                        */
5527 /*-----------------------------------------------------------------*/
5528 pCode * pic16_findNextInstruction(pCode *pci)
5529 {
5530   pCode *pc = pci;
5531
5532   while(pc) {
5533     if((pc->type == PC_OPCODE)
5534         || (pc->type == PC_WILD)
5535         || (pc->type == PC_ASMDIR)
5536         )
5537       return pc;
5538
5539 #ifdef PCODE_DEBUG
5540     fprintf(stderr,"pic16_findNextInstruction:  ");
5541     printpCode(stderr, pc);
5542 #endif
5543     pc = pc->next;
5544   }
5545
5546   //fprintf(stderr,"Couldn't find instruction\n");
5547   return NULL;
5548 }
5549
5550 /*-----------------------------------------------------------------*/
5551 /* pic16_findPrevInstruction - given a pCode, find the next instruction  */
5552 /*                       in the linked list                        */
5553 /*-----------------------------------------------------------------*/
5554 pCode * pic16_findPrevInstruction(pCode *pci)
5555 {
5556   pCode *pc = pci;
5557
5558   while(pc) {
5559
5560     if((pc->type == PC_OPCODE)
5561         || (pc->type == PC_WILD)
5562         || (pc->type == PC_ASMDIR)
5563         )
5564       return pc;
5565       
5566
5567 #ifdef PCODE_DEBUG
5568     fprintf(stderr,"pic16_findPrevInstruction:  ");
5569     printpCode(stderr, pc);
5570 #endif
5571     pc = pc->prev;
5572   }
5573
5574   //fprintf(stderr,"Couldn't find instruction\n");
5575   return NULL;
5576 }
5577
5578 #undef PCODE_DEBUG
5579
5580 #if 0
5581 /*-----------------------------------------------------------------*/
5582 /* findFunctionEnd - given a pCode find the end of the function    */
5583 /*                   that contains it                              */
5584 /*-----------------------------------------------------------------*/
5585 static pCode * findFunctionEnd(pCode *pc)
5586 {
5587
5588   while(pc) {
5589     if(pc->type == PC_FUNCTION &&  !(PCF(pc)->fname))
5590       return pc;
5591
5592     pc = pc->next;
5593   }
5594
5595   fprintf(stderr,"Couldn't find function end\n");
5596   return NULL;
5597 }
5598 #endif
5599 #if 0
5600 /*-----------------------------------------------------------------*/
5601 /* AnalyzeLabel - if the pCode is a label, then merge it with the  */
5602 /*                instruction with which it is associated.         */
5603 /*-----------------------------------------------------------------*/
5604 static void AnalyzeLabel(pCode *pc)
5605 {
5606
5607   pic16_pCodeUnlink(pc);
5608
5609 }
5610 #endif
5611
5612 #if 0
5613 static void AnalyzeGOTO(pCode *pc)
5614 {
5615
5616   pBranchLink(pc,findLabel( (pCodeOpLabel *) (PCI(pc)->pcop) ));
5617
5618 }
5619
5620 static void AnalyzeSKIP(pCode *pc)
5621 {
5622
5623   pBranchLink(pc,pic16_findNextInstruction(pc->next));
5624   pBranchLink(pc,pic16_findNextInstruction(pc->next->next));
5625
5626 }
5627
5628 static void AnalyzeRETURN(pCode *pc)
5629 {
5630
5631   //  branch_link(pc,findFunctionEnd(pc->next));
5632
5633 }
5634
5635 #endif
5636
5637 /*-----------------------------------------------------------------*/
5638 /*-----------------------------------------------------------------*/
5639 regs * pic16_getRegFromInstruction(pCode *pc)
5640 {
5641
5642   if(!pc                   || 
5643      !isPCI(pc)            ||
5644      !PCI(pc)->pcop        ||
5645      PCI(pc)->num_ops == 0 ||
5646      (PCI(pc)->num_ops == 1 && PCI(pc)->isFastCall))
5647     return NULL;
5648
5649 #if 0
5650   fprintf(stderr, "pic16_getRegFromInstruction - reg type %s (%d)\n",
5651         dumpPicOptype( PCI(pc)->pcop->type), PCI(pc)->pcop->type);
5652 #endif
5653
5654   switch(PCI(pc)->pcop->type) {
5655   case PO_PRODL:
5656   case PO_PRODH:
5657
5658   case PO_INDF0:
5659   case PO_FSR0:
5660     return PCOR(PCI(pc)->pcop)->r;
5661
5662   case PO_BIT:
5663   case PO_GPR_TEMP:
5664 //      fprintf(stderr, "pic16_getRegFromInstruction - bit or temp\n");
5665     return PCOR(PCI(pc)->pcop)->r;
5666
5667   case PO_IMMEDIATE:
5668 //    return pic16_dirregWithName(PCOI(PCI(pc)->pcop)->r->name);
5669
5670     if(PCOI(PCI(pc)->pcop)->r)
5671       return (PCOI(PCI(pc)->pcop)->r);
5672     else
5673       return NULL;
5674     
5675   case PO_GPR_BIT:
5676     return PCOR(PCI(pc)->pcop)->r;
5677
5678   case PO_GPR_REGISTER:
5679   case PO_DIR:
5680 //      fprintf(stderr, "pic16_getRegFromInstruction - dir\n");
5681     return PCOR(PCI(pc)->pcop)->r;
5682
5683   case PO_LITERAL:
5684     //fprintf(stderr, "pic16_getRegFromInstruction - literal\n");
5685     break;
5686
5687   default:
5688 //      fprintf(stderr, "pic16_getRegFromInstruction - unknown reg type %d\n",PCI(pc)->pcop->type);
5689 //      genericPrint(stderr, pc);
5690 //      assert( 0 );
5691         break;
5692   }
5693
5694   return NULL;
5695 }
5696
5697 /*-------------------------------------------------------------------------------*/
5698 /* pic16_getRegFromInstruction2 - variant to support two memory operand commands */
5699 /*-------------------------------------------------------------------------------*/
5700 regs * pic16_getRegFromInstruction2(pCode *pc)
5701 {
5702
5703   if(!pc                   || 
5704      !isPCI(pc)            ||
5705      !PCI(pc)->pcop        ||
5706      PCI(pc)->num_ops == 0 ||
5707      (PCI(pc)->num_ops == 1))           // accept only 2 operand commands
5708     return NULL;
5709
5710
5711 #if 0
5712   fprintf(stderr, "pic16_getRegFromInstruction2 - reg type %s (%d)\n",
5713         dumpPicOptype( PCI(pc)->pcop->type), PCI(pc)->pcop->type);
5714 #endif
5715
5716 /*
5717  * operands supported in MOVFF:
5718  *  PO_INF0/PO_FSR0
5719  *  PO_GPR_TEMP
5720  *  PO_IMMEDIATE
5721  *  PO_DIR
5722  *
5723  */
5724   switch(PCI(pc)->pcop->type) {
5725   case PO_PRODL:
5726   case PO_PRODH:
5727
5728   case PO_INDF0:
5729   case PO_FSR0:
5730     return PCOR(PCOR2(PCI(pc)->pcop)->pcop2)->r;
5731
5732     //    return typeRegWithIdx (PCOR(PCI(pc)->pcop)->rIdx, REG_SFR, 0);
5733
5734 //  case PO_BIT:
5735   case PO_GPR_TEMP:
5736     //fprintf(stderr, "pic16_getRegFromInstruction2 - bit or temp\n");
5737     return PCOR(PCOR2(PCI(pc)->pcop)->pcop2)->r;
5738
5739   case PO_IMMEDIATE:
5740 #if 0
5741 //    if(PCOI(PCI(pc)->pcop)->r)
5742 //      return (PCOI(PCOR2(PCI(pc)->pcop)->pcop2)->r);
5743
5744     //fprintf(stderr, "pic16_getRegFromInstruction2 - immediate\n");
5745     return pic16_dirregWithName(PCOI(PCOR2(PCI(pc)->pcop)->pcop2)->r->name);
5746 #endif
5747
5748     if(PCOI(PCOR2(PCI(pc)->pcop)->pcop2)->r)
5749       return (PCOI(PCOR2(PCI(pc)->pcop)->pcop2)->r);
5750     else
5751       return NULL;
5752
5753
5754   case PO_GPR_BIT:
5755         break;
5756 //    return PCOR2(PCI(pc)->pcop)->r;
5757
5758   case PO_GPR_REGISTER:
5759   case PO_DIR:
5760     //fprintf(stderr, "pic16_getRegFromInstruction2 - dir\n");
5761     return PCOR(PCOR2(PCI(pc)->pcop)->pcop2)->r;
5762
5763   case PO_LITERAL:
5764         break;
5765     //fprintf(stderr, "pic16_getRegFromInstruction2 - literal\n");
5766
5767   default:
5768     //fprintf(stderr, "pic16_getRegFromInstruction2 - unknown reg type %d\n",PCI(pc)->pcop->type);
5769     //genericPrint(stderr, pc);
5770     break;
5771   }
5772
5773   return NULL;
5774
5775 }
5776
5777 /*-----------------------------------------------------------------*/
5778 /*-----------------------------------------------------------------*/
5779
5780 static void AnalyzepBlock(pBlock *pb)
5781 {
5782   pCode *pc;
5783
5784   if(!pb)
5785     return;
5786
5787   /* Find all of the registers used in this pBlock 
5788    * by looking at each instruction and examining it's
5789    * operands
5790    */
5791   for(pc = pb->pcHead; pc; pc = pc->next) {
5792
5793     /* Is this an instruction with operands? */
5794     if(pc->type == PC_OPCODE && PCI(pc)->pcop) {
5795
5796       if(PCI(pc)->pcop->type == PO_GPR_TEMP) {
5797
5798         /* Loop through all of the registers declared so far in
5799            this block and see if we find this one there */
5800
5801         regs *r = setFirstItem(pb->tregisters);
5802
5803         while(r) {
5804           if(r->rIdx == PCOR(PCI(pc)->pcop)->r->rIdx) {
5805             PCOR(PCI(pc)->pcop)->r = r;
5806             break;
5807           }
5808           r = setNextItem(pb->tregisters);
5809         }
5810
5811         if(!r) {
5812           /* register wasn't found */
5813           //r = Safe_calloc(1, sizeof(regs));
5814           //memcpy(r,PCOR(PCI(pc)->pcop)->r, sizeof(regs));
5815           //addSet(&pb->tregisters, r);
5816           addSet(&pb->tregisters, PCOR(PCI(pc)->pcop)->r);
5817           //PCOR(PCI(pc)->pcop)->r = r;
5818           //fprintf(stderr,"added register to pblock: reg %d\n",r->rIdx);
5819         }/* else 
5820           fprintf(stderr,"found register in pblock: reg %d\n",r->rIdx);
5821          */
5822       }
5823       if(PCI(pc)->pcop->type == PO_GPR_REGISTER) {
5824         if(PCOR(PCI(pc)->pcop)->r) {
5825           pic16_allocWithIdx (PCOR(PCI(pc)->pcop)->r->rIdx);
5826           DFPRINTF((stderr,"found register in pblock: reg 0x%x\n",PCOR(PCI(pc)->pcop)->r->rIdx));
5827         } else {
5828           if(PCI(pc)->pcop->name)
5829             fprintf(stderr,"ERROR: %s is a NULL register\n",PCI(pc)->pcop->name );
5830           else
5831             fprintf(stderr,"ERROR: NULL register\n");
5832         }
5833       }
5834     }
5835
5836
5837   }
5838 }
5839
5840 /*-----------------------------------------------------------------*/
5841 /* */
5842 /*-----------------------------------------------------------------*/
5843 #define PCI_HAS_LABEL(x) ((x) && (PCI(x)->label != NULL))
5844
5845 static void InsertpFlow(pCode *pc, pCode **pflow)
5846 {
5847   if(*pflow)
5848     PCFL(*pflow)->end = pc;
5849
5850   if(!pc || !pc->next)
5851     return;
5852
5853   *pflow = pic16_newpCodeFlow();
5854   pic16_pCodeInsertAfter(pc, *pflow);
5855 }
5856
5857 /*-----------------------------------------------------------------*/
5858 /* pic16_BuildFlow(pBlock *pb) - examine the code in a pBlock and build  */
5859 /*                         the flow blocks.                        */
5860 /*
5861  * pic16_BuildFlow inserts pCodeFlow objects into the pCode chain at each
5862  * point the instruction flow changes. 
5863  */
5864 /*-----------------------------------------------------------------*/
5865 void pic16_BuildFlow(pBlock *pb)
5866 {
5867   pCode *pc;
5868   pCode *last_pci=NULL;
5869   pCode *pflow=NULL;
5870   int seq = 0;
5871
5872   if(!pb)
5873     return;
5874
5875   //fprintf (stderr,"build flow start seq %d  ",GpcFlowSeq);
5876   /* Insert a pCodeFlow object at the beginning of a pBlock */
5877
5878   InsertpFlow(pb->pcHead, &pflow);
5879
5880   //pflow = pic16_newpCodeFlow();    /* Create a new Flow object */
5881   //pflow->next = pb->pcHead;  /* Make the current head the next object */
5882   //pb->pcHead->prev = pflow;  /* let the current head point back to the flow object */
5883   //pb->pcHead = pflow;        /* Make the Flow object the head */
5884   //pflow->pb = pb;
5885
5886   for( pc = pic16_findNextInstruction(pb->pcHead);
5887        pc != NULL;
5888        pc=pic16_findNextInstruction(pc)) { 
5889
5890     pc->seq = seq++;
5891     PCI(pc)->pcflow = PCFL(pflow);
5892
5893     //fprintf(stderr," build: ");
5894     //pflow->print(stderr,pflow);
5895
5896     if( PCI(pc)->isSkip) {
5897
5898       /* The two instructions immediately following this one 
5899        * mark the beginning of a new flow segment */
5900
5901       while(pc && PCI(pc)->isSkip) {
5902
5903         PCI(pc)->pcflow = PCFL(pflow);
5904         pc->seq = seq-1;
5905         seq = 1;
5906
5907         InsertpFlow(pc, &pflow);
5908         pc=pic16_findNextInstruction(pc->next);
5909       }
5910
5911       seq = 0;
5912
5913       if(!pc)
5914         break;
5915
5916       PCI(pc)->pcflow = PCFL(pflow);
5917       pc->seq = 0;
5918       InsertpFlow(pc, &pflow);
5919
5920     } else if ( PCI(pc)->isBranch && !checkLabel(pic16_findNextInstruction(pc->next)))  {
5921
5922       InsertpFlow(pc, &pflow);
5923       seq = 0;
5924
5925     } else if (checkLabel(pc)) { 
5926
5927       /* This instruction marks the beginning of a
5928        * new flow segment */
5929
5930       pc->seq = 0;
5931       seq = 1;
5932
5933       /* If the previous pCode is not a flow object, then 
5934        * insert a new flow object. (This check prevents 
5935        * two consecutive flow objects from being insert in
5936        * the case where a skip instruction preceeds an
5937        * instruction containing a label.) */
5938
5939       if(last_pci && (PCI(last_pci)->pcflow == PCFL(pflow)))
5940         InsertpFlow(pic16_findPrevInstruction(pc->prev), &pflow);
5941
5942       PCI(pc)->pcflow = PCFL(pflow);
5943       
5944     }
5945     last_pci = pc;
5946     pc = pc->next;
5947   }
5948
5949   //fprintf (stderr,",end seq %d",GpcFlowSeq);
5950   if(pflow)
5951     PCFL(pflow)->end = pb->pcTail;
5952 }
5953
5954 /*-------------------------------------------------------------------*/
5955 /* unBuildFlow(pBlock *pb) - examine the code in a pBlock and build  */
5956 /*                           the flow blocks.                        */
5957 /*
5958  * unBuildFlow removes pCodeFlow objects from a pCode chain
5959  */
5960 /*-----------------------------------------------------------------*/
5961 static void unBuildFlow(pBlock *pb)
5962 {
5963   pCode *pc,*pcnext;
5964
5965   if(!pb)
5966     return;
5967
5968   pc = pb->pcHead;
5969
5970   while(pc) {
5971     pcnext = pc->next;
5972
5973     if(isPCI(pc)) {
5974
5975       pc->seq = 0;
5976       if(PCI(pc)->pcflow) {
5977         //free(PCI(pc)->pcflow);
5978         PCI(pc)->pcflow = NULL;
5979       }
5980
5981     } else if(isPCFL(pc) )
5982       pc->destruct(pc);
5983
5984     pc = pcnext;
5985   }
5986
5987
5988 }
5989 #if 0
5990 /*-----------------------------------------------------------------*/
5991 /*-----------------------------------------------------------------*/
5992 static void dumpCond(int cond)
5993 {
5994
5995   static char *pcc_str[] = {
5996     //"PCC_NONE",
5997     "PCC_REGISTER",
5998     "PCC_C",
5999     "PCC_Z",
6000     "PCC_DC",
6001     "PCC_OV",
6002     "PCC_N",
6003     "PCC_W",
6004     "PCC_EXAMINE_PCOP",
6005     "PCC_LITERAL",
6006     "PCC_REL_ADDR"
6007   };
6008
6009   int ncond = sizeof(pcc_str) / sizeof(char *);
6010   int i,j;
6011
6012   fprintf(stderr, "0x%04X\n",cond);
6013
6014   for(i=0,j=1; i<ncond; i++, j<<=1)
6015     if(cond & j)
6016       fprintf(stderr, "  %s\n",pcc_str[i]);
6017
6018 }
6019 #endif
6020
6021 #if 0
6022 /*-----------------------------------------------------------------*/
6023 /*-----------------------------------------------------------------*/
6024 static void FlowStats(pCodeFlow *pcflow)
6025 {
6026
6027   pCode *pc;
6028
6029   if(!isPCFL(pcflow))
6030     return;
6031
6032   fprintf(stderr, " FlowStats - flow block (seq=%d)\n", pcflow->pc.seq);
6033
6034   pc = pic16_findNextpCode(PCODE(pcflow), PC_OPCODE); 
6035
6036   if(!pc) {
6037     fprintf(stderr, " FlowStats - empty flow (seq=%d)\n", pcflow->pc.seq);
6038     return;
6039   }
6040
6041
6042   fprintf(stderr, "  FlowStats inCond: ");
6043   dumpCond(pcflow->inCond);
6044   fprintf(stderr, "  FlowStats outCond: ");
6045   dumpCond(pcflow->outCond);
6046
6047 }
6048 #endif
6049 /*-----------------------------------------------------------------*
6050  * int isBankInstruction(pCode *pc) - examine the pCode *pc to determine
6051  *    if it affects the banking bits. 
6052  * 
6053  * return: -1 == Banking bits are unaffected by this pCode.
6054  *
6055  * return: > 0 == Banking bits are affected.
6056  *
6057  *  If the banking bits are affected, then the returned value describes
6058  * which bits are affected and how they're affected. The lower half
6059  * of the integer maps to the bits that are affected, the upper half
6060  * to whether they're set or cleared.
6061  *
6062  *-----------------------------------------------------------------*/
6063
6064 static int isBankInstruction(pCode *pc)
6065 {
6066   regs *reg;
6067   int bank = -1;
6068
6069   if(!isPCI(pc))
6070     return 0;
6071
6072   if( PCI(pc)->op == POC_MOVLB ||
6073       (( (reg = pic16_getRegFromInstruction(pc)) != NULL) && isBSR_REG(reg))) {
6074     bank = PCOL(pc)->lit;
6075   }
6076
6077   return 1;
6078 }
6079
6080
6081 /*-----------------------------------------------------------------*/
6082 /*-----------------------------------------------------------------*/
6083 static void FillFlow(pCodeFlow *pcflow)
6084 {
6085
6086   pCode *pc;
6087   int cur_bank;
6088
6089   if(!isPCFL(pcflow))
6090     return;
6091
6092   //  fprintf(stderr, " FillFlow - flow block (seq=%d)\n", pcflow->pc.seq);
6093
6094   pc = pic16_findNextpCode(PCODE(pcflow), PC_OPCODE); 
6095
6096   if(!pc) {
6097     //fprintf(stderr, " FillFlow - empty flow (seq=%d)\n", pcflow->pc.seq);
6098     return;
6099   }
6100
6101   cur_bank = -1;
6102
6103   do {
6104     isBankInstruction(pc);
6105     pc = pc->next;
6106   } while (pc && (pc != pcflow->end) && !isPCFL(pc));
6107
6108 /*
6109   if(!pc ) {
6110     fprintf(stderr, "  FillFlow - Bad end of flow\n");
6111   } else {
6112     fprintf(stderr, "  FillFlow - Ending flow with\n  ");
6113     pc->print(stderr,pc);
6114   }
6115
6116   fprintf(stderr, "  FillFlow inCond: ");
6117   dumpCond(pcflow->inCond);
6118   fprintf(stderr, "  FillFlow outCond: ");
6119   dumpCond(pcflow->outCond);
6120 */
6121 }
6122
6123 /*-----------------------------------------------------------------*/
6124 /*-----------------------------------------------------------------*/
6125 static void LinkFlow_pCode(pCodeInstruction *from, pCodeInstruction *to)
6126 {
6127   pCodeFlowLink *fromLink, *toLink;
6128
6129   if(!from || !to || !to->pcflow || !from->pcflow)
6130     return;
6131
6132   fromLink = pic16_newpCodeFlowLink(from->pcflow);
6133   toLink   = pic16_newpCodeFlowLink(to->pcflow);
6134
6135   addSetIfnotP(&(from->pcflow->to), toLink);   //to->pcflow);
6136   addSetIfnotP(&(to->pcflow->from), fromLink); //from->pcflow);
6137
6138 }
6139
6140 /*-----------------------------------------------------------------*
6141  * void LinkFlow(pBlock *pb)
6142  *
6143  * In pic16_BuildFlow, the PIC code has been partitioned into contiguous
6144  * non-branching segments. In LinkFlow, we determine the execution
6145  * order of these segments. For example, if one of the segments ends
6146  * with a skip, then we know that there are two possible flow segments
6147  * to which control may be passed.
6148  *-----------------------------------------------------------------*/
6149 static void LinkFlow(pBlock *pb)
6150 {
6151   pCode *pc=NULL;
6152   pCode *pcflow;
6153   pCode *pct;
6154
6155   //fprintf(stderr,"linkflow \n");
6156
6157   for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
6158        pcflow != NULL;
6159        pcflow = pic16_findNextpCode(pcflow->next, PC_FLOW) ) {
6160
6161     if(!isPCFL(pcflow))
6162       fprintf(stderr, "LinkFlow - pcflow is not a flow object ");
6163
6164     //fprintf(stderr," link: ");
6165     //pcflow->print(stderr,pcflow);
6166
6167     //FillFlow(PCFL(pcflow));
6168
6169     pc = PCFL(pcflow)->end;
6170
6171     //fprintf(stderr, "LinkFlow - flow block (seq=%d) ", pcflow->seq);
6172     if(isPCI_SKIP(pc)) {
6173       //fprintf(stderr, "ends with skip\n");
6174       //pc->print(stderr,pc);
6175       pct=pic16_findNextInstruction(pc->next);
6176       LinkFlow_pCode(PCI(pc),PCI(pct));
6177       pct=pic16_findNextInstruction(pct->next);
6178       LinkFlow_pCode(PCI(pc),PCI(pct));
6179       continue;
6180     }
6181
6182     if(isPCI_BRANCH(pc)) {
6183       pCodeOpLabel *pcol = PCOLAB(PCI(pc)->pcop);
6184
6185       //fprintf(stderr, "ends with branch\n  ");
6186       //pc->print(stderr,pc);
6187
6188       if(!(pcol && isPCOLAB(pcol))) {
6189         if((PCI(pc)->op != POC_RETLW)
6190                 && (PCI(pc)->op != POC_RETURN) && (PCI(pc)->op != POC_CALL) && (PCI(pc)->op != POC_RETFIE) ) {
6191         
6192                 /* continue if label is '$' which assembler knows how to parse */
6193                 if(((PCI(pc)->pcop->type == PO_STR) && !strcmp(PCI(pc)->pcop->name, "$")))continue;
6194
6195                 if(pic16_pcode_verbose) {
6196                         pc->print(stderr,pc);
6197                         fprintf(stderr, "ERROR: %s, branch instruction doesn't have label\n",__FUNCTION__);
6198                 }
6199         }
6200         continue;
6201       }
6202
6203       if( (pct = findLabelinpBlock(pb,pcol)) != NULL)
6204         LinkFlow_pCode(PCI(pc),PCI(pct));
6205       else
6206         fprintf(stderr, "ERROR: %s, couldn't find label. key=%d,lab=%s\n",
6207                 __FUNCTION__,pcol->key,((PCOP(pcol)->name)?PCOP(pcol)->name:"-"));
6208
6209 //      fprintf(stderr,"pic16_newpCodeOpLabel: key=%d, name=%s\n",pcol->key,(PCOP(pcol)->name)?(PCOP(pcol)->name):"<unknown>");
6210
6211       continue;
6212     }
6213
6214     if(isPCI(pc)) {
6215       //fprintf(stderr, "ends with non-branching instruction:\n");
6216       //pc->print(stderr,pc);
6217
6218       LinkFlow_pCode(PCI(pc),PCI(pic16_findNextInstruction(pc->next)));
6219
6220       continue;
6221     }
6222
6223     if(pc) {
6224       //fprintf(stderr, "ends with unknown\n");
6225       //pc->print(stderr,pc);
6226       continue;
6227     }
6228
6229     //fprintf(stderr, "ends with nothing: ERROR\n");
6230     
6231   }
6232 }
6233 /*-----------------------------------------------------------------*/
6234 /*-----------------------------------------------------------------*/
6235
6236 /*-----------------------------------------------------------------*/
6237 /*-----------------------------------------------------------------*/
6238 int pic16_isPCinFlow(pCode *pc, pCode *pcflow)
6239 {
6240
6241   if(!pc || !pcflow)
6242     return 0;
6243
6244   if((!isPCI(pc) && !isPCAD(pc)) || !PCI(pc)->pcflow || !isPCFL(pcflow) )
6245     return 0;
6246
6247   if( PCI(pc)->pcflow->pc.seq == pcflow->seq)
6248     return 1;
6249
6250   return 0;
6251 }
6252
6253
6254
6255
6256
6257 /*-----------------------------------------------------------------*/
6258 /* insertBankSwitch - inserts a bank switch statement in the       */
6259 /*                    assembly listing                             */
6260 /*                                                                 */
6261 /* position == 0: insert before                                    */
6262 /* position == 1: insert after pc                                  */
6263 /* position == 2: like 0 but previous was a skip instruction       */
6264 /*-----------------------------------------------------------------*/
6265 pCodeOp *pic16_popGetLabel(unsigned int key);
6266 extern int pic16_labelOffset;
6267
6268 static void insertBankSwitch(unsigned char position, pCode *pc)
6269 {
6270   pCode *new_pc;
6271
6272         if(!pc)
6273                 return;
6274
6275         /* emit BANKSEL [symbol] */
6276
6277
6278         new_pc = pic16_newpCodeAsmDir("BANKSEL", "%s", pic16_get_op_from_instruction(PCI(pc)));
6279         
6280 //      position = 0;           // position is always before (sanity check!)
6281
6282 #if 0
6283         fprintf(stderr, "%s:%d: inserting bank switch (pos: %d)\n", __FUNCTION__, __LINE__, position);
6284         pc->print(stderr, pc);
6285 #endif
6286
6287         switch(position) {
6288                 case 1: {
6289                         /* insert the bank switch after this pc instruction */
6290                         pCode *pcnext = pic16_findNextInstruction(pc);
6291
6292                                 pic16_pCodeInsertAfter(pc, new_pc);
6293                                 if(pcnext)pc = pcnext;
6294                 }; break;
6295                 
6296                 case 0:
6297                         /* insert the bank switch BEFORE this pc instruction */
6298                         pic16_pCodeInsertAfter(pc->prev, new_pc);
6299                         break;
6300
6301                 case 2: {
6302                           symbol *tlbl;
6303                           pCode *pcnext, *pcprev, *npci, *ppc;
6304                           PIC_OPCODE ipci;
6305                           int ofs1=0, ofs2=0, len=0;
6306                           
6307                         /* just like 0, but previous was a skip instruction,
6308                          * so some care should be taken */
6309                           
6310                                 pic16_labelOffset += 10000;
6311                                 tlbl = newiTempLabel(NULL);
6312                                 
6313                                 /* invert skip instruction */
6314                                 pcprev = pic16_findPrevInstruction(pc->prev);
6315                                 ipci = PCI(pcprev)->inverted_op;
6316                                 npci = pic16_newpCode(ipci, PCI(pcprev)->pcop);
6317
6318 //                              fprintf(stderr, "%s:%d old OP: %d\tnew OP: %d\n", __FILE__, __LINE__, PCI(pcprev)->op, ipci);
6319
6320                                 /* copy info from old pCode */
6321                                 ofs1 = ofs2 = sizeof( pCode ) + sizeof(PIC_OPCODE);
6322                                 len = sizeof(pCodeInstruction) - ofs1 - sizeof( char const * const *);
6323                                 ofs1 += strlen( PCI(pcprev)->mnemonic) + 1;
6324                                 ofs2 += strlen( PCI(npci)->mnemonic) + 1;
6325                                 memcpy(&PCI(npci)->from, &PCI(pcprev)->from, (char *)(&(PCI(npci)->pci_magic)) - (char *)(&(PCI(npci)->from)));
6326                                 PCI(npci)->op = PCI(pcprev)->inverted_op;
6327                                 
6328                                 /* unlink old pCode */
6329                                 ppc = pcprev->prev;
6330                                 ppc->next = pcprev->next;
6331                                 pcprev->next->prev = ppc;
6332                                 pic16_pCodeInsertAfter(ppc, npci);
6333                                 
6334                                 /* extra instructions to handle invertion */
6335                                 pcnext = pic16_newpCode(POC_GOTO, pic16_popGetLabel(tlbl->key));
6336                                 pic16_pCodeInsertAfter(npci, pcnext);
6337                                 pic16_pCodeInsertAfter(pc->prev, new_pc);
6338                                 
6339                                 pcnext = pic16_newpCodeLabel(NULL,tlbl->key+100+pic16_labelOffset);
6340                                 pic16_pCodeInsertAfter(pc, pcnext);
6341                         }; break;
6342         }
6343         
6344
6345         /* Move the label, if there is one */
6346         if(PCI(pc)->label) {
6347 //              fprintf(stderr, "%s:%d: moving label due to bank switch directive src= 0x%p dst= 0x%p\n",
6348 //                      __FILE__, __LINE__, pc, new_pc);
6349                 PCAD(new_pc)->pci.label = PCI(pc)->label;
6350                 PCI(pc)->label = NULL;
6351         }
6352 }
6353
6354
6355 /*-----------------------------------------------------------------*/
6356 /*int compareBankFlow - compare the banking requirements between   */
6357 /*  flow objects. */
6358 /*-----------------------------------------------------------------*/
6359 static int compareBankFlow(pCodeFlow *pcflow, pCodeFlowLink *pcflowLink, int toORfrom)
6360 {
6361
6362   if(!pcflow || !pcflowLink || !pcflowLink->pcflow)
6363     return 0;
6364
6365   if(!isPCFL(pcflow) || !isPCFL(pcflowLink->pcflow))
6366     return 0;
6367
6368   if(pcflow->firstBank == -1)
6369     return 0;
6370
6371
6372   if(pcflowLink->pcflow->firstBank == -1) {
6373     pCodeFlowLink *pctl = setFirstItem( toORfrom ? 
6374                                         pcflowLink->pcflow->to : 
6375                                         pcflowLink->pcflow->from);
6376     return compareBankFlow(pcflow, pctl, toORfrom);
6377   }
6378
6379   if(toORfrom) {
6380     if(pcflow->lastBank == pcflowLink->pcflow->firstBank)
6381       return 0;
6382
6383     pcflowLink->bank_conflict++;
6384     pcflowLink->pcflow->FromConflicts++;
6385     pcflow->ToConflicts++;
6386   } else {
6387     
6388     if(pcflow->firstBank == pcflowLink->pcflow->lastBank)
6389       return 0;
6390
6391     pcflowLink->bank_conflict++;
6392     pcflowLink->pcflow->ToConflicts++;
6393     pcflow->FromConflicts++;
6394
6395   }
6396   /*
6397   fprintf(stderr,"compare flow found conflict: seq %d from conflicts %d, to conflicts %d\n",
6398           pcflowLink->pcflow->pc.seq,
6399           pcflowLink->pcflow->FromConflicts,
6400           pcflowLink->pcflow->ToConflicts);
6401   */
6402   return 1;
6403
6404 }
6405
6406 #if 0
6407 /*-----------------------------------------------------------------*/
6408 /*-----------------------------------------------------------------*/
6409 static void DumpFlow(pBlock *pb)
6410 {
6411   pCode *pc=NULL;
6412   pCode *pcflow;
6413   pCodeFlowLink *pcfl;
6414
6415
6416   fprintf(stderr,"Dump flow \n");
6417   pb->pcHead->print(stderr, pb->pcHead);
6418
6419   pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW);
6420   pcflow->print(stderr,pcflow);
6421
6422   for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
6423        pcflow != NULL;
6424        pcflow = pic16_findNextpCode(pcflow->next, PC_FLOW) ) {
6425
6426     if(!isPCFL(pcflow)) {
6427       fprintf(stderr, "DumpFlow - pcflow is not a flow object ");
6428       continue;
6429     }
6430     fprintf(stderr,"dumping: ");
6431     pcflow->print(stderr,pcflow);
6432     FlowStats(PCFL(pcflow));
6433
6434     for(pcfl = setFirstItem(PCFL(pcflow)->to); pcfl; pcfl=setNextItem(PCFL(pcflow)->to)) {
6435
6436       pc = PCODE(pcfl->pcflow);
6437
6438       fprintf(stderr, "    from seq %d:\n",pc->seq);
6439       if(!isPCFL(pc)) {
6440         fprintf(stderr,"oops dumpflow - from is not a pcflow\n");
6441         pc->print(stderr,pc);
6442       }
6443
6444     }
6445
6446     for(pcfl = setFirstItem(PCFL(pcflow)->to); pcfl; pcfl=setNextItem(PCFL(pcflow)->to)) {
6447
6448       pc = PCODE(pcfl->pcflow);
6449
6450       fprintf(stderr, "    to seq %d:\n",pc->seq);
6451       if(!isPCFL(pc)) {
6452         fprintf(stderr,"oops dumpflow - to is not a pcflow\n");
6453         pc->print(stderr,pc);
6454       }
6455
6456     }
6457
6458   }
6459
6460 }
6461 #endif
6462 /*-----------------------------------------------------------------*/
6463 /*-----------------------------------------------------------------*/
6464 static int OptimizepBlock(pBlock *pb)
6465 {
6466   pCode *pc, *pcprev;
6467   int matches =0;
6468
6469   if(!pb || !peepOptimizing)
6470     return 0;
6471
6472   DFPRINTF((stderr," Optimizing pBlock: %c\n",getpBlock_dbName(pb)));
6473 /*
6474   for(pc = pb->pcHead; pc; pc = pc->next)
6475     matches += pic16_pCodePeepMatchRule(pc);
6476 */
6477
6478   pc = pic16_findNextInstruction(pb->pcHead);
6479   if(!pc)
6480     return 0;
6481
6482   pcprev = pc->prev;
6483   do {
6484
6485
6486     if(pic16_pCodePeepMatchRule(pc)) {
6487
6488       matches++;
6489
6490       if(pcprev)
6491         pc = pic16_findNextInstruction(pcprev->next);
6492       else 
6493         pc = pic16_findNextInstruction(pb->pcHead);
6494     } else
6495       pc = pic16_findNextInstruction(pc->next);
6496   } while(pc);
6497
6498   if(matches)
6499     DFPRINTF((stderr," Optimizing pBlock: %c - matches=%d\n",getpBlock_dbName(pb),matches));
6500   return matches;
6501
6502 }
6503
6504 /*-----------------------------------------------------------------*/
6505 /*-----------------------------------------------------------------*/
6506 static pCode * findInstructionUsingLabel(pCodeLabel *pcl, pCode *pcs)
6507 {
6508   pCode *pc;
6509
6510   for(pc = pcs; pc; pc = pc->next) {
6511
6512     if(((pc->type == PC_OPCODE) || (pc->type == PC_INLINE)) && 
6513        (PCI(pc)->pcop) && 
6514        (PCI(pc)->pcop->type == PO_LABEL) &&
6515        (PCOLAB(PCI(pc)->pcop)->key == pcl->key))
6516       return pc;
6517   }
6518  
6519
6520   return NULL;
6521 }
6522
6523 /*-----------------------------------------------------------------*/
6524 /*-----------------------------------------------------------------*/
6525 static void exchangeLabels(pCodeLabel *pcl, pCode *pc)
6526 {
6527
6528   char *s=NULL;
6529
6530   if(isPCI(pc) && 
6531      (PCI(pc)->pcop) && 
6532      (PCI(pc)->pcop->type == PO_LABEL)) {
6533
6534     pCodeOpLabel *pcol = PCOLAB(PCI(pc)->pcop);
6535
6536 //      fprintf(stderr,"changing label key from %d to %d\n",pcol->key, pcl->key);
6537 //    if(pcol->pcop.name)
6538 //      free(pcol->pcop.name);
6539
6540     /* If the key is negative, then we (probably) have a label to
6541      * a function and the name is already defined */
6542        
6543     if(pcl->key>0)
6544       sprintf(s=buffer,"_%05d_DS_",pcl->key);
6545     else 
6546       s = pcl->label;
6547
6548     //sprintf(buffer,"_%05d_DS_",pcl->key);
6549     if(!s) {
6550       fprintf(stderr, "ERROR %s:%d function label is null\n",__FUNCTION__,__LINE__);
6551     }
6552     pcol->pcop.name = Safe_strdup(s);
6553     pcol->key = pcl->key;
6554     //pc->print(stderr,pc);
6555
6556   }
6557
6558
6559 }
6560
6561 /*-----------------------------------------------------------------*/
6562 /* pBlockRemoveUnusedLabels - remove the pCode labels from the     */
6563 /*                            pCode chain if they're not used.     */
6564 /*-----------------------------------------------------------------*/
6565 static void pBlockRemoveUnusedLabels(pBlock *pb)
6566 {
6567   pCode *pc; pCodeLabel *pcl;
6568
6569   if(!pb)
6570     return;
6571
6572   for(pc = pb->pcHead; (pc=pic16_findNextInstruction(pc->next)) != NULL; ) {
6573
6574     pBranch *pbr = PCI(pc)->label;
6575     if(pbr && pbr->next) {
6576       pCode *pcd = pb->pcHead;
6577
6578 //      fprintf(stderr, "multiple labels\n");
6579 //      pc->print(stderr,pc);
6580
6581       pbr = pbr->next;
6582       while(pbr) {
6583
6584         while ( (pcd = findInstructionUsingLabel(PCL(PCI(pc)->label->pc), pcd)) != NULL) {
6585           //fprintf(stderr,"Used by:\n");
6586           //pcd->print(stderr,pcd);
6587
6588           exchangeLabels(PCL(pbr->pc),pcd);
6589
6590           pcd = pcd->next;
6591         }
6592         pbr = pbr->next;
6593       }
6594     }
6595   }
6596
6597   for(pc = pb->pcHead; pc; pc = pc->next) {
6598
6599     if(isPCL(pc)) // pc->type == PC_LABEL)
6600       pcl = PCL(pc);
6601     else if (isPCI(pc) && PCI(pc)->label) //((pc->type == PC_OPCODE) && PCI(pc)->label)
6602       pcl = PCL(PCI(pc)->label->pc);
6603     else continue;
6604
6605 //      fprintf(stderr," found  A LABEL !!! key = %d, %s\n", pcl->key,pcl->label);
6606
6607     /* This pCode is a label, so search the pBlock to see if anyone
6608      * refers to it */
6609
6610     if( (pcl->key>0) && (!findInstructionUsingLabel(pcl, pb->pcHead))
6611         && (!pcl->force)) {
6612     //if( !findInstructionUsingLabel(pcl, pb->pcHead)) {
6613       /* Couldn't find an instruction that refers to this label
6614        * So, unlink the pCode label from it's pCode chain
6615        * and destroy the label */
6616 //      fprintf(stderr," removed  A LABEL !!! key = %d, %s\n", pcl->key,pcl->label);
6617
6618       DFPRINTF((stderr," !!! REMOVED A LABEL !!! key = %d, %s\n", pcl->key,pcl->label));
6619       if(pc->type == PC_LABEL) {
6620         pic16_unlinkpCode(pc);
6621         pCodeLabelDestruct(pc);
6622       } else {
6623         unlinkpCodeFromBranch(pc, PCODE(pcl));
6624         /*if(pc->label->next == NULL && pc->label->pc == NULL) {
6625           free(pc->label);
6626         }*/
6627       }
6628
6629     }
6630   }
6631
6632 }
6633
6634
6635 /*-----------------------------------------------------------------*/
6636 /* pic16_pBlockMergeLabels - remove the pCode labels from the pCode      */
6637 /*                     chain and put them into pBranches that are  */
6638 /*                     associated with the appropriate pCode       */
6639 /*                     instructions.                               */
6640 /*-----------------------------------------------------------------*/
6641 void pic16_pBlockMergeLabels(pBlock *pb)
6642 {
6643   pBranch *pbr;
6644   pCode *pc, *pcnext=NULL;
6645
6646   if(!pb)
6647     return;
6648
6649   /* First, Try to remove any unused labels */
6650   //pBlockRemoveUnusedLabels(pb);
6651
6652   /* Now loop through the pBlock and merge the labels with the opcodes */
6653
6654   pc = pb->pcHead;
6655   //  for(pc = pb->pcHead; pc; pc = pc->next) {
6656
6657   while(pc) {
6658     pCode *pcn = pc->next;
6659
6660     if(pc->type == PC_LABEL) {
6661
6662 //      fprintf(stderr," checking merging label %s\n",PCL(pc)->label);
6663 //      fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key);
6664
6665       if((pcnext = pic16_findNextInstruction(pc) )) {
6666
6667 //              pcnext->print(stderr, pcnext);
6668
6669         // Unlink the pCode label from it's pCode chain
6670         pic16_unlinkpCode(pc);
6671         
6672 //      fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key);
6673         // And link it into the instruction's pBranch labels. (Note, since
6674         // it's possible to have multiple labels associated with one instruction
6675         // we must provide a means to accomodate the additional labels. Thus
6676         // the labels are placed into the singly-linked list "label" as 
6677         // opposed to being a single member of the pCodeInstruction.)
6678
6679         //_ALLOC(pbr,sizeof(pBranch));
6680 #if 1
6681         pbr = Safe_calloc(1,sizeof(pBranch));
6682         pbr->pc = pc;
6683         pbr->next = NULL;
6684
6685         PCI(pcnext)->label = pic16_pBranchAppend(PCI(pcnext)->label,pbr);
6686 #endif
6687       } else {
6688         if(pic16_pcode_verbose)
6689         fprintf(stderr, "WARNING: couldn't associate label %s with an instruction\n",PCL(pc)->label);
6690       }
6691     } else if(pc->type == PC_CSOURCE) {
6692
6693       /* merge the source line symbolic info into the next instruction */
6694       if((pcnext = pic16_findNextInstruction(pc) )) {
6695
6696         // Unlink the pCode label from it's pCode chain
6697         pic16_unlinkpCode(pc);
6698         PCI(pcnext)->cline = PCCS(pc);
6699         //fprintf(stderr, "merging CSRC\n");
6700         //genericPrint(stderr,pcnext);
6701       }
6702
6703     }
6704     pc = pcn;
6705   }
6706   pBlockRemoveUnusedLabels(pb);
6707
6708 }
6709
6710 /*-----------------------------------------------------------------*/
6711 /*-----------------------------------------------------------------*/
6712 static int OptimizepCode(char dbName)
6713 {
6714 #define MAX_PASSES 4
6715
6716   int matches = 0;
6717   int passes = 0;
6718   pBlock *pb;
6719
6720   if(!the_pFile)
6721     return 0;
6722
6723   DFPRINTF((stderr," Optimizing pCode\n"));
6724
6725   do {
6726     matches = 0;
6727     for(pb = the_pFile->pbHead; pb; pb = pb->next) {
6728       if('*' == dbName || getpBlock_dbName(pb) == dbName)
6729         matches += OptimizepBlock(pb);
6730     }
6731   }
6732   while(matches && ++passes < MAX_PASSES);
6733
6734   return matches;
6735 }
6736
6737
6738
6739 const char *pic16_pCodeOpType(pCodeOp *pcop);
6740 const char *pic16_pCodeOpSubType(pCodeOp *pcop);
6741
6742
6743 /*-----------------------------------------------------------------*/
6744 /* pic16_popCopyGPR2Bit - copy a pcode operator                          */
6745 /*-----------------------------------------------------------------*/
6746
6747 pCodeOp *pic16_popCopyGPR2Bit(pCodeOp *pc, int bitval)
6748 {
6749   pCodeOp *pcop=NULL;
6750
6751 //  fprintf(stderr, "%s:%d pc type: %s\tname: %s\n", __FILE__, __LINE__, pic16_pCodeOpType(pc), pc->name);
6752
6753   if(pc->name) {
6754         pcop = pic16_newpCodeOpBit(pc->name, bitval, 0, pc->type);
6755   } else {
6756     if(PCOR(pc)->r)pcop = pic16_newpCodeOpBit(PCOR(pc)->r->name, bitval, 0, pc->type);
6757   }
6758
6759   assert(pcop != NULL);
6760
6761   if( !( (pcop->type == PO_LABEL) ||
6762          (pcop->type == PO_LITERAL) ||
6763          (pcop->type == PO_STR) ))
6764     PCOR(pcop)->r = PCOR(pc)->r;  /* This is dangerous... */
6765     PCOR(pcop)->r->wasUsed = 1;
6766     PCOR(pcop)->instance = PCOR(pc)->instance;
6767
6768   return pcop;
6769 }
6770
6771
6772 /*----------------------------------------------------------------------*
6773  * pic16_areRegsSame - check to see if the names of two registers match *
6774  *----------------------------------------------------------------------*/
6775 int pic16_areRegsSame(regs *r1, regs *r2)
6776 {
6777         if(!strcmp(r1->name, r2->name))return 1;
6778
6779   return 0;
6780 }
6781
6782
6783 /*-----------------------------------------------------------------*/
6784 /*-----------------------------------------------------------------*/
6785 static void pic16_FixRegisterBanking(pBlock *pb)
6786 {
6787   pCode *pc=NULL;
6788   pCode *pcprev=NULL;
6789   regs *reg, *prevreg;
6790   unsigned char flag=0;
6791   
6792         if(!pb)
6793                 return;
6794
6795         pc = pic16_findNextpCode(pb->pcHead, PC_OPCODE);
6796         if(!pc)return;
6797
6798         /* loop through all of the flow blocks with in one pblock */
6799
6800 //      fprintf(stderr,"%s:%d: Register banking\n", __FUNCTION__, __LINE__);
6801
6802         prevreg = NULL;
6803         do {
6804                 /* at this point, pc should point to a PC_FLOW object */
6805                 /* for each flow block, determine the register banking 
6806                  * requirements */
6807
6808                 
6809                 /* if label, then might come from other point, force banksel */
6810                 if(isPCL(pc))prevreg = NULL;
6811                 
6812                 if(!isPCI(pc))goto loop;
6813
6814                 if(PCI(pc)->label)prevreg = NULL;
6815
6816                 if(PCI(pc)->is2MemOp)goto loop;
6817
6818                 /* if goto, then force banksel */
6819 //              if(PCI(pc)->op == POC_GOTO)prevreg = NULL;
6820        
6821                 reg = pic16_getRegFromInstruction(pc);
6822
6823 #if 0
6824                 pc->print(stderr, pc);
6825                 fprintf(stderr, "reg = %p\n", reg);
6826
6827                 if(reg) {
6828                         fprintf(stderr, "%s:%d:  %s  %d\n",__FUNCTION__, __LINE__, reg->name, reg->rIdx);
6829                         fprintf(stderr, "addr = 0x%03x, bit=%d\tfix=%d\n",
6830                                 reg->address,reg->isBitField, reg->isFixed);
6831                 }
6832 #endif
6833
6834                 /* now make some tests to make sure that instruction needs bank switch */
6835
6836                 /* if no register exists, and if not a bit opcode goto loop */
6837                 if(!reg) {
6838                         if(!(PCI(pc)->pcop && PCI(pc)->pcop->type == PO_GPR_BIT))goto loop;
6839                 }
6840                  
6841                 if(isPCI_SKIP(pc)) {
6842 //                      fprintf(stderr, "instruction is SKIP instruction\n");
6843 //                prevreg = NULL;
6844                 }
6845                 if(reg && isACCESS_BANK(reg))goto loop;
6846
6847                 if(!isBankInstruction(pc))goto loop;
6848
6849                 if(isPCI_LIT(pc))goto loop;
6850          
6851                 if(PCI(pc)->op == POC_CALL)goto loop;
6852
6853                 /* Examine the instruction before this one to make sure it is
6854                  * not a skip type instruction */
6855                 pcprev = findPrevpCode(pc->prev, PC_OPCODE);
6856
6857                 flag = 0;               /* add before this instruction */
6858                 
6859                 /* if previous instruction is a skip one, then set flag
6860                  * to 2 and call insertBankSwitch */
6861                 if(pcprev && isPCI_SKIP(pcprev)) {
6862                   flag=2;       //goto loop
6863 //                prevreg = NULL;
6864                 }
6865                  
6866                 if(pic16_options.opt_banksel>0) {
6867                   char op1[128], op2[128];
6868                   
6869                     if(prevreg) {
6870                       strcpy(op1, pic16_get_op_from_instruction(PCI(pc)));
6871                       strcpy(op2, pic16_get_op_from_instruction(PCI(pcprev)));
6872                       if(!strcmp(op1, op2))goto loop;
6873                     }
6874                 }
6875                 prevreg = reg;
6876                 insertBankSwitch(flag, pc);
6877
6878 //              fprintf(stderr, "BANK SWITCH inserted\n");
6879                 
6880 loop:
6881                 pcprev = pc;
6882                 pc = pc->next;
6883         } while (pc);
6884 }
6885
6886
6887
6888 static void pBlockDestruct(pBlock *pb)
6889 {
6890
6891   if(!pb)
6892     return;
6893
6894
6895 //  free(pb);
6896
6897 }
6898
6899 /*-----------------------------------------------------------------*/
6900 /* void mergepBlocks(char dbName) - Search for all pBlocks with the*/
6901 /*                                  name dbName and combine them   */
6902 /*                                  into one block                 */
6903 /*-----------------------------------------------------------------*/
6904 static void mergepBlocks(char dbName)
6905 {
6906
6907   pBlock *pb, *pbmerged = NULL,*pbn;
6908
6909   pb = the_pFile->pbHead;
6910
6911   //fprintf(stderr," merging blocks named %c\n",dbName);
6912   while(pb) {
6913
6914     pbn = pb->next;
6915     //fprintf(stderr,"looking at %c\n",getpBlock_dbName(pb));
6916     if( getpBlock_dbName(pb) == dbName) {
6917
6918       //fprintf(stderr," merged block %c\n",dbName);
6919
6920       if(!pbmerged) {
6921         pbmerged = pb;
6922       } else {
6923         pic16_addpCode2pBlock(pbmerged, pb->pcHead);
6924         /* pic16_addpCode2pBlock doesn't handle the tail: */
6925         pbmerged->pcTail = pb->pcTail;
6926
6927         pb->prev->next = pbn;
6928         if(pbn) 
6929           pbn->prev = pb->prev;
6930
6931
6932         pBlockDestruct(pb);
6933       }
6934       //pic16_printpBlock(stderr, pbmerged);
6935     } 
6936     pb = pbn;
6937   }
6938
6939 }
6940
6941 /*-----------------------------------------------------------------*/
6942 /* AnalyzeFlow - Examine the flow of the code and optimize         */
6943 /*                                                                 */
6944 /* level 0 == minimal optimization                                 */
6945 /*   optimize registers that are used only by two instructions     */
6946 /* level 1 == maximal optimization                                 */
6947 /*   optimize by looking at pairs of instructions that use the     */
6948 /*   register.                                                     */
6949 /*-----------------------------------------------------------------*/
6950
6951 static void AnalyzeFlow(int level)
6952 {
6953   static int times_called=0;
6954   pBlock *pb;
6955
6956         if(!the_pFile) {
6957
6958                 /* remove unused allocated registers before exiting */
6959                 pic16_RemoveUnusedRegisters();
6960         
6961           return;
6962         }
6963
6964
6965   /* if this is not the first time this function has been called,
6966      then clean up old flow information */
6967         if(times_called++) {
6968                 for(pb = the_pFile->pbHead; pb; pb = pb->next)
6969                         unBuildFlow(pb);
6970
6971                 pic16_RegsUnMapLiveRanges();
6972         }
6973
6974         GpcFlowSeq = 1;
6975
6976   /* Phase 2 - Flow Analysis - Register Banking
6977    *
6978    * In this phase, the individual flow blocks are examined
6979    * and register banking is fixed.
6980    */
6981
6982 #if 0
6983         for(pb = the_pFile->pbHead; pb; pb = pb->next)
6984                 pic16_FixRegisterBanking(pb);
6985 #endif
6986
6987   /* Phase 2 - Flow Analysis
6988    *
6989    * In this phase, the pCode is partition into pCodeFlow 
6990    * blocks. The flow blocks mark the points where a continuous
6991    * stream of instructions changes flow (e.g. because of
6992    * a call or goto or whatever).
6993    */
6994
6995         for(pb = the_pFile->pbHead; pb; pb = pb->next)
6996                 pic16_BuildFlow(pb);
6997
6998
6999   /* Phase 2 - Flow Analysis - linking flow blocks
7000    *
7001    * In this phase, the individual flow blocks are examined
7002    * to determine their order of excution.
7003    */
7004
7005         for(pb = the_pFile->pbHead; pb; pb = pb->next)
7006                 LinkFlow(pb);
7007
7008   /* Phase 3 - Flow Analysis - Flow Tree
7009    *
7010    * In this phase, the individual flow blocks are examined
7011    * to determine their order of execution.
7012    */
7013
7014         for(pb = the_pFile->pbHead; pb; pb = pb->next)
7015                 pic16_BuildFlowTree(pb);
7016
7017
7018   /* Phase x - Flow Analysis - Used Banks
7019    *
7020    * In this phase, the individual flow blocks are examined
7021    * to determine the Register Banks they use
7022    */
7023
7024 #if 0
7025         for(pb = the_pFile->pbHead; pb; pb = pb->next)
7026                 FixBankFlow(pb);
7027 #endif
7028
7029
7030         for(pb = the_pFile->pbHead; pb; pb = pb->next)
7031                 pic16_pCodeRegMapLiveRanges(pb);
7032
7033         pic16_RemoveUnusedRegisters();
7034
7035   //  for(pb = the_pFile->pbHead; pb; pb = pb->next)
7036         pic16_pCodeRegOptimizeRegUsage(level);
7037
7038
7039         if(!options.nopeep)
7040                 OptimizepCode('*');
7041
7042
7043 #if 0
7044         for(pb = the_pFile->pbHead; pb; pb = pb->next)
7045                 DumpFlow(pb);
7046 #endif
7047
7048   /* debug stuff */ 
7049         for(pb = the_pFile->pbHead; pb; pb = pb->next) {
7050           pCode *pcflow;
7051                 for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
7052                         (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL;
7053                         pcflow = pcflow->next) {
7054
7055                         FillFlow(PCFL(pcflow));
7056                 }
7057         }
7058
7059 #if 0
7060         for(pb = the_pFile->pbHead; pb; pb = pb->next) {
7061           pCode *pcflow;
7062
7063                 for( pcflow = pic16_findNextpCode(pb->pcHead, PC_FLOW); 
7064                         (pcflow = pic16_findNextpCode(pcflow, PC_FLOW)) != NULL;
7065                         pcflow = pcflow->next) {
7066
7067                         FlowStats(PCFL(pcflow));
7068                 }
7069         }
7070 #endif
7071 }
7072
7073 /* VR -- no need to analyze banking in flow, but left here :
7074  *      1. because it may be used in the future for other purposes
7075  *      2. because if omitted we'll miss some optimization done here
7076  *
7077  * Perhaps I should rename it to something else
7078  */
7079
7080 /*-----------------------------------------------------------------*/
7081 /* pic16_AnalyzeBanking - Called after the memory addresses have been    */
7082 /*                  assigned to the registers.                     */
7083 /*                                                                 */
7084 /*-----------------------------------------------------------------*/
7085
7086 void pic16_AnalyzeBanking(void)
7087 {
7088   pBlock  *pb;
7089
7090
7091         /* Phase x - Flow Analysis - Used Banks
7092          *
7093          * In this phase, the individual flow blocks are examined
7094          * to determine the Register Banks they use
7095          */
7096
7097         AnalyzeFlow(0);
7098         AnalyzeFlow(1);
7099
7100         if(!the_pFile)return;
7101
7102         if(!pic16_options.no_banksel) {
7103                 for(pb = the_pFile->pbHead; pb; pb = pb->next) {
7104 //                      fprintf(stderr, "%s:%d: Fix register banking in pb= 0x%p\n", __FILE__, __LINE__, pb);
7105                         pic16_FixRegisterBanking(pb);
7106                 }
7107         }
7108
7109 }
7110
7111 /*-----------------------------------------------------------------*/
7112 /* buildCallTree - Look at the flow and extract all of the calls.  */
7113 /*-----------------------------------------------------------------*/
7114 static set *register_usage(pBlock *pb);
7115
7116 static void buildCallTree(void    )
7117 {
7118   pBranch *pbr;
7119   pBlock  *pb;
7120   pCode   *pc;
7121   regs *r;
7122   
7123   if(!the_pFile)
7124     return;
7125
7126
7127
7128   /* Now build the call tree.
7129      First we examine all of the pCodes for functions.
7130      Keep in mind that the function boundaries coincide
7131      with pBlock boundaries. 
7132
7133      The algorithm goes something like this:
7134      We have two nested loops. The outer loop iterates
7135      through all of the pBlocks/functions. The inner
7136      loop iterates through all of the pCodes for
7137      a given pBlock. When we begin iterating through
7138      a pBlock, the variable pc_fstart, pCode of the start
7139      of a function, is cleared. We then search for pCodes
7140      of type PC_FUNCTION. When one is encountered, we
7141      initialize pc_fstart to this and at the same time
7142      associate a new pBranch object that signifies a 
7143      branch entry. If a return is found, then this signifies
7144      a function exit point. We'll link the pCodes of these
7145      returns to the matching pc_fstart.
7146
7147      When we're done, a doubly linked list of pBranches
7148      will exist. The head of this list is stored in
7149      `the_pFile', which is the meta structure for all
7150      of the pCode. Look at the pic16_printCallTree function
7151      on how the pBranches are linked together.
7152
7153    */
7154   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
7155     pCode *pc_fstart=NULL;
7156     for(pc = pb->pcHead; pc; pc = pc->next) {
7157
7158         if(isPCI(pc) && pc_fstart) {
7159                 if(PCI(pc)->is2MemOp) {
7160                         r = pic16_getRegFromInstruction2(pc);
7161                         if(r && !strcmp(r->name, "POSTDEC1"))
7162                                 PCF(pc_fstart)->stackusage++;
7163                 } else {
7164                         r = pic16_getRegFromInstruction(pc);
7165                         if(r && !strcmp(r->name, "PREINC1"))
7166                                 PCF(pc_fstart)->stackusage--;
7167                 }
7168         }
7169
7170       if(isPCF(pc)) {
7171         if (PCF(pc)->fname) {
7172
7173           if(STRCASECMP(PCF(pc)->fname, "_main") == 0) {
7174             //fprintf(stderr," found main \n");
7175             pb->cmemmap = NULL;  /* FIXME do we need to free ? */
7176             pb->dbName = 'M';
7177           }
7178
7179           pbr = Safe_calloc(1,sizeof(pBranch));
7180           pbr->pc = pc_fstart = pc;
7181           pbr->next = NULL;
7182
7183           the_pFile->functions = pic16_pBranchAppend(the_pFile->functions,pbr);
7184
7185           // Here's a better way of doing the same:
7186           addSet(&pb->function_entries, pc);
7187
7188         } else {
7189           // Found an exit point in a function, e.g. return
7190           // (Note, there may be more than one return per function)
7191           if(pc_fstart)
7192             pBranchLink(PCF(pc_fstart), PCF(pc));
7193
7194           addSet(&pb->function_exits, pc);
7195         }
7196       } else if(isCALL(pc)) {
7197         addSet(&pb->function_calls,pc);
7198       }
7199     }
7200   }
7201
7202
7203 #if 0
7204   /* This is not needed because currently all register used
7205    * by a function are stored in stack -- VR */
7206    
7207   /* Re-allocate the registers so that there are no collisions
7208    * between local variables when one function call another */
7209
7210   // this is weird...
7211   //  pic16_deallocateAllRegs();
7212
7213   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
7214     if(!pb->visited)
7215       register_usage(pb);
7216   }
7217 #endif
7218
7219 }
7220
7221 /*-----------------------------------------------------------------*/
7222 /* pic16_AnalyzepCode - parse the pCode that has been generated and form */
7223 /*                all of the logical connections.                  */
7224 /*                                                                 */
7225 /* Essentially what's done here is that the pCode flow is          */
7226 /* determined.                                                     */
7227 /*-----------------------------------------------------------------*/
7228
7229 void pic16_AnalyzepCode(char dbName)
7230 {
7231   pBlock *pb;
7232   int i,changes;
7233
7234   if(!the_pFile)
7235     return;
7236
7237   mergepBlocks('D');
7238
7239
7240   /* Phase 1 - Register allocation and peep hole optimization
7241    *
7242    * The first part of the analysis is to determine the registers
7243    * that are used in the pCode. Once that is done, the peep rules
7244    * are applied to the code. We continue to loop until no more
7245    * peep rule optimizations are found (or until we exceed the
7246    * MAX_PASSES threshold). 
7247    *
7248    * When done, the required registers will be determined.
7249    *
7250    */
7251   i = 0;
7252   do {
7253
7254     DFPRINTF((stderr," Analyzing pCode: PASS #%d\n",i+1));
7255     //fprintf(stderr," Analyzing pCode: PASS #%d\n",i+1);
7256
7257     /* First, merge the labels with the instructions */
7258     for(pb = the_pFile->pbHead; pb; pb = pb->next) {
7259       if('*' == dbName || getpBlock_dbName(pb) == dbName) {
7260
7261         DFPRINTF((stderr," analyze and merging block %c\n",dbName));
7262         //fprintf(stderr," analyze and merging block %c\n",dbName);
7263         pic16_pBlockMergeLabels(pb);
7264         AnalyzepBlock(pb);
7265       } else {
7266         DFPRINTF((stderr," skipping block analysis dbName=%c blockname=%c\n",dbName,getpBlock_dbName));
7267       }
7268     }
7269
7270         if(!options.nopeep)
7271                 changes = OptimizepCode(dbName);
7272         else changes = 0;
7273
7274   } while(changes && (i++ < MAX_PASSES));
7275
7276   
7277   buildCallTree();
7278 }
7279
7280
7281 /* convert a series of movff's of local regs to stack, with a single call to
7282  * a support functions which does the same thing via loop */
7283 static void pic16_convertLocalRegs2Support(pCode *pcstart, pCode *pcend, int count, regs *r, int entry)
7284 {
7285   pBranch *pbr;
7286   pCode *pc, *pct;
7287   char *fname[]={"__lr_store", "__lr_restore"};
7288
7289 //    pc = pic16_newpCode(POC_CALL, pic16_popGetFromString( (entry?fname[0]:fname[1]) ));
7290
7291     pct = pic16_findNextInstruction(pcstart->next);
7292     do {
7293       pc = pct;
7294       pct = pc->next;   //pic16_findNextInstruction(pc->next);
7295 //      pc->print(stderr, pc);
7296       if(isPCI(pc) && PCI(pc)->label) {
7297         pbr = PCI(pc)->label;
7298         while(pbr && pbr->pc) {
7299           PCI(pcstart)->label = pic16_pBranchAppend(PCI(pcstart)->label, pbr);
7300           pbr = pbr->next;
7301         }
7302
7303 //        pc->print(stderr, pc);
7304         /* unlink pCode */
7305         pc->prev->next = pct;
7306         pct->prev = pc->prev;
7307 //        pc->next = NULL;
7308 //        pc->prev = NULL;
7309       }
7310     } while ((pc) && (pc != pcend));
7311
7312     /* unlink movff instructions */
7313     pcstart->next = pcend;
7314     pcend->prev = pcstart;
7315
7316     pc = pcstart;
7317 //    if(!entry) {
7318 //      pic16_pCodeInsertAfter(pc, pct = pic16_newpCode(POC_MOVFF, pic16_popGet2p(
7319 //              pic16_popCopyReg(&pic16_pc_fsr0l), pic16_popCopyReg(&pic16_pc_fsr2l)))); pc = pct;
7320 //    }
7321                 
7322     pic16_pCodeInsertAfter(pc, pct=pic16_newpCode(POC_LFSR, pic16_popGetLit2(0, pic16_popGetWithString(r->name)))); pc = pct;
7323     pic16_pCodeInsertAfter(pc, pct=pic16_newpCode(POC_MOVLW, pic16_popGetLit( count ))); pc = pct;
7324     pic16_pCodeInsertAfter(pc, pct=pic16_newpCode(POC_CALL, pic16_popGetWithString( fname[ (entry==1?0:1) ] ))); pc = pct;
7325
7326 //    if(!entry) {
7327 //      pic16_pCodeInsertAfter(pc, pct = pic16_newpCode(POC_MOVFF, pic16_popGet2p(
7328 //              pic16_popCopyReg(&pic16_pc_fsr2l), pic16_popCopyReg(&pic16_pc_fsr0l)))); pc = pct;
7329 //    }
7330
7331     
7332     {
7333       symbol *sym;
7334
7335         sym = newSymbol( fname[ entry?0:1 ], 0 );
7336         strcpy(sym->rname, fname[ entry?0:1 ]);
7337         checkAddSym(&externs, sym);
7338         
7339 //        fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fname[ entry?0:1 ]);
7340     }
7341
7342 }
7343
7344 /*-----------------------------------------------------------------*/
7345 /* OptimizeLocalRegs - turn sequence of MOVFF instructions for     */
7346 /*    local registers to a support function call                   */
7347 /*-----------------------------------------------------------------*/
7348 void pic16_OptimizeLocalRegs(void)
7349 {
7350   pBlock  *pb;
7351   pCode   *pc;
7352   pCodeInfo *pci;
7353   pCodeOpLocalReg *pclr;
7354   int regCount=0;
7355   int inRegCount=0;
7356   regs *r, *lastr=NULL, *firstr=NULL;
7357   pCode *pcstart=NULL, *pcend=NULL;
7358   int inEntry=0;
7359   char *curFunc=NULL;
7360
7361         /* Overview:
7362          *   local_regs begin mark
7363          *      MOVFF r0x01, POSTDEC1
7364          *      MOVFF r0x02, POSTDEC1
7365          *      ...
7366          *      ...
7367          *      MOVFF r0x0n, POSTDEC1
7368          *   local_regs end mark
7369          *
7370          * convert the above to the below:
7371          *      MOVLW   starting_register_index
7372          *      MOVWF   PRODL
7373          *      MOVLW   register_count
7374          *      call    __save_registers_in_stack
7375          */
7376
7377     if(!the_pFile)
7378       return;
7379
7380     for(pb = the_pFile->pbHead; pb; pb = pb->next) {
7381       inRegCount = regCount = 0;
7382       firstr = lastr = NULL;
7383       for(pc = pb->pcHead; pc; pc = pc->next) {
7384
7385         /* hold current function name */
7386         if(pc && isPCF(pc))curFunc = PCF(pc)->fname;
7387         
7388         if(pc && (pc->type == PC_INFO)) {
7389           pci = PCINF(pc);
7390
7391           if(pci->type == INF_LOCALREGS) {
7392             pclr = PCOLR(pci->oper1);
7393             
7394             if((pclr->type == LR_ENTRY_BEGIN)
7395               || (pclr->type == LR_ENTRY_END))inEntry = 1;
7396             else inEntry = 0;
7397             
7398             switch(pclr->type) {
7399               case LR_ENTRY_BEGIN:
7400               case LR_EXIT_BEGIN:
7401                         inRegCount = 1; regCount = 0;
7402                         pcstart = pc;   //pic16_findNextInstruction(pc->next);
7403                         firstr = lastr = NULL;
7404                         break;
7405               
7406               case LR_ENTRY_END:
7407               case LR_EXIT_END:
7408                         inRegCount = -1;
7409                         pcend = pc;     //pic16_findPrevInstruction(pc->prev);
7410
7411 #if 1
7412                         if(curFunc && inWparamList(curFunc+1)) {
7413                           fprintf(stderr, "sdcc: %s: warning: disabling lr-support for functionn %s\n",
7414                                         filename, curFunc);
7415                         } else {
7416                           if(regCount>2) {
7417                             pic16_convertLocalRegs2Support(pcstart, pcend, regCount,
7418                               firstr, inEntry);
7419                           }
7420                         }
7421 #endif
7422                         firstr = lastr = NULL;
7423                         break;
7424             }
7425             
7426             if(inRegCount == -1) {
7427 //              fprintf(stderr, "%s:%d registers used [%s] %d\n", __FILE__, __LINE__, inEntry?"entry":"exit", regCount);
7428               regCount = 0;
7429               inRegCount = 0;
7430             }
7431           }
7432         } else {
7433           if(isPCI(pc) && (PCI(pc)->op == POC_MOVFF) && (inRegCount == 1)) {
7434             if(inEntry)
7435               r = pic16_getRegFromInstruction(pc);
7436             else
7437               r = pic16_getRegFromInstruction2(pc);
7438             if(r && (r->type == REG_GPR) && (r->pc_type == PO_GPR_TEMP)) {
7439               if(!firstr)firstr = r;
7440               regCount++;
7441 //              fprintf(stderr, "%s:%d\t%s\t%i\t%d/%d\n", __FILE__, __LINE__, r->name, r->rIdx);
7442             }
7443           }
7444         }
7445       }
7446     }
7447 }
7448               
7449             
7450
7451
7452
7453 /*-----------------------------------------------------------------*/
7454 /* ispCodeFunction - returns true if *pc is the pCode of a         */
7455 /*                   function                                      */
7456 /*-----------------------------------------------------------------*/
7457 static bool ispCodeFunction(pCode *pc)
7458 {
7459
7460   if(pc && pc->type == PC_FUNCTION && PCF(pc)->fname)
7461     return 1;
7462
7463   return 0;
7464 }
7465
7466 /*-----------------------------------------------------------------*/
7467 /* findFunction - Search for a function by name (given the name)   */
7468 /*                in the set of all functions that are in a pBlock */
7469 /* (note - I expect this to change because I'm planning to limit   */
7470 /*  pBlock's to just one function declaration                      */
7471 /*-----------------------------------------------------------------*/
7472 static pCode *findFunction(char *fname)
7473 {
7474   pBlock *pb;
7475   pCode *pc;
7476   if(!fname)
7477     return NULL;
7478
7479   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
7480
7481     pc = setFirstItem(pb->function_entries);
7482     while(pc) {
7483     
7484       if((pc->type == PC_FUNCTION) &&
7485          (PCF(pc)->fname) && 
7486          (strcmp(fname, PCF(pc)->fname)==0))
7487         return pc;
7488
7489       pc = setNextItem(pb->function_entries);
7490
7491     }
7492
7493   }
7494   return NULL;
7495 }
7496
7497 static void MarkUsedRegisters(set *regset)
7498 {
7499
7500   regs *r1,*r2;
7501
7502   for(r1=setFirstItem(regset); r1; r1=setNextItem(regset)) {
7503 //      fprintf(stderr, "marking register = %s\t", r1->name);
7504     r2 = pic16_regWithIdx(r1->rIdx);
7505 //      fprintf(stderr, "to register = %s\n", r2->name);
7506     r2->isFree = 0;
7507     r2->wasUsed = 1;
7508   }
7509 }
7510
7511 static void pBlockStats(FILE *of, pBlock *pb)
7512 {
7513
7514   pCode *pc;
7515   regs  *r;
7516
7517         if(!pic16_pcode_verbose)return;
7518         
7519   fprintf(of,";***\n;  pBlock Stats: dbName = %c\n;***\n",getpBlock_dbName(pb));
7520
7521   // for now just print the first element of each set
7522   pc = setFirstItem(pb->function_entries);
7523   if(pc) {
7524     fprintf(of,";entry:  ");
7525     pc->print(of,pc);
7526   }
7527   pc = setFirstItem(pb->function_exits);
7528   if(pc) {
7529     fprintf(of,";has an exit\n");
7530     //pc->print(of,pc);
7531   }
7532
7533   pc = setFirstItem(pb->function_calls);
7534   if(pc) {
7535     fprintf(of,";functions called:\n");
7536
7537     while(pc) {
7538       if(pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL) {
7539         fprintf(of,";   %s\n",pic16_get_op_from_instruction(PCI(pc)));
7540       }
7541       pc = setNextItem(pb->function_calls);
7542     }
7543   }
7544
7545   r = setFirstItem(pb->tregisters);
7546   if(r) {
7547     int n = elementsInSet(pb->tregisters);
7548
7549     fprintf(of,";%d compiler assigned register%c:\n",n, ( (n!=1) ? 's' : ' '));
7550
7551     while (r) {
7552       fprintf(of,";   %s\n",r->name);
7553       r = setNextItem(pb->tregisters);
7554     }
7555   }
7556   
7557   fprintf(of, "; uses %d bytes of stack\n", 1+ elementsInSet(pb->tregisters));
7558 }
7559
7560 /*-----------------------------------------------------------------*/
7561 /*-----------------------------------------------------------------*/
7562 #if 0
7563 static void sequencepCode(void)
7564 {
7565   pBlock *pb;
7566   pCode *pc;
7567
7568
7569   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
7570
7571     pb->seq = GpCodeSequenceNumber+1;
7572
7573     for( pc = pb->pcHead; pc; pc = pc->next)
7574       pc->seq = ++GpCodeSequenceNumber;
7575   }
7576
7577 }
7578 #endif
7579
7580 /*-----------------------------------------------------------------*/
7581 /*-----------------------------------------------------------------*/
7582 static set *register_usage(pBlock *pb)
7583 {
7584   pCode *pc,*pcn;
7585   set *registers=NULL;
7586   set *registersInCallPath = NULL;
7587
7588   /* check recursion */
7589
7590   pc = setFirstItem(pb->function_entries);
7591
7592   if(!pc)
7593     return registers;
7594
7595   pb->visited = 1;
7596
7597   if(pc->type != PC_FUNCTION)
7598     fprintf(stderr,"%s, first pc is not a function???\n",__FUNCTION__);
7599
7600   pc = setFirstItem(pb->function_calls);
7601   for( ; pc; pc = setNextItem(pb->function_calls)) {
7602
7603     if(pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL) {
7604       char *dest = pic16_get_op_from_instruction(PCI(pc));
7605
7606       pcn = findFunction(dest);
7607       if(pcn) 
7608         registersInCallPath = register_usage(pcn->pb);
7609     } else
7610       fprintf(stderr,"BUG? pCode isn't a POC_CALL %d\n",__LINE__);
7611
7612   }
7613
7614 #ifdef PCODE_DEBUG
7615   pBlockStats(stderr,pb);  // debug
7616 #endif
7617
7618   // Mark the registers in this block as used.
7619
7620   MarkUsedRegisters(pb->tregisters);
7621   if(registersInCallPath) {
7622     /* registers were used in the functions this pBlock has called */
7623     /* so now, we need to see if these collide with the ones we are */
7624     /* using here */
7625
7626     regs *r1,*r2, *newreg;
7627
7628     DFPRINTF((stderr,"comparing registers\n"));
7629
7630     r1 = setFirstItem(registersInCallPath);
7631     while(r1) {
7632
7633       r2 = setFirstItem(pb->tregisters);
7634
7635       while(r2 && (r1->type != REG_STK)) {
7636
7637         if(r2->rIdx == r1->rIdx) {
7638           newreg = pic16_findFreeReg(REG_GPR);
7639
7640
7641           if(!newreg) {
7642             DFPRINTF((stderr,"Bummer, no more registers.\n"));
7643             exit(1);
7644           }
7645
7646           DFPRINTF((stderr,"Cool found register collision nIdx=%d moving to %d\n",
7647                   r1->rIdx, newreg->rIdx));
7648           r2->rIdx = newreg->rIdx;
7649           //if(r2->name) free(r2->name);
7650           if(newreg->name)
7651             r2->name = Safe_strdup(newreg->name);
7652           else
7653             r2->name = NULL;
7654           newreg->isFree = 0;
7655           newreg->wasUsed = 1;
7656         }
7657         r2 = setNextItem(pb->tregisters);
7658       }
7659
7660       r1 = setNextItem(registersInCallPath);
7661     }
7662
7663     /* Collisions have been resolved. Now free the registers in the call path */
7664     r1 = setFirstItem(registersInCallPath);
7665     while(r1) {
7666       if(r1->type != REG_STK) {
7667         newreg = pic16_regWithIdx(r1->rIdx);
7668         newreg->isFree = 1;
7669       }
7670       r1 = setNextItem(registersInCallPath);
7671     }
7672
7673   }// else
7674   //    MarkUsedRegisters(pb->registers);
7675
7676   registers = unionSets(pb->tregisters, registersInCallPath, THROW_NONE);
7677 #ifdef PCODE_DEBUG
7678   if(registers) 
7679     DFPRINTF((stderr,"returning regs\n"));
7680   else
7681     DFPRINTF((stderr,"not returning regs\n"));
7682
7683   DFPRINTF((stderr,"pBlock after register optim.\n"));
7684   pBlockStats(stderr,pb);  // debug
7685 #endif
7686
7687   return registers;
7688 }
7689
7690 /*-----------------------------------------------------------------*/
7691 /* pct2 - writes the call tree to a file                           */
7692 /*                                                                 */
7693 /*-----------------------------------------------------------------*/
7694 static void pct2(FILE *of,pBlock *pb,int indent,int usedstack)
7695 {
7696   pCode *pc,*pcn;
7697   int i;
7698   //  set *registersInCallPath = NULL;
7699
7700   if(!of)
7701     return;
7702
7703   if(indent > 10) {
7704         fprintf(of, "recursive function\n");
7705     return; //recursion ?
7706   }
7707
7708   pc = setFirstItem(pb->function_entries);
7709
7710   if(!pc)
7711     return;
7712
7713   pb->visited = 0;
7714
7715   for(i=0;i<indent;i++)   // Indentation
7716         fputs("+   ", of);
7717   fputs("+- ", of);
7718
7719   if(pc->type == PC_FUNCTION) {
7720     usedstack += PCF(pc)->stackusage;
7721     fprintf(of,"%s (stack: %i)\n",PCF(pc)->fname, usedstack);
7722   } else return;  // ???
7723
7724
7725   pc = setFirstItem(pb->function_calls);
7726   for( ; pc; pc = setNextItem(pb->function_calls)) {
7727
7728     if(pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL) {
7729       char *dest = pic16_get_op_from_instruction(PCI(pc));
7730
7731       pcn = findFunction(dest);
7732       if(pcn) 
7733         pct2(of,pcn->pb,indent+1, usedstack);   // + PCF(pcn)->stackusage);
7734     } else
7735       fprintf(of,"BUG? pCode isn't a POC_CALL %d\n",__LINE__);
7736
7737   }
7738
7739
7740 }
7741
7742
7743 /*-----------------------------------------------------------------*/
7744 /* pic16_printCallTree - writes the call tree to a file                  */
7745 /*                                                                 */
7746 /*-----------------------------------------------------------------*/
7747
7748 void pic16_printCallTree(FILE *of)
7749 {
7750   pBranch *pbr;
7751   pBlock  *pb;
7752   pCode   *pc;
7753
7754   if(!the_pFile)
7755     return;
7756
7757   if(!of)
7758     of = stderr;
7759
7760   fprintf(of, "\npBlock statistics\n");
7761   for(pb = the_pFile->pbHead; pb;  pb = pb->next )
7762     pBlockStats(of,pb);
7763
7764
7765   fprintf(of,"Call Tree\n");
7766   pbr = the_pFile->functions;
7767   while(pbr) {
7768     if(pbr->pc) {
7769       pc = pbr->pc;
7770       if(!ispCodeFunction(pc))
7771         fprintf(of,"bug in call tree");
7772
7773
7774       fprintf(of,"Function: %s\n", PCF(pc)->fname);
7775
7776       while(pc->next && !ispCodeFunction(pc->next)) {
7777         pc = pc->next;
7778         if(pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL)
7779           fprintf(of,"\t%s\n",pic16_get_op_from_instruction(PCI(pc)));
7780       }
7781     }
7782
7783     pbr = pbr->next;
7784   }
7785
7786
7787   fprintf(of,"\n**************\n\na better call tree\n");
7788   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
7789 //    if(pb->visited)
7790       pct2(of,pb,0,0);
7791   }
7792
7793   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
7794     fprintf(of,"block dbname: %c\n", getpBlock_dbName(pb));
7795   }
7796 }
7797
7798
7799
7800 /*-----------------------------------------------------------------*/
7801 /*                                                                 */
7802 /*-----------------------------------------------------------------*/
7803
7804 static void InlineFunction(pBlock *pb)
7805 {
7806   pCode *pc;
7807   pCode *pc_call;
7808
7809   if(!pb)
7810     return;
7811
7812   pc = setFirstItem(pb->function_calls);
7813
7814   for( ; pc; pc = setNextItem(pb->function_calls)) {
7815
7816     if(isCALL(pc)) {
7817       pCode *pcn = findFunction(pic16_get_op_from_instruction(PCI(pc)));
7818       pCode *pct;
7819       pCode *pce;
7820
7821       pBranch *pbr;
7822
7823       if(pcn && isPCF(pcn) && (PCF(pcn)->ncalled == 0)) {               /* change 0 to 1 to enable inlining */
7824         
7825         //fprintf(stderr,"Cool can inline:\n");
7826         //pcn->print(stderr,pcn);
7827
7828         //fprintf(stderr,"recursive call Inline\n");
7829         InlineFunction(pcn->pb);
7830         //fprintf(stderr,"return from recursive call Inline\n");
7831
7832         /*
7833           At this point, *pc points to a CALL mnemonic, and
7834           *pcn points to the function that is being called.
7835
7836           To in-line this call, we need to remove the CALL
7837           and RETURN(s), and link the function pCode in with
7838           the CALLee pCode.
7839
7840         */
7841
7842
7843         /* Remove the CALL */
7844         pc_call = pc;
7845         pc = pc->prev;
7846
7847         /* remove callee pBlock from the pBlock linked list */
7848         removepBlock(pcn->pb);
7849
7850         pce = pcn;
7851         while(pce) {
7852           pce->pb = pb;
7853           pce = pce->next;
7854         }
7855
7856         /* Remove the Function pCode */
7857         pct = pic16_findNextInstruction(pcn->next);
7858
7859         /* Link the function with the callee */
7860         pc->next = pcn->next;
7861         pcn->next->prev = pc;
7862         
7863         /* Convert the function name into a label */
7864
7865         pbr = Safe_calloc(1,sizeof(pBranch));
7866         pbr->pc = pic16_newpCodeLabel(PCF(pcn)->fname, -1);
7867         pbr->next = NULL;
7868         PCI(pct)->label = pic16_pBranchAppend(PCI(pct)->label,pbr);
7869         PCI(pct)->label = pic16_pBranchAppend(PCI(pct)->label,PCI(pc_call)->label);
7870
7871         /* turn all of the return's except the last into goto's */
7872         /* check case for 2 instruction pBlocks */
7873         pce = pic16_findNextInstruction(pcn->next);
7874         while(pce) {
7875           pCode *pce_next = pic16_findNextInstruction(pce->next);
7876
7877           if(pce_next == NULL) {
7878             /* found the last return */
7879             pCode *pc_call_next =  pic16_findNextInstruction(pc_call->next);
7880
7881             //fprintf(stderr,"found last return\n");
7882             //pce->print(stderr,pce);
7883             pce->prev->next = pc_call->next;
7884             pc_call->next->prev = pce->prev;
7885             PCI(pc_call_next)->label = pic16_pBranchAppend(PCI(pc_call_next)->label,
7886                                                       PCI(pce)->label);
7887           }
7888
7889           pce = pce_next;
7890         }
7891
7892
7893       }
7894     } else
7895       fprintf(stderr,"BUG? pCode isn't a POC_CALL %d\n",__LINE__);
7896
7897   }
7898
7899 }
7900
7901 /*-----------------------------------------------------------------*/
7902 /*                                                                 */
7903 /*-----------------------------------------------------------------*/
7904
7905 void pic16_InlinepCode(void)
7906 {
7907
7908   pBlock  *pb;
7909   pCode   *pc;
7910
7911   if(!the_pFile)
7912     return;
7913
7914   if(!functionInlining)
7915     return;
7916
7917   /* Loop through all of the function definitions and count the
7918    * number of times each one is called */
7919   //fprintf(stderr,"inlining %d\n",__LINE__);
7920
7921   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
7922
7923     pc = setFirstItem(pb->function_calls);
7924
7925     for( ; pc; pc = setNextItem(pb->function_calls)) {
7926
7927       if(isCALL(pc)) {
7928         pCode *pcn = findFunction(pic16_get_op_from_instruction(PCI(pc)));
7929         if(pcn && isPCF(pcn)) {
7930           PCF(pcn)->ncalled++;
7931         }
7932       } else
7933         fprintf(stderr,"BUG? pCode isn't a POC_CALL %d\n",__LINE__);
7934
7935     }
7936   }
7937
7938   //fprintf(stderr,"inlining %d\n",__LINE__);
7939
7940   /* Now, Loop through the function definitions again, but this
7941    * time inline those functions that have only been called once. */
7942   
7943   InlineFunction(the_pFile->pbHead);
7944   //fprintf(stderr,"inlining %d\n",__LINE__);
7945
7946   for(pb = the_pFile->pbHead; pb; pb = pb->next)
7947     unBuildFlow(pb);
7948
7949 }
7950
7951 char *pic_optype_names[]={
7952         "PO_NONE",         // No operand e.g. NOP
7953         "PO_W",              // The working register (as a destination)
7954         "PO_WREG",           // The working register (as a file register)
7955         "PO_STATUS",         // The 'STATUS' register
7956         "PO_BSR",            // The 'BSR' register
7957         "PO_FSR0",           // The "file select register" (in PIC18 family it's one 
7958                              // of three)
7959         "PO_INDF0",          // The Indirect register
7960         "PO_INTCON",         // Interrupt Control register
7961         "PO_GPR_REGISTER",   // A general purpose register
7962         "PO_GPR_BIT",        // A bit of a general purpose register
7963         "PO_GPR_TEMP",       // A general purpose temporary register
7964         "PO_SFR_REGISTER",   // A special function register (e.g. PORTA)
7965         "PO_PCL",            // Program counter Low register
7966         "PO_PCLATH",         // Program counter Latch high register
7967         "PO_PCLATU",         // Program counter Latch upper register
7968         "PO_PRODL",          // Product Register Low
7969         "PO_PRODH",          // Product Register High
7970         "PO_LITERAL",        // A constant
7971         "PO_REL_ADDR",       // A relative address
7972         "PO_IMMEDIATE",      //  (8051 legacy)
7973         "PO_DIR",            // Direct memory (8051 legacy)
7974         "PO_CRY",            // bit memory (8051 legacy)
7975         "PO_BIT",            // bit operand.
7976         "PO_STR",            //  (8051 legacy)
7977         "PO_LABEL",
7978         "PO_WILD"            // Wild card operand in peep optimizer
7979 };
7980
7981
7982 char *dumpPicOptype(PIC_OPTYPE type)
7983 {
7984         return (pic_optype_names[ type ]);
7985 }