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