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