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