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