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