Now the PIC port DOESN'T spew debug info by default.
[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 - dic is VOLATILE \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           /* A previous result was assigned to the same register - we'll our definition */
2185           debugLog ("  %d - dic result key == ic right key -- pointer set=%c\n",
2186                     __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2187           if (POINTER_SET (dic))
2188             dic = NULL;
2189
2190           break;
2191         }
2192
2193       if (IS_SYMOP (IC_RIGHT (dic)) &&
2194           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2195            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2196         {
2197           debugLog ("  %d - dic right key == ic rightor result key\n", __LINE__);
2198           dic = NULL;
2199           break;
2200         }
2201
2202       if (IS_SYMOP (IC_LEFT (dic)) &&
2203           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2204            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2205         {
2206           debugLog ("  %d - dic left key == ic rightor result key\n", __LINE__);
2207           dic = NULL;
2208           break;
2209         }
2210
2211       if (POINTER_SET (dic) &&
2212           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2213         {
2214           debugLog ("  %d - dic result key == ic result key -- pointer set=Y\n",
2215                     __LINE__);
2216           dic = NULL;
2217           break;
2218         }
2219     }
2220
2221   if (!dic)
2222     return 0;                   /* did not find */
2223
2224   /* if the result is on stack or iaccess then it must be
2225      the same atleast one of the operands */
2226   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2227       OP_SYMBOL (IC_RESULT (ic))->iaccess)
2228     {
2229
2230       /* the operation has only one symbol
2231          operator then we can pack */
2232       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2233           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2234         goto pack;
2235
2236       if (!((IC_LEFT (dic) &&
2237              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2238             (IC_RIGHT (dic) &&
2239              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2240         return 0;
2241     }
2242 pack:
2243   debugLog ("  packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2244   debugLog ("  replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2245   /* found the definition */
2246   /* replace the result with the result of */
2247   /* this assignment and remove this assignment */
2248   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2249   IC_RESULT (dic) = IC_RESULT (ic);
2250
2251   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2252     {
2253       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2254     }
2255   /* delete from liverange table also 
2256      delete from all the points inbetween and the new
2257      one */
2258   for (sic = dic; sic != ic; sic = sic->next)
2259     {
2260       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2261       if (IS_ITEMP (IC_RESULT (dic)))
2262         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2263     }
2264
2265   remiCodeFromeBBlock (ebp, ic);
2266   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2267   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2268   OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2269   return 1;
2270
2271
2272 }
2273
2274 /*-----------------------------------------------------------------*/
2275 /* findAssignToSym : scanning backwards looks for first assig found */
2276 /*-----------------------------------------------------------------*/
2277 static iCode *
2278 findAssignToSym (operand * op, iCode * ic)
2279 {
2280   iCode *dic;
2281
2282   debugLog ("%s\n", __FUNCTION__);
2283   for (dic = ic->prev; dic; dic = dic->prev)
2284     {
2285
2286       /* if definition by assignment */
2287       if (dic->op == '=' &&
2288           !POINTER_SET (dic) &&
2289           IC_RESULT (dic)->key == op->key
2290 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2291         )
2292         {
2293
2294           /* we are interested only if defined in far space */
2295           /* or in stack space in case of + & - */
2296
2297           /* if assigned to a non-symbol then return
2298              true */
2299           if (!IS_SYMOP (IC_RIGHT (dic)))
2300             break;
2301
2302           /* if the symbol is in far space then
2303              we should not */
2304           if (isOperandInFarSpace (IC_RIGHT (dic)))
2305             return NULL;
2306
2307           /* for + & - operations make sure that
2308              if it is on the stack it is the same
2309              as one of the three operands */
2310           if ((ic->op == '+' || ic->op == '-') &&
2311               OP_SYMBOL (IC_RIGHT (dic))->onStack)
2312             {
2313
2314               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
2315                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
2316                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
2317                 return NULL;
2318             }
2319
2320           break;
2321
2322         }
2323
2324       /* if we find an usage then we cannot delete it */
2325       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
2326         return NULL;
2327
2328       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
2329         return NULL;
2330
2331       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
2332         return NULL;
2333     }
2334
2335   /* now make sure that the right side of dic
2336      is not defined between ic & dic */
2337   if (dic)
2338     {
2339       iCode *sic = dic->next;
2340
2341       for (; sic != ic; sic = sic->next)
2342         if (IC_RESULT (sic) &&
2343             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
2344           return NULL;
2345     }
2346
2347   return dic;
2348
2349
2350 }
2351
2352 /*-----------------------------------------------------------------*/
2353 /* packRegsForSupport :- reduce some registers for support calls   */
2354 /*-----------------------------------------------------------------*/
2355 static int
2356 packRegsForSupport (iCode * ic, eBBlock * ebp)
2357 {
2358   int change = 0;
2359
2360   debugLog ("%s\n", __FUNCTION__);
2361   /* for the left & right operand :- look to see if the
2362      left was assigned a true symbol in far space in that
2363      case replace them */
2364   if (IS_ITEMP (IC_LEFT (ic)) &&
2365       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
2366     {
2367       iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
2368       iCode *sic;
2369
2370       if (!dic)
2371         goto right;
2372
2373       debugAopGet ("removing left:", IC_LEFT (ic));
2374
2375       /* found it we need to remove it from the
2376          block */
2377       for (sic = dic; sic != ic; sic = sic->next)
2378         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
2379
2380       IC_LEFT (ic)->operand.symOperand =
2381         IC_RIGHT (dic)->operand.symOperand;
2382       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2383       remiCodeFromeBBlock (ebp, dic);
2384       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2385       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2386       change++;
2387     }
2388
2389   /* do the same for the right operand */
2390 right:
2391   if (!change &&
2392       IS_ITEMP (IC_RIGHT (ic)) &&
2393       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
2394     {
2395       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
2396       iCode *sic;
2397
2398       if (!dic)
2399         return change;
2400
2401       /* if this is a subtraction & the result
2402          is a true symbol in far space then don't pack */
2403       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
2404         {
2405           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
2406           if (IN_FARSPACE (SPEC_OCLS (etype)))
2407             return change;
2408         }
2409
2410       debugAopGet ("removing right:", IC_RIGHT (ic));
2411
2412       /* found it we need to remove it from the
2413          block */
2414       for (sic = dic; sic != ic; sic = sic->next)
2415         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
2416
2417       IC_RIGHT (ic)->operand.symOperand =
2418         IC_RIGHT (dic)->operand.symOperand;
2419       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
2420
2421       remiCodeFromeBBlock (ebp, dic);
2422       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2423       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2424       change++;
2425     }
2426
2427   return change;
2428 }
2429
2430 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
2431
2432
2433 /*-----------------------------------------------------------------*/
2434 /* packRegsForOneuse : - will reduce some registers for single Use */
2435 /*-----------------------------------------------------------------*/
2436 static iCode *
2437 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
2438 {
2439   bitVect *uses;
2440   iCode *dic, *sic;
2441
2442   debugLog ("%s\n", __FUNCTION__);
2443   /* if returning a literal then do nothing */
2444   if (!IS_SYMOP (op))
2445     return NULL;
2446
2447   /* only upto 2 bytes since we cannot predict
2448      the usage of b, & acc */
2449   if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
2450       ic->op != RETURN &&
2451       ic->op != SEND)
2452     return NULL;
2453
2454   /* this routine will mark the a symbol as used in one 
2455      instruction use only && if the definition is local 
2456      (ie. within the basic block) && has only one definition &&
2457      that definition is either a return value from a 
2458      function or does not contain any variables in
2459      far space */
2460   uses = bitVectCopy (OP_USES (op));
2461   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
2462   if (!bitVectIsZero (uses))    /* has other uses */
2463     return NULL;
2464
2465   /* if it has only one defintion */
2466   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
2467     return NULL;                /* has more than one definition */
2468
2469   /* get that definition */
2470   if (!(dic =
2471         hTabItemWithKey (iCodehTab,
2472                          bitVectFirstBit (OP_DEFS (op)))))
2473     return NULL;
2474
2475   /* found the definition now check if it is local */
2476   if (dic->seq < ebp->fSeq ||
2477       dic->seq > ebp->lSeq)
2478     return NULL;                /* non-local */
2479
2480   /* now check if it is the return from
2481      a function call */
2482   if (dic->op == CALL || dic->op == PCALL)
2483     {
2484       if (ic->op != SEND && ic->op != RETURN &&
2485           !POINTER_SET(ic) && !POINTER_GET(ic))
2486         {
2487           OP_SYMBOL (op)->ruonly = 1;
2488           return dic;
2489         }
2490       dic = dic->next;
2491     }
2492
2493
2494   /* otherwise check that the definition does
2495      not contain any symbols in far space */
2496   if (isOperandInFarSpace (IC_LEFT (dic)) ||
2497       isOperandInFarSpace (IC_RIGHT (dic)) ||
2498       IS_OP_RUONLY (IC_LEFT (ic)) ||
2499       IS_OP_RUONLY (IC_RIGHT (ic)))
2500     {
2501       return NULL;
2502     }
2503
2504   /* if pointer set then make sure the pointer
2505      is one byte */
2506   if (POINTER_SET (dic) &&
2507       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2508     return NULL;
2509
2510   if (POINTER_GET (dic) &&
2511       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2512     return NULL;
2513
2514   sic = dic;
2515
2516   /* also make sure the intervenening instructions
2517      don't have any thing in far space */
2518   for (dic = dic->next; dic && dic != ic; dic = dic->next)
2519     {
2520
2521       /* if there is an intervening function call then no */
2522       if (dic->op == CALL || dic->op == PCALL)
2523         return NULL;
2524       /* if pointer set then make sure the pointer
2525          is one byte */
2526       if (POINTER_SET (dic) &&
2527           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
2528         return NULL;
2529
2530       if (POINTER_GET (dic) &&
2531           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
2532         return NULL;
2533
2534       /* if address of & the result is remat then okay */
2535       if (dic->op == ADDRESS_OF &&
2536           OP_SYMBOL (IC_RESULT (dic))->remat)
2537         continue;
2538
2539       /* if operand has size of three or more & this
2540          operation is a '*','/' or '%' then 'b' may
2541          cause a problem */
2542       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
2543           getSize (operandType (op)) >= 3)
2544         return NULL;
2545
2546       /* if left or right or result is in far space */
2547       if (isOperandInFarSpace (IC_LEFT (dic)) ||
2548           isOperandInFarSpace (IC_RIGHT (dic)) ||
2549           isOperandInFarSpace (IC_RESULT (dic)) ||
2550           IS_OP_RUONLY (IC_LEFT (dic)) ||
2551           IS_OP_RUONLY (IC_RIGHT (dic)) ||
2552           IS_OP_RUONLY (IC_RESULT (dic)))
2553         {
2554           return NULL;
2555         }
2556     }
2557
2558   OP_SYMBOL (op)->ruonly = 1;
2559   return sic;
2560
2561 }
2562
2563 /*-----------------------------------------------------------------*/
2564 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
2565 /*-----------------------------------------------------------------*/
2566 static bool
2567 isBitwiseOptimizable (iCode * ic)
2568 {
2569   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
2570   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
2571
2572   debugLog ("%s\n", __FUNCTION__);
2573   /* bitwise operations are considered optimizable
2574      under the following conditions (Jean-Louis VERN) 
2575
2576      x & lit
2577      bit & bit
2578      bit & x
2579      bit ^ bit
2580      bit ^ x
2581      x   ^ lit
2582      x   | lit
2583      bit | bit
2584      bit | x
2585    */
2586   if (IS_LITERAL (rtype) ||
2587       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
2588     return TRUE;
2589   else
2590     return FALSE;
2591 }
2592
2593 /*-----------------------------------------------------------------*/
2594 /* packRegsForAccUse - pack registers for acc use                  */
2595 /*-----------------------------------------------------------------*/
2596 static void
2597 packRegsForAccUse (iCode * ic)
2598 {
2599   iCode *uic;
2600
2601   debugLog ("%s\n", __FUNCTION__);
2602
2603   /* if this is an aggregate, e.g. a one byte char array */
2604   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
2605     return;
2606   }
2607
2608   /* if + or - then it has to be one byte result */
2609   if ((ic->op == '+' || ic->op == '-')
2610       && getSize (operandType (IC_RESULT (ic))) > 1)
2611     return;
2612
2613   /* if shift operation make sure right side is not a literal */
2614   if (ic->op == RIGHT_OP &&
2615       (isOperandLiteral (IC_RIGHT (ic)) ||
2616        getSize (operandType (IC_RESULT (ic))) > 1))
2617     return;
2618
2619   if (ic->op == LEFT_OP &&
2620       (isOperandLiteral (IC_RIGHT (ic)) ||
2621        getSize (operandType (IC_RESULT (ic))) > 1))
2622     return;
2623
2624   if (IS_BITWISE_OP (ic) &&
2625       getSize (operandType (IC_RESULT (ic))) > 1)
2626     return;
2627
2628
2629   /* has only one definition */
2630   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
2631     return;
2632
2633   /* has only one use */
2634   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
2635     return;
2636
2637   /* and the usage immediately follows this iCode */
2638   if (!(uic = hTabItemWithKey (iCodehTab,
2639                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
2640     return;
2641
2642   if (ic->next != uic)
2643     return;
2644
2645   /* if it is a conditional branch then we definitely can */
2646   if (uic->op == IFX)
2647     goto accuse;
2648
2649   if (uic->op == JUMPTABLE)
2650     return;
2651
2652   /* if the usage is not is an assignment
2653      or an arithmetic / bitwise / shift operation then not */
2654   if (POINTER_SET (uic) &&
2655       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
2656     return;
2657
2658   if (uic->op != '=' &&
2659       !IS_ARITHMETIC_OP (uic) &&
2660       !IS_BITWISE_OP (uic) &&
2661       uic->op != LEFT_OP &&
2662       uic->op != RIGHT_OP)
2663     return;
2664
2665   /* if used in ^ operation then make sure right is not a 
2666      literl */
2667   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
2668     return;
2669
2670   /* if shift operation make sure right side is not a literal */
2671   if (uic->op == RIGHT_OP &&
2672       (isOperandLiteral (IC_RIGHT (uic)) ||
2673        getSize (operandType (IC_RESULT (uic))) > 1))
2674     return;
2675
2676   if (uic->op == LEFT_OP &&
2677       (isOperandLiteral (IC_RIGHT (uic)) ||
2678        getSize (operandType (IC_RESULT (uic))) > 1))
2679     return;
2680
2681   /* make sure that the result of this icode is not on the
2682      stack, since acc is used to compute stack offset */
2683   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
2684       OP_SYMBOL (IC_RESULT (uic))->onStack)
2685     return;
2686
2687   /* if either one of them in far space then we cannot */
2688   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2689        isOperandInFarSpace (IC_LEFT (uic))) ||
2690       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2691        isOperandInFarSpace (IC_RIGHT (uic))))
2692     return;
2693
2694   /* if the usage has only one operand then we can */
2695   if (IC_LEFT (uic) == NULL ||
2696       IC_RIGHT (uic) == NULL)
2697     goto accuse;
2698
2699   /* make sure this is on the left side if not
2700      a '+' since '+' is commutative */
2701   if (ic->op != '+' &&
2702       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
2703     return;
2704
2705   /* if one of them is a literal then we can */
2706   if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
2707       (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
2708     {
2709       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2710       return;
2711     }
2712
2713   /* if the other one is not on stack then we can */
2714   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
2715       (IS_ITEMP (IC_RIGHT (uic)) ||
2716        (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
2717         !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
2718     goto accuse;
2719
2720   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
2721       (IS_ITEMP (IC_LEFT (uic)) ||
2722        (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
2723         !OP_SYMBOL (IC_LEFT (uic))->onStack)))
2724     goto accuse;
2725
2726   return;
2727
2728 accuse:
2729   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
2730
2731
2732 }
2733
2734 /*-----------------------------------------------------------------*/
2735 /* packForPush - hueristics to reduce iCode for pushing            */
2736 /*-----------------------------------------------------------------*/
2737 static void
2738 packForReceive (iCode * ic, eBBlock * ebp)
2739 {
2740   iCode *dic;
2741
2742   debugLog ("%s\n", __FUNCTION__);
2743   debugAopGet ("  result:", IC_RESULT (ic));
2744   debugAopGet ("  left:", IC_LEFT (ic));
2745   debugAopGet ("  right:", IC_RIGHT (ic));
2746
2747   if (!ic->next)
2748     return;
2749
2750   for (dic = ic->next; dic; dic = dic->next)
2751     {
2752
2753
2754
2755       if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
2756         debugLog ("    used on left\n");
2757       if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
2758         debugLog ("    used on right\n");
2759       if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
2760         debugLog ("    used on result\n");
2761
2762       if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
2763           (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
2764         return;
2765
2766     }
2767
2768   debugLog ("  hey we can remove this unnecessary assign\n");
2769 }
2770 /*-----------------------------------------------------------------*/
2771 /* packForPush - hueristics to reduce iCode for pushing            */
2772 /*-----------------------------------------------------------------*/
2773 static void
2774 packForPush (iCode * ic, eBBlock * ebp)
2775 {
2776   iCode *dic;
2777
2778   debugLog ("%s\n", __FUNCTION__);
2779   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
2780     return;
2781
2782   /* must have only definition & one usage */
2783   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
2784       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
2785     return;
2786
2787   /* find the definition */
2788   if (!(dic = hTabItemWithKey (iCodehTab,
2789                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
2790     return;
2791
2792   if (dic->op != '=' || POINTER_SET (dic))
2793     return;
2794
2795   /* we now we know that it has one & only one def & use
2796      and the that the definition is an assignment */
2797   IC_LEFT (ic) = IC_RIGHT (dic);
2798
2799   remiCodeFromeBBlock (ebp, dic);
2800   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2801   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
2802 }
2803
2804 /*-----------------------------------------------------------------*/
2805 /* packRegisters - does some transformations to reduce register    */
2806 /*                   pressure                                      */
2807 /*-----------------------------------------------------------------*/
2808 static void
2809 packRegisters (eBBlock * ebp)
2810 {
2811   iCode *ic;
2812   int change = 0;
2813
2814   debugLog ("%s\n", __FUNCTION__);
2815
2816   while (1)
2817     {
2818
2819       change = 0;
2820
2821       /* look for assignments of the form */
2822       /* iTempNN = TRueSym (someoperation) SomeOperand */
2823       /*       ....                       */
2824       /* TrueSym := iTempNN:1             */
2825       for (ic = ebp->sch; ic; ic = ic->next)
2826         {
2827
2828           /* find assignment of the form TrueSym := iTempNN:1 */
2829           if (ic->op == '=' && !POINTER_SET (ic))
2830             change += packRegsForAssign (ic, ebp);
2831           /* debug stuff */
2832           if (ic->op == '=')
2833             {
2834               if (POINTER_SET (ic))
2835                 debugLog ("pointer is set\n");
2836               debugAopGet ("  result:", IC_RESULT (ic));
2837               debugAopGet ("  left:", IC_LEFT (ic));
2838               debugAopGet ("  right:", IC_RIGHT (ic));
2839             }
2840
2841         }
2842
2843       if (!change)
2844         break;
2845     }
2846
2847   for (ic = ebp->sch; ic; ic = ic->next)
2848     {
2849
2850       /* if this is an itemp & result of a address of a true sym 
2851          then mark this as rematerialisable   */
2852       if (ic->op == ADDRESS_OF &&
2853           IS_ITEMP (IC_RESULT (ic)) &&
2854           IS_TRUE_SYMOP (IC_LEFT (ic)) &&
2855           bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2856           !OP_SYMBOL (IC_LEFT (ic))->onStack)
2857         {
2858
2859           debugLog ("  %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
2860
2861           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2862           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2863           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2864
2865         }
2866
2867       /* if straight assignment then carry remat flag if
2868          this is the only definition */
2869       if (ic->op == '=' &&
2870           !POINTER_SET (ic) &&
2871           IS_SYMOP (IC_RIGHT (ic)) &&
2872           OP_SYMBOL (IC_RIGHT (ic))->remat &&
2873           bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
2874         {
2875           debugLog ("  %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
2876
2877           OP_SYMBOL (IC_RESULT (ic))->remat =
2878             OP_SYMBOL (IC_RIGHT (ic))->remat;
2879           OP_SYMBOL (IC_RESULT (ic))->rematiCode =
2880             OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
2881         }
2882
2883       /* if this is a +/- operation with a rematerizable 
2884          then mark this as rematerializable as well */
2885       if ((ic->op == '+' || ic->op == '-') &&
2886           (IS_SYMOP (IC_LEFT (ic)) &&
2887            IS_ITEMP (IC_RESULT (ic)) &&
2888            OP_SYMBOL (IC_LEFT (ic))->remat &&
2889            bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
2890            IS_OP_LITERAL (IC_RIGHT (ic))))
2891         {
2892           debugLog ("  %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
2893           //int i = 
2894           operandLitValue (IC_RIGHT (ic));
2895           OP_SYMBOL (IC_RESULT (ic))->remat = 1;
2896           OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
2897           OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
2898         }
2899
2900       /* mark the pointer usages */
2901       if (POINTER_SET (ic))
2902         {
2903           OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
2904           debugLog ("  marking as a pointer (set) =>");
2905           debugAopGet ("  result:", IC_RESULT (ic));
2906         }
2907       if (POINTER_GET (ic))
2908         {
2909           OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
2910           debugLog ("  marking as a pointer (get) =>");
2911           debugAopGet ("  left:", IC_LEFT (ic));
2912         }
2913
2914       if (!SKIP_IC2 (ic))
2915         {
2916           /* if we are using a symbol on the stack
2917              then we should say pic14_ptrRegReq */
2918           if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
2919             pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
2920                                  OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
2921           else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
2922             pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
2923                               OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
2924           else
2925             {
2926               if (IS_SYMOP (IC_LEFT (ic)))
2927                 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
2928                                 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
2929               if (IS_SYMOP (IC_RIGHT (ic)))
2930                 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
2931                                OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
2932               if (IS_SYMOP (IC_RESULT (ic)))
2933                 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
2934                               OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
2935             }
2936         }
2937
2938       /* if the condition of an if instruction
2939          is defined in the previous instruction then
2940          mark the itemp as a conditional */
2941       if ((IS_CONDITIONAL (ic) ||
2942            ((ic->op == BITWISEAND ||
2943              ic->op == '|' ||
2944              ic->op == '^') &&
2945             isBitwiseOptimizable (ic))) &&
2946           ic->next && ic->next->op == IFX &&
2947           isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
2948           OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
2949         {
2950
2951           OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
2952           continue;
2953         }
2954
2955       /* reduce for support function calls */
2956       if (ic->supportRtn || ic->op == '+' || ic->op == '-')
2957         packRegsForSupport (ic, ebp);
2958
2959       /* if a parameter is passed, it's in W, so we may not
2960          need to place a copy in a register */
2961       if (ic->op == RECEIVE)
2962         packForReceive (ic, ebp);
2963
2964       /* some cases the redundant moves can
2965          can be eliminated for return statements */
2966       if ((ic->op == RETURN || ic->op == SEND) &&
2967           !isOperandInFarSpace (IC_LEFT (ic)) &&
2968           !options.model)
2969         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2970
2971       /* if pointer set & left has a size more than
2972          one and right is not in far space */
2973       if (POINTER_SET (ic) &&
2974           !isOperandInFarSpace (IC_RIGHT (ic)) &&
2975           !OP_SYMBOL (IC_RESULT (ic))->remat &&
2976           !IS_OP_RUONLY (IC_RIGHT (ic)) &&
2977           getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
2978
2979         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
2980
2981       /* if pointer get */
2982       if (POINTER_GET (ic) &&
2983           !isOperandInFarSpace (IC_RESULT (ic)) &&
2984           !OP_SYMBOL (IC_LEFT (ic))->remat &&
2985           !IS_OP_RUONLY (IC_RESULT (ic)) &&
2986           getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
2987
2988         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
2989
2990
2991       /* if this is cast for intergral promotion then
2992          check if only use of  the definition of the 
2993          operand being casted/ if yes then replace
2994          the result of that arithmetic operation with 
2995          this result and get rid of the cast */
2996       if (ic->op == CAST)
2997         {
2998           sym_link *fromType = operandType (IC_RIGHT (ic));
2999           sym_link *toType = operandType (IC_LEFT (ic));
3000
3001           if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3002               getSize (fromType) != getSize (toType))
3003             {
3004
3005               iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3006               if (dic)
3007                 {
3008                   if (IS_ARITHMETIC_OP (dic))
3009                     {
3010                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3011                       IC_RESULT (dic) = IC_RESULT (ic);
3012                       remiCodeFromeBBlock (ebp, ic);
3013                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3014                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3015                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3016                       ic = ic->prev;
3017                     }
3018                   else
3019                     OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3020                 }
3021             }
3022           else
3023             {
3024
3025               /* if the type from and type to are the same
3026                  then if this is the only use then packit */
3027               if (compareType (operandType (IC_RIGHT (ic)),
3028                              operandType (IC_LEFT (ic))) == 1)
3029                 {
3030                   iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3031                   if (dic)
3032                     {
3033                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3034                       IC_RESULT (dic) = IC_RESULT (ic);
3035                       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3036                       remiCodeFromeBBlock (ebp, ic);
3037                       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3038                       OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3039                       ic = ic->prev;
3040                     }
3041                 }
3042             }
3043         }
3044
3045       /* pack for PUSH 
3046          iTempNN := (some variable in farspace) V1
3047          push iTempNN ;
3048          -------------
3049          push V1
3050        */
3051       if (ic->op == IPUSH)
3052         {
3053           packForPush (ic, ebp);
3054         }
3055
3056
3057       /* pack registers for accumulator use, when the
3058          result of an arithmetic or bit wise operation
3059          has only one use, that use is immediately following
3060          the defintion and the using iCode has only one
3061          operand or has two operands but one is literal &
3062          the result of that operation is not on stack then
3063          we can leave the result of this operation in acc:b
3064          combination */
3065       if ((IS_ARITHMETIC_OP (ic)
3066
3067            || IS_BITWISE_OP (ic)
3068
3069            || ic->op == LEFT_OP || ic->op == RIGHT_OP
3070
3071           ) &&
3072           IS_ITEMP (IC_RESULT (ic)) &&
3073           getSize (operandType (IC_RESULT (ic))) <= 2)
3074
3075         packRegsForAccUse (ic);
3076
3077     }
3078 }
3079
3080 static void
3081 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3082 {
3083   int i;
3084
3085   if (!debug || !debugF)
3086     return;
3087
3088   for (i = 0; i < count; i++)
3089     {
3090       fprintf (debugF, "\n----------------------------------------------------------------\n");
3091       fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3092                ebbs[i]->entryLabel->name,
3093                ebbs[i]->depth,
3094                ebbs[i]->noPath,
3095                ebbs[i]->isLastInLoop);
3096       fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3097                ebbs[i]->dfnum,
3098                ebbs[i]->bbnum,
3099                ebbs[i]->fSeq,
3100                ebbs[i]->lSeq);
3101       fprintf (debugF, "visited %d : hasFcall = %d\n",
3102                ebbs[i]->visited,
3103                ebbs[i]->hasFcall);
3104
3105       fprintf (debugF, "\ndefines bitVector :");
3106       bitVectDebugOn (ebbs[i]->defSet, debugF);
3107       fprintf (debugF, "\nlocal defines bitVector :");
3108       bitVectDebugOn (ebbs[i]->ldefs, debugF);
3109       fprintf (debugF, "\npointers Set bitvector :");
3110       bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3111       fprintf (debugF, "\nin pointers Set bitvector :");
3112       bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3113       fprintf (debugF, "\ninDefs Set bitvector :");
3114       bitVectDebugOn (ebbs[i]->inDefs, debugF);
3115       fprintf (debugF, "\noutDefs Set bitvector :");
3116       bitVectDebugOn (ebbs[i]->outDefs, debugF);
3117       fprintf (debugF, "\nusesDefs Set bitvector :");
3118       bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3119       fprintf (debugF, "\n----------------------------------------------------------------\n");
3120       printiCChain (ebbs[i]->sch, debugF);
3121     }
3122 }
3123 /*-----------------------------------------------------------------*/
3124 /* assignRegisters - assigns registers to each live range as need  */
3125 /*-----------------------------------------------------------------*/
3126 void
3127 pic14_assignRegisters (eBBlock ** ebbs, int count)
3128 {
3129   iCode *ic;
3130   int i;
3131
3132   debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3133   debugLog ("\nebbs before optimizing:\n");
3134   dumpEbbsToDebug (ebbs, count);
3135
3136   setToNull ((void *) &_G.funcrUsed);
3137   pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3138
3139
3140   /* change assignments this will remove some
3141      live ranges reducing some register pressure */
3142   for (i = 0; i < count; i++)
3143     packRegisters (ebbs[i]);
3144
3145   if (options.dump_pack)
3146     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3147
3148   /* first determine for each live range the number of 
3149      registers & the type of registers required for each */
3150   regTypeNum ();
3151
3152   /* and serially allocate registers */
3153   serialRegAssign (ebbs, count);
3154
3155   /* if stack was extended then tell the user */
3156   if (_G.stackExtend)
3157     {
3158 /*      werror(W_TOOMANY_SPILS,"stack", */
3159 /*             _G.stackExtend,currFunc->name,""); */
3160       _G.stackExtend = 0;
3161     }
3162
3163   if (_G.dataExtend)
3164     {
3165 /*      werror(W_TOOMANY_SPILS,"data space", */
3166 /*             _G.dataExtend,currFunc->name,""); */
3167       _G.dataExtend = 0;
3168     }
3169
3170   /* after that create the register mask
3171      for each of the instruction */
3172   createRegMask (ebbs, count);
3173
3174   /* redo that offsets for stacked automatic variables */
3175   redoStackOffsets ();
3176
3177   if (options.dump_rassgn)
3178     dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
3179
3180   /* now get back the chain */
3181   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
3182
3183   debugLog ("ebbs after optimizing:\n");
3184   dumpEbbsToDebug (ebbs, count);
3185
3186
3187   genpic14Code (ic);
3188
3189   /* free up any _G.stackSpil locations allocated */
3190   applyToSet (_G.stackSpil, deallocStackSpil);
3191   _G.slocNum = 0;
3192   setToNull ((void **) &_G.stackSpil);
3193   setToNull ((void **) &_G.spiltSet);
3194   /* mark all registers as free */
3195   pic14_freeAllRegs ();
3196
3197   debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
3198   debugLogClose ();
3199   return;
3200 }