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