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