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