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