Signed comparisons are now working (except for signed longs)
[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\n", __FUNCTION__);
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
1613               for (j = 0; j < sym->nRegs; j++)
1614                 {
1615                   if (sym->regType == REG_PTR)
1616                     sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
1617                   else
1618                     sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
1619
1620                   /* if the allocation falied which means
1621                      this was spilt then break */
1622                   if (!sym->regs[j])
1623                     break;
1624                 }
1625               debugLog ("  %d - \n", __LINE__);
1626
1627               /* if it shares registers with operands make sure
1628                  that they are in the same position */
1629               if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
1630                   OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
1631                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1632                               OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
1633               /* do the same for the right operand */
1634               if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
1635                   OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
1636                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
1637                               OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
1638
1639               debugLog ("  %d - \n", __LINE__);
1640               if (ptrRegSet)
1641                 {
1642                   debugLog ("  %d - \n", __LINE__);
1643                   pic14_ptrRegReq--;
1644                   ptrRegSet = 0;
1645                 }
1646
1647             }
1648         }
1649     }
1650 }
1651
1652 /*-----------------------------------------------------------------*/
1653 /* rUmaskForOp :- returns register mask for an operand             */
1654 /*-----------------------------------------------------------------*/
1655 static bitVect *
1656 rUmaskForOp (operand * op)
1657 {
1658   bitVect *rumask;
1659   symbol *sym;
1660   int j;
1661
1662   debugLog ("%s\n", __FUNCTION__);
1663   /* only temporaries are assigned registers */
1664   if (!IS_ITEMP (op))
1665     return NULL;
1666
1667   sym = OP_SYMBOL (op);
1668
1669   /* if spilt or no registers assigned to it
1670      then nothing */
1671   if (sym->isspilt || !sym->nRegs)
1672     return NULL;
1673
1674   rumask = newBitVect (pic14_nRegs);
1675
1676   for (j = 0; j < sym->nRegs; j++)
1677     {
1678       rumask = bitVectSetBit (rumask,
1679                               sym->regs[j]->rIdx);
1680     }
1681
1682   return rumask;
1683 }
1684
1685 /*-----------------------------------------------------------------*/
1686 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
1687 /*-----------------------------------------------------------------*/
1688 static bitVect *
1689 regsUsedIniCode (iCode * ic)
1690 {
1691   bitVect *rmask = newBitVect (pic14_nRegs);
1692
1693   debugLog ("%s\n", __FUNCTION__);
1694   /* do the special cases first */
1695   if (ic->op == IFX)
1696     {
1697       rmask = bitVectUnion (rmask,
1698                             rUmaskForOp (IC_COND (ic)));
1699       goto ret;
1700     }
1701
1702   /* for the jumptable */
1703   if (ic->op == JUMPTABLE)
1704     {
1705       rmask = bitVectUnion (rmask,
1706                             rUmaskForOp (IC_JTCOND (ic)));
1707
1708       goto ret;
1709     }
1710
1711   /* of all other cases */
1712   if (IC_LEFT (ic))
1713     rmask = bitVectUnion (rmask,
1714                           rUmaskForOp (IC_LEFT (ic)));
1715
1716
1717   if (IC_RIGHT (ic))
1718     rmask = bitVectUnion (rmask,
1719                           rUmaskForOp (IC_RIGHT (ic)));
1720
1721   if (IC_RESULT (ic))
1722     rmask = bitVectUnion (rmask,
1723                           rUmaskForOp (IC_RESULT (ic)));
1724
1725 ret:
1726   return rmask;
1727 }
1728
1729 /*-----------------------------------------------------------------*/
1730 /* createRegMask - for each instruction will determine the regsUsed */
1731 /*-----------------------------------------------------------------*/
1732 static void
1733 createRegMask (eBBlock ** ebbs, int count)
1734 {
1735   int i;
1736
1737   debugLog ("%s\n", __FUNCTION__);
1738   /* for all blocks */
1739   for (i = 0; i < count; i++)
1740     {
1741       iCode *ic;
1742
1743       if (ebbs[i]->noPath &&
1744           (ebbs[i]->entryLabel != entryLabel &&
1745            ebbs[i]->entryLabel != returnLabel))
1746         continue;
1747
1748       /* for all instructions */
1749       for (ic = ebbs[i]->sch; ic; ic = ic->next)
1750         {
1751
1752           int j;
1753
1754           if (SKIP_IC2 (ic) || !ic->rlive)
1755             continue;
1756
1757           /* first mark the registers used in this
1758              instruction */
1759           ic->rUsed = regsUsedIniCode (ic);
1760           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
1761
1762           /* now create the register mask for those 
1763              registers that are in use : this is a
1764              super set of ic->rUsed */
1765           ic->rMask = newBitVect (pic14_nRegs + 1);
1766
1767           /* for all live Ranges alive at this point */
1768           for (j = 1; j < ic->rlive->size; j++)
1769             {
1770               symbol *sym;
1771               int k;
1772
1773               /* if not alive then continue */
1774               if (!bitVectBitValue (ic->rlive, j))
1775                 continue;
1776
1777               /* find the live range we are interested in */
1778               if (!(sym = hTabItemWithKey (liveRanges, j)))
1779                 {
1780                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1781                           "createRegMask cannot find live range");
1782                   exit (0);
1783                 }
1784
1785               /* if no register assigned to it */
1786               if (!sym->nRegs || sym->isspilt)
1787                 continue;
1788
1789               /* for all the registers allocated to it */
1790               for (k = 0; k < sym->nRegs; k++)
1791                 if (sym->regs[k])
1792                   ic->rMask =
1793                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
1794             }
1795         }
1796     }
1797 }
1798
1799 /*-----------------------------------------------------------------*/
1800 /* rematStr - returns the rematerialized string for a remat var    */
1801 /*-----------------------------------------------------------------*/
1802 static char *
1803 rematStr (symbol * sym)
1804 {
1805   char *s = buffer;
1806   iCode *ic = sym->rematiCode;
1807
1808   debugLog ("%s\n", __FUNCTION__);
1809   while (1)
1810     {
1811
1812       printf ("%s\n", s);
1813       /* if plus or minus print the right hand side */
1814 /*
1815    if (ic->op == '+' || ic->op == '-') {
1816    sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
1817    ic->op );
1818    s += strlen(s);
1819    ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1820    continue ;
1821    }
1822  */
1823       if (ic->op == '+' || ic->op == '-')
1824         {
1825           iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
1826           sprintf (s, "(%s %c 0x%04x)",
1827                    OP_SYMBOL (IC_LEFT (ric))->rname,
1828                    ic->op,
1829                    (int) operandLitValue (IC_RIGHT (ic)));
1830
1831           //s += strlen(s);
1832           //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
1833           //continue ;
1834           return buffer;
1835         }
1836
1837       /* we reached the end */
1838       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
1839       break;
1840     }
1841
1842   printf ("%s\n", buffer);
1843   return buffer;
1844 }
1845
1846 /*-----------------------------------------------------------------*/
1847 /* regTypeNum - computes the type & number of registers required   */
1848 /*-----------------------------------------------------------------*/
1849 static void
1850 regTypeNum ()
1851 {
1852   symbol *sym;
1853   int k;
1854   iCode *ic;
1855
1856   debugLog ("%s\n", __FUNCTION__);
1857   /* for each live range do */
1858   for (sym = hTabFirstItem (liveRanges, &k); sym;
1859        sym = hTabNextItem (liveRanges, &k))
1860     {
1861
1862       debugLog ("  %d - %s\n", __LINE__, sym->rname);
1863
1864       /* if used zero times then no registers needed */
1865       if ((sym->liveTo - sym->liveFrom) == 0)
1866         continue;
1867
1868
1869       /* if the live range is a temporary */
1870       if (sym->isitmp)
1871         {
1872
1873           debugLog ("  %d - \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             {
1883               if (IS_AGGREGATE (sym->type) || sym->isptr)
1884                 sym->type = aggrToPtr (sym->type, FALSE);
1885               debugLog ("  %d - \n", __LINE__);
1886
1887               continue;
1888             }
1889
1890           /* if the symbol has only one definition &
1891              that definition is a get_pointer and the
1892              pointer we are getting is rematerializable and
1893              in "data" space */
1894
1895           if (bitVectnBitsOn (sym->defs) == 1 &&
1896               (ic = hTabItemWithKey (iCodehTab,
1897                                      bitVectFirstBit (sym->defs))) &&
1898               POINTER_GET (ic) &&
1899               !sym->noSpilLoc &&
1900               !IS_BITVAR (sym->etype))
1901             {
1902
1903               debugLog ("  %d - \n", __LINE__);
1904
1905               /* if remat in data space */
1906               if (OP_SYMBOL (IC_LEFT (ic))->remat &&
1907                   DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER)
1908                 {
1909
1910                   /* create a psuedo symbol & force a spil */
1911                   symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
1912                   psym->type = sym->type;
1913                   psym->etype = sym->etype;
1914                   strcpy (psym->rname, psym->name);
1915                   sym->isspilt = 1;
1916                   sym->usl.spillLoc = psym;
1917                   continue;
1918                 }
1919
1920               /* if in data space or idata space then try to
1921                  allocate pointer register */
1922
1923             }
1924
1925           /* if not then we require registers */
1926           sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
1927                         getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
1928                         getSize (sym->type));
1929
1930           if (sym->nRegs > 4)
1931             {
1932               fprintf (stderr, "allocated more than 4 or 0 registers for type ");
1933               printTypeChain (sym->type, stderr);
1934               fprintf (stderr, "\n");
1935             }
1936
1937           debugLog ("  %d - \n", __LINE__);
1938
1939           /* determine the type of register required */
1940           if (sym->nRegs == 1 &&
1941               IS_PTR (sym->type) &&
1942               sym->uptr)
1943             sym->regType = REG_PTR;
1944           else
1945             sym->regType = REG_GPR;
1946           debugLog ("  reg type %s\n", debugLogRegType (sym->regType));
1947
1948         }
1949       else
1950         /* for the first run we don't provide */
1951         /* registers for true symbols we will */
1952         /* see how things go                  */
1953         sym->nRegs = 0;
1954     }
1955
1956 }
1957
1958 /*-----------------------------------------------------------------*/
1959 /* freeAllRegs - mark all registers as free                        */
1960 /*-----------------------------------------------------------------*/
1961 void
1962 pic14_freeAllRegs ()
1963 {
1964   int i;
1965
1966   debugLog ("%s\n", __FUNCTION__);
1967   for (i = 0; i < pic14_nRegs; i++)
1968     regspic14[i].isFree = 1;
1969 }
1970
1971 /*-----------------------------------------------------------------*/
1972 /*-----------------------------------------------------------------*/
1973 void
1974 pic14_deallocateAllRegs ()
1975 {
1976   int i;
1977
1978   debugLog ("%s\n", __FUNCTION__);
1979   for (i = 0; i < pic14_nRegs; i++) {
1980     regspic14[i].isFree = 1;
1981     regspic14[i].wasUsed = 0;
1982   }
1983 }
1984
1985
1986 /*-----------------------------------------------------------------*/
1987 /* deallocStackSpil - this will set the stack pointer back         */
1988 /*-----------------------------------------------------------------*/
1989 static
1990 DEFSETFUNC (deallocStackSpil)
1991 {
1992   symbol *sym = item;
1993
1994   debugLog ("%s\n", __FUNCTION__);
1995   deallocLocal (sym);
1996   return 0;
1997 }
1998
1999 /*-----------------------------------------------------------------*/
2000 /* farSpacePackable - returns the packable icode for far variables */
2001 /*-----------------------------------------------------------------*/
2002 static iCode *
2003 farSpacePackable (iCode * ic)
2004 {
2005   iCode *dic;
2006
2007   debugLog ("%s\n", __FUNCTION__);
2008   /* go thru till we find a definition for the
2009      symbol on the right */
2010   for (dic = ic->prev; dic; dic = dic->prev)
2011     {
2012
2013       /* if the definition is a call then no */
2014       if ((dic->op == CALL || dic->op == PCALL) &&
2015           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2016         {
2017           return NULL;
2018         }
2019
2020       /* if shift by unknown amount then not */
2021       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2022           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2023         return NULL;
2024
2025       /* if pointer get and size > 1 */
2026       if (POINTER_GET (dic) &&
2027           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2028         return NULL;
2029
2030       if (POINTER_SET (dic) &&
2031           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2032         return NULL;
2033
2034       /* if any three is a true symbol in far space */
2035       if (IC_RESULT (dic) &&
2036           IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2037           isOperandInFarSpace (IC_RESULT (dic)))
2038         return NULL;
2039
2040       if (IC_RIGHT (dic) &&
2041           IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2042           isOperandInFarSpace (IC_RIGHT (dic)) &&
2043           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2044         return NULL;
2045
2046       if (IC_LEFT (dic) &&
2047           IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2048           isOperandInFarSpace (IC_LEFT (dic)) &&
2049           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2050         return NULL;
2051
2052       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2053         {
2054           if ((dic->op == LEFT_OP ||
2055                dic->op == RIGHT_OP ||
2056                dic->op == '-') &&
2057               IS_OP_LITERAL (IC_RIGHT (dic)))
2058             return NULL;
2059           else
2060             return dic;
2061         }
2062     }
2063
2064   return NULL;
2065 }
2066
2067 /*-----------------------------------------------------------------*/
2068 /* packRegsForAssign - register reduction for assignment           */
2069 /*-----------------------------------------------------------------*/
2070 static int
2071 packRegsForAssign (iCode * ic, eBBlock * ebp)
2072 {
2073
2074   iCode *dic, *sic;
2075
2076   debugLog ("%s\n", __FUNCTION__);
2077
2078   debugAopGet ("  result:", IC_RESULT (ic));
2079   debugAopGet ("  left:", IC_LEFT (ic));
2080   debugAopGet ("  right:", IC_RIGHT (ic));
2081
2082   if (!IS_ITEMP (IC_RIGHT (ic)) ||
2083       OP_SYMBOL (IC_RIGHT (ic))->isind ||
2084       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2085     {
2086       return 0;
2087     }
2088
2089   /* if the true symbol is defined in far space or on stack
2090      then we should not since this will increase register pressure */
2091   if (isOperandInFarSpace (IC_RESULT (ic)))
2092     {
2093       if ((dic = farSpacePackable (ic)))
2094         goto pack;
2095       else
2096         return 0;
2097
2098     }
2099   /* find the definition of iTempNN scanning backwards if we find a 
2100      a use of the true symbol before we find the definition then 
2101      we cannot pack */
2102   for (dic = ic->prev; dic; dic = dic->prev)
2103     {
2104
2105       /* if there is a function call and this is
2106          a parameter & not my parameter then don't pack it */
2107       if ((dic->op == CALL || dic->op == PCALL) &&
2108           (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2109            !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2110         {
2111           debugLog ("  %d - \n", __LINE__);
2112           dic = NULL;
2113           break;
2114         }
2115
2116       if (SKIP_IC2 (dic))
2117         continue;
2118
2119       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2120           IS_OP_VOLATILE (IC_RESULT (dic)))
2121         {
2122           debugLog ("  %d - \n", __LINE__);
2123           dic = NULL;
2124           break;
2125         }
2126
2127       if (IS_SYMOP (IC_RESULT (dic)) &&
2128           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2129         {
2130           debugLog ("  %d - dic key == ic key -- pointer set=%c\n", __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2131           if (POINTER_SET (dic))
2132             dic = NULL;
2133
2134           break;
2135         }
2136
2137       if (IS_SYMOP (IC_RIGHT (dic)) &&
2138           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2139            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2140         {
2141           debugLog ("  %d - \n", __LINE__);
2142           dic = NULL;
2143           break;
2144         }
2145
2146       if (IS_SYMOP (IC_LEFT (dic)) &&
2147           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2148            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2149         {
2150           debugLog ("  %d - \n", __LINE__);
2151           dic = NULL;
2152           break;
2153         }
2154
2155       if (POINTER_SET (dic) &&
2156           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2157         {
2158           debugLog ("  %d - \n", __LINE__);
2159           dic = NULL;
2160           break;
2161         }
2162     }
2163
2164   if (!dic)
2165     return 0;                   /* did not find */
2166
2167   /* if the result is on stack or iaccess then it must be
2168      the same atleast one of the operands */
2169   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2170       OP_SYMBOL (IC_RESULT (ic))->iaccess)
2171     {
2172
2173       /* the operation has only one symbol
2174          operator then we can pack */
2175       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2176           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2177         goto pack;
2178
2179       if (!((IC_LEFT (dic) &&
2180              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2181             (IC_RIGHT (dic) &&
2182              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2183         return 0;
2184     }
2185 pack:
2186   debugLog ("  packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2187   /* found the definition */
2188   /* replace the result with the result of */
2189   /* this assignment and remove this assignment */
2190   IC_RESULT (dic) = IC_RESULT (ic);
2191
2192   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2193     {
2194       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2195     }
2196   /* delete from liverange table also 
2197      delete from all the points inbetween and the new
2198      one */
2199   for (sic = dic; sic != ic; sic = sic->next)
2200     {
2201       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2202       if (IS_ITEMP (IC_RESULT (dic)))
2203         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2204     }
2205
2206   remiCodeFromeBBlock (ebp, ic);
2207   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2208   OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2209   return 1;
2210
2211
2212 }
2213
2214 /*-----------------------------------------------------------------*/
2215 /* findAssignToSym : scanning backwards looks for first assig found */
2216 /*-----------------------------------------------------------------*/
2217 static iCode *
2218 findAssignToSym (operand * op, iCode * ic)
2219 {
2220   iCode *dic;
2221
2222   debugLog ("%s\n", __FUNCTION__);
2223   for (dic = ic->prev; dic; dic = dic->prev)
2224     {
2225
2226       /* if definition by assignment */
2227       if (dic->op == '=' &&
2228           !POINTER_SET (dic) &&
2229           IC_RESULT (dic)->key == op->key
2230 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2231         )
2232         {
2233
2234           /* we are interested only if defined in far space */
2235           /* or in stack space in case of + & - */
2236
2237           /* if assigned to a non-symbol then return
2238              true */
2239           if (!IS_SYMOP (IC_RIGHT (dic)))
2240             break;
2241
2242           /* if the symbol is in far space then
2243              we should not */
2244           if (isOperandInFarSpace (IC_RIGHT (dic)))
2245             return NULL;
2246
2247           /* for + & - operations make sure that
2248              if it is on the stack it is the same
2249              as one of the three operands */
2250           if ((ic->op == '+' || ic->op == '-') &&
2251               OP_SYMBOL (IC_RIGHT (dic))->onStack)
2252             {
2253
2254               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2255                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2256                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2257                 return NULL;
2258             }
2259
2260           break;
2261
2262         }
2263
2264       /* if we find an usage then we cannot delete it */
2265       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2266         return NULL;
2267
2268       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2269         return NULL;
2270
2271       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2272         return NULL;
2273     }
2274
2275   /* now make sure that the right side of dic
2276      is not defined between ic & dic */
2277   if (dic)
2278     {
2279       iCode *sic = dic->next;
2280
2281       for (; sic != ic; sic = sic->next)
2282         if (IC_RESULT (sic) &&
2283             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2284           return NULL;
2285     }
2286
2287   return dic;
2288
2289
2290 }
2291
2292 /*-----------------------------------------------------------------*/
2293 /* packRegsForSupport :- reduce some registers for support calls   */
2294 /*-----------------------------------------------------------------*/
2295 static int
2296 packRegsForSupport (iCode * ic, eBBlock * ebp)
2297 {
2298   int change = 0;
2299
2300   debugLog ("%s\n", __FUNCTION__);
2301   /* for the left & right operand :- look to see if the
2302      left was assigned a true symbol in far space in that
2303      case replace them */
2304   if (IS_ITEMP (IC_LEFT (ic)) &&
2305       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2306     {
2307       iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2308       iCode *sic;
2309
2310       if (!dic)
2311         goto right;
2312
2313       debugAopGet ("removing left:", IC_LEFT (ic));
2314
2315       /* found it we need to remove it from the
2316          block */
2317       for (sic = dic; sic != ic; sic = sic->next)
2318         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2319
2320       IC_LEFT (ic)->operand.symOperand =
2321         IC_RIGHT (dic)->operand.symOperand;
2322       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2323       remiCodeFromeBBlock (ebp, dic);
2324       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2325       change++;
2326     }
2327
2328   /* do the same for the right operand */
2329 right:
2330   if (!change &&
2331       IS_ITEMP (IC_RIGHT (ic)) &&
2332       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2333     {
2334       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2335       iCode *sic;
2336
2337       if (!dic)
2338         return change;
2339
2340       /* if this is a subtraction & the result
2341          is a true symbol in far space then don't pack */
2342       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2343         {
2344           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2345           if (IN_FARSPACE (SPEC_OCLS (etype)))
2346             return change;
2347         }
2348
2349       debugAopGet ("removing right:", IC_RIGHT (ic));
2350
2351       /* found it we need to remove it from the
2352          block */
2353       for (sic = dic; sic != ic; sic = sic->next)
2354         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2355
2356       IC_RIGHT (ic)->operand.symOperand =
2357         IC_RIGHT (dic)->operand.symOperand;
2358       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2359
2360       remiCodeFromeBBlock (ebp, dic);
2361       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2362       change++;
2363     }
2364
2365   return change;
2366 }
2367
2368 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2369
2370
2371 /*-----------------------------------------------------------------*/
2372 /* packRegsForOneuse : - will reduce some registers for single Use */
2373 /*-----------------------------------------------------------------*/
2374 static iCode *
2375 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2376 {
2377   bitVect *uses;
2378   iCode *dic, *sic;
2379
2380   debugLog ("%s\n", __FUNCTION__);
2381   /* if returning a literal then do nothing */
2382   if (!IS_SYMOP (op))
2383     return NULL;
2384
2385   /* only upto 2 bytes since we cannot predict
2386      the usage of b, & acc */
2387   if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
2388       ic->op != RETURN &&
2389       ic->op != SEND)
2390     return NULL;
2391
2392   /* this routine will mark the a symbol as used in one 
2393      instruction use only && if the definition is local 
2394      (ie. within the basic block) && has only one definition &&
2395      that definition is either a return value from a 
2396      function or does not contain any variables in
2397      far space */
2398   uses = bitVectCopy (OP_USES (op));
2399   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
2400   if (!bitVectIsZero (uses))    /* has other uses */
2401     return NULL;
2402
2403   /* if it has only one defintion */
2404   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2405     return NULL;                /* has more than one definition */
2406
2407   /* get that definition */
2408   if (!(dic =
2409         hTabItemWithKey (iCodehTab,
2410                          bitVectFirstBit (OP_DEFS (op)))))
2411     return NULL;
2412
2413   /* found the definition now check if it is local */
2414   if (dic->seq < ebp->fSeq ||
2415       dic->seq > ebp->lSeq)
2416     return NULL;                /* non-local */
2417
2418   /* now check if it is the return from
2419      a function call */
2420   if (dic->op == CALL || dic->op == PCALL)
2421     {
2422       if (ic->op != SEND && ic->op != RETURN)
2423         {
2424           OP_SYMBOL (op)->ruonly = 1;
2425           return dic;
2426         }
2427       dic = dic->next;
2428     }
2429
2430
2431   /* otherwise check that the definition does
2432      not contain any symbols in far space */
2433   if (isOperandInFarSpace (IC_LEFT (dic)) ||
2434       isOperandInFarSpace (IC_RIGHT (dic)) ||
2435       IS_OP_RUONLY (IC_LEFT (ic)) ||
2436       IS_OP_RUONLY (IC_RIGHT (ic)))
2437     {
2438       return NULL;
2439     }
2440
2441   /* if pointer set then make sure the pointer
2442      is one byte */
2443   if (POINTER_SET (dic) &&
2444       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2445     return NULL;
2446
2447   if (POINTER_GET (dic) &&
2448       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2449     return NULL;
2450
2451   sic = dic;
2452
2453   /* also make sure the intervenening instructions
2454      don't have any thing in far space */
2455   for (dic = dic->next; dic && dic != ic; dic = dic->next)
2456     {
2457
2458       /* if there is an intervening function call then no */
2459       if (dic->op == CALL || dic->op == PCALL)
2460         return NULL;
2461       /* if pointer set then make sure the pointer
2462          is one byte */
2463       if (POINTER_SET (dic) &&
2464           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2465         return NULL;
2466
2467       if (POINTER_GET (dic) &&
2468           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2469         return NULL;
2470
2471       /* if address of & the result is remat then okay */
2472       if (dic->op == ADDRESS_OF &&
2473           OP_SYMBOL (IC_RESULT (dic))->remat)
2474         continue;
2475
2476       /* if operand has size of three or more & this
2477          operation is a '*','/' or '%' then 'b' may
2478          cause a problem */
2479       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2480           getSize (operandType (op)) >= 3)
2481         return NULL;
2482
2483       /* if left or right or result is in far space */
2484       if (isOperandInFarSpace (IC_LEFT (dic)) ||
2485           isOperandInFarSpace (IC_RIGHT (dic)) ||
2486           isOperandInFarSpace (IC_RESULT (dic)) ||
2487           IS_OP_RUONLY (IC_LEFT (dic)) ||
2488           IS_OP_RUONLY (IC_RIGHT (dic)) ||
2489           IS_OP_RUONLY (IC_RESULT (dic)))
2490         {
2491           return NULL;
2492         }
2493     }
2494
2495   OP_SYMBOL (op)->ruonly = 1;
2496   return sic;
2497
2498 }
2499
2500 /*-----------------------------------------------------------------*/
2501 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2502 /*-----------------------------------------------------------------*/
2503 static bool
2504 isBitwiseOptimizable (iCode * ic)
2505 {
2506   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2507   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2508
2509   debugLog ("%s\n", __FUNCTION__);
2510   /* bitwise operations are considered optimizable
2511      under the following conditions (Jean-Louis VERN) 
2512
2513      x & lit
2514      bit & bit
2515      bit & x
2516      bit ^ bit
2517      bit ^ x
2518      x   ^ lit
2519      x   | lit
2520      bit | bit
2521      bit | x
2522    */
2523   if (IS_LITERAL (rtype) ||
2524       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2525     return TRUE;
2526   else
2527     return FALSE;
2528 }
2529
2530 /*-----------------------------------------------------------------*/
2531 /* packRegsForAccUse - pack registers for acc use                  */
2532 /*-----------------------------------------------------------------*/
2533 static void
2534 packRegsForAccUse (iCode * ic)
2535 {
2536   iCode *uic;
2537
2538   debugLog ("%s\n", __FUNCTION__);
2539   /* if + or - then it has to be one byte result */
2540   if ((ic->op == '+' || ic->op == '-')
2541       && getSize (operandType (IC_RESULT (ic))) > 1)
2542     return;
2543
2544   /* if shift operation make sure right side is not a literal */
2545   if (ic->op == RIGHT_OP &&
2546       (isOperandLiteral (IC_RIGHT (ic)) ||
2547        getSize (operandType (IC_RESULT (ic))) > 1))
2548     return;
2549
2550   if (ic->op == LEFT_OP &&
2551       (isOperandLiteral (IC_RIGHT (ic)) ||
2552        getSize (operandType (IC_RESULT (ic))) > 1))
2553     return;
2554
2555   if (IS_BITWISE_OP (ic) &&
2556       getSize (operandType (IC_RESULT (ic))) > 1)
2557     return;
2558
2559
2560   /* has only one definition */
2561   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2562     return;
2563
2564   /* has only one use */
2565   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2566     return;
2567
2568   /* and the usage immediately follows this iCode */
2569   if (!(uic = hTabItemWithKey (iCodehTab,
2570                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2571     return;
2572
2573   if (ic->next != uic)
2574     return;
2575
2576   /* if it is a conditional branch then we definitely can */
2577   if (uic->op == IFX)
2578     goto accuse;
2579
2580   if (uic->op == JUMPTABLE)
2581     return;
2582
2583   /* if the usage is not is an assignment
2584      or an arithmetic / bitwise / shift operation then not */
2585   if (POINTER_SET (uic) &&
2586       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2587     return;
2588
2589   if (uic->op != '=' &&
2590       !IS_ARITHMETIC_OP (uic) &&
2591       !IS_BITWISE_OP (uic) &&
2592       uic->op != LEFT_OP &&
2593       uic->op != RIGHT_OP)
2594     return;
2595
2596   /* if used in ^ operation then make sure right is not a 
2597      literl */
2598   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2599     return;
2600
2601   /* if shift operation make sure right side is not a literal */
2602   if (uic->op == RIGHT_OP &&
2603       (isOperandLiteral (IC_RIGHT (uic)) ||
2604        getSize (operandType (IC_RESULT (uic))) > 1))
2605     return;
2606
2607   if (uic->op == LEFT_OP &&
2608       (isOperandLiteral (IC_RIGHT (uic)) ||
2609        getSize (operandType (IC_RESULT (uic))) > 1))
2610     return;
2611
2612   /* make sure that the result of this icode is not on the
2613      stack, since acc is used to compute stack offset */
2614   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2615       OP_SYMBOL (IC_RESULT (uic))->onStack)
2616     return;
2617
2618   /* if either one of them in far space then we cannot */
2619   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2620        isOperandInFarSpace (IC_LEFT (uic))) ||
2621       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2622        isOperandInFarSpace (IC_RIGHT (uic))))
2623     return;
2624
2625   /* if the usage has only one operand then we can */
2626   if (IC_LEFT (uic) == NULL ||
2627       IC_RIGHT (uic) == NULL)
2628     goto accuse;
2629
2630   /* make sure this is on the left side if not
2631      a '+' since '+' is commutative */
2632   if (ic->op != '+' &&
2633       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2634     return;
2635
2636   /* if one of them is a literal then we can */
2637   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2638       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2639     {
2640       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2641       return;
2642     }
2643
2644   /* if the other one is not on stack then we can */
2645   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2646       (IS_ITEMP (IC_RIGHT (uic)) ||
2647        (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2648         !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
2649     goto accuse;
2650
2651   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2652       (IS_ITEMP (IC_LEFT (uic)) ||
2653        (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2654         !OP_SYMBOL (IC_LEFT (uic))->onStack)))
2655     goto accuse;
2656
2657   return;
2658
2659 accuse:
2660   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2661
2662
2663 }
2664
2665 /*-----------------------------------------------------------------*/
2666 /* packForPush - hueristics to reduce iCode for pushing            */
2667 /*-----------------------------------------------------------------*/
2668 static void
2669 packForReceive (iCode * ic, eBBlock * ebp)
2670 {
2671   iCode *dic;
2672
2673   debugLog ("%s\n", __FUNCTION__);
2674   debugAopGet ("  result:", IC_RESULT (ic));
2675   debugAopGet ("  left:", IC_LEFT (ic));
2676   debugAopGet ("  right:", IC_RIGHT (ic));
2677
2678   if (!ic->next)
2679     return;
2680
2681   for (dic = ic->next; dic; dic = dic->next)
2682     {
2683
2684
2685
2686       if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
2687         debugLog ("    used on left\n");
2688       if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
2689         debugLog ("    used on right\n");
2690       if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
2691         debugLog ("    used on result\n");
2692
2693       if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
2694           (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
2695         return;
2696
2697     }
2698
2699   debugLog ("  hey we can remove this unnecessary assign\n");
2700 }
2701 /*-----------------------------------------------------------------*/
2702 /* packForPush - hueristics to reduce iCode for pushing            */
2703 /*-----------------------------------------------------------------*/
2704 static void
2705 packForPush (iCode * ic, eBBlock * ebp)
2706 {
2707   iCode *dic;
2708
2709   debugLog ("%s\n", __FUNCTION__);
2710   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2711     return;
2712
2713   /* must have only definition & one usage */
2714   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2715       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2716     return;
2717
2718   /* find the definition */
2719   if (!(dic = hTabItemWithKey (iCodehTab,
2720                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2721     return;
2722
2723   if (dic->op != '=' || POINTER_SET (dic))
2724     return;
2725
2726   /* we now we know that it has one & only one def & use
2727      and the that the definition is an assignment */
2728   IC_LEFT (ic) = IC_RIGHT (dic);
2729
2730   remiCodeFromeBBlock (ebp, dic);
2731   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2732 }
2733
2734 /*-----------------------------------------------------------------*/
2735 /* packRegisters - does some transformations to reduce register    */
2736 /*                   pressure                                      */
2737 /*-----------------------------------------------------------------*/
2738 static void
2739 packRegisters (eBBlock * ebp)
2740 {
2741   iCode *ic;
2742   int change = 0;
2743
2744   debugLog ("%s\n", __FUNCTION__);
2745
2746   while (1)
2747     {
2748
2749       change = 0;
2750
2751       /* look for assignments of the form */
2752       /* iTempNN = TRueSym (someoperation) SomeOperand */
2753       /*       ....                       */
2754       /* TrueSym := iTempNN:1             */
2755       for (ic = ebp->sch; ic; ic = ic->next)
2756         {
2757
2758           /* find assignment of the form TrueSym := iTempNN:1 */
2759           if (ic->op == '=' && !POINTER_SET (ic))
2760             change += packRegsForAssign (ic, ebp);
2761           /* debug stuff */
2762           if (ic->op == '=')
2763             {
2764               if (POINTER_SET (ic))
2765                 debugLog ("pointer is set\n");
2766               debugAopGet ("  result:", IC_RESULT (ic));
2767               debugAopGet ("  left:", IC_LEFT (ic));
2768               debugAopGet ("  right:", IC_RIGHT (ic));
2769             }
2770
2771         }
2772
2773       if (!change)
2774         break;
2775     }
2776
2777   for (ic = ebp->sch; ic; ic = ic->next)
2778     {
2779
2780       /* if this is an itemp & result of a address of a true sym 
2781          then mark this as rematerialisable   */
2782       if (ic->op == ADDRESS_OF &&
2783           IS_ITEMP (IC_RESULT (ic)) &&
2784           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2785           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2786           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2787         {
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
2804           OP_SYMBOL (IC_RESULT (ic))->remat =
2805             OP_SYMBOL (IC_RIGHT (ic))->remat;
2806           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2807             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2808         }
2809
2810       /* if this is a +/- operation with a rematerizable 
2811          then mark this as rematerializable as well */
2812       if ((ic->op == '+' || ic->op == '-') &&
2813           (IS_SYMOP (IC_LEFT (ic)) &&
2814            IS_ITEMP (IC_RESULT (ic)) &&
2815            OP_SYMBOL (IC_LEFT (ic))->remat &&
2816            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2817            IS_OP_LITERAL (IC_RIGHT (ic))))
2818         {
2819
2820           //int i = 
2821           operandLitValue (IC_RIGHT (ic));
2822           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2823           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2824           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2825         }
2826
2827       /* mark the pointer usages */
2828       if (POINTER_SET (ic))
2829         {
2830           OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2831           debugLog ("  marking as a pointer (set)\n");
2832         }
2833       if (POINTER_GET (ic))
2834         {
2835           OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2836           debugLog ("  marking as a pointer (get)\n");
2837         }
2838
2839       if (!SKIP_IC2 (ic))
2840         {
2841           /* if we are using a symbol on the stack
2842              then we should say pic14_ptrRegReq */
2843           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2844             pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2845                                  OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2846           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2847             pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2848                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2849           else
2850             {
2851               if (IS_SYMOP (IC_LEFT (ic)))
2852                 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2853                                 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2854               if (IS_SYMOP (IC_RIGHT (ic)))
2855                 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2856                                OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2857               if (IS_SYMOP (IC_RESULT (ic)))
2858                 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2859                               OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2860             }
2861         }
2862
2863       /* if the condition of an if instruction
2864          is defined in the previous instruction then
2865          mark the itemp as a conditional */
2866       if ((IS_CONDITIONAL (ic) ||
2867            ((ic->op == BITWISEAND ||
2868              ic->op == '|' ||
2869              ic->op == '^') &&
2870             isBitwiseOptimizable (ic))) &&
2871           ic->next && ic->next->op == IFX &&
2872           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2873           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2874         {
2875
2876           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2877           continue;
2878         }
2879
2880       /* reduce for support function calls */
2881       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2882         packRegsForSupport (ic, ebp);
2883
2884       /* if a parameter is passed, it's in W, so we may not
2885          need to place a copy in a register */
2886       if (ic->op == RECEIVE)
2887         packForReceive (ic, ebp);
2888
2889       /* some cases the redundant moves can
2890          can be eliminated for return statements */
2891       if ((ic->op == RETURN || ic->op == SEND) &&
2892           !isOperandInFarSpace (IC_LEFT (ic)) &&
2893           !options.model)
2894         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2895
2896       /* if pointer set & left has a size more than
2897          one and right is not in far space */
2898       if (POINTER_SET (ic) &&
2899           !isOperandInFarSpace (IC_RIGHT (ic)) &&
2900           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2901           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2902           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2903
2904         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2905
2906       /* if pointer get */
2907       if (POINTER_GET (ic) &&
2908           !isOperandInFarSpace (IC_RESULT (ic)) &&
2909           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2910           !IS_OP_RUONLY (IC_RESULT (ic)) &&
2911           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2912
2913         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2914
2915
2916       /* if this is cast for intergral promotion then
2917          check if only use of  the definition of the 
2918          operand being casted/ if yes then replace
2919          the result of that arithmetic operation with 
2920          this result and get rid of the cast */
2921       if (ic->op == CAST)
2922         {
2923           sym_link *fromType = operandType (IC_RIGHT (ic));
2924           sym_link *toType = operandType (IC_LEFT (ic));
2925
2926           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
2927               getSize (fromType) != getSize (toType))
2928             {
2929
2930               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2931               if (dic)
2932                 {
2933                   if (IS_ARITHMETIC_OP (dic))
2934                     {
2935                       IC_RESULT (dic) = IC_RESULT (ic);
2936                       remiCodeFromeBBlock (ebp, ic);
2937                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2938                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2939                       ic = ic->prev;
2940                     }
2941                   else
2942                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
2943                 }
2944             }
2945           else
2946             {
2947
2948               /* if the type from and type to are the same
2949                  then if this is the only use then packit */
2950               if (compareType (operandType (IC_RIGHT (ic)),
2951                              operandType (IC_LEFT (ic))) == 1)
2952                 {
2953                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
2954                   if (dic)
2955                     {
2956                       IC_RESULT (dic) = IC_RESULT (ic);
2957                       remiCodeFromeBBlock (ebp, ic);
2958                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2959                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2960                       ic = ic->prev;
2961                     }
2962                 }
2963             }
2964         }
2965
2966       /* pack for PUSH 
2967          iTempNN := (some variable in farspace) V1
2968          push iTempNN ;
2969          -------------
2970          push V1
2971        */
2972       if (ic->op == IPUSH)
2973         {
2974           packForPush (ic, ebp);
2975         }
2976
2977
2978       /* pack registers for accumulator use, when the
2979          result of an arithmetic or bit wise operation
2980          has only one use, that use is immediately following
2981          the defintion and the using iCode has only one
2982          operand or has two operands but one is literal &
2983          the result of that operation is not on stack then
2984          we can leave the result of this operation in acc:b
2985          combination */
2986       if ((IS_ARITHMETIC_OP (ic)
2987
2988            || IS_BITWISE_OP (ic)
2989
2990            || ic->op == LEFT_OP || ic->op == RIGHT_OP
2991
2992           ) &&
2993           IS_ITEMP (IC_RESULT (ic)) &&
2994           getSize (operandType (IC_RESULT (ic))) <= 2)
2995
2996         packRegsForAccUse (ic);
2997
2998     }
2999 }
3000
3001 static void
3002 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3003 {
3004   int i;
3005
3006   if (!debug || !debugF)
3007     return;
3008
3009   for (i = 0; i < count; i++)
3010     {
3011       fprintf (debugF, "\n----------------------------------------------------------------\n");
3012       fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3013                ebbs[i]->entryLabel->name,
3014                ebbs[i]->depth,
3015                ebbs[i]->noPath,
3016                ebbs[i]->isLastInLoop);
3017       fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3018                ebbs[i]->dfnum,
3019                ebbs[i]->bbnum,
3020                ebbs[i]->fSeq,
3021                ebbs[i]->lSeq);
3022       fprintf (debugF, "visited %d : hasFcall = %d\n",
3023                ebbs[i]->visited,
3024                ebbs[i]->hasFcall);
3025
3026       fprintf (debugF, "\ndefines bitVector :");
3027       bitVectDebugOn (ebbs[i]->defSet, debugF);
3028       fprintf (debugF, "\nlocal defines bitVector :");
3029       bitVectDebugOn (ebbs[i]->ldefs, debugF);
3030       fprintf (debugF, "\npointers Set bitvector :");
3031       bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3032       fprintf (debugF, "\nin pointers Set bitvector :");
3033       bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3034       fprintf (debugF, "\ninDefs Set bitvector :");
3035       bitVectDebugOn (ebbs[i]->inDefs, debugF);
3036       fprintf (debugF, "\noutDefs Set bitvector :");
3037       bitVectDebugOn (ebbs[i]->outDefs, debugF);
3038       fprintf (debugF, "\nusesDefs Set bitvector :");
3039       bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3040       fprintf (debugF, "\n----------------------------------------------------------------\n");
3041       printiCChain (ebbs[i]->sch, debugF);
3042     }
3043 }
3044 /*-----------------------------------------------------------------*/
3045 /* assignRegisters - assigns registers to each live range as need  */
3046 /*-----------------------------------------------------------------*/
3047 void
3048 pic14_assignRegisters (eBBlock ** ebbs, int count)
3049 {
3050   iCode *ic;
3051   int i;
3052
3053   debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3054   debugLog ("ebbs before optimizing:\n");
3055   dumpEbbsToDebug (ebbs, count);
3056
3057   setToNull ((void *) &_G.funcrUsed);
3058   pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3059
3060
3061   /* change assignments this will remove some
3062      live ranges reducing some register pressure */
3063   for (i = 0; i < count; i++)
3064     packRegisters (ebbs[i]);
3065
3066   if (options.dump_pack)
3067     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3068
3069   /* first determine for each live range the number of 
3070      registers & the type of registers required for each */
3071   regTypeNum ();
3072
3073   /* and serially allocate registers */
3074   serialRegAssign (ebbs, count);
3075
3076   /* if stack was extended then tell the user */
3077   if (_G.stackExtend)
3078     {
3079 /*      werror(W_TOOMANY_SPILS,"stack", */
3080 /*             _G.stackExtend,currFunc->name,""); */
3081       _G.stackExtend = 0;
3082     }
3083
3084   if (_G.dataExtend)
3085     {
3086 /*      werror(W_TOOMANY_SPILS,"data space", */
3087 /*             _G.dataExtend,currFunc->name,""); */
3088       _G.dataExtend = 0;
3089     }
3090
3091   /* after that create the register mask
3092      for each of the instruction */
3093   createRegMask (ebbs, count);
3094
3095   /* redo that offsets for stacked automatic variables */
3096   redoStackOffsets ();
3097
3098   if (options.dump_rassgn)
3099     dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3100
3101   /* now get back the chain */
3102   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3103
3104   debugLog ("ebbs after optimizing:\n");
3105   dumpEbbsToDebug (ebbs, count);
3106
3107
3108   genpic14Code (ic);
3109
3110   /* free up any _G.stackSpil locations allocated */
3111   applyToSet (_G.stackSpil, deallocStackSpil);
3112   _G.slocNum = 0;
3113   setToNull ((void **) &_G.stackSpil);
3114   setToNull ((void **) &_G.spiltSet);
3115   /* mark all registers as free */
3116   pic14_freeAllRegs ();
3117
3118   debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
3119   debugLogClose ();
3120   return;
3121 }