The PIC Port was assuming ifx was always true. (A recent [valid] change
[fw/sdcc] / src / pic / ralloc.c
1 /*------------------------------------------------------------------------
2
3   SDCCralloc.c - source file for register allocation. (8051) specific
4
5                 Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
6                 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
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    In other words, you are welcome to use, share and improve this program.
23    You are forbidden to forbid anyone else to use, share and improve
24    what you give them.   Help stamp out software-hoarding!  
25 -------------------------------------------------------------------------*/
26
27 #include "common.h"
28 #include "ralloc.h"
29 #include "pcode.h"
30 #include "gen.h"
31
32 /*-----------------------------------------------------------------*/
33 /* At this point we start getting processor specific although      */
34 /* some routines are non-processor specific & can be reused when   */
35 /* targetting other processors. The decision for this will have    */
36 /* to be made on a routine by routine basis                        */
37 /* routines used to pack registers are most definitely not reusable */
38 /* since the pack the registers depending strictly on the MCU      */
39 /*-----------------------------------------------------------------*/
40
41 extern void genpic14Code (iCode *);
42
43 /* Global data */
44 static struct
45   {
46     bitVect *spiltSet;
47     set *stackSpil;
48     bitVect *regAssigned;
49     short blockSpil;
50     int slocNum;
51     bitVect *funcrUsed;         /* registers used in a function */
52     int stackExtend;
53     int dataExtend;
54   }
55 _G;
56
57 /* Shared with gen.c */
58 int pic14_ptrRegReq;            /* one byte pointer register required */
59
60 /* pic14 registers */
61 /* A nasty, awful, disgusting hack for register declarations */
62 #ifdef p16c84
63
64 regs regspic14[] =
65 {
66
67   {REG_GPR, PO_GPR_TEMP, 0x0C, "r0x0C", "r0x0C", 0x0C, 1, 0},
68   {REG_GPR, PO_GPR_TEMP, 0x0D, "r0x0D", "r0x0C", 0x0D, 1, 0},
69   {REG_GPR, PO_GPR_TEMP, 0x0E, "r0x0E", "r0x0C", 0x0E, 1, 0},
70   {REG_GPR, PO_GPR_TEMP, 0x0F, "r0x0F", "r0x0C", 0x0F, 1, 0},
71   {REG_GPR, PO_GPR_TEMP, 0x10, "r0x10", "r0x10", 0x10, 1, 0},
72   {REG_GPR, PO_GPR_TEMP, 0x11, "r0x11", "r0x11", 0x11, 1, 0},
73   {REG_GPR, PO_GPR_TEMP, 0x12, "r0x12", "r0x12", 0x12, 1, 0},
74   {REG_GPR, PO_GPR_TEMP, 0x13, "r0x13", "r0x13", 0x13, 1, 0},
75   {REG_GPR, PO_GPR_TEMP, 0x14, "r0x14", "r0x14", 0x14, 1, 0},
76   {REG_GPR, PO_GPR_TEMP, 0x15, "r0x15", "r0x15", 0x15, 1, 0},
77   {REG_GPR, PO_GPR_TEMP, 0x16, "r0x16", "r0x16", 0x16, 1, 0},
78   {REG_GPR, PO_GPR_TEMP, 0x17, "r0x17", "r0x17", 0x17, 1, 0},
79   {REG_GPR, PO_GPR_TEMP, 0x18, "r0x18", "r0x18", 0x18, 1, 0},
80   {REG_GPR, PO_GPR_TEMP, 0x19, "r0x19", "r0x19", 0x19, 1, 0},
81   {REG_GPR, PO_GPR_TEMP, 0x1A, "r0x1A", "r0x1A", 0x1A, 1, 0},
82   {REG_GPR, PO_GPR_TEMP, 0x1B, "r0x1B", "r0x1B", 0x1B, 1, 0},
83   {REG_GPR, PO_GPR_TEMP, 0x1C, "r0x1C", "r0x1C", 0x1C, 1, 0},
84   {REG_GPR, PO_GPR_TEMP, 0x1D, "r0x1D", "r0x1D", 0x1D, 1, 0},
85   {REG_GPR, PO_GPR_TEMP, 0x1E, "r0x1E", "r0x1E", 0x1E, 1, 0},
86   {REG_GPR, PO_GPR_TEMP, 0x1F, "r0x1F", "r0x1F", 0x1F, 1, 0},
87   {REG_PTR, PO_FSR, 4, "FSR", "FSR", 4, 1, 0},
88
89 };
90 #else
91 regs regspic14[] =
92 {
93   {REG_GPR, PO_GPR_TEMP, 0x20, "r0x20", "r0x20", 0x20, 1, 0},
94   {REG_GPR, PO_GPR_TEMP, 0x21, "r0x21", "r0x21", 0x21, 1, 0},
95   {REG_GPR, PO_GPR_TEMP, 0x22, "r0x22", "r0x22", 0x22, 1, 0},
96   {REG_GPR, PO_GPR_TEMP, 0x23, "r0x23", "r0x23", 0x23, 1, 0},
97   {REG_GPR, PO_GPR_TEMP, 0x24, "r0x24", "r0x24", 0x24, 1, 0},
98   {REG_GPR, PO_GPR_TEMP, 0x25, "r0x25", "r0x25", 0x25, 1, 0},
99   {REG_GPR, PO_GPR_TEMP, 0x26, "r0x26", "r0x26", 0x26, 1, 0},
100   {REG_GPR, PO_GPR_TEMP, 0x27, "r0x27", "r0x27", 0x27, 1, 0},
101   {REG_GPR, PO_GPR_TEMP, 0x28, "r0x28", "r0x28", 0x28, 1, 0},
102   {REG_GPR, PO_GPR_TEMP, 0x29, "r0x29", "r0x29", 0x29, 1, 0},
103   {REG_GPR, PO_GPR_TEMP, 0x2A, "r0x2A", "r0x2A", 0x2A, 1, 0},
104   {REG_GPR, PO_GPR_TEMP, 0x2B, "r0x2B", "r0x2B", 0x2B, 1, 0},
105   {REG_GPR, PO_GPR_TEMP, 0x2C, "r0x2C", "r0x2C", 0x2C, 1, 0},
106   {REG_GPR, PO_GPR_TEMP, 0x2D, "r0x2D", "r0x2D", 0x2D, 1, 0},
107   {REG_GPR, PO_GPR_TEMP, 0x2E, "r0x2E", "r0x2E", 0x2E, 1, 0},
108   {REG_GPR, PO_GPR_TEMP, 0x2F, "r0x2F", "r0x2F", 0x2F, 1, 0},
109   {REG_GPR, PO_GPR_TEMP, 0x30, "r0x30", "r0x30", 0x30, 1, 0},
110   {REG_GPR, PO_GPR_TEMP, 0x31, "r0x31", "r0x31", 0x31, 1, 0},
111   {REG_GPR, PO_GPR_TEMP, 0x32, "r0x32", "r0x32", 0x32, 1, 0},
112   {REG_GPR, PO_GPR_TEMP, 0x33, "r0x33", "r0x33", 0x33, 1, 0},
113   {REG_GPR, PO_GPR_TEMP, 0x34, "r0x34", "r0x34", 0x34, 1, 0},
114   {REG_GPR, PO_GPR_TEMP, 0x35, "r0x35", "r0x35", 0x35, 1, 0},
115   {REG_GPR, PO_GPR_TEMP, 0x36, "r0x36", "r0x36", 0x36, 1, 0},
116   {REG_GPR, PO_GPR_TEMP, 0x37, "r0x37", "r0x37", 0x37, 1, 0},
117
118   {REG_PTR, PO_FSR, 4, "FSR", "FSR", 4, 1, 0},
119
120 };
121
122 #endif
123
124 int pic14_nRegs = sizeof (regspic14) / sizeof (regs);
125 static void spillThis (symbol *);
126 static int debug = 1;
127 static FILE *debugF = NULL;
128 /*-----------------------------------------------------------------*/
129 /* debugLog - open a file for debugging information                */
130 /*-----------------------------------------------------------------*/
131 //static void debugLog(char *inst,char *fmt, ...)
132 static void
133 debugLog (char *fmt,...)
134 {
135   static int append = 0;        // First time through, open the file without append.
136
137   char buffer[256];
138   //char *bufferP=buffer;
139   va_list ap;
140
141   if (!debug || !srcFileName)
142     return;
143
144
145   if (!debugF)
146     {
147       /* create the file name */
148       strcpy (buffer, srcFileName);
149       strcat (buffer, ".d");
150
151       if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
152         {
153           werror (E_FILE_OPEN_ERR, buffer);
154           exit (1);
155         }
156       append = 1;               // Next time debubLog is called, we'll append the debug info
157
158     }
159
160   va_start (ap, fmt);
161
162   vsprintf (buffer, fmt, ap);
163
164   fprintf (debugF, "%s", buffer);
165 /*
166    while (isspace(*bufferP)) bufferP++;
167
168    if (bufferP && *bufferP) 
169    lineCurr = (lineCurr ?
170    connectLine(lineCurr,newLineNode(lb)) :
171    (lineHead = newLineNode(lb)));
172    lineCurr->isInline = _G.inLine;
173    lineCurr->isDebug  = _G.debugLine;
174  */
175   va_end (ap);
176
177 }
178
179 static void
180 debugNewLine (void)
181 {
182   if (debugF)
183     fputc ('\n', debugF);
184 }
185 /*-----------------------------------------------------------------*/
186 /* debugLogClose - closes the debug log file (if opened)           */
187 /*-----------------------------------------------------------------*/
188 static void
189 debugLogClose (void)
190 {
191   if (debugF)
192     {
193       fclose (debugF);
194       debugF = NULL;
195     }
196 }
197 #define AOP(op) op->aop
198
199 static char *
200 debugAopGet (char *str, operand * op)
201 {
202   if (str)
203     debugLog (str);
204
205   printOperand (op, debugF);
206   debugNewLine ();
207
208   return NULL;
209
210 }
211
212 static char *
213 decodeOp (unsigned int op)
214 {
215
216   if (op < 128 && op > ' ')
217     {
218       buffer[0] = (op & 0xff);
219       buffer[1] = 0;
220       return buffer;
221     }
222
223   switch (op)
224     {
225     case IDENTIFIER:
226       return "IDENTIFIER";
227     case TYPE_NAME:
228       return "TYPE_NAME";
229     case CONSTANT:
230       return "CONSTANT";
231     case STRING_LITERAL:
232       return "STRING_LITERAL";
233     case SIZEOF:
234       return "SIZEOF";
235     case PTR_OP:
236       return "PTR_OP";
237     case INC_OP:
238       return "INC_OP";
239     case DEC_OP:
240       return "DEC_OP";
241     case LEFT_OP:
242       return "LEFT_OP";
243     case RIGHT_OP:
244       return "RIGHT_OP";
245     case LE_OP:
246       return "LE_OP";
247     case GE_OP:
248       return "GE_OP";
249     case EQ_OP:
250       return "EQ_OP";
251     case NE_OP:
252       return "NE_OP";
253     case AND_OP:
254       return "AND_OP";
255     case OR_OP:
256       return "OR_OP";
257     case MUL_ASSIGN:
258       return "MUL_ASSIGN";
259     case DIV_ASSIGN:
260       return "DIV_ASSIGN";
261     case MOD_ASSIGN:
262       return "MOD_ASSIGN";
263     case ADD_ASSIGN:
264       return "ADD_ASSIGN";
265     case SUB_ASSIGN:
266       return "SUB_ASSIGN";
267     case LEFT_ASSIGN:
268       return "LEFT_ASSIGN";
269     case RIGHT_ASSIGN:
270       return "RIGHT_ASSIGN";
271     case AND_ASSIGN:
272       return "AND_ASSIGN";
273     case XOR_ASSIGN:
274       return "XOR_ASSIGN";
275     case OR_ASSIGN:
276       return "OR_ASSIGN";
277     case TYPEDEF:
278       return "TYPEDEF";
279     case EXTERN:
280       return "EXTERN";
281     case STATIC:
282       return "STATIC";
283     case AUTO:
284       return "AUTO";
285     case REGISTER:
286       return "REGISTER";
287     case CODE:
288       return "CODE";
289     case EEPROM:
290       return "EEPROM";
291     case INTERRUPT:
292       return "INTERRUPT";
293     case SFR:
294       return "SFR";
295     case AT:
296       return "AT";
297     case SBIT:
298       return "SBIT";
299     case REENTRANT:
300       return "REENTRANT";
301     case USING:
302       return "USING";
303     case XDATA:
304       return "XDATA";
305     case DATA:
306       return "DATA";
307     case IDATA:
308       return "IDATA";
309     case PDATA:
310       return "PDATA";
311     case VAR_ARGS:
312       return "VAR_ARGS";
313     case CRITICAL:
314       return "CRITICAL";
315     case NONBANKED:
316       return "NONBANKED";
317     case BANKED:
318       return "BANKED";
319     case CHAR:
320       return "CHAR";
321     case SHORT:
322       return "SHORT";
323     case INT:
324       return "INT";
325     case LONG:
326       return "LONG";
327     case SIGNED:
328       return "SIGNED";
329     case UNSIGNED:
330       return "UNSIGNED";
331     case FLOAT:
332       return "FLOAT";
333     case DOUBLE:
334       return "DOUBLE";
335     case CONST:
336       return "CONST";
337     case VOLATILE:
338       return "VOLATILE";
339     case VOID:
340       return "VOID";
341     case BIT:
342       return "BIT";
343     case STRUCT:
344       return "STRUCT";
345     case UNION:
346       return "UNION";
347     case ENUM:
348       return "ENUM";
349     case ELIPSIS:
350       return "ELIPSIS";
351     case RANGE:
352       return "RANGE";
353     case FAR:
354       return "FAR";
355     case CASE:
356       return "CASE";
357     case DEFAULT:
358       return "DEFAULT";
359     case IF:
360       return "IF";
361     case ELSE:
362       return "ELSE";
363     case SWITCH:
364       return "SWITCH";
365     case WHILE:
366       return "WHILE";
367     case DO:
368       return "DO";
369     case FOR:
370       return "FOR";
371     case GOTO:
372       return "GOTO";
373     case CONTINUE:
374       return "CONTINUE";
375     case BREAK:
376       return "BREAK";
377     case RETURN:
378       return "RETURN";
379     case INLINEASM:
380       return "INLINEASM";
381     case IFX:
382       return "IFX";
383     case ADDRESS_OF:
384       return "ADDRESS_OF";
385     case GET_VALUE_AT_ADDRESS:
386       return "GET_VALUE_AT_ADDRESS";
387     case SPIL:
388       return "SPIL";
389     case UNSPIL:
390       return "UNSPIL";
391     case GETHBIT:
392       return "GETHBIT";
393     case BITWISEAND:
394       return "BITWISEAND";
395     case UNARYMINUS:
396       return "UNARYMINUS";
397     case IPUSH:
398       return "IPUSH";
399     case IPOP:
400       return "IPOP";
401     case PCALL:
402       return "PCALL";
403     case ENDFUNCTION:
404       return "ENDFUNCTION";
405     case JUMPTABLE:
406       return "JUMPTABLE";
407     case RRC:
408       return "RRC";
409     case RLC:
410       return "RLC";
411     case CAST:
412       return "CAST";
413     case CALL:
414       return "CALL";
415     case PARAM:
416       return "PARAM  ";
417     case NULLOP:
418       return "NULLOP";
419     case BLOCK:
420       return "BLOCK";
421     case LABEL:
422       return "LABEL";
423     case RECEIVE:
424       return "RECEIVE";
425     case SEND:
426       return "SEND";
427     }
428   sprintf (buffer, "unkown op %d %c", op, op & 0xff);
429   return buffer;
430 }
431 /*-----------------------------------------------------------------*/
432 /*-----------------------------------------------------------------*/
433 static char *
434 debugLogRegType (short type)
435 {
436
437   switch (type)
438     {
439     case REG_GPR:
440       return "REG_GPR";
441     case REG_PTR:
442       return "REG_PTR";
443     case REG_CND:
444       return "REG_CND";
445     }
446
447   sprintf (buffer, "unkown reg type %d", type);
448   return buffer;
449 }
450
451 /*-----------------------------------------------------------------*/
452 /* allocReg - allocates register of given type                     */
453 /*-----------------------------------------------------------------*/
454 static regs *
455 allocReg (short type)
456 {
457   int i;
458
459   debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
460
461   for (i = 0; i < pic14_nRegs; i++)
462     {
463
464       /* if type is given as 0 then any
465          free register will do */
466       if (!type &&
467           regspic14[i].isFree)
468         {
469           regspic14[i].isFree = 0;
470           regspic14[i].wasUsed = 1;
471           if (currFunc)
472             currFunc->regsUsed =
473               bitVectSetBit (currFunc->regsUsed, i);
474           debugLog ("  returning %s\n", regspic14[i].name);
475           return &regspic14[i];
476         }
477       /* other wise look for specific type
478          of register */
479       if (regspic14[i].isFree &&
480           regspic14[i].type == type)
481         {
482           regspic14[i].isFree = 0;
483           regspic14[i].wasUsed = 1;
484           if (currFunc)
485             currFunc->regsUsed =
486               bitVectSetBit (currFunc->regsUsed, i);
487           debugLog ("  returning %s\n", regspic14[i].name);
488           return &regspic14[i];
489         }
490     }
491   return NULL;
492 }
493
494 /*-----------------------------------------------------------------*/
495 /* pic14_regWithIdx - returns pointer to register wit index number       */
496 /*-----------------------------------------------------------------*/
497 regs *
498 pic14_regWithIdx (int idx)
499 {
500   int i;
501
502   debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
503
504   for (i = 0; i < pic14_nRegs; i++)
505     if (regspic14[i].rIdx == idx)
506       return &regspic14[i];
507
508   return &regspic14[0];
509
510   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
511           "regWithIdx not found");
512   exit (1);
513 }
514
515 /*-----------------------------------------------------------------*/
516 /*-----------------------------------------------------------------*/
517 regs *
518 pic14_findFreeReg(void)
519 {
520   int i;
521
522   for (i = 0; i < pic14_nRegs; i++)
523     if (regspic14[i].isFree)
524       return &regspic14[i];
525
526   return NULL;
527 }
528 /*-----------------------------------------------------------------*/
529 /* freeReg - frees a register                                      */
530 /*-----------------------------------------------------------------*/
531 static void
532 freeReg (regs * reg)
533 {
534   debugLog ("%s\n", __FUNCTION__);
535   reg->isFree = 1;
536 }
537
538
539 /*-----------------------------------------------------------------*/
540 /* nFreeRegs - returns number of free registers                    */
541 /*-----------------------------------------------------------------*/
542 static int
543 nFreeRegs (int type)
544 {
545   int i;
546   int nfr = 0;
547
548   debugLog ("%s\n", __FUNCTION__);
549   for (i = 0; i < pic14_nRegs; i++)
550     if (regspic14[i].isFree && regspic14[i].type == type)
551       nfr++;
552   return nfr;
553 }
554
555 /*-----------------------------------------------------------------*/
556 /* nfreeRegsType - free registers with type                         */
557 /*-----------------------------------------------------------------*/
558 static int
559 nfreeRegsType (int type)
560 {
561   int nfr;
562   debugLog ("%s\n", __FUNCTION__);
563   if (type == REG_PTR)
564     {
565       if ((nfr = nFreeRegs (type)) == 0)
566         return nFreeRegs (REG_GPR);
567     }
568
569   return nFreeRegs (type);
570 }
571
572
573 /*-----------------------------------------------------------------*/
574 /* allDefsOutOfRange - all definitions are out of a range          */
575 /*-----------------------------------------------------------------*/
576 static bool
577 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
578 {
579   int i;
580
581   debugLog ("%s\n", __FUNCTION__);
582   if (!defs)
583     return TRUE;
584
585   for (i = 0; i < defs->size; i++)
586     {
587       iCode *ic;
588
589       if (bitVectBitValue (defs, i) &&
590           (ic = hTabItemWithKey (iCodehTab, i)) &&
591           (ic->seq >= fseq && ic->seq <= toseq))
592
593         return FALSE;
594
595     }
596
597   return TRUE;
598 }
599
600 /*-----------------------------------------------------------------*/
601 /* computeSpillable - given a point find the spillable live ranges */
602 /*-----------------------------------------------------------------*/
603 static bitVect *
604 computeSpillable (iCode * ic)
605 {
606   bitVect *spillable;
607
608   debugLog ("%s\n", __FUNCTION__);
609   /* spillable live ranges are those that are live at this 
610      point . the following categories need to be subtracted
611      from this set. 
612      a) - those that are already spilt
613      b) - if being used by this one
614      c) - defined by this one */
615
616   spillable = bitVectCopy (ic->rlive);
617   spillable =
618     bitVectCplAnd (spillable, _G.spiltSet);     /* those already spilt */
619   spillable =
620     bitVectCplAnd (spillable, ic->uses);        /* used in this one */
621   bitVectUnSetBit (spillable, ic->defKey);
622   spillable = bitVectIntersect (spillable, _G.regAssigned);
623   return spillable;
624
625 }
626
627 /*-----------------------------------------------------------------*/
628 /* noSpilLoc - return true if a variable has no spil location      */
629 /*-----------------------------------------------------------------*/
630 static int
631 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
632 {
633   debugLog ("%s\n", __FUNCTION__);
634   return (sym->usl.spillLoc ? 0 : 1);
635 }
636
637 /*-----------------------------------------------------------------*/
638 /* hasSpilLoc - will return 1 if the symbol has spil location      */
639 /*-----------------------------------------------------------------*/
640 static int
641 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
642 {
643   debugLog ("%s\n", __FUNCTION__);
644   return (sym->usl.spillLoc ? 1 : 0);
645 }
646
647 /*-----------------------------------------------------------------*/
648 /* directSpilLoc - will return 1 if the splilocation is in direct  */
649 /*-----------------------------------------------------------------*/
650 static int
651 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
652 {
653   debugLog ("%s\n", __FUNCTION__);
654   if (sym->usl.spillLoc &&
655       (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
656     return 1;
657   else
658     return 0;
659 }
660
661 /*-----------------------------------------------------------------*/
662 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
663 /*                    but is not used as a pointer                 */
664 /*-----------------------------------------------------------------*/
665 static int
666 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
667 {
668   debugLog ("%s\n", __FUNCTION__);
669   return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
670 }
671
672 /*-----------------------------------------------------------------*/
673 /* rematable - will return 1 if the remat flag is set              */
674 /*-----------------------------------------------------------------*/
675 static int
676 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
677 {
678   debugLog ("%s\n", __FUNCTION__);
679   return sym->remat;
680 }
681
682 /*-----------------------------------------------------------------*/
683 /* notUsedInBlock - not used in this block                         */
684 /*-----------------------------------------------------------------*/
685 static int
686 notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic)
687 {
688   debugLog ("%s\n", __FUNCTION__);
689   return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) &&
690           allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
691 /*     return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */
692 }
693
694 /*-----------------------------------------------------------------*/
695 /* notUsedInRemaining - not used or defined in remain of the block */
696 /*-----------------------------------------------------------------*/
697 static int
698 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
699 {
700   debugLog ("%s\n", __FUNCTION__);
701   return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
702           allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
703 }
704
705 /*-----------------------------------------------------------------*/
706 /* allLRs - return true for all                                    */
707 /*-----------------------------------------------------------------*/
708 static int
709 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
710 {
711   debugLog ("%s\n", __FUNCTION__);
712   return 1;
713 }
714
715 /*-----------------------------------------------------------------*/
716 /* liveRangesWith - applies function to a given set of live range  */
717 /*-----------------------------------------------------------------*/
718 static set *
719 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
720                 eBBlock * ebp, iCode * ic)
721 {
722   set *rset = NULL;
723   int i;
724
725   debugLog ("%s\n", __FUNCTION__);
726   if (!lrs || !lrs->size)
727     return NULL;
728
729   for (i = 1; i < lrs->size; i++)
730     {
731       symbol *sym;
732       if (!bitVectBitValue (lrs, i))
733         continue;
734
735       /* if we don't find it in the live range 
736          hash table we are in serious trouble */
737       if (!(sym = hTabItemWithKey (liveRanges, i)))
738         {
739           werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
740                   "liveRangesWith could not find liveRange");
741           exit (1);
742         }
743
744       if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
745         addSetHead (&rset, sym);
746     }
747
748   return rset;
749 }
750
751
752 /*-----------------------------------------------------------------*/
753 /* leastUsedLR - given a set determines which is the least used    */
754 /*-----------------------------------------------------------------*/
755 static symbol *
756 leastUsedLR (set * sset)
757 {
758   symbol *sym = NULL, *lsym = NULL;
759
760   debugLog ("%s\n", __FUNCTION__);
761   sym = lsym = setFirstItem (sset);
762
763   if (!lsym)
764     return NULL;
765
766   for (; lsym; lsym = setNextItem (sset))
767     {
768
769       /* if usage is the same then prefer
770          the spill the smaller of the two */
771       if (lsym->used == sym->used)
772         if (getSize (lsym->type) < getSize (sym->type))
773           sym = lsym;
774
775       /* if less usage */
776       if (lsym->used < sym->used)
777         sym = lsym;
778
779     }
780
781   setToNull ((void **) &sset);
782   sym->blockSpil = 0;
783   return sym;
784 }
785
786 /*-----------------------------------------------------------------*/
787 /* noOverLap - will iterate through the list looking for over lap  */
788 /*-----------------------------------------------------------------*/
789 static int
790 noOverLap (set * itmpStack, symbol * fsym)
791 {
792   symbol *sym;
793   debugLog ("%s\n", __FUNCTION__);
794
795
796   for (sym = setFirstItem (itmpStack); sym;
797        sym = setNextItem (itmpStack))
798     {
799       if (sym->liveTo > fsym->liveFrom)
800         return 0;
801
802     }
803
804   return 1;
805 }
806
807 /*-----------------------------------------------------------------*/
808 /* isFree - will return 1 if the a free spil location is found     */
809 /*-----------------------------------------------------------------*/
810 static
811 DEFSETFUNC (isFree)
812 {
813   symbol *sym = item;
814   V_ARG (symbol **, sloc);
815   V_ARG (symbol *, fsym);
816
817   debugLog ("%s\n", __FUNCTION__);
818   /* if already found */
819   if (*sloc)
820     return 0;
821
822   /* if it is free && and the itmp assigned to
823      this does not have any overlapping live ranges
824      with the one currently being assigned and
825      the size can be accomodated  */
826   if (sym->isFree &&
827       noOverLap (sym->usl.itmpStack, fsym) &&
828       getSize (sym->type) >= getSize (fsym->type))
829     {
830       *sloc = sym;
831       return 1;
832     }
833
834   return 0;
835 }
836
837 /*-----------------------------------------------------------------*/
838 /* spillLRWithPtrReg :- will spil those live ranges which use PTR  */
839 /*-----------------------------------------------------------------*/
840 static void
841 spillLRWithPtrReg (symbol * forSym)
842 {
843   symbol *lrsym;
844   regs *r0, *r1;
845   int k;
846
847   debugLog ("%s\n", __FUNCTION__);
848   if (!_G.regAssigned ||
849       bitVectIsZero (_G.regAssigned))
850     return;
851
852   r0 = pic14_regWithIdx (R0_IDX);
853   r1 = pic14_regWithIdx (R1_IDX);
854
855   /* for all live ranges */
856   for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
857        lrsym = hTabNextItem (liveRanges, &k))
858     {
859       int j;
860
861       /* if no registers assigned to it or
862          spilt */
863       /* if it does not overlap with this then 
864          not need to spill it */
865
866       if (lrsym->isspilt || !lrsym->nRegs ||
867           (lrsym->liveTo < forSym->liveFrom))
868         continue;
869
870       /* go thru the registers : if it is either
871          r0 or r1 then spil it */
872       for (j = 0; j < lrsym->nRegs; j++)
873         if (lrsym->regs[j] == r0 ||
874             lrsym->regs[j] == r1)
875           {
876             spillThis (lrsym);
877             break;
878           }
879     }
880
881 }
882
883 /*-----------------------------------------------------------------*/
884 /* createStackSpil - create a location on the stack to spil        */
885 /*-----------------------------------------------------------------*/
886 static symbol *
887 createStackSpil (symbol * sym)
888 {
889   symbol *sloc = NULL;
890   int useXstack, model, noOverlay;
891
892   char slocBuffer[30];
893   debugLog ("%s\n", __FUNCTION__);
894
895   /* first go try and find a free one that is already 
896      existing on the stack */
897   if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
898     {
899       /* found a free one : just update & return */
900       sym->usl.spillLoc = sloc;
901       sym->stackSpil = 1;
902       sloc->isFree = 0;
903       addSetHead (&sloc->usl.itmpStack, sym);
904       return sym;
905     }
906
907   /* could not then have to create one , this is the hard part
908      we need to allocate this on the stack : this is really a
909      hack!! but cannot think of anything better at this time */
910
911   if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
912     {
913       fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
914                __FILE__, __LINE__);
915       exit (1);
916     }
917
918   sloc = newiTemp (slocBuffer);
919
920   /* set the type to the spilling symbol */
921   sloc->type = copyLinkChain (sym->type);
922   sloc->etype = getSpec (sloc->type);
923   SPEC_SCLS (sloc->etype) = S_DATA;
924   SPEC_EXTR (sloc->etype) = 0;
925
926   /* we don't allow it to be allocated`
927      onto the external stack since : so we
928      temporarily turn it off ; we also
929      turn off memory model to prevent
930      the spil from going to the external storage
931      and turn off overlaying 
932    */
933
934   useXstack = options.useXstack;
935   model = options.model;
936   noOverlay = options.noOverlay;
937   options.noOverlay = 1;
938   options.model = options.useXstack = 0;
939
940   allocLocal (sloc);
941
942   options.useXstack = useXstack;
943   options.model = model;
944   options.noOverlay = noOverlay;
945   sloc->isref = 1;              /* to prevent compiler warning */
946
947   /* if it is on the stack then update the stack */
948   if (IN_STACK (sloc->etype))
949     {
950       currFunc->stack += getSize (sloc->type);
951       _G.stackExtend += getSize (sloc->type);
952     }
953   else
954     _G.dataExtend += getSize (sloc->type);
955
956   /* add it to the _G.stackSpil set */
957   addSetHead (&_G.stackSpil, sloc);
958   sym->usl.spillLoc = sloc;
959   sym->stackSpil = 1;
960
961   /* add it to the set of itempStack set 
962      of the spill location */
963   addSetHead (&sloc->usl.itmpStack, sym);
964   return sym;
965 }
966
967 /*-----------------------------------------------------------------*/
968 /* isSpiltOnStack - returns true if the spil location is on stack  */
969 /*-----------------------------------------------------------------*/
970 static bool
971 isSpiltOnStack (symbol * sym)
972 {
973   sym_link *etype;
974
975   debugLog ("%s\n", __FUNCTION__);
976   if (!sym)
977     return FALSE;
978
979   if (!sym->isspilt)
980     return FALSE;
981
982 /*     if (sym->_G.stackSpil) */
983 /*      return TRUE; */
984
985   if (!sym->usl.spillLoc)
986     return FALSE;
987
988   etype = getSpec (sym->usl.spillLoc->type);
989   if (IN_STACK (etype))
990     return TRUE;
991
992   return FALSE;
993 }
994
995 /*-----------------------------------------------------------------*/
996 /* spillThis - spils a specific operand                            */
997 /*-----------------------------------------------------------------*/
998 static void
999 spillThis (symbol * sym)
1000 {
1001   int i;
1002   debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1003
1004   /* if this is rematerializable or has a spillLocation
1005      we are okay, else we need to create a spillLocation
1006      for it */
1007   if (!(sym->remat || sym->usl.spillLoc))
1008     createStackSpil (sym);
1009
1010
1011   /* mark it has spilt & put it in the spilt set */
1012   sym->isspilt = 1;
1013   _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1014
1015   bitVectUnSetBit (_G.regAssigned, sym->key);
1016
1017   for (i = 0; i < sym->nRegs; i++)
1018
1019     if (sym->regs[i])
1020       {
1021         freeReg (sym->regs[i]);
1022         sym->regs[i] = NULL;
1023       }
1024
1025   /* if spilt on stack then free up r0 & r1 
1026      if they could have been assigned to some
1027      LIVE ranges */
1028   if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1029     {
1030       pic14_ptrRegReq++;
1031       spillLRWithPtrReg (sym);
1032     }
1033
1034   if (sym->usl.spillLoc && !sym->remat)
1035     sym->usl.spillLoc->allocreq = 1;
1036   return;
1037 }
1038
1039 /*-----------------------------------------------------------------*/
1040 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1041 /*-----------------------------------------------------------------*/
1042 static symbol *
1043 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1044 {
1045   bitVect *lrcs = NULL;
1046   set *selectS;
1047   symbol *sym;
1048
1049   debugLog ("%s\n", __FUNCTION__);
1050   /* get the spillable live ranges */
1051   lrcs = computeSpillable (ic);
1052
1053   /* get all live ranges that are rematerizable */
1054   if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1055     {
1056
1057       /* return the least used of these */
1058       return leastUsedLR (selectS);
1059     }
1060
1061   /* get live ranges with spillLocations in direct space */
1062   if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1063     {
1064       sym = leastUsedLR (selectS);
1065       strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1066                            sym->usl.spillLoc->rname :
1067                            sym->usl.spillLoc->name));
1068       sym->spildir = 1;
1069       /* mark it as allocation required */
1070       sym->usl.spillLoc->allocreq = 1;
1071       return sym;
1072     }
1073
1074   /* if the symbol is local to the block then */
1075   if (forSym->liveTo < ebp->lSeq)
1076     {
1077
1078       /* check if there are any live ranges allocated
1079          to registers that are not used in this block */
1080       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1081         {
1082           sym = leastUsedLR (selectS);
1083           /* if this is not rematerializable */
1084           if (!sym->remat)
1085             {
1086               _G.blockSpil++;
1087               sym->blockSpil = 1;
1088             }
1089           return sym;
1090         }
1091
1092       /* check if there are any live ranges that not
1093          used in the remainder of the block */
1094       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1095         {
1096           sym = leastUsedLR (selectS);
1097           if (!sym->remat)
1098             {
1099               sym->remainSpil = 1;
1100               _G.blockSpil++;
1101             }
1102           return sym;
1103         }
1104     }
1105
1106   /* find live ranges with spillocation && not used as pointers */
1107   if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1108     {
1109
1110       sym = leastUsedLR (selectS);
1111       /* mark this as allocation required */
1112       sym->usl.spillLoc->allocreq = 1;
1113       return sym;
1114     }
1115
1116   /* find live ranges with spillocation */
1117   if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1118     {
1119
1120       sym = leastUsedLR (selectS);
1121       sym->usl.spillLoc->allocreq = 1;
1122       return sym;
1123     }
1124
1125   /* couldn't find then we need to create a spil
1126      location on the stack , for which one? the least
1127      used ofcourse */
1128   if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1129     {
1130
1131       /* return a created spil location */
1132       sym = createStackSpil (leastUsedLR (selectS));
1133       sym->usl.spillLoc->allocreq = 1;
1134       return sym;
1135     }
1136
1137   /* this is an extreme situation we will spill
1138      this one : happens very rarely but it does happen */
1139   spillThis (forSym);
1140   return forSym;
1141
1142 }
1143
1144 /*-----------------------------------------------------------------*/
1145 /* spilSomething - spil some variable & mark registers as free     */
1146 /*-----------------------------------------------------------------*/
1147 static bool
1148 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1149 {
1150   symbol *ssym;
1151   int i;
1152
1153   debugLog ("%s\n", __FUNCTION__);
1154   /* get something we can spil */
1155   ssym = selectSpil (ic, ebp, forSym);
1156
1157   /* mark it as spilt */
1158   ssym->isspilt = 1;
1159   _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1160
1161   /* mark it as not register assigned &
1162      take it away from the set */
1163   bitVectUnSetBit (_G.regAssigned, ssym->key);
1164
1165   /* mark the registers as free */
1166   for (i = 0; i < ssym->nRegs; i++)
1167     if (ssym->regs[i])
1168       freeReg (ssym->regs[i]);
1169
1170   /* if spilt on stack then free up r0 & r1 
1171      if they could have been assigned to as gprs */
1172   if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1173     {
1174       pic14_ptrRegReq++;
1175       spillLRWithPtrReg (ssym);
1176     }
1177
1178   /* if this was a block level spil then insert push & pop 
1179      at the start & end of block respectively */
1180   if (ssym->blockSpil)
1181     {
1182       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1183       /* add push to the start of the block */
1184       addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1185                                     ebp->sch->next : ebp->sch));
1186       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1187       /* add pop to the end of the block */
1188       addiCodeToeBBlock (ebp, nic, NULL);
1189     }
1190
1191   /* if spilt because not used in the remainder of the
1192      block then add a push before this instruction and
1193      a pop at the end of the block */
1194   if (ssym->remainSpil)
1195     {
1196
1197       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1198       /* add push just before this instruction */
1199       addiCodeToeBBlock (ebp, nic, ic);
1200
1201       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1202       /* add pop to the end of the block */
1203       addiCodeToeBBlock (ebp, nic, NULL);
1204     }
1205
1206   if (ssym == forSym)
1207     return FALSE;
1208   else
1209     return TRUE;
1210 }
1211
1212 /*-----------------------------------------------------------------*/
1213 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
1214 /*-----------------------------------------------------------------*/
1215 static regs *
1216 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1217 {
1218   regs *reg;
1219
1220   debugLog ("%s\n", __FUNCTION__);
1221 tryAgain:
1222   /* try for a ptr type */
1223   if ((reg = allocReg (REG_PTR)))
1224     return reg;
1225
1226   /* try for gpr type */
1227   if ((reg = allocReg (REG_GPR)))
1228     return reg;
1229
1230   /* we have to spil */
1231   if (!spilSomething (ic, ebp, sym))
1232     return NULL;
1233
1234   /* this looks like an infinite loop but 
1235      in really selectSpil will abort  */
1236   goto tryAgain;
1237 }
1238
1239 /*-----------------------------------------------------------------*/
1240 /* getRegGpr - will try for GPR if not spil                        */
1241 /*-----------------------------------------------------------------*/
1242 static regs *
1243 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1244 {
1245   regs *reg;
1246
1247   debugLog ("%s\n", __FUNCTION__);
1248 tryAgain:
1249   /* try for gpr type */
1250   if ((reg = allocReg (REG_GPR)))
1251     return reg;
1252
1253   if (!pic14_ptrRegReq)
1254     if ((reg = allocReg (REG_PTR)))
1255       return reg;
1256
1257   /* we have to spil */
1258   if (!spilSomething (ic, ebp, sym))
1259     return NULL;
1260
1261   /* this looks like an infinite loop but 
1262      in really selectSpil will abort  */
1263   goto tryAgain;
1264 }
1265
1266 /*-----------------------------------------------------------------*/
1267 /* symHasReg - symbol has a given register                         */
1268 /*-----------------------------------------------------------------*/
1269 static bool
1270 symHasReg (symbol * sym, regs * reg)
1271 {
1272   int i;
1273
1274   debugLog ("%s\n", __FUNCTION__);
1275   for (i = 0; i < sym->nRegs; i++)
1276     if (sym->regs[i] == reg)
1277       return TRUE;
1278
1279   return FALSE;
1280 }
1281
1282 /*-----------------------------------------------------------------*/
1283 /* deassignLRs - check the live to and if they have registers & are */
1284 /*               not spilt then free up the registers              */
1285 /*-----------------------------------------------------------------*/
1286 static void
1287 deassignLRs (iCode * ic, eBBlock * ebp)
1288 {
1289   symbol *sym;
1290   int k;
1291   symbol *result;
1292
1293   debugLog ("%s\n", __FUNCTION__);
1294   for (sym = hTabFirstItem (liveRanges, &k); sym;
1295        sym = hTabNextItem (liveRanges, &k))
1296     {
1297
1298       symbol *psym = NULL;
1299       /* if it does not end here */
1300       if (sym->liveTo > ic->seq)
1301         continue;
1302
1303       /* if it was spilt on stack then we can 
1304          mark the stack spil location as free */
1305       if (sym->isspilt)
1306         {
1307           if (sym->stackSpil)
1308             {
1309               sym->usl.spillLoc->isFree = 1;
1310               sym->stackSpil = 0;
1311             }
1312           continue;
1313         }
1314
1315       if (!bitVectBitValue (_G.regAssigned, sym->key))
1316         continue;
1317
1318       /* special case check if this is an IFX &
1319          the privious one was a pop and the 
1320          previous one was not spilt then keep track
1321          of the symbol */
1322       if (ic->op == IFX && ic->prev &&
1323           ic->prev->op == IPOP &&
1324           !ic->prev->parmPush &&
1325           !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1326         psym = OP_SYMBOL (IC_LEFT (ic->prev));
1327
1328       if (sym->nRegs)
1329         {
1330           int i = 0;
1331
1332           bitVectUnSetBit (_G.regAssigned, sym->key);
1333
1334           /* if the result of this one needs registers
1335              and does not have it then assign it right
1336              away */
1337           if (IC_RESULT (ic) &&
1338               !(SKIP_IC2 (ic) ||        /* not a special icode */
1339                 ic->op == JUMPTABLE ||
1340                 ic->op == IFX ||
1341                 ic->op == IPUSH ||
1342                 ic->op == IPOP ||
1343                 ic->op == RETURN ||
1344                 POINTER_SET (ic)) &&
1345               (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
1346               result->liveTo > ic->seq &&       /* and will live beyond this */
1347               result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
1348               result->regType == sym->regType &&        /* same register types */
1349               result->nRegs &&  /* which needs registers */
1350               !result->isspilt &&       /* and does not already have them */
1351               !result->remat &&
1352               !bitVectBitValue (_G.regAssigned, result->key) &&
1353           /* the number of free regs + number of regs in this LR
1354              can accomodate the what result Needs */
1355               ((nfreeRegsType (result->regType) +
1356                 sym->nRegs) >= result->nRegs)
1357             )
1358             {
1359
1360               for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1361                 if (i < sym->nRegs)
1362                   result->regs[i] = sym->regs[i];
1363                 else
1364                   result->regs[i] = getRegGpr (ic, ebp, result);
1365
1366               _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1367
1368             }
1369
1370           /* free the remaining */
1371           for (; i < sym->nRegs; i++)
1372             {
1373               if (psym)
1374                 {
1375                   if (!symHasReg (psym, sym->regs[i]))
1376                     freeReg (sym->regs[i]);
1377                 }
1378               else
1379                 freeReg (sym->regs[i]);
1380             }
1381         }
1382     }
1383 }
1384
1385
1386 /*-----------------------------------------------------------------*/
1387 /* reassignLR - reassign this to registers                         */
1388 /*-----------------------------------------------------------------*/
1389 static void
1390 reassignLR (operand * op)
1391 {
1392   symbol *sym = OP_SYMBOL (op);
1393   int i;
1394
1395   debugLog ("%s\n", __FUNCTION__);
1396   /* not spilt any more */
1397   sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1398   bitVectUnSetBit (_G.spiltSet, sym->key);
1399
1400   _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1401
1402   _G.blockSpil--;
1403
1404   for (i = 0; i < sym->nRegs; i++)
1405     sym->regs[i]->isFree = 0;
1406 }
1407
1408 /*-----------------------------------------------------------------*/
1409 /* willCauseSpill - determines if allocating will cause a spill    */
1410 /*-----------------------------------------------------------------*/
1411 static int
1412 willCauseSpill (int nr, int rt)
1413 {
1414   debugLog ("%s\n", __FUNCTION__);
1415   /* first check if there are any avlb registers
1416      of te type required */
1417   if (rt == REG_PTR)
1418     {
1419       /* special case for pointer type 
1420          if pointer type not avlb then 
1421          check for type gpr */
1422       if (nFreeRegs (rt) >= nr)
1423         return 0;
1424       if (nFreeRegs (REG_GPR) >= nr)
1425         return 0;
1426     }
1427   else
1428     {
1429       if (pic14_ptrRegReq)
1430         {
1431           if (nFreeRegs (rt) >= nr)
1432             return 0;
1433         }
1434       else
1435         {
1436           if (nFreeRegs (REG_PTR) +
1437               nFreeRegs (REG_GPR) >= nr)
1438             return 0;
1439         }
1440     }
1441
1442   debugLog (" ... yep it will (cause a spill)\n");
1443   /* it will cause a spil */
1444   return 1;
1445 }
1446
1447 /*-----------------------------------------------------------------*/
1448 /* positionRegs - the allocator can allocate same registers to res- */
1449 /* ult and operand, if this happens make sure they are in the same */
1450 /* position as the operand otherwise chaos results                 */
1451 /*-----------------------------------------------------------------*/
1452 static void
1453 positionRegs (symbol * result, symbol * opsym, int lineno)
1454 {
1455   int count = min (result->nRegs, opsym->nRegs);
1456   int i, j = 0, shared = 0;
1457
1458   debugLog ("%s\n", __FUNCTION__);
1459   /* if the result has been spilt then cannot share */
1460   if (opsym->isspilt)
1461     return;
1462 again:
1463   shared = 0;
1464   /* first make sure that they actually share */
1465   for (i = 0; i < count; i++)
1466     {
1467       for (j = 0; j < count; j++)
1468         {
1469           if (result->regs[i] == opsym->regs[j] && i != j)
1470             {
1471               shared = 1;
1472               goto xchgPositions;
1473             }
1474         }
1475     }
1476 xchgPositions:
1477   if (shared)
1478     {
1479       regs *tmp = result->regs[i];
1480       result->regs[i] = result->regs[j];
1481       result->regs[j] = tmp;
1482       goto again;
1483     }
1484 }
1485
1486 /*-----------------------------------------------------------------*/
1487 /* serialRegAssign - serially allocate registers to the variables  */
1488 /*-----------------------------------------------------------------*/
1489 static void
1490 serialRegAssign (eBBlock ** ebbs, int count)
1491 {
1492   int i;
1493
1494   debugLog ("%s\n", __FUNCTION__);
1495   /* for all blocks */
1496   for (i = 0; i < count; i++)
1497     {
1498
1499       iCode *ic;
1500
1501       if (ebbs[i]->noPath &&
1502           (ebbs[i]->entryLabel != entryLabel &&
1503            ebbs[i]->entryLabel != returnLabel))
1504         continue;
1505
1506       /* of all instructions do */
1507       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1508         {
1509
1510           debugLog ("  op: %s\n", decodeOp (ic->op));
1511
1512           /* if this is an ipop that means some live
1513              range will have to be assigned again */
1514           if (ic->op == IPOP)
1515             reassignLR (IC_LEFT (ic));
1516
1517           /* if result is present && is a true symbol */
1518           if (IC_RESULT (ic) && ic->op != IFX &&
1519               IS_TRUE_SYMOP (IC_RESULT (ic)))
1520             OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
1521
1522           /* take away registers from live
1523              ranges that end at this instruction */
1524           deassignLRs (ic, ebbs[i]);
1525
1526           /* some don't need registers */
1527           if (SKIP_IC2 (ic) ||
1528               ic->op == JUMPTABLE ||
1529               ic->op == IFX ||
1530               ic->op == IPUSH ||
1531               ic->op == IPOP ||
1532               (IC_RESULT (ic) && POINTER_SET (ic)))
1533             continue;
1534
1535           /* now we need to allocate registers
1536              only for the result */
1537           if (IC_RESULT (ic))
1538             {
1539               symbol *sym = OP_SYMBOL (IC_RESULT (ic));
1540               bitVect *spillable;
1541               int willCS;
1542               int j;
1543               int ptrRegSet = 0;
1544
1545               /* if it does not need or is spilt 
1546                  or is already assigned to registers
1547                  or will not live beyond this instructions */
1548               if (!sym->nRegs ||
1549                   sym->isspilt ||
1550                   bitVectBitValue (_G.regAssigned, sym->key) ||
1551                   sym->liveTo <= ic->seq)
1552                 continue;
1553
1554               /* if some liverange has been spilt at the block level
1555                  and this one live beyond this block then spil this
1556                  to be safe */
1557               if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
1558                 {
1559                   spillThis (sym);
1560                   continue;
1561                 }
1562               /* if trying to allocate this will cause
1563                  a spill and there is nothing to spill 
1564                  or this one is rematerializable then
1565                  spill this one */
1566               willCS = willCauseSpill (sym->nRegs, sym->regType);
1567               spillable = computeSpillable (ic);
1568               if (sym->remat ||
1569                   (willCS && bitVectIsZero (spillable)))
1570                 {
1571
1572                   spillThis (sym);
1573                   continue;
1574
1575                 }
1576
1577               /* if it has a spillocation & is used less than
1578                  all other live ranges then spill this */
1579                 if (willCS) {
1580                     if (sym->usl.spillLoc) {
1581                         symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
1582                                                                          allLRs, ebbs[i], ic));
1583                         if (leastUsed && leastUsed->used > sym->used) {
1584                             spillThis (sym);
1585                             continue;
1586                         }
1587                     } else {
1588                         /* if none of the liveRanges have a spillLocation then better
1589                            to spill this one than anything else already assigned to registers */
1590                         if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
1591                             spillThis (sym);
1592                             continue;
1593                         }
1594                     }
1595                 }
1596
1597               if (ic->op == RECEIVE)
1598                 debugLog ("When I get clever, I'll optimize the receive logic\n");
1599
1600               /* if we need ptr regs for the right side
1601                  then mark it */
1602               if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
1603                   <= (unsigned) PTRSIZE)
1604                 {
1605                   pic14_ptrRegReq++;
1606                   ptrRegSet = 1;
1607                 }
1608               /* else we assign registers to it */
1609               _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1610
1611               debugLog ("  %d - \n", __LINE__);
1612               if(debugF) 
1613                 bitVectDebugOn(_G.regAssigned, debugF);
1614
1615               for (j = 0; j < sym->nRegs; j++)
1616                 {
1617                   if (sym->regType == REG_PTR)
1618                     sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1619                   else
1620                     sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1621
1622                   /* if the allocation falied which means
1623                      this was spilt then break */
1624                   if (!sym->regs[j])
1625                     break;
1626                 }
1627               debugLog ("  %d - \n", __LINE__);
1628
1629               /* if it shares registers with operands make sure
1630                  that they are in the same position */
1631               if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1632                   OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
1633                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1634                               OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
1635               /* do the same for the right operand */
1636               if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1637                   OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
1638                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1639                               OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
1640
1641               debugLog ("  %d - \n", __LINE__);
1642               if (ptrRegSet)
1643                 {
1644                   debugLog ("  %d - \n", __LINE__);
1645                   pic14_ptrRegReq--;
1646                   ptrRegSet = 0;
1647                 }
1648
1649             }
1650         }
1651     }
1652 }
1653
1654 /*-----------------------------------------------------------------*/
1655 /* rUmaskForOp :- returns register mask for an operand             */
1656 /*-----------------------------------------------------------------*/
1657 static bitVect *
1658 rUmaskForOp (operand * op)
1659 {
1660   bitVect *rumask;
1661   symbol *sym;
1662   int j;
1663
1664   debugLog ("%s\n", __FUNCTION__);
1665   /* only temporaries are assigned registers */
1666   if (!IS_ITEMP (op))
1667     return NULL;
1668
1669   sym = OP_SYMBOL (op);
1670
1671   /* if spilt or no registers assigned to it
1672      then nothing */
1673   if (sym->isspilt || !sym->nRegs)
1674     return NULL;
1675
1676   rumask = newBitVect (pic14_nRegs);
1677
1678   for (j = 0; j < sym->nRegs; j++)
1679     {
1680       rumask = bitVectSetBit (rumask,
1681                               sym->regs[j]->rIdx);
1682     }
1683
1684   return rumask;
1685 }
1686
1687 /*-----------------------------------------------------------------*/
1688 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1689 /*-----------------------------------------------------------------*/
1690 static bitVect *
1691 regsUsedIniCode (iCode * ic)
1692 {
1693   bitVect *rmask = newBitVect (pic14_nRegs);
1694
1695   debugLog ("%s\n", __FUNCTION__);
1696   /* do the special cases first */
1697   if (ic->op == IFX)
1698     {
1699       rmask = bitVectUnion (rmask,
1700                             rUmaskForOp (IC_COND (ic)));
1701       goto ret;
1702     }
1703
1704   /* for the jumptable */
1705   if (ic->op == JUMPTABLE)
1706     {
1707       rmask = bitVectUnion (rmask,
1708                             rUmaskForOp (IC_JTCOND (ic)));
1709
1710       goto ret;
1711     }
1712
1713   /* of all other cases */
1714   if (IC_LEFT (ic))
1715     rmask = bitVectUnion (rmask,
1716                           rUmaskForOp (IC_LEFT (ic)));
1717
1718
1719   if (IC_RIGHT (ic))
1720     rmask = bitVectUnion (rmask,
1721                           rUmaskForOp (IC_RIGHT (ic)));
1722
1723   if (IC_RESULT (ic))
1724     rmask = bitVectUnion (rmask,
1725                           rUmaskForOp (IC_RESULT (ic)));
1726
1727 ret:
1728   return rmask;
1729 }
1730
1731 /*-----------------------------------------------------------------*/
1732 /* createRegMask - for each instruction will determine the regsUsed */
1733 /*-----------------------------------------------------------------*/
1734 static void
1735 createRegMask (eBBlock ** ebbs, int count)
1736 {
1737   int i;
1738
1739   debugLog ("%s\n", __FUNCTION__);
1740   /* for all blocks */
1741   for (i = 0; i < count; i++)
1742     {
1743       iCode *ic;
1744
1745       if (ebbs[i]->noPath &&
1746           (ebbs[i]->entryLabel != entryLabel &&
1747            ebbs[i]->entryLabel != returnLabel))
1748         continue;
1749
1750       /* for all instructions */
1751       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1752         {
1753
1754           int j;
1755
1756           if (SKIP_IC2 (ic) || !ic->rlive)
1757             continue;
1758
1759           /* first mark the registers used in this
1760              instruction */
1761           ic->rUsed = regsUsedIniCode (ic);
1762           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1763
1764           /* now create the register mask for those 
1765              registers that are in use : this is a
1766              super set of ic->rUsed */
1767           ic->rMask = newBitVect (pic14_nRegs + 1);
1768
1769           /* for all live Ranges alive at this point */
1770           for (j = 1; j < ic->rlive->size; j++)
1771             {
1772               symbol *sym;
1773               int k;
1774
1775               /* if not alive then continue */
1776               if (!bitVectBitValue (ic->rlive, j))
1777                 continue;
1778
1779               /* find the live range we are interested in */
1780               if (!(sym = hTabItemWithKey (liveRanges, j)))
1781                 {
1782                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1783                           "createRegMask cannot find live range");
1784                   exit (0);
1785                 }
1786
1787               /* if no register assigned to it */
1788               if (!sym->nRegs || sym->isspilt)
1789                 continue;
1790
1791               /* for all the registers allocated to it */
1792               for (k = 0; k < sym->nRegs; k++)
1793                 if (sym->regs[k])
1794                   ic->rMask =
1795                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1796             }
1797         }
1798     }
1799 }
1800
1801 /*-----------------------------------------------------------------*/
1802 /* rematStr - returns the rematerialized string for a remat var    */
1803 /*-----------------------------------------------------------------*/
1804 static char *
1805 rematStr (symbol * sym)
1806 {
1807   char *s = buffer;
1808   iCode *ic = sym->rematiCode;
1809
1810   debugLog ("%s\n", __FUNCTION__);
1811   while (1)
1812     {
1813
1814       printf ("%s\n", s);
1815       /* if plus or minus print the right hand side */
1816 /*
1817    if (ic->op == '+' || ic->op == '-') {
1818    sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
1819    ic->op );
1820    s += strlen(s);
1821    ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1822    continue ;
1823    }
1824  */
1825       if (ic->op == '+' || ic->op == '-')
1826         {
1827           iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1828           sprintf (s, "(%s %c 0x%04x)",
1829                    OP_SYMBOL (IC_LEFT (ric))->rname,
1830                    ic->op,
1831                    (int) operandLitValue (IC_RIGHT (ic)));
1832
1833           //s += strlen(s);
1834           //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1835           //continue ;
1836           return buffer;
1837         }
1838
1839       /* we reached the end */
1840       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1841       break;
1842     }
1843
1844   printf ("%s\n", buffer);
1845   return buffer;
1846 }
1847
1848 /*-----------------------------------------------------------------*/
1849 /* regTypeNum - computes the type & number of registers required   */
1850 /*-----------------------------------------------------------------*/
1851 static void
1852 regTypeNum ()
1853 {
1854   symbol *sym;
1855   int k;
1856   iCode *ic;
1857
1858   debugLog ("%s\n", __FUNCTION__);
1859   /* for each live range do */
1860   for (sym = hTabFirstItem (liveRanges, &k); sym;
1861        sym = hTabNextItem (liveRanges, &k)) {
1862
1863     debugLog ("  %d - %s\n", __LINE__, sym->rname);
1864
1865     /* if used zero times then no registers needed */
1866     if ((sym->liveTo - sym->liveFrom) == 0)
1867       continue;
1868
1869
1870     /* if the live range is a temporary */
1871     if (sym->isitmp) {
1872
1873       debugLog ("  %d - itemp register\n", __LINE__);
1874
1875       /* if the type is marked as a conditional */
1876       if (sym->regType == REG_CND)
1877         continue;
1878
1879       /* if used in return only then we don't 
1880          need registers */
1881       if (sym->ruonly || sym->accuse) {
1882         if (IS_AGGREGATE (sym->type) || sym->isptr)
1883           sym->type = aggrToPtr (sym->type, FALSE);
1884         debugLog ("  %d - no reg needed - used as a return\n", __LINE__);
1885
1886         continue;
1887       }
1888
1889       /* if the symbol has only one definition &
1890          that definition is a get_pointer and the
1891          pointer we are getting is rematerializable and
1892          in "data" space */
1893
1894       if (bitVectnBitsOn (sym->defs) == 1 &&
1895           (ic = hTabItemWithKey (iCodehTab,
1896                                  bitVectFirstBit (sym->defs))) &&
1897           POINTER_GET (ic) &&
1898           !sym->noSpilLoc &&
1899           !IS_BITVAR (sym->etype)) {
1900         
1901
1902         debugLog ("  %d - \n", __LINE__);
1903
1904         /* if remat in data space */
1905         if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1906             DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
1907
1908           /* create a psuedo symbol & force a spil */
1909           symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1910           psym->type = sym->type;
1911           psym->etype = sym->etype;
1912           strcpy (psym->rname, psym->name);
1913           sym->isspilt = 1;
1914           sym->usl.spillLoc = psym;
1915           continue;
1916         }
1917
1918         /* if in data space or idata space then try to
1919            allocate pointer register */
1920
1921       }
1922
1923       /* if not then we require registers */
1924       sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1925                     getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1926                     getSize (sym->type));
1927
1928       if (sym->nRegs > 4) {
1929         fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1930         printTypeChain (sym->type, stderr);
1931         fprintf (stderr, "\n");
1932       }
1933
1934       /* determine the type of register required */
1935       if (sym->nRegs == 1 &&
1936           IS_PTR (sym->type) &&
1937           sym->uptr)
1938         sym->regType = REG_PTR;
1939       else
1940         sym->regType = REG_GPR;
1941
1942
1943       debugLog ("  reg name %s,  reg type %s\n", sym->rname, debugLogRegType (sym->regType));
1944
1945     }
1946     else
1947       /* for the first run we don't provide */
1948       /* registers for true symbols we will */
1949       /* see how things go                  */
1950       sym->nRegs = 0;
1951   }
1952
1953 }
1954
1955 /*-----------------------------------------------------------------*/
1956 /* freeAllRegs - mark all registers as free                        */
1957 /*-----------------------------------------------------------------*/
1958 void
1959 pic14_freeAllRegs ()
1960 {
1961   int i;
1962
1963   debugLog ("%s\n", __FUNCTION__);
1964   for (i = 0; i < pic14_nRegs; i++)
1965     regspic14[i].isFree = 1;
1966 }
1967
1968 /*-----------------------------------------------------------------*/
1969 /*-----------------------------------------------------------------*/
1970 void
1971 pic14_deallocateAllRegs ()
1972 {
1973   int i;
1974
1975   debugLog ("%s\n", __FUNCTION__);
1976   for (i = 0; i < pic14_nRegs; i++) {
1977     regspic14[i].isFree = 1;
1978     regspic14[i].wasUsed = 0;
1979   }
1980 }
1981
1982
1983 /*-----------------------------------------------------------------*/
1984 /* deallocStackSpil - this will set the stack pointer back         */
1985 /*-----------------------------------------------------------------*/
1986 static
1987 DEFSETFUNC (deallocStackSpil)
1988 {
1989   symbol *sym = item;
1990
1991   debugLog ("%s\n", __FUNCTION__);
1992   deallocLocal (sym);
1993   return 0;
1994 }
1995
1996 /*-----------------------------------------------------------------*/
1997 /* farSpacePackable - returns the packable icode for far variables */
1998 /*-----------------------------------------------------------------*/
1999 static iCode *
2000 farSpacePackable (iCode * ic)
2001 {
2002   iCode *dic;
2003
2004   debugLog ("%s\n", __FUNCTION__);
2005   /* go thru till we find a definition for the
2006      symbol on the right */
2007   for (dic = ic->prev; dic; dic = dic->prev)
2008     {
2009
2010       /* if the definition is a call then no */
2011       if ((dic->op == CALL || dic->op == PCALL) &&
2012           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2013         {
2014           return NULL;
2015         }
2016
2017       /* if shift by unknown amount then not */
2018       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2019           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2020         return NULL;
2021
2022       /* if pointer get and size > 1 */
2023       if (POINTER_GET (dic) &&
2024           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2025         return NULL;
2026
2027       if (POINTER_SET (dic) &&
2028           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2029         return NULL;
2030
2031       /* if any three is a true symbol in far space */
2032       if (IC_RESULT (dic) &&
2033           IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2034           isOperandInFarSpace (IC_RESULT (dic)))
2035         return NULL;
2036
2037       if (IC_RIGHT (dic) &&
2038           IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2039           isOperandInFarSpace (IC_RIGHT (dic)) &&
2040           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2041         return NULL;
2042
2043       if (IC_LEFT (dic) &&
2044           IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2045           isOperandInFarSpace (IC_LEFT (dic)) &&
2046           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2047         return NULL;
2048
2049       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2050         {
2051           if ((dic->op == LEFT_OP ||
2052                dic->op == RIGHT_OP ||
2053                dic->op == '-') &&
2054               IS_OP_LITERAL (IC_RIGHT (dic)))
2055             return NULL;
2056           else
2057             return dic;
2058         }
2059     }
2060
2061   return NULL;
2062 }
2063
2064 /*-----------------------------------------------------------------*/
2065 /* packRegsForAssign - register reduction for assignment           */
2066 /*-----------------------------------------------------------------*/
2067 static int
2068 packRegsForAssign (iCode * ic, eBBlock * ebp)
2069 {
2070
2071   iCode *dic, *sic;
2072
2073   debugLog ("%s\n", __FUNCTION__);
2074
2075   debugAopGet ("  result:", IC_RESULT (ic));
2076   debugAopGet ("  left:", IC_LEFT (ic));
2077   debugAopGet ("  right:", IC_RIGHT (ic));
2078
2079   if (!IS_ITEMP (IC_RIGHT (ic)) ||
2080       OP_SYMBOL (IC_RIGHT (ic))->isind ||
2081       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2082     {
2083       debugLog ("  %d - not packing - right side fails \n", __LINE__);
2084       return 0;
2085     }
2086
2087   /* if the true symbol is defined in far space or on stack
2088      then we should not since this will increase register pressure */
2089   if (isOperandInFarSpace (IC_RESULT (ic)))
2090     {
2091       if ((dic = farSpacePackable (ic)))
2092         goto pack;
2093       else
2094         return 0;
2095
2096     }
2097   /* find the definition of iTempNN scanning backwards if we find a 
2098      a use of the true symbol before we find the definition then 
2099      we cannot pack */
2100   for (dic = ic->prev; dic; dic = dic->prev)
2101     {
2102
2103       /* if there is a function call and this is
2104          a parameter & not my parameter then don't pack it */
2105       if ((dic->op == CALL || dic->op == PCALL) &&
2106           (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2107            !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2108         {
2109           debugLog ("  %d - \n", __LINE__);
2110           dic = NULL;
2111           break;
2112         }
2113
2114       if (SKIP_IC2 (dic))
2115         continue;
2116
2117       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2118           IS_OP_VOLATILE (IC_RESULT (dic)))
2119         {
2120           debugLog ("  %d - \n", __LINE__);
2121           dic = NULL;
2122           break;
2123         }
2124
2125       if (IS_SYMOP (IC_RESULT (dic)) &&
2126           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2127         {
2128           debugLog ("  %d - dic key == ic key -- pointer set=%c\n", __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2129           if (POINTER_SET (dic))
2130             dic = NULL;
2131
2132           break;
2133         }
2134
2135       if (IS_SYMOP (IC_RIGHT (dic)) &&
2136           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2137            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2138         {
2139           debugLog ("  %d - \n", __LINE__);
2140           dic = NULL;
2141           break;
2142         }
2143
2144       if (IS_SYMOP (IC_LEFT (dic)) &&
2145           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2146            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2147         {
2148           debugLog ("  %d - \n", __LINE__);
2149           dic = NULL;
2150           break;
2151         }
2152
2153       if (POINTER_SET (dic) &&
2154           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2155         {
2156           debugLog ("  %d - \n", __LINE__);
2157           dic = NULL;
2158           break;
2159         }
2160     }
2161
2162   if (!dic)
2163     return 0;                   /* did not find */
2164
2165   /* if the result is on stack or iaccess then it must be
2166      the same atleast one of the operands */
2167   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2168       OP_SYMBOL (IC_RESULT (ic))->iaccess)
2169     {
2170
2171       /* the operation has only one symbol
2172          operator then we can pack */
2173       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2174           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2175         goto pack;
2176
2177       if (!((IC_LEFT (dic) &&
2178              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2179             (IC_RIGHT (dic) &&
2180              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2181         return 0;
2182     }
2183 pack:
2184   debugLog ("  packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2185   /* found the definition */
2186   /* replace the result with the result of */
2187   /* this assignment and remove this assignment */
2188   IC_RESULT (dic) = IC_RESULT (ic);
2189
2190   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2191     {
2192       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2193     }
2194   /* delete from liverange table also 
2195      delete from all the points inbetween and the new
2196      one */
2197   for (sic = dic; sic != ic; sic = sic->next)
2198     {
2199       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2200       if (IS_ITEMP (IC_RESULT (dic)))
2201         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2202     }
2203
2204   remiCodeFromeBBlock (ebp, ic);
2205   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2206   OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2207   return 1;
2208
2209
2210 }
2211
2212 /*-----------------------------------------------------------------*/
2213 /* findAssignToSym : scanning backwards looks for first assig found */
2214 /*-----------------------------------------------------------------*/
2215 static iCode *
2216 findAssignToSym (operand * op, iCode * ic)
2217 {
2218   iCode *dic;
2219
2220   debugLog ("%s\n", __FUNCTION__);
2221   for (dic = ic->prev; dic; dic = dic->prev)
2222     {
2223
2224       /* if definition by assignment */
2225       if (dic->op == '=' &&
2226           !POINTER_SET (dic) &&
2227           IC_RESULT (dic)->key == op->key
2228 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2229         )
2230         {
2231
2232           /* we are interested only if defined in far space */
2233           /* or in stack space in case of + & - */
2234
2235           /* if assigned to a non-symbol then return
2236              true */
2237           if (!IS_SYMOP (IC_RIGHT (dic)))
2238             break;
2239
2240           /* if the symbol is in far space then
2241              we should not */
2242           if (isOperandInFarSpace (IC_RIGHT (dic)))
2243             return NULL;
2244
2245           /* for + & - operations make sure that
2246              if it is on the stack it is the same
2247              as one of the three operands */
2248           if ((ic->op == '+' || ic->op == '-') &&
2249               OP_SYMBOL (IC_RIGHT (dic))->onStack)
2250             {
2251
2252               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2253                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2254                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2255                 return NULL;
2256             }
2257
2258           break;
2259
2260         }
2261
2262       /* if we find an usage then we cannot delete it */
2263       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2264         return NULL;
2265
2266       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2267         return NULL;
2268
2269       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2270         return NULL;
2271     }
2272
2273   /* now make sure that the right side of dic
2274      is not defined between ic & dic */
2275   if (dic)
2276     {
2277       iCode *sic = dic->next;
2278
2279       for (; sic != ic; sic = sic->next)
2280         if (IC_RESULT (sic) &&
2281             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2282           return NULL;
2283     }
2284
2285   return dic;
2286
2287
2288 }
2289
2290 /*-----------------------------------------------------------------*/
2291 /* packRegsForSupport :- reduce some registers for support calls   */
2292 /*-----------------------------------------------------------------*/
2293 static int
2294 packRegsForSupport (iCode * ic, eBBlock * ebp)
2295 {
2296   int change = 0;
2297
2298   debugLog ("%s\n", __FUNCTION__);
2299   /* for the left & right operand :- look to see if the
2300      left was assigned a true symbol in far space in that
2301      case replace them */
2302   if (IS_ITEMP (IC_LEFT (ic)) &&
2303       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2304     {
2305       iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2306       iCode *sic;
2307
2308       if (!dic)
2309         goto right;
2310
2311       debugAopGet ("removing left:", IC_LEFT (ic));
2312
2313       /* found it we need to remove it from the
2314          block */
2315       for (sic = dic; sic != ic; sic = sic->next)
2316         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2317
2318       IC_LEFT (ic)->operand.symOperand =
2319         IC_RIGHT (dic)->operand.symOperand;
2320       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2321       remiCodeFromeBBlock (ebp, dic);
2322       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2323       change++;
2324     }
2325
2326   /* do the same for the right operand */
2327 right:
2328   if (!change &&
2329       IS_ITEMP (IC_RIGHT (ic)) &&
2330       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2331     {
2332       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2333       iCode *sic;
2334
2335       if (!dic)
2336         return change;
2337
2338       /* if this is a subtraction & the result
2339          is a true symbol in far space then don't pack */
2340       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2341         {
2342           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2343           if (IN_FARSPACE (SPEC_OCLS (etype)))
2344             return change;
2345         }
2346
2347       debugAopGet ("removing right:", IC_RIGHT (ic));
2348
2349       /* found it we need to remove it from the
2350          block */
2351       for (sic = dic; sic != ic; sic = sic->next)
2352         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2353
2354       IC_RIGHT (ic)->operand.symOperand =
2355         IC_RIGHT (dic)->operand.symOperand;
2356       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2357
2358       remiCodeFromeBBlock (ebp, dic);
2359       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2360       change++;
2361     }
2362
2363   return change;
2364 }
2365
2366 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2367
2368
2369 /*-----------------------------------------------------------------*/
2370 /* packRegsForOneuse : - will reduce some registers for single Use */
2371 /*-----------------------------------------------------------------*/
2372 static iCode *
2373 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2374 {
2375   bitVect *uses;
2376   iCode *dic, *sic;
2377
2378   debugLog ("%s\n", __FUNCTION__);
2379   /* if returning a literal then do nothing */
2380   if (!IS_SYMOP (op))
2381     return NULL;
2382
2383   /* only upto 2 bytes since we cannot predict
2384      the usage of b, & acc */
2385   if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
2386       ic->op != RETURN &&
2387       ic->op != SEND)
2388     return NULL;
2389
2390   /* this routine will mark the a symbol as used in one 
2391      instruction use only && if the definition is local 
2392      (ie. within the basic block) && has only one definition &&
2393      that definition is either a return value from a 
2394      function or does not contain any variables in
2395      far space */
2396   uses = bitVectCopy (OP_USES (op));
2397   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
2398   if (!bitVectIsZero (uses))    /* has other uses */
2399     return NULL;
2400
2401   /* if it has only one defintion */
2402   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2403     return NULL;                /* has more than one definition */
2404
2405   /* get that definition */
2406   if (!(dic =
2407         hTabItemWithKey (iCodehTab,
2408                          bitVectFirstBit (OP_DEFS (op)))))
2409     return NULL;
2410
2411   /* found the definition now check if it is local */
2412   if (dic->seq < ebp->fSeq ||
2413       dic->seq > ebp->lSeq)
2414     return NULL;                /* non-local */
2415
2416   /* now check if it is the return from
2417      a function call */
2418   if (dic->op == CALL || dic->op == PCALL)
2419     {
2420       if (ic->op != SEND && ic->op != RETURN)
2421         {
2422           OP_SYMBOL (op)->ruonly = 1;
2423           return dic;
2424         }
2425       dic = dic->next;
2426     }
2427
2428
2429   /* otherwise check that the definition does
2430      not contain any symbols in far space */
2431   if (isOperandInFarSpace (IC_LEFT (dic)) ||
2432       isOperandInFarSpace (IC_RIGHT (dic)) ||
2433       IS_OP_RUONLY (IC_LEFT (ic)) ||
2434       IS_OP_RUONLY (IC_RIGHT (ic)))
2435     {
2436       return NULL;
2437     }
2438
2439   /* if pointer set then make sure the pointer
2440      is one byte */
2441   if (POINTER_SET (dic) &&
2442       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2443     return NULL;
2444
2445   if (POINTER_GET (dic) &&
2446       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2447     return NULL;
2448
2449   sic = dic;
2450
2451   /* also make sure the intervenening instructions
2452      don't have any thing in far space */
2453   for (dic = dic->next; dic && dic != ic; dic = dic->next)
2454     {
2455
2456       /* if there is an intervening function call then no */
2457       if (dic->op == CALL || dic->op == PCALL)
2458         return NULL;
2459       /* if pointer set then make sure the pointer
2460          is one byte */
2461       if (POINTER_SET (dic) &&
2462           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2463         return NULL;
2464
2465       if (POINTER_GET (dic) &&
2466           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2467         return NULL;
2468
2469       /* if address of & the result is remat then okay */
2470       if (dic->op == ADDRESS_OF &&
2471           OP_SYMBOL (IC_RESULT (dic))->remat)
2472         continue;
2473
2474       /* if operand has size of three or more & this
2475          operation is a '*','/' or '%' then 'b' may
2476          cause a problem */
2477       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2478           getSize (operandType (op)) >= 3)
2479         return NULL;
2480
2481       /* if left or right or result is in far space */
2482       if (isOperandInFarSpace (IC_LEFT (dic)) ||
2483           isOperandInFarSpace (IC_RIGHT (dic)) ||
2484           isOperandInFarSpace (IC_RESULT (dic)) ||
2485           IS_OP_RUONLY (IC_LEFT (dic)) ||
2486           IS_OP_RUONLY (IC_RIGHT (dic)) ||
2487           IS_OP_RUONLY (IC_RESULT (dic)))
2488         {
2489           return NULL;
2490         }
2491     }
2492
2493   OP_SYMBOL (op)->ruonly = 1;
2494   return sic;
2495
2496 }
2497
2498 /*-----------------------------------------------------------------*/
2499 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2500 /*-----------------------------------------------------------------*/
2501 static bool
2502 isBitwiseOptimizable (iCode * ic)
2503 {
2504   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2505   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2506
2507   debugLog ("%s\n", __FUNCTION__);
2508   /* bitwise operations are considered optimizable
2509      under the following conditions (Jean-Louis VERN) 
2510
2511      x & lit
2512      bit & bit
2513      bit & x
2514      bit ^ bit
2515      bit ^ x
2516      x   ^ lit
2517      x   | lit
2518      bit | bit
2519      bit | x
2520    */
2521   if (IS_LITERAL (rtype) ||
2522       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2523     return TRUE;
2524   else
2525     return FALSE;
2526 }
2527
2528 /*-----------------------------------------------------------------*/
2529 /* packRegsForAccUse - pack registers for acc use                  */
2530 /*-----------------------------------------------------------------*/
2531 static void
2532 packRegsForAccUse (iCode * ic)
2533 {
2534   iCode *uic;
2535
2536   debugLog ("%s\n", __FUNCTION__);
2537   /* if + or - then it has to be one byte result */
2538   if ((ic->op == '+' || ic->op == '-')
2539       && getSize (operandType (IC_RESULT (ic))) > 1)
2540     return;
2541
2542   /* if shift operation make sure right side is not a literal */
2543   if (ic->op == RIGHT_OP &&
2544       (isOperandLiteral (IC_RIGHT (ic)) ||
2545        getSize (operandType (IC_RESULT (ic))) > 1))
2546     return;
2547
2548   if (ic->op == LEFT_OP &&
2549       (isOperandLiteral (IC_RIGHT (ic)) ||
2550        getSize (operandType (IC_RESULT (ic))) > 1))
2551     return;
2552
2553   if (IS_BITWISE_OP (ic) &&
2554       getSize (operandType (IC_RESULT (ic))) > 1)
2555     return;
2556
2557
2558   /* has only one definition */
2559   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2560     return;
2561
2562   /* has only one use */
2563   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2564     return;
2565
2566   /* and the usage immediately follows this iCode */
2567   if (!(uic = hTabItemWithKey (iCodehTab,
2568                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2569     return;
2570
2571   if (ic->next != uic)
2572     return;
2573
2574   /* if it is a conditional branch then we definitely can */
2575   if (uic->op == IFX)
2576     goto accuse;
2577
2578   if (uic->op == JUMPTABLE)
2579     return;
2580
2581   /* if the usage is not is an assignment
2582      or an arithmetic / bitwise / shift operation then not */
2583   if (POINTER_SET (uic) &&
2584       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2585     return;
2586
2587   if (uic->op != '=' &&
2588       !IS_ARITHMETIC_OP (uic) &&
2589       !IS_BITWISE_OP (uic) &&
2590       uic->op != LEFT_OP &&
2591       uic->op != RIGHT_OP)
2592     return;
2593
2594   /* if used in ^ operation then make sure right is not a 
2595      literl */
2596   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2597     return;
2598
2599   /* if shift operation make sure right side is not a literal */
2600   if (uic->op == RIGHT_OP &&
2601       (isOperandLiteral (IC_RIGHT (uic)) ||
2602        getSize (operandType (IC_RESULT (uic))) > 1))
2603     return;
2604
2605   if (uic->op == LEFT_OP &&
2606       (isOperandLiteral (IC_RIGHT (uic)) ||
2607        getSize (operandType (IC_RESULT (uic))) > 1))
2608     return;
2609
2610   /* make sure that the result of this icode is not on the
2611      stack, since acc is used to compute stack offset */
2612   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2613       OP_SYMBOL (IC_RESULT (uic))->onStack)
2614     return;
2615
2616   /* if either one of them in far space then we cannot */
2617   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2618        isOperandInFarSpace (IC_LEFT (uic))) ||
2619       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2620        isOperandInFarSpace (IC_RIGHT (uic))))
2621     return;
2622
2623   /* if the usage has only one operand then we can */
2624   if (IC_LEFT (uic) == NULL ||
2625       IC_RIGHT (uic) == NULL)
2626     goto accuse;
2627
2628   /* make sure this is on the left side if not
2629      a '+' since '+' is commutative */
2630   if (ic->op != '+' &&
2631       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2632     return;
2633
2634   /* if one of them is a literal then we can */
2635   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2636       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2637     {
2638       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2639       return;
2640     }
2641
2642   /* if the other one is not on stack then we can */
2643   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2644       (IS_ITEMP (IC_RIGHT (uic)) ||
2645        (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2646         !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
2647     goto accuse;
2648
2649   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2650       (IS_ITEMP (IC_LEFT (uic)) ||
2651        (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2652         !OP_SYMBOL (IC_LEFT (uic))->onStack)))
2653     goto accuse;
2654
2655   return;
2656
2657 accuse:
2658   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2659
2660
2661 }
2662
2663 /*-----------------------------------------------------------------*/
2664 /* packForPush - hueristics to reduce iCode for pushing            */
2665 /*-----------------------------------------------------------------*/
2666 static void
2667 packForReceive (iCode * ic, eBBlock * ebp)
2668 {
2669   iCode *dic;
2670
2671   debugLog ("%s\n", __FUNCTION__);
2672   debugAopGet ("  result:", IC_RESULT (ic));
2673   debugAopGet ("  left:", IC_LEFT (ic));
2674   debugAopGet ("  right:", IC_RIGHT (ic));
2675
2676   if (!ic->next)
2677     return;
2678
2679   for (dic = ic->next; dic; dic = dic->next)
2680     {
2681
2682
2683
2684       if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
2685         debugLog ("    used on left\n");
2686       if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
2687         debugLog ("    used on right\n");
2688       if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
2689         debugLog ("    used on result\n");
2690
2691       if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
2692           (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
2693         return;
2694
2695     }
2696
2697   debugLog ("  hey we can remove this unnecessary assign\n");
2698 }
2699 /*-----------------------------------------------------------------*/
2700 /* packForPush - hueristics to reduce iCode for pushing            */
2701 /*-----------------------------------------------------------------*/
2702 static void
2703 packForPush (iCode * ic, eBBlock * ebp)
2704 {
2705   iCode *dic;
2706
2707   debugLog ("%s\n", __FUNCTION__);
2708   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2709     return;
2710
2711   /* must have only definition & one usage */
2712   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2713       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2714     return;
2715
2716   /* find the definition */
2717   if (!(dic = hTabItemWithKey (iCodehTab,
2718                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2719     return;
2720
2721   if (dic->op != '=' || POINTER_SET (dic))
2722     return;
2723
2724   /* we now we know that it has one & only one def & use
2725      and the that the definition is an assignment */
2726   IC_LEFT (ic) = IC_RIGHT (dic);
2727
2728   remiCodeFromeBBlock (ebp, dic);
2729   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2730 }
2731
2732 /*-----------------------------------------------------------------*/
2733 /* packRegisters - does some transformations to reduce register    */
2734 /*                   pressure                                      */
2735 /*-----------------------------------------------------------------*/
2736 static void
2737 packRegisters (eBBlock * ebp)
2738 {
2739   iCode *ic;
2740   int change = 0;
2741
2742   debugLog ("%s\n", __FUNCTION__);
2743
2744   while (1)
2745     {
2746
2747       change = 0;
2748
2749       /* look for assignments of the form */
2750       /* iTempNN = TRueSym (someoperation) SomeOperand */
2751       /*       ....                       */
2752       /* TrueSym := iTempNN:1             */
2753       for (ic = ebp->sch; ic; ic = ic->next)
2754         {
2755
2756           /* find assignment of the form TrueSym := iTempNN:1 */
2757           if (ic->op == '=' && !POINTER_SET (ic))
2758             change += packRegsForAssign (ic, ebp);
2759           /* debug stuff */
2760           if (ic->op == '=')
2761             {
2762               if (POINTER_SET (ic))
2763                 debugLog ("pointer is set\n");
2764               debugAopGet ("  result:", IC_RESULT (ic));
2765               debugAopGet ("  left:", IC_LEFT (ic));
2766               debugAopGet ("  right:", IC_RIGHT (ic));
2767             }
2768
2769         }
2770
2771       if (!change)
2772         break;
2773     }
2774
2775   for (ic = ebp->sch; ic; ic = ic->next)
2776     {
2777
2778       /* if this is an itemp & result of a address of a true sym 
2779          then mark this as rematerialisable   */
2780       if (ic->op == ADDRESS_OF &&
2781           IS_ITEMP (IC_RESULT (ic)) &&
2782           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2783           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2784           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2785         {
2786
2787           debugLog ("  %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
2788
2789           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2790           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2791           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2792
2793         }
2794
2795       /* if straight assignment then carry remat flag if
2796          this is the only definition */
2797       if (ic->op == '=' &&
2798           !POINTER_SET (ic) &&
2799           IS_SYMOP (IC_RIGHT (ic)) &&
2800           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2801           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2802         {
2803           debugLog ("  %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
2804
2805           OP_SYMBOL (IC_RESULT (ic))->remat =
2806             OP_SYMBOL (IC_RIGHT (ic))->remat;
2807           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2808             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2809         }
2810
2811       /* if this is a +/- operation with a rematerizable 
2812          then mark this as rematerializable as well */
2813       if ((ic->op == '+' || ic->op == '-') &&
2814           (IS_SYMOP (IC_LEFT (ic)) &&
2815            IS_ITEMP (IC_RESULT (ic)) &&
2816            OP_SYMBOL (IC_LEFT (ic))->remat &&
2817            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2818            IS_OP_LITERAL (IC_RIGHT (ic))))
2819         {
2820           debugLog ("  %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
2821           //int i = 
2822           operandLitValue (IC_RIGHT (ic));
2823           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2824           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2825           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2826         }
2827
2828       /* mark the pointer usages */
2829       if (POINTER_SET (ic))
2830         {
2831           OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2832           debugLog ("  marking as a pointer (set) =>");
2833           debugAopGet ("  result:", IC_RESULT (ic));
2834         }
2835       if (POINTER_GET (ic))
2836         {
2837           OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2838           debugLog ("  marking as a pointer (get) =>");
2839           debugAopGet ("  left:", IC_LEFT (ic));
2840         }
2841
2842       if (!SKIP_IC2 (ic))
2843         {
2844           /* if we are using a symbol on the stack
2845              then we should say pic14_ptrRegReq */
2846           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2847             pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2848                                  OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2849           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2850             pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2851                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2852           else
2853             {
2854               if (IS_SYMOP (IC_LEFT (ic)))
2855                 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2856                                 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2857               if (IS_SYMOP (IC_RIGHT (ic)))
2858                 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2859                                OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2860               if (IS_SYMOP (IC_RESULT (ic)))
2861                 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2862                               OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2863             }
2864         }
2865
2866       /* if the condition of an if instruction
2867          is defined in the previous instruction then
2868          mark the itemp as a conditional */
2869       if ((IS_CONDITIONAL (ic) ||
2870            ((ic->op == BITWISEAND ||
2871              ic->op == '|' ||
2872              ic->op == '^') &&
2873             isBitwiseOptimizable (ic))) &&
2874           ic->next && ic->next->op == IFX &&
2875           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2876           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2877         {
2878
2879           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2880           continue;
2881         }
2882
2883       /* reduce for support function calls */
2884       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2885         packRegsForSupport (ic, ebp);
2886
2887       /* if a parameter is passed, it's in W, so we may not
2888          need to place a copy in a register */
2889       if (ic->op == RECEIVE)
2890         packForReceive (ic, ebp);
2891
2892       /* some cases the redundant moves can
2893          can be eliminated for return statements */
2894       if ((ic->op == RETURN || ic->op == SEND) &&
2895           !isOperandInFarSpace (IC_LEFT (ic)) &&
2896           !options.model)
2897         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2898
2899       /* if pointer set & left has a size more than
2900          one and right is not in far space */
2901       if (POINTER_SET (ic) &&
2902           !isOperandInFarSpace (IC_RIGHT (ic)) &&
2903           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2904           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2905           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2906
2907         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2908
2909       /* if pointer get */
2910       if (POINTER_GET (ic) &&
2911           !isOperandInFarSpace (IC_RESULT (ic)) &&
2912           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2913           !IS_OP_RUONLY (IC_RESULT (ic)) &&
2914           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2915
2916         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2917
2918
2919       /* if this is cast for intergral promotion then
2920          check if only use of  the definition of the 
2921          operand being casted/ if yes then replace
2922          the result of that arithmetic operation with 
2923          this result and get rid of the cast */
2924       if (ic->op == CAST)
2925         {
2926           sym_link *fromType = operandType (IC_RIGHT (ic));
2927           sym_link *toType = operandType (IC_LEFT (ic));
2928
2929           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2930               getSize (fromType) != getSize (toType))
2931             {
2932
2933               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2934               if (dic)
2935                 {
2936                   if (IS_ARITHMETIC_OP (dic))
2937                     {
2938                       IC_RESULT (dic) = IC_RESULT (ic);
2939                       remiCodeFromeBBlock (ebp, ic);
2940                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2941                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2942                       ic = ic->prev;
2943                     }
2944                   else
2945                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2946                 }
2947             }
2948           else
2949             {
2950
2951               /* if the type from and type to are the same
2952                  then if this is the only use then packit */
2953               if (compareType (operandType (IC_RIGHT (ic)),
2954                              operandType (IC_LEFT (ic))) == 1)
2955                 {
2956                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2957                   if (dic)
2958                     {
2959                       IC_RESULT (dic) = IC_RESULT (ic);
2960                       remiCodeFromeBBlock (ebp, ic);
2961                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2962                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2963                       ic = ic->prev;
2964                     }
2965                 }
2966             }
2967         }
2968
2969       /* pack for PUSH 
2970          iTempNN := (some variable in farspace) V1
2971          push iTempNN ;
2972          -------------
2973          push V1
2974        */
2975       if (ic->op == IPUSH)
2976         {
2977           packForPush (ic, ebp);
2978         }
2979
2980
2981       /* pack registers for accumulator use, when the
2982          result of an arithmetic or bit wise operation
2983          has only one use, that use is immediately following
2984          the defintion and the using iCode has only one
2985          operand or has two operands but one is literal &
2986          the result of that operation is not on stack then
2987          we can leave the result of this operation in acc:b
2988          combination */
2989       if ((IS_ARITHMETIC_OP (ic)
2990
2991            || IS_BITWISE_OP (ic)
2992
2993            || ic->op == LEFT_OP || ic->op == RIGHT_OP
2994
2995           ) &&
2996           IS_ITEMP (IC_RESULT (ic)) &&
2997           getSize (operandType (IC_RESULT (ic))) <= 2)
2998
2999         packRegsForAccUse (ic);
3000
3001     }
3002 }
3003
3004 static void
3005 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3006 {
3007   int i;
3008
3009   if (!debug || !debugF)
3010     return;
3011
3012   for (i = 0; i < count; i++)
3013     {
3014       fprintf (debugF, "\n----------------------------------------------------------------\n");
3015       fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3016                ebbs[i]->entryLabel->name,
3017                ebbs[i]->depth,
3018                ebbs[i]->noPath,
3019                ebbs[i]->isLastInLoop);
3020       fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3021                ebbs[i]->dfnum,
3022                ebbs[i]->bbnum,
3023                ebbs[i]->fSeq,
3024                ebbs[i]->lSeq);
3025       fprintf (debugF, "visited %d : hasFcall = %d\n",
3026                ebbs[i]->visited,
3027                ebbs[i]->hasFcall);
3028
3029       fprintf (debugF, "\ndefines bitVector :");
3030       bitVectDebugOn (ebbs[i]->defSet, debugF);
3031       fprintf (debugF, "\nlocal defines bitVector :");
3032       bitVectDebugOn (ebbs[i]->ldefs, debugF);
3033       fprintf (debugF, "\npointers Set bitvector :");
3034       bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3035       fprintf (debugF, "\nin pointers Set bitvector :");
3036       bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3037       fprintf (debugF, "\ninDefs Set bitvector :");
3038       bitVectDebugOn (ebbs[i]->inDefs, debugF);
3039       fprintf (debugF, "\noutDefs Set bitvector :");
3040       bitVectDebugOn (ebbs[i]->outDefs, debugF);
3041       fprintf (debugF, "\nusesDefs Set bitvector :");
3042       bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3043       fprintf (debugF, "\n----------------------------------------------------------------\n");
3044       printiCChain (ebbs[i]->sch, debugF);
3045     }
3046 }
3047 /*-----------------------------------------------------------------*/
3048 /* assignRegisters - assigns registers to each live range as need  */
3049 /*-----------------------------------------------------------------*/
3050 void
3051 pic14_assignRegisters (eBBlock ** ebbs, int count)
3052 {
3053   iCode *ic;
3054   int i;
3055
3056   debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3057   debugLog ("ebbs before optimizing:\n");
3058   dumpEbbsToDebug (ebbs, count);
3059
3060   setToNull ((void *) &_G.funcrUsed);
3061   pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3062
3063
3064   /* change assignments this will remove some
3065      live ranges reducing some register pressure */
3066   for (i = 0; i < count; i++)
3067     packRegisters (ebbs[i]);
3068
3069   if (options.dump_pack)
3070     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3071
3072   /* first determine for each live range the number of 
3073      registers & the type of registers required for each */
3074   regTypeNum ();
3075
3076   /* and serially allocate registers */
3077   serialRegAssign (ebbs, count);
3078
3079   /* if stack was extended then tell the user */
3080   if (_G.stackExtend)
3081     {
3082 /*      werror(W_TOOMANY_SPILS,"stack", */
3083 /*             _G.stackExtend,currFunc->name,""); */
3084       _G.stackExtend = 0;
3085     }
3086
3087   if (_G.dataExtend)
3088     {
3089 /*      werror(W_TOOMANY_SPILS,"data space", */
3090 /*             _G.dataExtend,currFunc->name,""); */
3091       _G.dataExtend = 0;
3092     }
3093
3094   /* after that create the register mask
3095      for each of the instruction */
3096   createRegMask (ebbs, count);
3097
3098   /* redo that offsets for stacked automatic variables */
3099   redoStackOffsets ();
3100
3101   if (options.dump_rassgn)
3102     dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3103
3104   /* now get back the chain */
3105   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3106
3107   debugLog ("ebbs after optimizing:\n");
3108   dumpEbbsToDebug (ebbs, count);
3109
3110
3111   genpic14Code (ic);
3112
3113   /* free up any _G.stackSpil locations allocated */
3114   applyToSet (_G.stackSpil, deallocStackSpil);
3115   _G.slocNum = 0;
3116   setToNull ((void **) &_G.stackSpil);
3117   setToNull ((void **) &_G.spiltSet);
3118   /* mark all registers as free */
3119   pic14_freeAllRegs ();
3120
3121   debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
3122   debugLogClose ();
3123   return;
3124 }