7d5e782dce4bf89e3a19a231979715bc1cd612fb
[fw/sdcc] / src / pic16 / ralloc.c
1 /*------------------------------------------------------------------------
2
3   ralloc.c - source file for register allocation. PIC16 specific
4
5                 Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
6                 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
7                 Added Pic16 Port Martin Dubuc m.dubuc@rogers.com (2002)
8
9    This program is free software; you can redistribute it and/or modify it
10    under the terms of the GNU General Public License as published by the
11    Free Software Foundation; either version 2, or (at your option) any
12    later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22    
23    In other words, you are welcome to use, share and improve this program.
24    You are forbidden to forbid anyone else to use, share and improve
25    what you give them.   Help stamp out software-hoarding!  
26 -------------------------------------------------------------------------*/
27
28 #include "common.h"
29 #include "ralloc.h"
30 #include "pcode.h"
31 #include "gen.h"
32 #include "device.h"
33
34 #if defined(__BORLANDC__) || defined(_MSC_VER)
35 #define STRCASECMP stricmp
36 #else
37 #define STRCASECMP strcasecmp
38 #endif
39
40 /*-----------------------------------------------------------------*/
41 /* At this point we start getting processor specific although      */
42 /* some routines are non-processor specific & can be reused when   */
43 /* targetting other processors. The decision for this will have    */
44 /* to be made on a routine by routine basis                        */
45 /* routines used to pack registers are most definitely not reusable */
46 /* since the pack the registers depending strictly on the MCU      */
47 /*-----------------------------------------------------------------*/
48
49 regs *pic16_typeRegWithIdx (int idx, int type, int fixed);
50 extern void genpic16Code (iCode *);
51
52 /* Global data */
53 static struct
54   {
55     bitVect *spiltSet;
56     set *stackSpil;
57     bitVect *regAssigned;
58     short blockSpil;
59     int slocNum;
60     bitVect *funcrUsed;         /* registers used in a function */
61     int stackExtend;
62     int dataExtend;
63   }
64 _G;
65
66 /* Shared with gen.c */
67 int pic16_ptrRegReq;            /* one byte pointer register required */
68
69
70 set *pic16_dynAllocRegs=NULL;
71 set *pic16_dynStackRegs=NULL;
72 set *pic16_dynProcessorRegs=NULL;
73 set *pic16_dynDirectRegs=NULL;
74 set *pic16_dynDirectBitRegs=NULL;
75 set *pic16_dynInternalRegs=NULL;
76
77 static hTab  *dynDirectRegNames= NULL;
78 //static hTab  *regHash = NULL;    /* a hash table containing ALL registers */
79
80 set *pic16_rel_udata=NULL;      /* relocatable uninitialized registers */
81 set *pic16_fix_udata=NULL;      /* absolute uninitialized registers */
82 set *pic16_equ_data=NULL;       /* registers used by equates */
83 set *pic16_int_regs=NULL;       /* internal registers placed in access bank 0 to 0x7f */
84
85 set *pic16_builtin_functions=NULL;
86
87 static int dynrIdx=0x10;                //0x20;         // starting temporary register rIdx
88 static int rDirectIdx=0;
89
90 int pic16_nRegs = 128;   // = sizeof (regspic16) / sizeof (regs);
91
92 int pic16_Gstack_base_addr=0; /* The starting address of registers that
93                          * are used to pass and return parameters */
94
95
96
97
98 static void spillThis (symbol *);
99 int pic16_ralloc_debug = 0;
100 static FILE *debugF = NULL;
101 /*-----------------------------------------------------------------*/
102 /* debugLog - open a file for debugging information                */
103 /*-----------------------------------------------------------------*/
104 //static void debugLog(char *inst,char *fmt, ...)
105 static void
106 debugLog (char *fmt,...)
107 {
108   static int append = 0;        // First time through, open the file without append.
109
110   char buffer[256];
111   //char *bufferP=buffer;
112   va_list ap;
113
114   if (!pic16_ralloc_debug || !dstFileName)
115     return;
116
117
118   if (!debugF)
119     {
120       /* create the file name */
121       strcpy (buffer, dstFileName);
122       strcat (buffer, ".d");
123
124       if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
125         {
126           werror (E_FILE_OPEN_ERR, buffer);
127           exit (1);
128         }
129       append = 1;               // Next time debubLog is called, we'll append the debug info
130
131     }
132
133   va_start (ap, fmt);
134
135   vsprintf (buffer, fmt, ap);
136
137   fprintf (debugF, "%s", buffer);
138 /*
139    while (isspace(*bufferP)) bufferP++;
140
141    if (bufferP && *bufferP) 
142    lineCurr = (lineCurr ?
143    connectLine(lineCurr,newLineNode(lb)) :
144    (lineHead = newLineNode(lb)));
145    lineCurr->isInline = _G.inLine;
146    lineCurr->isDebug  = _G.debugLine;
147  */
148   va_end (ap);
149
150 }
151
152 static void
153 debugNewLine (void)
154 {
155         if(!pic16_ralloc_debug)return;
156         
157         if (debugF)
158                 fputc ('\n', debugF);
159 }
160 /*-----------------------------------------------------------------*/
161 /* debugLogClose - closes the debug log file (if opened)           */
162 /*-----------------------------------------------------------------*/
163 static void
164 debugLogClose (void)
165 {
166         if (debugF) {
167                 fclose (debugF);
168                 debugF = NULL;
169         }
170 }
171
172 #define AOP(op) op->aop
173
174 static char *
175 debugAopGet (char *str, operand * op)
176 {
177         if(!pic16_ralloc_debug)return NULL;
178
179         if (str)
180                 debugLog (str);
181
182         printOperand (op, debugF);
183         debugNewLine ();
184
185   return NULL;
186 }
187
188 static char *
189 decodeOp (unsigned int op)
190 {
191         if (op < 128 && op > ' ') {
192                 buffer[0] = (op & 0xff);
193                 buffer[1] = 0;
194           return buffer;
195         }
196
197         switch (op) {
198                 case IDENTIFIER:        return "IDENTIFIER";
199                 case TYPE_NAME:         return "TYPE_NAME";
200                 case CONSTANT:          return "CONSTANT";
201                 case STRING_LITERAL:    return "STRING_LITERAL";
202                 case SIZEOF:            return "SIZEOF";
203                 case PTR_OP:            return "PTR_OP";
204                 case INC_OP:            return "INC_OP";
205                 case DEC_OP:            return "DEC_OP";
206                 case LEFT_OP:           return "LEFT_OP";
207                 case RIGHT_OP:          return "RIGHT_OP";
208                 case LE_OP:             return "LE_OP";
209                 case GE_OP:             return "GE_OP";
210                 case EQ_OP:             return "EQ_OP";
211                 case NE_OP:             return "NE_OP";
212                 case AND_OP:            return "AND_OP";
213                 case OR_OP:             return "OR_OP";
214                 case MUL_ASSIGN:        return "MUL_ASSIGN";
215                 case DIV_ASSIGN:        return "DIV_ASSIGN";
216                 case MOD_ASSIGN:        return "MOD_ASSIGN";
217                 case ADD_ASSIGN:        return "ADD_ASSIGN";
218                 case SUB_ASSIGN:        return "SUB_ASSIGN";
219                 case LEFT_ASSIGN:       return "LEFT_ASSIGN";
220                 case RIGHT_ASSIGN:      return "RIGHT_ASSIGN";
221                 case AND_ASSIGN:        return "AND_ASSIGN";
222                 case XOR_ASSIGN:        return "XOR_ASSIGN";
223                 case OR_ASSIGN:         return "OR_ASSIGN";
224                 case TYPEDEF:           return "TYPEDEF";
225                 case EXTERN:            return "EXTERN";
226                 case STATIC:            return "STATIC";
227                 case AUTO:              return "AUTO";
228                 case REGISTER:          return "REGISTER";
229                 case CODE:              return "CODE";
230                 case EEPROM:            return "EEPROM";
231                 case INTERRUPT:         return "INTERRUPT";
232                 case SFR:               return "SFR";
233                 case AT:                return "AT";
234                 case SBIT:              return "SBIT";
235                 case REENTRANT:         return "REENTRANT";
236                 case USING:             return "USING";
237                 case XDATA:             return "XDATA";
238                 case DATA:              return "DATA";
239                 case IDATA:             return "IDATA";
240                 case PDATA:             return "PDATA";
241                 case VAR_ARGS:          return "VAR_ARGS";
242                 case CRITICAL:          return "CRITICAL";
243                 case NONBANKED:         return "NONBANKED";
244                 case BANKED:            return "BANKED";
245                 case CHAR:              return "CHAR";
246                 case SHORT:             return "SHORT";
247                 case INT:               return "INT";
248                 case LONG:              return "LONG";
249                 case SIGNED:            return "SIGNED";
250                 case UNSIGNED:          return "UNSIGNED";
251                 case FLOAT:             return "FLOAT";
252                 case DOUBLE:            return "DOUBLE";
253                 case CONST:             return "CONST";
254                 case VOLATILE:          return "VOLATILE";
255                 case VOID:              return "VOID";
256                 case BIT:               return "BIT";
257                 case STRUCT:            return "STRUCT";
258                 case UNION:             return "UNION";
259                 case ENUM:              return "ENUM";
260                 case ELIPSIS:           return "ELIPSIS";
261                 case RANGE:             return "RANGE";
262                 case FAR:               return "FAR";
263                 case CASE:              return "CASE";
264                 case DEFAULT:           return "DEFAULT";
265                 case IF:                return "IF";
266                 case ELSE:              return "ELSE";
267                 case SWITCH:            return "SWITCH";
268                 case WHILE:             return "WHILE";
269                 case DO:                return "DO";
270                 case FOR:               return "FOR";
271                 case GOTO:              return "GOTO";
272                 case CONTINUE:          return "CONTINUE";
273                 case BREAK:             return "BREAK";
274                 case RETURN:            return "RETURN";
275                 case INLINEASM:         return "INLINEASM";
276                 case IFX:               return "IFX";
277                 case ADDRESS_OF:        return "ADDRESS_OF";
278                 case GET_VALUE_AT_ADDRESS:      return "GET_VALUE_AT_ADDRESS";
279                 case SPIL:              return "SPIL";
280                 case UNSPIL:            return "UNSPIL";
281                 case GETHBIT:           return "GETHBIT";
282                 case BITWISEAND:        return "BITWISEAND";
283                 case UNARYMINUS:        return "UNARYMINUS";
284                 case IPUSH:             return "IPUSH";
285                 case IPOP:              return "IPOP";
286                 case PCALL:             return "PCALL";
287                 case ENDFUNCTION:       return "ENDFUNCTION";
288                 case JUMPTABLE:         return "JUMPTABLE";
289                 case RRC:               return "RRC";
290                 case RLC:               return "RLC";
291                 case CAST:              return "CAST";
292                 case CALL:              return "CALL";
293                 case PARAM:             return "PARAM  ";
294                 case NULLOP:            return "NULLOP";
295                 case BLOCK:             return "BLOCK";
296                 case LABEL:             return "LABEL";
297                 case RECEIVE:           return "RECEIVE";
298                 case SEND:              return "SEND";
299         }
300         sprintf (buffer, "unkown op %d %c", op, op & 0xff);
301
302   return buffer;
303 }
304 /*-----------------------------------------------------------------*/
305 /*-----------------------------------------------------------------*/
306 static char *
307 debugLogRegType (short type)
308 {
309         if(!pic16_ralloc_debug)return NULL;
310         switch (type) {
311                 case REG_GPR: return "REG_GPR";
312                 case REG_PTR: return "REG_PTR";
313                 case REG_CND: return "REG_CND";
314         }
315         sprintf (buffer, "unknown reg type %d", type);
316
317   return buffer;
318 }
319
320 /*-----------------------------------------------------------------*/
321 /*-----------------------------------------------------------------*/
322 static int regname2key(char const *name)
323 {
324   int key = 0;
325
326   if(!name)
327     return 0;
328
329   while(*name) {
330
331     key += (*name++) + 1;
332
333   }
334
335   return ( (key + (key >> 4) + (key>>8)) & 0x3f);
336
337 }
338
339 /*-----------------------------------------------------------------*/
340 /* newReg - allocate and init memory for a new register            */
341 /*-----------------------------------------------------------------*/
342 regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
343 {
344
345   regs *dReg;
346
347         dReg = Safe_calloc(1,sizeof(regs));
348         dReg->type = type;
349         dReg->pc_type = pc_type;
350         dReg->rIdx = rIdx;
351         if(name) 
352                 dReg->name = Safe_strdup(name);
353         else {
354                 sprintf(buffer,"r0x%02X", dReg->rIdx);
355                 if(type == REG_STK)
356                         *buffer = 's';
357                         dReg->name = Safe_strdup(buffer);
358         }
359
360
361         dReg->isFree = 0;
362         dReg->wasUsed = 1;
363         dReg->isEmitted = 0;
364
365         if(type == REG_SFR) {
366                 dReg->isFixed = 1;
367                 dReg->address = rIdx;
368                 dReg->accessBank = 1;
369         } else {
370                 dReg->isFixed = 0;
371                 dReg->address = 0;
372                 dReg->accessBank = 0;
373         }
374
375 //      fprintf(stderr,"newReg: %s, rIdx = 0x%02x\taccess= %d\tregop= %p\n",dReg->name,rIdx, dReg->accessBank, refop);
376
377         dReg->size = size;
378         dReg->alias = alias;
379         dReg->reg_alias = NULL;
380         dReg->reglives.usedpFlows = newSet();
381         dReg->reglives.assignedpFlows = newSet();
382         dReg->regop = refop;
383   
384         if(!(type == REG_SFR && alias == 0x80))
385                 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
386
387   return dReg;
388 }
389
390 /*-----------------------------------------------------------------*/
391 /* regWithIdx - Search through a set of registers that matches idx */
392 /*-----------------------------------------------------------------*/
393 static regs *
394 regWithIdx (set *dRegs, int idx, int fixed)
395 {
396   regs *dReg;
397
398   for (dReg = setFirstItem(dRegs) ; dReg ; 
399        dReg = setNextItem(dRegs)) {
400
401     if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
402       return dReg;
403     }
404   }
405
406   return NULL;
407 }
408
409 /*-----------------------------------------------------------------*/
410 /* regFindFree - Search for a free register in a set of registers  */
411 /*-----------------------------------------------------------------*/
412 static regs *
413 regFindFree (set *dRegs)
414 {
415   regs *dReg;
416
417   for (dReg = setFirstItem(dRegs) ; dReg ; 
418        dReg = setNextItem(dRegs)) {
419
420 //      fprintf(stderr, "%s:%d checking register %s (%p) [rIdx: 0x%02x] if free= %d\n",
421 //              __FILE__, __LINE__, dReg->name, dReg, dReg->rIdx, dReg->isFree);
422
423     if(dReg->isFree) {
424       return dReg;
425     }
426   }
427
428   return NULL;
429 }
430 /*-----------------------------------------------------------------*/
431 /* pic16_initStack - allocate registers for a pseudo stack               */
432 /*-----------------------------------------------------------------*/
433 void pic16_initStack(int base_address, int size)
434 {
435
436   int i;
437
438   pic16_Gstack_base_addr = base_address;
439   //fprintf(stderr,"initStack");
440
441   for(i = 0; i<size; i++)
442     addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
443 }
444
445 /*-----------------------------------------------------------------*
446  *-----------------------------------------------------------------*/
447 regs *
448 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
449 {
450   regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
451
452 //      fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
453
454         reg->wasUsed = 0;               // we do not know if they are going to be used at all
455         reg->accessBank = 1;            // implicit add access Bank
456
457   return addSet(&pic16_dynProcessorRegs, reg);
458 }
459
460 /*-----------------------------------------------------------------*
461  *-----------------------------------------------------------------*/
462
463 regs *
464 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
465 {
466   regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
467
468 //  fprintf(stderr,"%s:%d: %s   %s addr =0x%x\n",__FILE__, __LINE__, __FUNCTION__, name, rIdx);
469
470     if(reg) {
471       reg->wasUsed = 0;
472       return addSet(&pic16_dynInternalRegs,reg);
473     }
474
475   return NULL;
476 }
477 /*-----------------------------------------------------------------*/
478 /* allocReg - allocates register of given type                     */
479 /*-----------------------------------------------------------------*/
480 static regs *
481 allocReg (short type)
482 {
483   regs * reg=NULL;
484   
485 #if 0
486   if(dynrIdx > pic16_nRegs)
487         return NULL;
488 #endif
489
490         /* try to reuse some unused registers */
491         reg = regFindFree( pic16_dynAllocRegs );
492
493         if(reg) {
494 //              fprintf(stderr, "%s: found FREE register %s\n", __FILE__, reg->name);
495         }
496
497         if(!reg) {
498                 reg = newReg(REG_GPR, PO_GPR_TEMP, dynrIdx++, NULL, 1, 0, NULL);
499 //              addSet(&pic16_dynAllocRegs, reg);
500         }
501
502         addSet(&pic16_dynAllocRegs, reg);
503
504         reg->isFree=0;
505
506 //      debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
507
508 //      fprintf(stderr,"%s:%d: %s\t%s addr= 0x%x\trIdx= 0x%02x isFree: %d\n",
509 //              __FILE__, __LINE__, __FUNCTION__, reg->name, reg->address, reg->rIdx, reg->isFree);
510
511         if(reg) {
512                 reg->accessBank = 1;    /* this is a temporary register alloc in accessBank */
513                 reg->isLocal = 1;       /* this is a local frame register */
514         }
515         
516         if (currFunc) {
517 //              fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
518                 currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
519         }
520  
521   return (reg);         // addSet(&pic16_dynAllocRegs,reg);
522
523 }
524
525
526 /*-----------------------------------------------------------------*/
527 /* pic16_dirregWithName - search for register by name                    */
528 /*-----------------------------------------------------------------*/
529 regs *
530 pic16_dirregWithName (char *name)
531 {
532   int hkey;
533   regs *reg;
534
535   if(!name)
536     return NULL;
537
538   /* hash the name to get a key */
539
540   hkey = regname2key(name);
541
542 //      fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
543
544   reg = hTabFirstItemWK(dynDirectRegNames, hkey);
545
546   while(reg) {
547
548     if(STRCASECMP(reg->name, name) == 0) {
549       return(reg);
550     }
551
552     reg = hTabNextItemWK (dynDirectRegNames);
553   
554   }
555
556   return NULL; // name wasn't found in the hash table
557 }
558
559
560 /*-----------------------------------------------------------------*/
561 /* pic16_allocDirReg - allocates register of given type                  */
562 /*-----------------------------------------------------------------*/
563 regs *
564 pic16_allocDirReg (operand *op )
565 {
566   regs *reg;
567   char *name;
568
569         if(!IS_SYMOP(op)) {
570                 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
571 //              fprintf(stderr, "%s BAD, op is NULL\n", __FUNCTION__);
572           return NULL;
573         }
574
575         name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
576
577         if(!SPEC_OCLS( OP_SYM_ETYPE(op))) {                                                                     // patch 13
578                 if(pic16_debug_verbose)                                                                         //
579                 {                                                                                               //
580                         fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__,      //
581                                 OP_SYMBOL(op)->name, OP_SYMBOL(op)->rname);                                                             //
582                 }                                                                                               //
583                 return NULL;                                                                                    //
584         }                                                                                                       // patch 13
585
586         debugLog ("%s:%d symbol name %s\n", __FUNCTION__, __LINE__, name);
587 //      fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
588
589         {
590                 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
591                         debugLog(" %d  const char\n",__LINE__);
592                         debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
593 //                      fprintf(stderr, " %d  const char\n",__LINE__);
594 //                      fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
595                 }
596
597         
598                 debugLog("  %d  storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
599                 if (IS_CODE ( OP_SYM_ETYPE(op)) )
600                         debugLog(" %d  code space\n",__LINE__);
601
602                 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
603                         debugLog(" %d  integral\n",__LINE__);
604
605                 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
606                         debugLog(" %d  literal\n",__LINE__);
607
608                 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
609                         debugLog(" %d  specifier\n",__LINE__);
610
611                 debugAopGet(NULL, op);
612         }
613
614         if (IS_CODE ( OP_SYM_ETYPE(op)) )
615                 return NULL;
616
617         /* First, search the hash table to see if there is a register with this name */
618         if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
619                 reg=NULL;
620 //              reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
621
622 #if 0
623                 if(!reg) 
624                         fprintf(stderr,"%s:%d: ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
625                                         __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
626                 else
627                         fprintf(stderr,"%s:%d: ralloc %s at fixed address has already been declared, addr=0x%x\n",
628                                         __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
629 #endif
630         } else {
631 //              fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
632     
633                 reg = pic16_dirregWithName(name);
634         }
635
636         if(!reg) {
637           int address = 0;
638           int regtype = REG_GPR;
639     
640                 /* if this is at an absolute address, then get the address. */
641                 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
642                         address = SPEC_ADDR ( OP_SYM_ETYPE(op));
643 //                      fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
644                 }
645
646                 /* Register wasn't found in hash, so let's create
647                  * a new one and put it in the hash table AND in the 
648                  * dynDirectRegNames set */
649                 if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {
650
651 //                      if(pic16_debug_verbose)
652 //                              fprintf(stderr, "%s:%d symbol %s in codespace\n", __FILE__, __LINE__,
653 //                                      OP_SYMBOL(op)->name);
654
655                         debugLog("%s:%d sym: %s in codespace\n", __FUNCTION__, __LINE__, OP_SYMBOL(op)->name);
656                   return NULL;
657                 }
658
659                 if(1) { //!PIC16_IS_CONFIG_ADDRESS(address)) {
660 //                      fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
661
662                         /* this is an error, why added? -- VR */
663 //                      if(SPEC_SCLS(OP_SYM_ETYPE(op)))regtype = REG_SFR;
664
665                         if(OP_SYMBOL(op)->onStack) {
666 //                              fprintf(stderr, "%s:%d onStack %s\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
667                                 OP_SYMBOL(op)->onStack = 0;
668                                 SPEC_OCLS(OP_SYM_ETYPE(op)) = data;
669                                 regtype = REG_GPR;
670                         }
671
672                         if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {                                               // patch 13
673                                 if(pic16_debug_verbose)                                                                 //
674                                 {                                                                                       //
675                                         fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d\n",
676                                                 IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
677                                                 IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
678                                                 IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
679                                                 IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
680                                                 IN_STACK( OP_SYM_ETYPE(op)));
681
682                                         fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,        //
683                                                 OP_SYMBOL(op)->name);                                                   //
684                                 }                                                                                       //
685 //                              return NULL;                                                                            //
686                         }                                                                                               // patch 13
687
688                         reg = newReg(regtype, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
689                         debugLog ("%d  -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
690
691 //                      hTabAddItem(&dynDirectRegNames, regname2key(name), reg);        /* commented out */
692
693 //                      if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
694 //                              fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
695 //                              reg->type = REG_SFR;
696 //                      }
697
698                         if (IS_BITVAR (OP_SYM_ETYPE(op))) {
699 //                              fprintf(stderr, "%s:%d adding %s in bit registers\n", __FILE__, __LINE__, reg->name);
700                                 addSet(&pic16_dynDirectBitRegs, reg);
701                                 reg->isBitField = 1;
702                         } else {
703 //                              fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
704 //                              addSet(&pic16_dynDirectRegs, reg);
705                                 checkAddReg(&pic16_dynDirectRegs, reg);
706                         }
707         
708                 } else {
709                         debugLog ("  -- %s is declared at address 0x30000x\n",name);
710 //                      fprintf(stderr, "  -- %s is declared at address 0x30000x\n",name);
711         
712                   return NULL;
713                 }
714         }
715
716         if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
717                 reg->isFixed = 1;
718                 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
719
720                 /* work around for user defined registers in access bank */
721                 if((reg->address>= 0x00 && reg->address < 0x80)
722                         || (reg->address >= 0xf80 && reg->address <= 0xfff))
723                         reg->accessBank = 1;
724                 
725                 debugLog ("  -- and it is at a fixed address 0x%02x\n",reg->address);
726         }
727
728   return reg;
729 }
730
731 /*-----------------------------------------------------------------*/
732 /* pic16_allocRegByName - allocates register of given type                  */
733 /*-----------------------------------------------------------------*/
734 regs *
735 pic16_allocRegByName (char *name, int size, operand *op)
736 {
737
738   regs *reg;
739
740   if(!name) {
741     fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
742     exit(1);
743   }
744
745   /* First, search the hash table to see if there is a register with this name */
746   reg = pic16_dirregWithName(name);
747
748   if(!reg) {
749
750     /* Register wasn't found in hash, so let's create
751      * a new one and put it in the hash table AND in the 
752      * dynDirectRegNames set */
753
754 //      fprintf (stderr,"%s:%d symbol name %s\tregop= %p\n", __FUNCTION__, __LINE__, name, op);
755
756     reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, op);
757
758     debugLog ("%d  -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
759         //fprintf(stderr, "  -- added %s to hash, size = %d\n", name,reg->size);
760
761     //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);  /* initially commented out */
762     addSet(&pic16_dynDirectRegs, reg);
763   }
764
765   return reg;
766 }
767
768 /*-----------------------------------------------------------------*/
769 /* RegWithIdx - returns pointer to register with index number       */
770 /*-----------------------------------------------------------------*/
771 regs *pic16_typeRegWithIdx (int idx, int type, int fixed)
772 {
773
774   regs *dReg;
775
776   debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
777 //  fprintf(stderr, "%s - requesting index = 0x%x\n", __FUNCTION__, idx);
778
779   switch (type) {
780
781   case REG_GPR:
782     if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
783
784       debugLog ("Found a Dynamic Register!\n");
785       return dReg;
786     }
787     if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
788       debugLog ("Found a Direct Register!\n");
789       return dReg;
790     }
791
792     break;
793   case REG_STK:
794     if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
795       debugLog ("Found a Stack Register!\n");
796       return dReg;
797     }
798     break;
799   case REG_SFR:
800     if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, fixed)) != NULL ) {
801       debugLog ("Found a Processor Register!\n");
802       return dReg;
803     }
804
805   case REG_CND:
806   case REG_PTR:
807   default:
808     break;
809   }
810
811
812   return NULL;
813 }
814
815 /*-----------------------------------------------------------------*/
816 /* pic16_regWithIdx - returns pointer to register with index number*/
817 /*-----------------------------------------------------------------*/
818 regs *
819 pic16_regWithIdx (int idx)
820 {
821   regs *dReg;
822
823   if( (dReg = pic16_typeRegWithIdx(idx,REG_GPR,0)) != NULL)
824     return dReg;
825
826   if( (dReg = pic16_typeRegWithIdx(idx,REG_SFR,0)) != NULL)
827     return dReg;
828
829   if( (dReg = pic16_typeRegWithIdx(idx,REG_STK,0)) != NULL)
830     return dReg;
831
832   return NULL;
833 }
834
835 /*-----------------------------------------------------------------*/
836 /* pic16_regWithIdx - returns pointer to register with index number       */
837 /*-----------------------------------------------------------------*/
838 regs *
839 pic16_allocWithIdx (int idx)
840 {
841
842   regs *dReg;
843
844   debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
845 //  fprintf(stderr, "%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
846
847   if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
848
849     debugLog ("Found a Dynamic Register!\n");
850   } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
851     debugLog ("Found a Stack Register!\n");
852   } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
853     debugLog ("Found a Processor Register!\n");
854     fprintf(stderr, "Found a processor register! %s\n", dReg->name);
855   } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
856     debugLog ("Found an Internal Register!\n");
857   } else {
858     
859     debugLog ("Dynamic Register not found\n");
860
861
862     //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
863     werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
864             "regWithIdx not found");
865     exit (1);
866
867   }
868
869   dReg->wasUsed = 1;
870   dReg->isFree = 0;
871
872   return dReg;
873 }
874 /*-----------------------------------------------------------------*/
875 /*-----------------------------------------------------------------*/
876 regs *
877 pic16_findFreeReg(short type)
878 {
879   //  int i;
880   regs* dReg;
881
882   switch (type) {
883   case REG_GPR:
884     if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
885       return dReg;
886     return allocReg( REG_GPR );         //addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
887
888   case REG_STK:
889
890     if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
891       return dReg;
892
893     return NULL;
894
895   case REG_PTR:
896   case REG_CND:
897   case REG_SFR:
898   default:
899     return NULL;
900   }
901 }
902 /*-----------------------------------------------------------------*/
903 /* freeReg - frees a register                                      */
904 /*-----------------------------------------------------------------*/
905 static void
906 freeReg (regs * reg)
907 {
908         debugLog ("%s\n", __FUNCTION__);
909 //      fprintf(stderr, "%s:%d register %s (%p) is freed\n", __FILE__, __LINE__, reg->name, reg);
910         reg->isFree = 1;
911 }
912
913
914 /*-----------------------------------------------------------------*/
915 /* nFreeRegs - returns number of free registers                    */
916 /*-----------------------------------------------------------------*/
917 static int
918 nFreeRegs (int type)
919 {
920   regs *reg;
921   int nfr=0;
922
923
924                 /* although I fixed the register allocation/freeing scheme
925                  * the for loop below doesn't give valid results. I do not
926                  * know why yet. -- VR 10-Jan-2003 */
927                  
928         return 100;
929
930
931   /* dynamically allocate as many as we need and worry about
932    * fitting them into a PIC later */
933
934   debugLog ("%s\n", __FUNCTION__);
935
936         for(reg = setFirstItem(pic16_dynAllocRegs); reg; reg=setNextItem(pic16_dynAllocRegs))
937                 if((reg->type == type) && reg->isFree)nfr++;
938
939         fprintf(stderr, "%s:%d # of free registers= %d\n", __FILE__, __LINE__, nfr);
940   return nfr;
941 }
942
943 /*-----------------------------------------------------------------*/
944 /* nfreeRegsType - free registers with type                         */
945 /*-----------------------------------------------------------------*/
946 static int
947 nfreeRegsType (int type)
948 {
949   int nfr;
950   debugLog ("%s\n", __FUNCTION__);
951   if (type == REG_PTR)
952     {
953       if ((nfr = nFreeRegs (type)) == 0)
954         return nFreeRegs (REG_GPR);
955     }
956
957   return nFreeRegs (type);
958 }
959 #if 0
960 static void writeSetUsedRegs(FILE *of, set *dRegs)
961 {
962
963   regs *dReg;
964
965   for (dReg = setFirstItem(dRegs) ; dReg ; 
966        dReg = setNextItem(dRegs)) {
967
968     if(dReg->wasUsed)
969       fprintf (of, "\t%s\n",dReg->name);
970   }
971
972 }
973 #endif
974
975 extern void pic16_groupRegistersInSection(set *regset);
976
977 extern void pic16_dump_equates(FILE *of, set *equs);
978 //extern void pic16_dump_map(void);
979 extern void pic16_dump_usection(FILE *of, set *section, int fix);
980 extern void pic16_dump_isection(FILE *of, set *section, int fix);
981 extern void pic16_dump_int_registers(FILE *of, set *section);
982 extern void pic16_dump_idata(FILE *of, set *idataSymSet);
983
984 static void packBits(set *bregs)
985 {
986   set *regset;
987   regs *breg;
988   regs *bitfield=NULL;
989   regs *relocbitfield=NULL;
990   int bit_no=0;
991   int byte_no=-1;
992   char buffer[20];
993
994
995   for (regset = bregs ; regset ;
996        regset = regset->next) {
997
998     breg = regset->item;
999     breg->isBitField = 1;
1000     //fprintf(stderr,"bit reg: %s\n",breg->name);
1001
1002     if(breg->isFixed) {
1003       //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1004
1005       bitfield = pic16_typeRegWithIdx (breg->address >> 3, -1 , 1);
1006       breg->rIdx = breg->address & 7;
1007       breg->address >>= 3;
1008
1009       if(!bitfield) {
1010         sprintf (buffer, "fbitfield%02x", breg->address);
1011         //fprintf(stderr,"new bit field\n");
1012         bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1013         bitfield->isBitField = 1;
1014         bitfield->isFixed = 1;
1015         bitfield->address = breg->address;
1016         addSet(&pic16_dynDirectRegs,bitfield);
1017         //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1018       } else {
1019         //fprintf(stderr,"  which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1020         ;
1021       }
1022       breg->reg_alias = bitfield;
1023       bitfield = NULL;
1024
1025     } else {
1026       if(!relocbitfield || bit_no >7) {
1027         byte_no++;
1028         bit_no=0;
1029         sprintf (buffer, "bitfield%d", byte_no);
1030         //fprintf(stderr,"new relocatable bit field\n");
1031         relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1032         relocbitfield->isBitField = 1;
1033         addSet(&pic16_dynDirectRegs,relocbitfield);
1034         //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1035
1036       }
1037
1038       breg->reg_alias = relocbitfield;
1039       breg->address = rDirectIdx;   /* byte_no; */
1040       breg->rIdx = bit_no++;
1041     }
1042   }
1043       
1044 }
1045
1046
1047
1048 #if 0
1049 static void bitEQUs(FILE *of, set *bregs)
1050 {
1051   regs *breg,*bytereg;
1052   int bit_no=0;
1053
1054   //fprintf(stderr," %s\n",__FUNCTION__);
1055   for (breg = setFirstItem(bregs) ; breg ;
1056        breg = setNextItem(bregs)) {
1057
1058     //fprintf(stderr,"bit reg: %s\n",breg->name);
1059
1060     bytereg = breg->reg_alias;
1061     if(bytereg)
1062       fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1063                breg->name,
1064                bytereg->name,
1065                breg->rIdx & 0x0007);
1066
1067     else {
1068       fprintf(stderr, "bit field is not assigned to a register\n");
1069       fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1070                breg->name,
1071                bit_no>>3,
1072                bit_no & 0x0007);
1073
1074       bit_no++;
1075     }
1076   }
1077       
1078 }
1079
1080 static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1081 {
1082   regs *reg;
1083
1084
1085   for (reg = setFirstItem(fregs) ; reg ;
1086        reg = setNextItem(fregs)) {
1087
1088     if(!reg->isEmitted && reg->wasUsed) {
1089       if(use_rIdx) {
1090         if (reg->type != REG_SFR) {
1091           fprintf (of, "%s\tEQU\t0x%03x\n",
1092                    reg->name,
1093                    reg->rIdx);
1094         }
1095       }
1096       else
1097         fprintf (of, "%s\tEQU\t0x%03x\n",
1098                  reg->name,
1099                  reg->address);
1100     }
1101   }
1102       
1103 }
1104 #endif
1105
1106 void pic16_writeUsedRegs(FILE *of) 
1107 {
1108         packBits(pic16_dynDirectBitRegs);
1109
1110         pic16_groupRegistersInSection(pic16_dynAllocRegs);
1111         pic16_groupRegistersInSection(pic16_dynInternalRegs);
1112         pic16_groupRegistersInSection(pic16_dynStackRegs);
1113         pic16_groupRegistersInSection(pic16_dynDirectRegs);
1114         pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1115         pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1116         
1117         
1118 #if 0
1119         pic16_assignFixedRegisters(pic16_dynAllocRegs);
1120         pic16_assignFixedRegisters(pic16_dynStackRegs);
1121         pic16_assignFixedRegisters(pic16_dynDirectRegs);
1122         pic16_assignFixedRegisters(pic16_dynProcessorRegs);
1123
1124         pic16_assignRelocatableRegisters(pic16_dynDirectBitRegs, 0);
1125         pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
1126         pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
1127         pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
1128         pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
1129 #endif
1130
1131 //      pic16_dump_map();
1132 //      pic16_dump_cblock(of);
1133
1134         /* dump equates */
1135         pic16_dump_equates(of, pic16_equ_data);
1136
1137         /* dump initialised data */
1138         pic16_dump_isection(of, rel_idataSymSet, 0);
1139         pic16_dump_isection(of, fix_idataSymSet, 1);
1140
1141 //      pic16_dump_idata(of, idataSymSet);
1142
1143         /* dump internal registers */
1144         pic16_dump_int_registers(of, pic16_int_regs);
1145         
1146         /* dump other variables */
1147         pic16_dump_usection(of, pic16_rel_udata, 0);
1148         pic16_dump_usection(of, pic16_fix_udata, 1);
1149         
1150 }
1151
1152 #if 0
1153 /*-----------------------------------------------------------------*/
1154 /* allDefsOutOfRange - all definitions are out of a range          */
1155 /*-----------------------------------------------------------------*/
1156 static bool
1157 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1158 {
1159   int i;
1160
1161   debugLog ("%s\n", __FUNCTION__);
1162   if (!defs)
1163     return TRUE;
1164
1165   for (i = 0; i < defs->size; i++)
1166     {
1167       iCode *ic;
1168
1169       if (bitVectBitValue (defs, i) &&
1170           (ic = hTabItemWithKey (iCodehTab, i)) &&
1171           (ic->seq >= fseq && ic->seq <= toseq))
1172
1173         return FALSE;
1174
1175     }
1176
1177   return TRUE;
1178 }
1179 #endif
1180
1181 /*-----------------------------------------------------------------*/
1182 /* computeSpillable - given a point find the spillable live ranges */
1183 /*-----------------------------------------------------------------*/
1184 static bitVect *
1185 computeSpillable (iCode * ic)
1186 {
1187   bitVect *spillable;
1188
1189   debugLog ("%s\n", __FUNCTION__);
1190   /* spillable live ranges are those that are live at this 
1191      point . the following categories need to be subtracted
1192      from this set. 
1193      a) - those that are already spilt
1194      b) - if being used by this one
1195      c) - defined by this one */
1196
1197   spillable = bitVectCopy (ic->rlive);
1198   spillable =
1199     bitVectCplAnd (spillable, _G.spiltSet);     /* those already spilt */
1200   spillable =
1201     bitVectCplAnd (spillable, ic->uses);        /* used in this one */
1202   bitVectUnSetBit (spillable, ic->defKey);
1203   spillable = bitVectIntersect (spillable, _G.regAssigned);
1204   return spillable;
1205
1206 }
1207
1208 /*-----------------------------------------------------------------*/
1209 /* noSpilLoc - return true if a variable has no spil location      */
1210 /*-----------------------------------------------------------------*/
1211 static int
1212 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1213 {
1214   debugLog ("%s\n", __FUNCTION__);
1215   return (sym->usl.spillLoc ? 0 : 1);
1216 }
1217
1218 /*-----------------------------------------------------------------*/
1219 /* hasSpilLoc - will return 1 if the symbol has spil location      */
1220 /*-----------------------------------------------------------------*/
1221 static int
1222 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1223 {
1224   debugLog ("%s\n", __FUNCTION__);
1225   return (sym->usl.spillLoc ? 1 : 0);
1226 }
1227
1228 /*-----------------------------------------------------------------*/
1229 /* directSpilLoc - will return 1 if the splilocation is in direct  */
1230 /*-----------------------------------------------------------------*/
1231 static int
1232 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1233 {
1234   debugLog ("%s\n", __FUNCTION__);
1235   if (sym->usl.spillLoc &&
1236       (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1237     return 1;
1238   else
1239     return 0;
1240 }
1241
1242 /*-----------------------------------------------------------------*/
1243 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1244 /*                    but is not used as a pointer                 */
1245 /*-----------------------------------------------------------------*/
1246 static int
1247 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1248 {
1249   debugLog ("%s\n", __FUNCTION__);
1250   return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1251 }
1252
1253 /*-----------------------------------------------------------------*/
1254 /* rematable - will return 1 if the remat flag is set              */
1255 /*-----------------------------------------------------------------*/
1256 static int
1257 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1258 {
1259   debugLog ("%s\n", __FUNCTION__);
1260   return sym->remat;
1261 }
1262
1263 /*-----------------------------------------------------------------*/
1264 /* notUsedInRemaining - not used or defined in remain of the block */
1265 /*-----------------------------------------------------------------*/
1266 static int
1267 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1268 {
1269   debugLog ("%s\n", __FUNCTION__);
1270   return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1271           allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1272 }
1273
1274 /*-----------------------------------------------------------------*/
1275 /* allLRs - return true for all                                    */
1276 /*-----------------------------------------------------------------*/
1277 static int
1278 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1279 {
1280   debugLog ("%s\n", __FUNCTION__);
1281   return 1;
1282 }
1283
1284 /*-----------------------------------------------------------------*/
1285 /* liveRangesWith - applies function to a given set of live range  */
1286 /*-----------------------------------------------------------------*/
1287 static set *
1288 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1289                 eBBlock * ebp, iCode * ic)
1290 {
1291   set *rset = NULL;
1292   int i;
1293
1294   debugLog ("%s\n", __FUNCTION__);
1295   if (!lrs || !lrs->size)
1296     return NULL;
1297
1298   for (i = 1; i < lrs->size; i++)
1299     {
1300       symbol *sym;
1301       if (!bitVectBitValue (lrs, i))
1302         continue;
1303
1304       /* if we don't find it in the live range 
1305          hash table we are in serious trouble */
1306       if (!(sym = hTabItemWithKey (liveRanges, i)))
1307         {
1308           werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1309                   "liveRangesWith could not find liveRange");
1310           exit (1);
1311         }
1312
1313       if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1314         addSetHead (&rset, sym);
1315     }
1316
1317   return rset;
1318 }
1319
1320
1321 /*-----------------------------------------------------------------*/
1322 /* leastUsedLR - given a set determines which is the least used    */
1323 /*-----------------------------------------------------------------*/
1324 static symbol *
1325 leastUsedLR (set * sset)
1326 {
1327   symbol *sym = NULL, *lsym = NULL;
1328
1329   debugLog ("%s\n", __FUNCTION__);
1330   sym = lsym = setFirstItem (sset);
1331
1332   if (!lsym)
1333     return NULL;
1334
1335   for (; lsym; lsym = setNextItem (sset))
1336     {
1337
1338       /* if usage is the same then prefer
1339          the spill the smaller of the two */
1340       if (lsym->used == sym->used)
1341         if (getSize (lsym->type) < getSize (sym->type))
1342           sym = lsym;
1343
1344       /* if less usage */
1345       if (lsym->used < sym->used)
1346         sym = lsym;
1347
1348     }
1349
1350   setToNull ((void *) &sset);
1351   sym->blockSpil = 0;
1352   return sym;
1353 }
1354
1355 /*-----------------------------------------------------------------*/
1356 /* noOverLap - will iterate through the list looking for over lap  */
1357 /*-----------------------------------------------------------------*/
1358 static int
1359 noOverLap (set * itmpStack, symbol * fsym)
1360 {
1361   symbol *sym;
1362   debugLog ("%s\n", __FUNCTION__);
1363
1364
1365   for (sym = setFirstItem (itmpStack); sym;
1366        sym = setNextItem (itmpStack))
1367     {
1368       if (sym->liveTo > fsym->liveFrom)
1369         return 0;
1370
1371     }
1372
1373   return 1;
1374 }
1375
1376 /*-----------------------------------------------------------------*/
1377 /* isFree - will return 1 if the a free spil location is found     */
1378 /*-----------------------------------------------------------------*/
1379 static
1380 DEFSETFUNC (isFree)
1381 {
1382   symbol *sym = item;
1383   V_ARG (symbol **, sloc);
1384   V_ARG (symbol *, fsym);
1385
1386   debugLog ("%s\n", __FUNCTION__);
1387   /* if already found */
1388   if (*sloc)
1389     return 0;
1390
1391   /* if it is free && and the itmp assigned to
1392      this does not have any overlapping live ranges
1393      with the one currently being assigned and
1394      the size can be accomodated  */
1395   if (sym->isFree &&
1396       noOverLap (sym->usl.itmpStack, fsym) &&
1397       getSize (sym->type) >= getSize (fsym->type))
1398     {
1399       *sloc = sym;
1400       return 1;
1401     }
1402
1403   return 0;
1404 }
1405
1406 /*-----------------------------------------------------------------*/
1407 /* spillLRWithPtrReg :- will spil those live ranges which use PTR  */
1408 /*-----------------------------------------------------------------*/
1409 static void
1410 spillLRWithPtrReg (symbol * forSym)
1411 {
1412   symbol *lrsym;
1413   regs *r0, *r1;
1414   int k;
1415
1416   debugLog ("%s\n", __FUNCTION__);
1417   if (!_G.regAssigned ||
1418       bitVectIsZero (_G.regAssigned))
1419     return;
1420
1421   r0 = pic16_regWithIdx (R0_IDX);
1422   r1 = pic16_regWithIdx (R1_IDX);
1423
1424   /* for all live ranges */
1425   for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1426        lrsym = hTabNextItem (liveRanges, &k))
1427     {
1428       int j;
1429
1430       /* if no registers assigned to it or
1431          spilt */
1432       /* if it does not overlap with this then 
1433          not need to spill it */
1434
1435       if (lrsym->isspilt || !lrsym->nRegs ||
1436           (lrsym->liveTo < forSym->liveFrom))
1437         continue;
1438
1439       /* go thru the registers : if it is either
1440          r0 or r1 then spil it */
1441       for (j = 0; j < lrsym->nRegs; j++)
1442         if (lrsym->regs[j] == r0 ||
1443             lrsym->regs[j] == r1)
1444           {
1445             spillThis (lrsym);
1446             break;
1447           }
1448     }
1449
1450 }
1451
1452 /*-----------------------------------------------------------------*/
1453 /* createStackSpil - create a location on the stack to spil        */
1454 /*-----------------------------------------------------------------*/
1455 static symbol *
1456 createStackSpil (symbol * sym)
1457 {
1458   symbol *sloc = NULL;
1459   int useXstack, model, noOverlay;
1460
1461   char slocBuffer[30];
1462   debugLog ("%s\n", __FUNCTION__);
1463
1464   /* first go try and find a free one that is already 
1465      existing on the stack */
1466   if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1467     {
1468       /* found a free one : just update & return */
1469       sym->usl.spillLoc = sloc;
1470       sym->stackSpil = 1;
1471       sloc->isFree = 0;
1472       addSetHead (&sloc->usl.itmpStack, sym);
1473       return sym;
1474     }
1475
1476   /* could not then have to create one , this is the hard part
1477      we need to allocate this on the stack : this is really a
1478      hack!! but cannot think of anything better at this time */
1479
1480   if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1481     {
1482       fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1483                __FILE__, __LINE__);
1484       exit (1);
1485     }
1486
1487   sloc = newiTemp (slocBuffer);
1488
1489   /* set the type to the spilling symbol */
1490   sloc->type = copyLinkChain (sym->type);
1491   sloc->etype = getSpec (sloc->type);
1492   SPEC_SCLS (sloc->etype) = S_DATA;
1493   SPEC_EXTR (sloc->etype) = 0;
1494   SPEC_STAT (sloc->etype) = 0;
1495
1496   /* we don't allow it to be allocated`
1497      onto the external stack since : so we
1498      temporarily turn it off ; we also
1499      turn off memory model to prevent
1500      the spil from going to the external storage
1501      and turn off overlaying 
1502    */
1503
1504   useXstack = options.useXstack;
1505   model = options.model;
1506   noOverlay = options.noOverlay;
1507   options.noOverlay = 1;
1508   options.model = options.useXstack = 0;
1509
1510   allocLocal (sloc);
1511
1512   options.useXstack = useXstack;
1513   options.model = model;
1514   options.noOverlay = noOverlay;
1515   sloc->isref = 1;              /* to prevent compiler warning */
1516
1517   /* if it is on the stack then update the stack */
1518   if (IN_STACK (sloc->etype))
1519     {
1520       currFunc->stack += getSize (sloc->type);
1521       _G.stackExtend += getSize (sloc->type);
1522     }
1523   else
1524     _G.dataExtend += getSize (sloc->type);
1525
1526   /* add it to the _G.stackSpil set */
1527   addSetHead (&_G.stackSpil, sloc);
1528   sym->usl.spillLoc = sloc;
1529   sym->stackSpil = 1;
1530
1531   /* add it to the set of itempStack set 
1532      of the spill location */
1533   addSetHead (&sloc->usl.itmpStack, sym);
1534   return sym;
1535 }
1536
1537 /*-----------------------------------------------------------------*/
1538 /* isSpiltOnStack - returns true if the spil location is on stack  */
1539 /*-----------------------------------------------------------------*/
1540 static bool
1541 isSpiltOnStack (symbol * sym)
1542 {
1543   sym_link *etype;
1544
1545   debugLog ("%s\n", __FUNCTION__);
1546   if (!sym)
1547     return FALSE;
1548
1549   if (!sym->isspilt)
1550     return FALSE;
1551
1552 /*     if (sym->_G.stackSpil) */
1553 /*      return TRUE; */
1554
1555   if (!sym->usl.spillLoc)
1556     return FALSE;
1557
1558   etype = getSpec (sym->usl.spillLoc->type);
1559   if (IN_STACK (etype))
1560     return TRUE;
1561
1562   return FALSE;
1563 }
1564
1565 /*-----------------------------------------------------------------*/
1566 /* spillThis - spils a specific operand                            */
1567 /*-----------------------------------------------------------------*/
1568 static void
1569 spillThis (symbol * sym)
1570 {
1571   int i;
1572   debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1573
1574   /* if this is rematerializable or has a spillLocation
1575      we are okay, else we need to create a spillLocation
1576      for it */
1577   if (!(sym->remat || sym->usl.spillLoc))
1578     createStackSpil (sym);
1579
1580
1581   /* mark it has spilt & put it in the spilt set */
1582   sym->isspilt = 1;
1583   _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1584
1585   bitVectUnSetBit (_G.regAssigned, sym->key);
1586
1587   for (i = 0; i < sym->nRegs; i++)
1588
1589     if (sym->regs[i])
1590       {
1591         freeReg (sym->regs[i]);
1592         sym->regs[i] = NULL;
1593       }
1594
1595   /* if spilt on stack then free up r0 & r1 
1596      if they could have been assigned to some
1597      LIVE ranges */
1598   if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1599     {
1600       pic16_ptrRegReq++;
1601       spillLRWithPtrReg (sym);
1602     }
1603
1604   if (sym->usl.spillLoc && !sym->remat)
1605     sym->usl.spillLoc->allocreq = 1;
1606   return;
1607 }
1608
1609 /*-----------------------------------------------------------------*/
1610 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1611 /*-----------------------------------------------------------------*/
1612 static symbol *
1613 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1614 {
1615   bitVect *lrcs = NULL;
1616   set *selectS;
1617   symbol *sym;
1618
1619   debugLog ("%s\n", __FUNCTION__);
1620   /* get the spillable live ranges */
1621   lrcs = computeSpillable (ic);
1622
1623   /* get all live ranges that are rematerizable */
1624   if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1625     {
1626
1627       /* return the least used of these */
1628       return leastUsedLR (selectS);
1629     }
1630
1631   /* get live ranges with spillLocations in direct space */
1632   if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1633     {
1634       sym = leastUsedLR (selectS);
1635       strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1636                            sym->usl.spillLoc->rname :
1637                            sym->usl.spillLoc->name));
1638       sym->spildir = 1;
1639       /* mark it as allocation required */
1640       sym->usl.spillLoc->allocreq = 1;
1641       return sym;
1642     }
1643
1644   /* if the symbol is local to the block then */
1645   if (forSym->liveTo < ebp->lSeq)
1646     {
1647
1648       /* check if there are any live ranges allocated
1649          to registers that are not used in this block */
1650       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1651         {
1652           sym = leastUsedLR (selectS);
1653           /* if this is not rematerializable */
1654           if (!sym->remat)
1655             {
1656               _G.blockSpil++;
1657               sym->blockSpil = 1;
1658             }
1659           return sym;
1660         }
1661
1662       /* check if there are any live ranges that not
1663          used in the remainder of the block */
1664       if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1665         {
1666           sym = leastUsedLR (selectS);
1667           if (!sym->remat)
1668             {
1669               sym->remainSpil = 1;
1670               _G.blockSpil++;
1671             }
1672           return sym;
1673         }
1674     }
1675
1676   /* find live ranges with spillocation && not used as pointers */
1677   if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1678     {
1679
1680       sym = leastUsedLR (selectS);
1681       /* mark this as allocation required */
1682       sym->usl.spillLoc->allocreq = 1;
1683       return sym;
1684     }
1685
1686   /* find live ranges with spillocation */
1687   if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1688     {
1689
1690       sym = leastUsedLR (selectS);
1691       sym->usl.spillLoc->allocreq = 1;
1692       return sym;
1693     }
1694
1695   /* couldn't find then we need to create a spil
1696      location on the stack , for which one? the least
1697      used ofcourse */
1698   if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1699     {
1700
1701       /* return a created spil location */
1702       sym = createStackSpil (leastUsedLR (selectS));
1703       sym->usl.spillLoc->allocreq = 1;
1704       return sym;
1705     }
1706
1707   /* this is an extreme situation we will spill
1708      this one : happens very rarely but it does happen */
1709   spillThis (forSym);
1710   return forSym;
1711
1712 }
1713
1714 /*-----------------------------------------------------------------*/
1715 /* spilSomething - spil some variable & mark registers as free     */
1716 /*-----------------------------------------------------------------*/
1717 static bool
1718 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1719 {
1720   symbol *ssym;
1721   int i;
1722
1723   debugLog ("%s\n", __FUNCTION__);
1724   /* get something we can spil */
1725   ssym = selectSpil (ic, ebp, forSym);
1726
1727   /* mark it as spilt */
1728   ssym->isspilt = 1;
1729   _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1730
1731   /* mark it as not register assigned &
1732      take it away from the set */
1733   bitVectUnSetBit (_G.regAssigned, ssym->key);
1734
1735   /* mark the registers as free */
1736   for (i = 0; i < ssym->nRegs; i++)
1737     if (ssym->regs[i])
1738       freeReg (ssym->regs[i]);
1739
1740   /* if spilt on stack then free up r0 & r1 
1741      if they could have been assigned to as gprs */
1742   if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1743     {
1744       pic16_ptrRegReq++;
1745       spillLRWithPtrReg (ssym);
1746     }
1747
1748   /* if this was a block level spil then insert push & pop 
1749      at the start & end of block respectively */
1750   if (ssym->blockSpil)
1751     {
1752       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1753       /* add push to the start of the block */
1754       addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1755                                     ebp->sch->next : ebp->sch));
1756       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1757       /* add pop to the end of the block */
1758       addiCodeToeBBlock (ebp, nic, NULL);
1759     }
1760
1761   /* if spilt because not used in the remainder of the
1762      block then add a push before this instruction and
1763      a pop at the end of the block */
1764   if (ssym->remainSpil)
1765     {
1766
1767       iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1768       /* add push just before this instruction */
1769       addiCodeToeBBlock (ebp, nic, ic);
1770
1771       nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1772       /* add pop to the end of the block */
1773       addiCodeToeBBlock (ebp, nic, NULL);
1774     }
1775
1776   if (ssym == forSym)
1777     return FALSE;
1778   else
1779     return TRUE;
1780 }
1781
1782 /*-----------------------------------------------------------------*/
1783 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
1784 /*-----------------------------------------------------------------*/
1785 static regs *
1786 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1787 {
1788   regs *reg;
1789   int j;
1790
1791   debugLog ("%s\n", __FUNCTION__);
1792 tryAgain:
1793   /* try for a ptr type */
1794   if ((reg = allocReg (REG_PTR)))
1795     return reg;
1796
1797   /* try for gpr type */
1798   if ((reg = allocReg (REG_GPR)))
1799     return reg;
1800
1801   /* we have to spil */
1802   if (!spilSomething (ic, ebp, sym))
1803     return NULL;
1804
1805   /* make sure partially assigned registers aren't reused */
1806   for (j=0; j<=sym->nRegs; j++)
1807     if (sym->regs[j])
1808       sym->regs[j]->isFree = 0;
1809       
1810   /* this looks like an infinite loop but 
1811      in really selectSpil will abort  */
1812   goto tryAgain;
1813 }
1814
1815 /*-----------------------------------------------------------------*/
1816 /* getRegGpr - will try for GPR if not spil                        */
1817 /*-----------------------------------------------------------------*/
1818 static regs *
1819 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1820 {
1821   regs *reg;
1822   int j;
1823
1824   debugLog ("%s\n", __FUNCTION__);
1825 tryAgain:
1826   /* try for gpr type */
1827   if ((reg = allocReg (REG_GPR)))
1828     return reg;
1829
1830   if (!pic16_ptrRegReq)
1831     if ((reg = allocReg (REG_PTR)))
1832       return reg;
1833
1834   /* we have to spil */
1835   if (!spilSomething (ic, ebp, sym))
1836     return NULL;
1837
1838   /* make sure partially assigned registers aren't reused */
1839   for (j=0; j<=sym->nRegs; j++)
1840     if (sym->regs[j])
1841       sym->regs[j]->isFree = 0;
1842       
1843   /* this looks like an infinite loop but 
1844      in really selectSpil will abort  */
1845   goto tryAgain;
1846 }
1847
1848 /*-----------------------------------------------------------------*/
1849 /* symHasReg - symbol has a given register                         */
1850 /*-----------------------------------------------------------------*/
1851 static bool
1852 symHasReg (symbol * sym, regs * reg)
1853 {
1854   int i;
1855
1856   debugLog ("%s\n", __FUNCTION__);
1857   for (i = 0; i < sym->nRegs; i++)
1858     if (sym->regs[i] == reg)
1859       return TRUE;
1860
1861   return FALSE;
1862 }
1863
1864 /*-----------------------------------------------------------------*/
1865 /* deassignLRs - check the live to and if they have registers & are */
1866 /*               not spilt then free up the registers              */
1867 /*-----------------------------------------------------------------*/
1868 static void
1869 deassignLRs (iCode * ic, eBBlock * ebp)
1870 {
1871   symbol *sym;
1872   int k;
1873   symbol *result;
1874
1875   debugLog ("%s\n", __FUNCTION__);
1876   for (sym = hTabFirstItem (liveRanges, &k); sym;
1877        sym = hTabNextItem (liveRanges, &k))
1878     {
1879
1880       symbol *psym = NULL;
1881       /* if it does not end here */
1882       if (sym->liveTo > ic->seq)
1883         continue;
1884
1885       /* if it was spilt on stack then we can 
1886          mark the stack spil location as free */
1887       if (sym->isspilt)
1888         {
1889           if (sym->stackSpil)
1890             {
1891               sym->usl.spillLoc->isFree = 1;
1892               sym->stackSpil = 0;
1893             }
1894           continue;
1895         }
1896
1897       if (!bitVectBitValue (_G.regAssigned, sym->key))
1898         continue;
1899
1900       /* special case check if this is an IFX &
1901          the privious one was a pop and the 
1902          previous one was not spilt then keep track
1903          of the symbol */
1904       if (ic->op == IFX && ic->prev &&
1905           ic->prev->op == IPOP &&
1906           !ic->prev->parmPush &&
1907           !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1908         psym = OP_SYMBOL (IC_LEFT (ic->prev));
1909
1910       if (sym->nRegs)
1911         {
1912           int i = 0;
1913
1914           bitVectUnSetBit (_G.regAssigned, sym->key);
1915
1916           /* if the result of this one needs registers
1917              and does not have it then assign it right
1918              away */
1919           if (IC_RESULT (ic) &&
1920               !(SKIP_IC2 (ic) ||        /* not a special icode */
1921                 ic->op == JUMPTABLE ||
1922                 ic->op == IFX ||
1923                 ic->op == IPUSH ||
1924                 ic->op == IPOP ||
1925                 ic->op == RETURN ||
1926                 POINTER_SET (ic)) &&
1927               (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
1928               result->liveTo > ic->seq &&       /* and will live beyond this */
1929               result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
1930               result->regType == sym->regType &&        /* same register types */
1931               result->nRegs &&  /* which needs registers */
1932               !result->isspilt &&       /* and does not already have them */
1933               !result->remat &&
1934               !bitVectBitValue (_G.regAssigned, result->key) &&
1935           /* the number of free regs + number of regs in this LR
1936              can accomodate the what result Needs */
1937               ((nfreeRegsType (result->regType) +
1938                 sym->nRegs) >= result->nRegs)
1939             )
1940             {
1941
1942               for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1943                 if (i < sym->nRegs)
1944                   result->regs[i] = sym->regs[i];
1945                 else
1946                   result->regs[i] = getRegGpr (ic, ebp, result);
1947
1948               _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1949
1950             }
1951
1952           /* free the remaining */
1953           for (; i < sym->nRegs; i++)
1954             {
1955               if (psym)
1956                 {
1957                   if (!symHasReg (psym, sym->regs[i]))
1958                     freeReg (sym->regs[i]);
1959                 }
1960               else
1961                 freeReg (sym->regs[i]);
1962             }
1963         }
1964     }
1965 }
1966
1967
1968 /*-----------------------------------------------------------------*/
1969 /* reassignLR - reassign this to registers                         */
1970 /*-----------------------------------------------------------------*/
1971 static void
1972 reassignLR (operand * op)
1973 {
1974   symbol *sym = OP_SYMBOL (op);
1975   int i;
1976
1977   debugLog ("%s\n", __FUNCTION__);
1978   /* not spilt any more */
1979   sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1980   bitVectUnSetBit (_G.spiltSet, sym->key);
1981
1982   _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1983
1984   _G.blockSpil--;
1985
1986   for (i = 0; i < sym->nRegs; i++)
1987     sym->regs[i]->isFree = 0;
1988 }
1989
1990 /*-----------------------------------------------------------------*/
1991 /* willCauseSpill - determines if allocating will cause a spill    */
1992 /*-----------------------------------------------------------------*/
1993 static int
1994 willCauseSpill (int nr, int rt)
1995 {
1996   debugLog ("%s\n", __FUNCTION__);
1997   /* first check if there are any avlb registers
1998      of te type required */
1999   if (rt == REG_PTR)
2000     {
2001       /* special case for pointer type 
2002          if pointer type not avlb then 
2003          check for type gpr */
2004       if (nFreeRegs (rt) >= nr)
2005         return 0;
2006       if (nFreeRegs (REG_GPR) >= nr)
2007         return 0;
2008     }
2009   else
2010     {
2011       if (pic16_ptrRegReq)
2012         {
2013           if (nFreeRegs (rt) >= nr)
2014             return 0;
2015         }
2016       else
2017         {
2018           if (nFreeRegs (REG_PTR) +
2019               nFreeRegs (REG_GPR) >= nr)
2020             return 0;
2021         }
2022     }
2023
2024   debugLog (" ... yep it will (cause a spill)\n");
2025   /* it will cause a spil */
2026   return 1;
2027 }
2028
2029 /*-----------------------------------------------------------------*/
2030 /* positionRegs - the allocator can allocate same registers to res- */
2031 /* ult and operand, if this happens make sure they are in the same */
2032 /* position as the operand otherwise chaos results                 */
2033 /*-----------------------------------------------------------------*/
2034 static void
2035 positionRegs (symbol * result, symbol * opsym, int lineno)
2036 {
2037   int count = min (result->nRegs, opsym->nRegs);
2038   int i, j = 0, shared = 0;
2039
2040   debugLog ("%s\n", __FUNCTION__);
2041   /* if the result has been spilt then cannot share */
2042   if (opsym->isspilt)
2043     return;
2044 again:
2045   shared = 0;
2046   /* first make sure that they actually share */
2047   for (i = 0; i < count; i++)
2048     {
2049       for (j = 0; j < count; j++)
2050         {
2051           if (result->regs[i] == opsym->regs[j] && i != j)
2052             {
2053               shared = 1;
2054               goto xchgPositions;
2055             }
2056         }
2057     }
2058 xchgPositions:
2059   if (shared)
2060     {
2061       regs *tmp = result->regs[i];
2062       result->regs[i] = result->regs[j];
2063       result->regs[j] = tmp;
2064       goto again;
2065     }
2066 }
2067
2068 /*------------------------------------------------------------------*/
2069 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2070 /* it should either have registers or have beed spilled. Otherwise, */
2071 /* there was an uninitialized variable, so just spill this to get   */
2072 /* the operand in a valid state.                                    */
2073 /*------------------------------------------------------------------*/
2074 static void
2075 verifyRegsAssigned (operand *op, iCode * ic)
2076 {
2077   symbol * sym;
2078   
2079   if (!op) return;
2080   if (!IS_ITEMP (op)) return;
2081   
2082   sym = OP_SYMBOL (op);
2083   if (sym->isspilt) return;
2084   if (!sym->nRegs) return;
2085   if (sym->regs[0]) return;
2086   
2087   werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT, 
2088             sym->prereqv ? sym->prereqv->name : sym->name);
2089   spillThis (sym);
2090 }
2091
2092
2093 /*-----------------------------------------------------------------*/
2094 /* serialRegAssign - serially allocate registers to the variables  */
2095 /*-----------------------------------------------------------------*/
2096 static void
2097 serialRegAssign (eBBlock ** ebbs, int count)
2098 {
2099   int i;
2100
2101   debugLog ("%s\n", __FUNCTION__);
2102   /* for all blocks */
2103   for (i = 0; i < count; i++)
2104     {
2105
2106       iCode *ic;
2107
2108       if (ebbs[i]->noPath &&
2109           (ebbs[i]->entryLabel != entryLabel &&
2110            ebbs[i]->entryLabel != returnLabel))
2111         continue;
2112
2113       /* of all instructions do */
2114       for (ic = ebbs[i]->sch; ic; ic = ic->next)
2115         {
2116
2117           debugLog ("  op: %s\n", decodeOp (ic->op));
2118
2119                 if(IC_RESULT(ic) && !IS_ITEMP( IC_RESULT(ic)))
2120                         pic16_allocDirReg(IC_RESULT(ic));
2121
2122                 if(IC_LEFT(ic) && !IS_ITEMP( IC_LEFT(ic)))
2123                         pic16_allocDirReg(IC_LEFT(ic));
2124
2125                 if(IC_RIGHT(ic) && !IS_ITEMP( IC_RIGHT(ic)))
2126                         pic16_allocDirReg(IC_RIGHT(ic));
2127
2128           /* if this is an ipop that means some live
2129              range will have to be assigned again */
2130           if (ic->op == IPOP)
2131             reassignLR (IC_LEFT (ic));
2132
2133           /* if result is present && is a true symbol */
2134           if (IC_RESULT (ic) && ic->op != IFX &&
2135               IS_TRUE_SYMOP (IC_RESULT (ic)))
2136             OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2137
2138           /* take away registers from live
2139              ranges that end at this instruction */
2140           deassignLRs (ic, ebbs[i]);
2141
2142           /* some don't need registers */
2143           if (SKIP_IC2 (ic) ||
2144               ic->op == JUMPTABLE ||
2145               ic->op == IFX ||
2146               ic->op == IPUSH ||
2147               ic->op == IPOP ||
2148               (IC_RESULT (ic) && POINTER_SET (ic)))
2149             continue;
2150
2151           /* now we need to allocate registers
2152              only for the result */
2153           if (IC_RESULT (ic))
2154             {
2155               symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2156               bitVect *spillable;
2157               int willCS;
2158               int j;
2159               int ptrRegSet = 0;
2160
2161               /* if it does not need or is spilt 
2162                  or is already assigned to registers
2163                  or will not live beyond this instructions */
2164               if (!sym->nRegs ||
2165                   sym->isspilt ||
2166                   bitVectBitValue (_G.regAssigned, sym->key) ||
2167                   sym->liveTo <= ic->seq)
2168                 continue;
2169
2170               /* if some liverange has been spilt at the block level
2171                  and this one live beyond this block then spil this
2172                  to be safe */
2173               if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2174                 {
2175                   spillThis (sym);
2176                   continue;
2177                 }
2178               /* if trying to allocate this will cause
2179                  a spill and there is nothing to spill 
2180                  or this one is rematerializable then
2181                  spill this one */
2182               willCS = willCauseSpill (sym->nRegs, sym->regType);
2183               spillable = computeSpillable (ic);
2184               if (sym->remat ||
2185                   (willCS && bitVectIsZero (spillable)))
2186                 {
2187
2188                   spillThis (sym);
2189                   continue;
2190
2191                 }
2192
2193               /* If the live range preceeds the point of definition 
2194                  then ideally we must take into account registers that 
2195                  have been allocated after sym->liveFrom but freed
2196                  before ic->seq. This is complicated, so spill this
2197                  symbol instead and let fillGaps handle the allocation. */
2198               if (sym->liveFrom < ic->seq)
2199                 {
2200                     spillThis (sym);
2201                     continue;                 
2202                 }
2203
2204               /* if it has a spillocation & is used less than
2205                  all other live ranges then spill this */
2206                 if (willCS) {
2207                     if (sym->usl.spillLoc) {
2208                         symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2209                                                                          allLRs, ebbs[i], ic));
2210                         if (leastUsed && leastUsed->used > sym->used) {
2211                             spillThis (sym);
2212                             continue;
2213                         }
2214                     } else {
2215                         /* if none of the liveRanges have a spillLocation then better
2216                            to spill this one than anything else already assigned to registers */
2217                         if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2218                             /* if this is local to this block then we might find a block spil */
2219                             if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2220                                 spillThis (sym);
2221                                 continue;
2222                             }
2223                         }
2224                     }
2225                 }
2226
2227               if (ic->op == RECEIVE)
2228                 debugLog ("When I get clever, I'll optimize the receive logic\n");
2229
2230               /* if we need ptr regs for the right side
2231                  then mark it */
2232               if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2233                   <= (unsigned) PTRSIZE)
2234                 {
2235                   pic16_ptrRegReq++;
2236                   ptrRegSet = 1;
2237                 }
2238               /* else we assign registers to it */
2239               _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2240
2241               debugLog ("  %d - \n", __LINE__);
2242               if(debugF) 
2243                 bitVectDebugOn(_G.regAssigned, debugF);
2244
2245               for (j = 0; j < sym->nRegs; j++)
2246                 {
2247                   if (sym->regType == REG_PTR)
2248                     sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2249                   else
2250                     sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2251
2252                   /* if the allocation falied which means
2253                      this was spilt then break */
2254                   if (!sym->regs[j])
2255                     break;
2256                 }
2257               debugLog ("  %d - \n", __LINE__);
2258
2259               /* if it shares registers with operands make sure
2260                  that they are in the same position */
2261               if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2262                   OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2263                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2264                               OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2265               /* do the same for the right operand */
2266               if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2267                   OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2268                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2269                               OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2270
2271               debugLog ("  %d - \n", __LINE__);
2272               if (ptrRegSet)
2273                 {
2274                   debugLog ("  %d - \n", __LINE__);
2275                   pic16_ptrRegReq--;
2276                   ptrRegSet = 0;
2277                 }
2278
2279             }
2280         }
2281     }
2282
2283     /* Check for and fix any problems with uninitialized operands */
2284     for (i = 0; i < count; i++)
2285       {
2286         iCode *ic;
2287
2288         if (ebbs[i]->noPath &&
2289             (ebbs[i]->entryLabel != entryLabel &&
2290              ebbs[i]->entryLabel != returnLabel))
2291             continue;
2292
2293         for (ic = ebbs[i]->sch; ic; ic = ic->next)
2294           {
2295             if (SKIP_IC2 (ic))
2296               continue;
2297
2298             if (ic->op == IFX)
2299               {
2300                 verifyRegsAssigned (IC_COND (ic), ic);
2301                 continue;
2302               }
2303
2304             if (ic->op == JUMPTABLE)
2305               {
2306                 verifyRegsAssigned (IC_JTCOND (ic), ic);
2307                 continue;
2308               }
2309
2310             verifyRegsAssigned (IC_RESULT (ic), ic);
2311             verifyRegsAssigned (IC_LEFT (ic), ic);
2312             verifyRegsAssigned (IC_RIGHT (ic), ic);
2313           }
2314       }    
2315     
2316 }
2317
2318 /*-----------------------------------------------------------------*/
2319 /* rUmaskForOp :- returns register mask for an operand             */
2320 /*-----------------------------------------------------------------*/
2321 static bitVect *
2322 rUmaskForOp (operand * op)
2323 {
2324   bitVect *rumask;
2325   symbol *sym;
2326   int j;
2327
2328   debugLog ("%s\n", __FUNCTION__);
2329   /* only temporaries are assigned registers */
2330   if (!IS_ITEMP (op))
2331     return NULL;
2332
2333   sym = OP_SYMBOL (op);
2334
2335   /* if spilt or no registers assigned to it
2336      then nothing */
2337   if (sym->isspilt || !sym->nRegs)
2338     return NULL;
2339
2340   rumask = newBitVect (pic16_nRegs);
2341
2342   for (j = 0; j < sym->nRegs; j++)
2343     {
2344       rumask = bitVectSetBit (rumask,
2345                               sym->regs[j]->rIdx);
2346     }
2347
2348   return rumask;
2349 }
2350
2351 /*-----------------------------------------------------------------*/
2352 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2353 /*-----------------------------------------------------------------*/
2354 static bitVect *
2355 regsUsedIniCode (iCode * ic)
2356 {
2357   bitVect *rmask = newBitVect (pic16_nRegs);
2358
2359   debugLog ("%s\n", __FUNCTION__);
2360   /* do the special cases first */
2361   if (ic->op == IFX)
2362     {
2363       rmask = bitVectUnion (rmask,
2364                             rUmaskForOp (IC_COND (ic)));
2365       goto ret;
2366     }
2367
2368   /* for the jumptable */
2369   if (ic->op == JUMPTABLE)
2370     {
2371       rmask = bitVectUnion (rmask,
2372                             rUmaskForOp (IC_JTCOND (ic)));
2373
2374       goto ret;
2375     }
2376
2377   /* of all other cases */
2378   if (IC_LEFT (ic))
2379     rmask = bitVectUnion (rmask,
2380                           rUmaskForOp (IC_LEFT (ic)));
2381
2382
2383   if (IC_RIGHT (ic))
2384     rmask = bitVectUnion (rmask,
2385                           rUmaskForOp (IC_RIGHT (ic)));
2386
2387   if (IC_RESULT (ic))
2388     rmask = bitVectUnion (rmask,
2389                           rUmaskForOp (IC_RESULT (ic)));
2390
2391 ret:
2392   return rmask;
2393 }
2394
2395 /*-----------------------------------------------------------------*/
2396 /* createRegMask - for each instruction will determine the regsUsed */
2397 /*-----------------------------------------------------------------*/
2398 static void
2399 createRegMask (eBBlock ** ebbs, int count)
2400 {
2401   int i;
2402
2403   debugLog ("%s\n", __FUNCTION__);
2404   /* for all blocks */
2405   for (i = 0; i < count; i++)
2406     {
2407       iCode *ic;
2408
2409       if (ebbs[i]->noPath &&
2410           (ebbs[i]->entryLabel != entryLabel &&
2411            ebbs[i]->entryLabel != returnLabel))
2412         continue;
2413
2414       /* for all instructions */
2415       for (ic = ebbs[i]->sch; ic; ic = ic->next)
2416         {
2417
2418           int j;
2419
2420           if (SKIP_IC2 (ic) || !ic->rlive)
2421             continue;
2422
2423           /* first mark the registers used in this
2424              instruction */
2425           ic->rUsed = regsUsedIniCode (ic);
2426           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2427
2428           /* now create the register mask for those 
2429              registers that are in use : this is a
2430              super set of ic->rUsed */
2431           ic->rMask = newBitVect (pic16_nRegs + 1);
2432
2433           /* for all live Ranges alive at this point */
2434           for (j = 1; j < ic->rlive->size; j++)
2435             {
2436               symbol *sym;
2437               int k;
2438
2439               /* if not alive then continue */
2440               if (!bitVectBitValue (ic->rlive, j))
2441                 continue;
2442
2443               /* find the live range we are interested in */
2444               if (!(sym = hTabItemWithKey (liveRanges, j)))
2445                 {
2446                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2447                           "createRegMask cannot find live range");
2448                   exit (0);
2449                 }
2450
2451               /* if no register assigned to it */
2452               if (!sym->nRegs || sym->isspilt)
2453                 continue;
2454
2455               /* for all the registers allocated to it */
2456               for (k = 0; k < sym->nRegs; k++)
2457                 if (sym->regs[k])
2458                   ic->rMask =
2459                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2460             }
2461         }
2462     }
2463 }
2464
2465 /*-----------------------------------------------------------------*/
2466 /* rematStr - returns the rematerialized string for a remat var    */
2467 /*-----------------------------------------------------------------*/
2468 static symbol *
2469 rematStr (symbol * sym)
2470 {
2471   char *s = buffer;
2472   iCode *ic = sym->rematiCode;
2473   symbol *psym = NULL;
2474
2475   debugLog ("%s\n", __FUNCTION__);
2476
2477   //printf ("%s\n", s);
2478
2479   /* if plus or minus print the right hand side */
2480
2481   if (ic->op == '+' || ic->op == '-') {
2482         
2483     iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2484
2485     sprintf (s, "(%s %c 0x%04x)",
2486              OP_SYMBOL (IC_LEFT (ric))->rname,
2487              ic->op,
2488              (int) operandLitValue (IC_RIGHT (ic)));
2489
2490
2491     //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2492
2493     psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2494     psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2495
2496     return psym;
2497   }
2498
2499   sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2500   psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2501
2502   //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2503   return psym;
2504 }
2505
2506 #if 0
2507 /*-----------------------------------------------------------------*/
2508 /* rematStr - returns the rematerialized string for a remat var    */
2509 /*-----------------------------------------------------------------*/
2510 static char *
2511 rematStr (symbol * sym)
2512 {
2513   char *s = buffer;
2514   iCode *ic = sym->rematiCode;
2515
2516   debugLog ("%s\n", __FUNCTION__);
2517   while (1)
2518     {
2519
2520       printf ("%s\n", s);
2521       /* if plus or minus print the right hand side */
2522 /*
2523    if (ic->op == '+' || ic->op == '-') {
2524    sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2525    ic->op );
2526    s += strlen(s);
2527    ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2528    continue ;
2529    }
2530  */
2531       if (ic->op == '+' || ic->op == '-')
2532         {
2533           iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2534           sprintf (s, "(%s %c 0x%04x)",
2535                    OP_SYMBOL (IC_LEFT (ric))->rname,
2536                    ic->op,
2537                    (int) operandLitValue (IC_RIGHT (ic)));
2538
2539           //s += strlen(s);
2540           //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2541           //continue ;
2542           //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2543           return buffer;
2544         }
2545
2546       /* we reached the end */
2547       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2548       break;
2549     }
2550
2551   printf ("%s\n", buffer);
2552   return buffer;
2553 }
2554 #endif
2555
2556 /*-----------------------------------------------------------------*/
2557 /* regTypeNum - computes the type & number of registers required   */
2558 /*-----------------------------------------------------------------*/
2559 static void
2560 regTypeNum ()
2561 {
2562   symbol *sym;
2563   int k;
2564   iCode *ic;
2565
2566   debugLog ("%s\n", __FUNCTION__);
2567   /* for each live range do */
2568   for (sym = hTabFirstItem (liveRanges, &k); sym;
2569        sym = hTabNextItem (liveRanges, &k)) {
2570
2571     debugLog ("  %d - %s\n", __LINE__, sym->rname);
2572     //fprintf(stderr,"  %d - %s\n", __LINE__, sym->rname);
2573
2574     /* if used zero times then no registers needed */
2575     if ((sym->liveTo - sym->liveFrom) == 0)
2576       continue;
2577
2578
2579     /* if the live range is a temporary */
2580     if (sym->isitmp) {
2581
2582       debugLog ("  %d - itemp register\n", __LINE__);
2583
2584       /* if the type is marked as a conditional */
2585       if (sym->regType == REG_CND)
2586         continue;
2587
2588       /* if used in return only then we don't 
2589          need registers */
2590       if (sym->ruonly || sym->accuse) {
2591         if (IS_AGGREGATE (sym->type) || sym->isptr)
2592           sym->type = aggrToPtr (sym->type, FALSE);
2593         debugLog ("  %d - no reg needed - used as a return\n", __LINE__);
2594
2595         continue;
2596       }
2597
2598       /* if the symbol has only one definition &
2599          that definition is a get_pointer and the
2600          pointer we are getting is rematerializable and
2601          in "data" space */
2602
2603       if (bitVectnBitsOn (sym->defs) == 1 &&
2604           (ic = hTabItemWithKey (iCodehTab,
2605                                  bitVectFirstBit (sym->defs))) &&
2606           POINTER_GET (ic) &&
2607           !IS_BITVAR (sym->etype) &&
2608           (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2609
2610         if (ptrPseudoSymSafe (sym, ic)) {
2611           
2612           symbol *psym;
2613           
2614           debugLog ("  %d - \n", __LINE__);
2615               
2616           /* create a psuedo symbol & force a spil */
2617           //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2618           psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2619           psym->type = sym->type;
2620           psym->etype = sym->etype;
2621           psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2622           strcpy (psym->rname, psym->name);
2623           sym->isspilt = 1;
2624           sym->usl.spillLoc = psym;
2625           continue;
2626         }
2627
2628         /* if in data space or idata space then try to
2629            allocate pointer register */
2630
2631       }
2632
2633       /* if not then we require registers */
2634       sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2635                     getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2636                     getSize (sym->type));
2637
2638
2639 #if 0
2640     if(IS_PTR_CONST (sym->type)) {
2641 #else
2642     if(IS_CODEPTR (sym->type)) {
2643 #endif
2644       // what IS this ???? (HJD)
2645       debugLog ("  %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2646       sym->nRegs = 3; // patch 14
2647     }
2648
2649       if (sym->nRegs > 4) {
2650         fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2651         printTypeChain (sym->type, stderr);
2652         fprintf (stderr, "\n");
2653       }
2654
2655       /* determine the type of register required */
2656       if (sym->nRegs == 1 &&
2657           IS_PTR (sym->type) &&
2658           sym->uptr)
2659         sym->regType = REG_PTR;
2660       else
2661         sym->regType = REG_GPR;
2662
2663
2664       debugLog ("  reg name %s,  reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2665
2666     }
2667     else
2668       /* for the first run we don't provide */
2669       /* registers for true symbols we will */
2670       /* see how things go                  */
2671       sym->nRegs = 0;
2672   }
2673
2674 }
2675 static DEFSETFUNC (markRegFree)
2676 {
2677   ((regs *)item)->isFree = 1;
2678
2679   return 0;
2680 }
2681
2682 DEFSETFUNC (pic16_deallocReg)
2683 {
2684   fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2685   ((regs *)item)->isFree = 1;
2686   ((regs *)item)->wasUsed = 0;
2687
2688   return 0;
2689 }
2690 /*-----------------------------------------------------------------*/
2691 /* freeAllRegs - mark all registers as free                        */
2692 /*-----------------------------------------------------------------*/
2693 void
2694 pic16_freeAllRegs ()
2695 {
2696   debugLog ("%s\n", __FUNCTION__);
2697
2698   applyToSet(pic16_dynAllocRegs,markRegFree);
2699   applyToSet(pic16_dynStackRegs,markRegFree);
2700 }
2701
2702 /*-----------------------------------------------------------------*/
2703 /*-----------------------------------------------------------------*/
2704 void
2705 pic16_deallocateAllRegs ()
2706 {
2707   debugLog ("%s\n", __FUNCTION__);
2708
2709   applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2710 }
2711
2712
2713 /*-----------------------------------------------------------------*/
2714 /* deallocStackSpil - this will set the stack pointer back         */
2715 /*-----------------------------------------------------------------*/
2716 static
2717 DEFSETFUNC (deallocStackSpil)
2718 {
2719   symbol *sym = item;
2720
2721   debugLog ("%s\n", __FUNCTION__);
2722   deallocLocal (sym);
2723   return 0;
2724 }
2725
2726 /*-----------------------------------------------------------------*/
2727 /* farSpacePackable - returns the packable icode for far variables */
2728 /*-----------------------------------------------------------------*/
2729 static iCode *
2730 farSpacePackable (iCode * ic)
2731 {
2732   iCode *dic;
2733
2734   debugLog ("%s\n", __FUNCTION__);
2735   /* go thru till we find a definition for the
2736      symbol on the right */
2737   for (dic = ic->prev; dic; dic = dic->prev)
2738     {
2739
2740       /* if the definition is a call then no */
2741       if ((dic->op == CALL || dic->op == PCALL) &&
2742           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2743         {
2744           return NULL;
2745         }
2746
2747       /* if shift by unknown amount then not */
2748       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2749           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2750         return NULL;
2751
2752       /* if pointer get and size > 1 */
2753       if (POINTER_GET (dic) &&
2754           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2755         return NULL;
2756
2757       if (POINTER_SET (dic) &&
2758           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2759         return NULL;
2760
2761       /* if any three is a true symbol in far space */
2762       if (IC_RESULT (dic) &&
2763           IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2764           isOperandInFarSpace (IC_RESULT (dic)))
2765         return NULL;
2766
2767       if (IC_RIGHT (dic) &&
2768           IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2769           isOperandInFarSpace (IC_RIGHT (dic)) &&
2770           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2771         return NULL;
2772
2773       if (IC_LEFT (dic) &&
2774           IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2775           isOperandInFarSpace (IC_LEFT (dic)) &&
2776           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2777         return NULL;
2778
2779       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2780         {
2781           if ((dic->op == LEFT_OP ||
2782                dic->op == RIGHT_OP ||
2783                dic->op == '-') &&
2784               IS_OP_LITERAL (IC_RIGHT (dic)))
2785             return NULL;
2786           else
2787             return dic;
2788         }
2789     }
2790
2791   return NULL;
2792 }
2793
2794 /*-----------------------------------------------------------------*/
2795 /* packRegsForAssign - register reduction for assignment           */
2796 /*-----------------------------------------------------------------*/
2797 static int
2798 packRegsForAssign (iCode * ic, eBBlock * ebp)
2799 {
2800
2801   iCode *dic, *sic;
2802
2803   debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2804   debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2805   debugAopGet ("  result:", IC_RESULT (ic));
2806   debugAopGet ("  left:", IC_LEFT (ic));
2807   debugAopGet ("  right:", IC_RIGHT (ic));
2808
2809 //      fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
2810
2811 #if 0
2812   /* if this is at an absolute address, then get the address. */
2813   if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2814     if(PIC16_IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2815       debugLog ("  %d - found config word declaration\n", __LINE__);
2816       if(IS_VALOP(IC_RIGHT(ic))) {
2817         debugLog ("  setting config word to %x\n", 
2818                   (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2819
2820         fprintf(stderr, "%s:%d  setting config word to %x\n", __FILE__, __LINE__, 
2821                   (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2822
2823         pic16_assignConfigWordValue(  SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2824                                 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2825       }
2826
2827
2828         debugLog(" %d\n", __LINE__);
2829
2830       /* remove the assignment from the iCode chain. */
2831
2832       remiCodeFromeBBlock (ebp, ic);
2833       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2834       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2835
2836       return 1;
2837
2838     }
2839   }
2840 #endif
2841         debugLog(" %d - actuall processing\n", __LINE__ );
2842
2843   if (!IS_ITEMP (IC_RESULT (ic))) {
2844     pic16_allocDirReg(IC_RESULT (ic));
2845     debugLog ("  %d - result is not temp\n", __LINE__);
2846   }
2847
2848
2849 /* See BUGLOG0001 - VR */
2850 #if 1
2851   if (!IS_ITEMP (IC_RIGHT (ic))) {
2852     debugLog ("  %d - not packing - right is not temp\n", __LINE__);
2853     pic16_allocDirReg(IC_RIGHT (ic));
2854     return 0;
2855   }
2856 #endif
2857
2858   if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2859       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2860     {
2861       debugLog ("  %d - not packing - right side fails \n", __LINE__);
2862       return 0;
2863     }
2864
2865   /* if the true symbol is defined in far space or on stack
2866      then we should not since this will increase register pressure */
2867   if (isOperandInFarSpace (IC_RESULT (ic)))
2868     {
2869       if ((dic = farSpacePackable (ic)))
2870         goto pack;
2871       else
2872         return 0;
2873
2874     }
2875
2876   /* find the definition of iTempNN scanning backwards if we find a 
2877      a use of the true symbol before we find the definition then 
2878      we cannot pack */
2879   for (dic = ic->prev; dic; dic = dic->prev)
2880     {
2881
2882       /* if there is a function call and this is
2883          a parameter & not my parameter then don't pack it */
2884       if ((dic->op == CALL || dic->op == PCALL) &&
2885           (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2886            !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2887         {
2888           debugLog ("  %d - \n", __LINE__);
2889           dic = NULL;
2890           break;
2891         }
2892
2893
2894       if (SKIP_IC2 (dic))
2895         continue;
2896
2897         debugLog("%d\tSearching for iTempNN\n", __LINE__);
2898
2899       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2900           IS_OP_VOLATILE (IC_RESULT (dic)))
2901         {
2902           debugLog ("  %d - dic is VOLATILE \n", __LINE__);
2903           dic = NULL;
2904           break;
2905         }
2906
2907 #if 1
2908       if( IS_SYMOP( IC_RESULT(dic)) &&
2909         IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
2910
2911           debugLog (" %d - result is bitfield\n", __LINE__);
2912           dic = NULL;
2913           break;
2914         }
2915 #endif
2916
2917       if (IS_SYMOP (IC_RESULT (dic)) &&
2918           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2919         {
2920           /* A previous result was assigned to the same register - we'll our definition */
2921           debugLog ("  %d - dic result key == ic right key -- pointer set=%c\n",
2922                     __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2923           if (POINTER_SET (dic))
2924             dic = NULL;
2925
2926           break;
2927         }
2928
2929       if (IS_SYMOP (IC_RIGHT (dic)) &&
2930           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2931            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2932         {
2933           debugLog ("  %d - dic right key == ic rightor result key\n", __LINE__);
2934           dic = NULL;
2935           break;
2936         }
2937
2938       if (IS_SYMOP (IC_LEFT (dic)) &&
2939           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2940            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2941         {
2942           debugLog ("  %d - dic left key == ic rightor result key\n", __LINE__);
2943           dic = NULL;
2944           break;
2945         }
2946
2947       if (POINTER_SET (dic) &&
2948           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2949         {
2950           debugLog ("  %d - dic result key == ic result key -- pointer set=Y\n",
2951                     __LINE__);
2952           dic = NULL;
2953           break;
2954         }
2955     }
2956
2957   if (!dic)
2958     return 0;                   /* did not find */
2959
2960 #if 1
2961         /* This code is taken from the hc08 port. Do not know
2962          * if it fits for pic16, but I leave it here just in case */
2963
2964         /* if assignment then check that right is not a bit */
2965         if (ASSIGNMENT (dic) && !POINTER_SET (dic)) {
2966           sym_link *etype = operandType (IC_RIGHT (dic));
2967
2968                 if (IS_BITFIELD (etype)) {
2969                         /* if result is a bit too then it's ok */
2970                         etype = operandType (IC_RESULT (dic));
2971                         if (!IS_BITFIELD (etype)) {
2972                                 debugLog(" %d bitfields\n");
2973                           return 0;
2974                         }
2975                 }
2976         }
2977 #endif
2978
2979   /* if the result is on stack or iaccess then it must be
2980      the same atleast one of the operands */
2981   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2982       OP_SYMBOL (IC_RESULT (ic))->iaccess)
2983     {
2984
2985 #if 0
2986         /* clear the onStack flag, the port doesn't support it yet! FIXME */
2987         if(OP_SYMBOL(IC_RESULT(ic))->onStack)
2988                 OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
2989 #endif
2990         
2991
2992       /* the operation has only one symbol
2993          operator then we can pack */
2994       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2995           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2996         goto pack;
2997
2998       if (!((IC_LEFT (dic) &&
2999              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3000             (IC_RIGHT (dic) &&
3001              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3002         return 0;
3003     }
3004 pack:
3005   debugLog ("  packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3006   debugLog ("  replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3007   /* found the definition */
3008   /* replace the result with the result of */
3009   /* this assignment and remove this assignment */
3010   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3011   IC_RESULT (dic) = IC_RESULT (ic);
3012
3013   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3014     {
3015       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3016     }
3017   /* delete from liverange table also 
3018      delete from all the points inbetween and the new
3019      one */
3020   for (sic = dic; sic != ic; sic = sic->next)
3021     {
3022       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3023       if (IS_ITEMP (IC_RESULT (dic)))
3024         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3025     }
3026
3027   remiCodeFromeBBlock (ebp, ic);
3028   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3029
3030         debugLog("  %d\n", __LINE__ );
3031   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3032   OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3033   return 1;
3034
3035
3036 }
3037
3038 #if 1
3039
3040 #define NO_packRegsForAccUse
3041 #define NO_packRegsForSupport
3042 #define NO_packRegsForOneuse
3043 #define NO_cast_peep
3044
3045 #endif
3046
3047
3048 #ifndef NO_packRegsForSupport
3049 /*-----------------------------------------------------------------*/
3050 /* findAssignToSym : scanning backwards looks for first assig found */
3051 /*-----------------------------------------------------------------*/
3052 static iCode *
3053 findAssignToSym (operand * op, iCode * ic)
3054 {
3055   iCode *dic;
3056
3057   debugLog ("%s\n", __FUNCTION__);
3058   for (dic = ic->prev; dic; dic = dic->prev)
3059     {
3060
3061       /* if definition by assignment */
3062       if (dic->op == '=' &&
3063           !POINTER_SET (dic) &&
3064           IC_RESULT (dic)->key == op->key
3065 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3066         )
3067         {
3068
3069           /* we are interested only if defined in far space */
3070           /* or in stack space in case of + & - */
3071
3072           /* if assigned to a non-symbol then return
3073              true */
3074           if (!IS_SYMOP (IC_RIGHT (dic)))
3075             break;
3076
3077           /* if the symbol is in far space then
3078              we should not */
3079           if (isOperandInFarSpace (IC_RIGHT (dic)))
3080             return NULL;
3081
3082           /* for + & - operations make sure that
3083              if it is on the stack it is the same
3084              as one of the three operands */
3085           if ((ic->op == '+' || ic->op == '-') &&
3086               OP_SYMBOL (IC_RIGHT (dic))->onStack)
3087             {
3088
3089 #if 0
3090                 if(OP_SYMBOL(IC_RESULT(ic))->onStack)
3091                         OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
3092 #endif
3093
3094               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3095                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3096                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3097                 return NULL;
3098             }
3099
3100           break;
3101
3102         }
3103
3104       /* if we find an usage then we cannot delete it */
3105       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3106         return NULL;
3107
3108       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3109         return NULL;
3110
3111       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3112         return NULL;
3113     }
3114
3115   /* now make sure that the right side of dic
3116      is not defined between ic & dic */
3117   if (dic)
3118     {
3119       iCode *sic = dic->next;
3120
3121       for (; sic != ic; sic = sic->next)
3122         if (IC_RESULT (sic) &&
3123             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3124           return NULL;
3125     }
3126
3127   return dic;
3128
3129
3130 }
3131 #endif
3132
3133
3134 #ifndef NO_packRegsForSupport
3135 /*-----------------------------------------------------------------*/
3136 /* packRegsForSupport :- reduce some registers for support calls   */
3137 /*-----------------------------------------------------------------*/
3138 static int
3139 packRegsForSupport (iCode * ic, eBBlock * ebp)
3140 {
3141   int change = 0;
3142
3143   debugLog ("%s\n", __FUNCTION__);
3144   /* for the left & right operand :- look to see if the
3145      left was assigned a true symbol in far space in that
3146      case replace them */
3147   if (IS_ITEMP (IC_LEFT (ic)) &&
3148       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3149     {
3150       iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3151       iCode *sic;
3152
3153       if (!dic)
3154         goto right;
3155
3156       debugAopGet ("removing left:", IC_LEFT (ic));
3157
3158       /* found it we need to remove it from the
3159          block */
3160       for (sic = dic; sic != ic; sic = sic->next)
3161         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3162
3163       IC_LEFT (ic)->operand.symOperand =
3164         IC_RIGHT (dic)->operand.symOperand;
3165       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3166       remiCodeFromeBBlock (ebp, dic);
3167       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3168       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3169       change++;
3170     }
3171
3172   /* do the same for the right operand */
3173 right:
3174   if (!change &&
3175       IS_ITEMP (IC_RIGHT (ic)) &&
3176       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3177     {
3178       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3179       iCode *sic;
3180
3181       if (!dic)
3182         return change;
3183
3184       /* if this is a subtraction & the result
3185          is a true symbol in far space then don't pack */
3186       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3187         {
3188           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3189           if (IN_FARSPACE (SPEC_OCLS (etype)))
3190             return change;
3191         }
3192
3193       debugAopGet ("removing right:", IC_RIGHT (ic));
3194
3195       /* found it we need to remove it from the
3196          block */
3197       for (sic = dic; sic != ic; sic = sic->next)
3198         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3199
3200       IC_RIGHT (ic)->operand.symOperand =
3201         IC_RIGHT (dic)->operand.symOperand;
3202       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3203
3204       remiCodeFromeBBlock (ebp, dic);
3205       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3206       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3207       change++;
3208     }
3209
3210   return change;
3211 }
3212 #endif
3213
3214
3215 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3216
3217 #ifndef NO_packRegsForOneuse
3218 /*-----------------------------------------------------------------*/
3219 /* packRegsForOneuse : - will reduce some registers for single Use */
3220 /*-----------------------------------------------------------------*/
3221 static iCode *
3222 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3223 {
3224   bitVect *uses;
3225   iCode *dic, *sic;
3226
3227   debugLog ("%s\n", __FUNCTION__);
3228   /* if returning a literal then do nothing */
3229   if (!IS_SYMOP (op))
3230     return NULL;
3231
3232   /* only upto 2 bytes since we cannot predict
3233      the usage of b, & acc */
3234   if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) &&        /* was 2, changed to 3 -- VR */
3235       ic->op != RETURN &&
3236       ic->op != SEND)
3237     return NULL;
3238
3239   /* this routine will mark the a symbol as used in one 
3240      instruction use only && if the definition is local 
3241      (ie. within the basic block) && has only one definition &&
3242      that definition is either a return value from a 
3243      function or does not contain any variables in
3244      far space */
3245   uses = bitVectCopy (OP_USES (op));
3246   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
3247   if (!bitVectIsZero (uses))    /* has other uses */
3248     return NULL;
3249
3250   /* if it has only one defintion */
3251   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3252     return NULL;                /* has more than one definition */
3253
3254   /* get that definition */
3255   if (!(dic =
3256         hTabItemWithKey (iCodehTab,
3257                          bitVectFirstBit (OP_DEFS (op)))))
3258     return NULL;
3259
3260   /* found the definition now check if it is local */
3261   if (dic->seq < ebp->fSeq ||
3262       dic->seq > ebp->lSeq)
3263     return NULL;                /* non-local */
3264
3265   /* now check if it is the return from
3266      a function call */
3267   if (dic->op == CALL || dic->op == PCALL)
3268     {
3269       if (ic->op != SEND && ic->op != RETURN &&
3270           !POINTER_SET(ic) && !POINTER_GET(ic))
3271         {
3272           OP_SYMBOL (op)->ruonly = 1;
3273           return dic;
3274         }
3275       dic = dic->next;
3276     }
3277
3278
3279   /* otherwise check that the definition does
3280      not contain any symbols in far space */
3281   if (isOperandInFarSpace (IC_LEFT (dic)) ||
3282       isOperandInFarSpace (IC_RIGHT (dic)) ||
3283       IS_OP_RUONLY (IC_LEFT (ic)) ||
3284       IS_OP_RUONLY (IC_RIGHT (ic)))
3285     {
3286       return NULL;
3287     }
3288
3289   /* if pointer set then make sure the pointer
3290      is one byte */
3291   if (POINTER_SET (dic) &&
3292       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3293     return NULL;
3294
3295   if (POINTER_GET (dic) &&
3296       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3297     return NULL;
3298
3299   sic = dic;
3300
3301   /* also make sure the intervenening instructions
3302      don't have any thing in far space */
3303   for (dic = dic->next; dic && dic != ic; dic = dic->next)
3304     {
3305
3306       /* if there is an intervening function call then no */
3307       if (dic->op == CALL || dic->op == PCALL)
3308         return NULL;
3309       /* if pointer set then make sure the pointer
3310          is one byte */
3311       if (POINTER_SET (dic) &&
3312           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3313         return NULL;
3314
3315       if (POINTER_GET (dic) &&
3316           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3317         return NULL;
3318
3319       /* if address of & the result is remat then okay */
3320       if (dic->op == ADDRESS_OF &&
3321           OP_SYMBOL (IC_RESULT (dic))->remat)
3322         continue;
3323
3324       /* if operand has size of three or more & this
3325          operation is a '*','/' or '%' then 'b' may
3326          cause a problem */
3327       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3328           getSize (operandType (op)) >= 3)
3329         return NULL;
3330
3331       /* if left or right or result is in far space */
3332       if (isOperandInFarSpace (IC_LEFT (dic)) ||
3333           isOperandInFarSpace (IC_RIGHT (dic)) ||
3334           isOperandInFarSpace (IC_RESULT (dic)) ||
3335           IS_OP_RUONLY (IC_LEFT (dic)) ||
3336           IS_OP_RUONLY (IC_RIGHT (dic)) ||
3337           IS_OP_RUONLY (IC_RESULT (dic)))
3338         {
3339           return NULL;
3340         }
3341     }
3342
3343   OP_SYMBOL (op)->ruonly = 1;
3344   return sic;
3345
3346 }
3347 #endif
3348
3349
3350 /*-----------------------------------------------------------------*/
3351 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
3352 /*-----------------------------------------------------------------*/
3353 static bool
3354 isBitwiseOptimizable (iCode * ic)
3355 {
3356   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3357   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3358
3359   debugLog ("%s\n", __FUNCTION__);
3360   /* bitwise operations are considered optimizable
3361      under the following conditions (Jean-Louis VERN) 
3362
3363      x & lit
3364      bit & bit
3365      bit & x
3366      bit ^ bit
3367      bit ^ x
3368      x   ^ lit
3369      x   | lit
3370      bit | bit
3371      bit | x
3372    */
3373   if (IS_LITERAL (rtype) ||
3374       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3375     return TRUE;
3376   else
3377     return FALSE;
3378 }
3379
3380
3381 #ifndef NO_packRegsForAccUse
3382
3383 /*-----------------------------------------------------------------*/
3384 /* packRegsForAccUse - pack registers for acc use                  */
3385 /*-----------------------------------------------------------------*/
3386 static void
3387 packRegsForAccUse (iCode * ic)
3388 {
3389   iCode *uic;
3390
3391   debugLog ("%s\n", __FUNCTION__);
3392
3393   /* if this is an aggregate, e.g. a one byte char array */
3394   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3395     return;
3396   }
3397   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3398
3399   /* if + or - then it has to be one byte result */
3400   if ((ic->op == '+' || ic->op == '-')
3401       && getSize (operandType (IC_RESULT (ic))) > 1)
3402     return;
3403
3404   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3405   /* if shift operation make sure right side is not a literal */
3406   if (ic->op == RIGHT_OP &&
3407       (isOperandLiteral (IC_RIGHT (ic)) ||
3408        getSize (operandType (IC_RESULT (ic))) > 1))
3409     return;
3410
3411   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3412   if (ic->op == LEFT_OP &&
3413       (isOperandLiteral (IC_RIGHT (ic)) ||
3414        getSize (operandType (IC_RESULT (ic))) > 1))
3415     return;
3416
3417   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3418   if (IS_BITWISE_OP (ic) &&
3419       getSize (operandType (IC_RESULT (ic))) > 1)
3420     return;
3421
3422
3423   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3424   /* has only one definition */
3425   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3426     return;
3427
3428   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3429   /* has only one use */
3430   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3431     return;
3432
3433   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3434   /* and the usage immediately follows this iCode */
3435   if (!(uic = hTabItemWithKey (iCodehTab,
3436                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3437     return;
3438
3439   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3440   if (ic->next != uic)
3441     return;
3442
3443   /* if it is a conditional branch then we definitely can */
3444   if (uic->op == IFX)
3445     goto accuse;
3446
3447   if (uic->op == JUMPTABLE)
3448     return;
3449
3450   /* if the usage is not is an assignment
3451      or an arithmetic / bitwise / shift operation then not */
3452   if (POINTER_SET (uic) &&
3453       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3454     return;
3455
3456   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3457   if (uic->op != '=' &&
3458       !IS_ARITHMETIC_OP (uic) &&
3459       !IS_BITWISE_OP (uic) &&
3460       uic->op != LEFT_OP &&
3461       uic->op != RIGHT_OP)
3462     return;
3463
3464   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3465   /* if used in ^ operation then make sure right is not a 
3466      literl */
3467   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3468     return;
3469
3470   /* if shift operation make sure right side is not a literal */
3471   if (uic->op == RIGHT_OP &&
3472       (isOperandLiteral (IC_RIGHT (uic)) ||
3473        getSize (operandType (IC_RESULT (uic))) > 1))
3474     return;
3475
3476   if (uic->op == LEFT_OP &&
3477       (isOperandLiteral (IC_RIGHT (uic)) ||
3478        getSize (operandType (IC_RESULT (uic))) > 1))
3479     return;
3480
3481   /* make sure that the result of this icode is not on the
3482      stack, since acc is used to compute stack offset */
3483   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3484       OP_SYMBOL (IC_RESULT (uic))->onStack)
3485     return;
3486
3487   /* if either one of them in far space then we cannot */
3488   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3489        isOperandInFarSpace (IC_LEFT (uic))) ||
3490       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3491        isOperandInFarSpace (IC_RIGHT (uic))))
3492     return;
3493
3494   /* if the usage has only one operand then we can */
3495   if (IC_LEFT (uic) == NULL ||
3496       IC_RIGHT (uic) == NULL)
3497     goto accuse;
3498
3499   /* make sure this is on the left side if not
3500      a '+' since '+' is commutative */
3501   if (ic->op != '+' &&
3502       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3503     return;
3504
3505 #if 1
3506   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3507   /* if one of them is a literal then we can */
3508   if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3509         (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))  &&
3510        (getSize (operandType (IC_RESULT (uic))) <= 1))
3511     {
3512       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3513       return;
3514     }
3515 #endif
3516
3517   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3518   /* if the other one is not on stack then we can */
3519   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3520       (IS_ITEMP (IC_RIGHT (uic)) ||
3521        (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3522         !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3523     goto accuse;
3524
3525   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3526       (IS_ITEMP (IC_LEFT (uic)) ||
3527        (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3528         !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3529     goto accuse;
3530
3531   return;
3532
3533 accuse:
3534   debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3535   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3536
3537
3538 }
3539 #endif
3540
3541
3542 /*-----------------------------------------------------------------*/
3543 /* packForPush - hueristics to reduce iCode for pushing            */
3544 /*-----------------------------------------------------------------*/
3545 static void
3546 packForReceive (iCode * ic, eBBlock * ebp)
3547 {
3548   iCode *dic;
3549
3550   debugLog ("%s\n", __FUNCTION__);
3551   debugAopGet ("  result:", IC_RESULT (ic));
3552   debugAopGet ("  left:", IC_LEFT (ic));
3553   debugAopGet ("  right:", IC_RIGHT (ic));
3554
3555   if (!ic->next)
3556     return;
3557
3558   for (dic = ic->next; dic; dic = dic->next)
3559     {
3560
3561
3562
3563       if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3564         debugLog ("    used on left\n");
3565       if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3566         debugLog ("    used on right\n");
3567       if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3568         debugLog ("    used on result\n");
3569
3570       if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3571           (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3572         return;
3573
3574     }
3575
3576   debugLog ("  hey we can remove this unnecessary assign\n");
3577 }
3578 /*-----------------------------------------------------------------*/
3579 /* packForPush - hueristics to reduce iCode for pushing            */
3580 /*-----------------------------------------------------------------*/
3581 static void
3582 packForPush (iCode * ic, eBBlock * ebp)
3583 {
3584   iCode *dic;
3585
3586   debugLog ("%s\n", __FUNCTION__);
3587   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3588     return;
3589
3590   /* must have only definition & one usage */
3591   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3592       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3593     return;
3594
3595   /* find the definition */
3596   if (!(dic = hTabItemWithKey (iCodehTab,
3597                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3598     return;
3599
3600   if (dic->op != '=' || POINTER_SET (dic))
3601     return;
3602
3603   /* we now we know that it has one & only one def & use
3604      and the that the definition is an assignment */
3605   IC_LEFT (ic) = IC_RIGHT (dic);
3606
3607   remiCodeFromeBBlock (ebp, dic);
3608   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3609   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3610 }
3611
3612 static void printSymType(char * str, sym_link *sl)
3613 {
3614         if(!pic16_ralloc_debug)return;
3615         
3616         debugLog ("    %s Symbol type: ",str);
3617         printTypeChain( sl, debugF);
3618         debugLog ("\n");
3619 }
3620
3621 /*-----------------------------------------------------------------*/
3622 /* some debug code to print the symbol S_TYPE. Note that
3623  * the function checkSClass in src/SDCCsymt.c dinks with
3624  * the S_TYPE in ways the PIC port doesn't fully like...*/
3625 /*-----------------------------------------------------------------*/
3626 static void isData(sym_link *sl)
3627 {
3628   FILE *of = stderr;
3629
3630         if(!pic16_ralloc_debug)return;
3631         
3632         if(!sl)return;
3633
3634         if(debugF)
3635                 of = debugF;
3636
3637         for ( ; sl; sl=sl->next) {
3638                 if(!IS_DECL(sl) ) {
3639                         switch (SPEC_SCLS(sl)) {
3640                                 case S_DATA: fprintf (of, "data "); break;
3641                                 case S_XDATA: fprintf (of, "xdata "); break;
3642                                 case S_SFR: fprintf (of, "sfr "); break;
3643                                 case S_SBIT: fprintf (of, "sbit "); break;
3644                                 case S_CODE: fprintf (of, "code "); break;
3645                                 case S_IDATA: fprintf (of, "idata "); break;
3646                                 case S_PDATA: fprintf (of, "pdata "); break;
3647                                 case S_LITERAL: fprintf (of, "literal "); break;
3648                                 case S_STACK: fprintf (of, "stack "); break;
3649                                 case S_XSTACK: fprintf (of, "xstack "); break;
3650                                 case S_BIT: fprintf (of, "bit "); break;
3651                                 case S_EEPROM: fprintf (of, "eeprom "); break;
3652                                 default: break;
3653                         }
3654
3655                 }
3656         }
3657 }
3658
3659
3660 /*--------------------------------------------------------------------*/
3661 /* pic16_packRegisters - does some transformations to reduce          */
3662 /*                   register pressure                                */
3663 /*                                                                    */
3664 /*--------------------------------------------------------------------*/
3665 static void
3666 pic16_packRegisters (eBBlock * ebp)
3667 {
3668   iCode *ic;
3669   int change = 0;
3670
3671   debugLog ("%s\n", __FUNCTION__);
3672
3673   while (1) {
3674
3675     change = 0;
3676
3677     /* look for assignments of the form */
3678     /* iTempNN = TRueSym (someoperation) SomeOperand */
3679     /*       ....                       */
3680     /* TrueSym := iTempNN:1             */
3681     for (ic = ebp->sch; ic; ic = ic->next)
3682       {
3683 //              debugLog("%d\n", __LINE__);
3684         /* find assignment of the form TrueSym := iTempNN:1 */
3685         /* see BUGLOG0001 for workaround with the CAST - VR */
3686 //      if ( (ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic) ) // patch 11
3687         if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3688           change += packRegsForAssign (ic, ebp);
3689         /* debug stuff */
3690         if (ic->op == '=')
3691           {
3692             if (POINTER_SET (ic))
3693               debugLog ("pointer is set\n");
3694             debugAopGet ("  result:", IC_RESULT (ic));
3695             debugAopGet ("  left:", IC_LEFT (ic));
3696             debugAopGet ("  right:", IC_RIGHT (ic));
3697           }
3698
3699       }
3700
3701     if (!change)
3702       break;
3703   }
3704
3705   for (ic = ebp->sch; ic; ic = ic->next) {
3706
3707     if(IS_SYMOP ( IC_LEFT(ic))) {
3708       sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3709
3710       debugAopGet ("x  left:", IC_LEFT (ic));
3711 #if 0
3712       if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3713 #else
3714       if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3715 #endif
3716         debugLog ("    is a pointer\n");
3717
3718       if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3719         debugLog ("    is a ptr\n");
3720
3721       if(IS_OP_VOLATILE(IC_LEFT(ic)))
3722         debugLog ("    is volatile\n");
3723
3724       isData(etype);
3725
3726         if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3727             debugLog ("  %d - left is not temp, allocating\n", __LINE__);
3728             pic16_allocDirReg(IC_LEFT (ic));
3729         }
3730
3731       printSymType("c  ", OP_SYMBOL(IC_LEFT(ic))->type);
3732     }
3733
3734     if(IS_SYMOP ( IC_RIGHT(ic))) {
3735       debugAopGet ("  right:", IC_RIGHT (ic));
3736       printSymType("    ", OP_SYMBOL(IC_RIGHT(ic))->type);
3737     }
3738
3739     if(IS_SYMOP ( IC_RESULT(ic))) {
3740       debugAopGet ("  result:", IC_RESULT (ic));
3741       printSymType("     ", OP_SYMBOL(IC_RESULT(ic))->type);
3742     }
3743
3744     if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3745       debugAopGet ("  right:", IC_RIGHT (ic));
3746       printSymType("    ", OP_SYMBOL(IC_RIGHT(ic))->type);
3747 //      pic16_allocDirReg(IC_RIGHT(ic));
3748     }
3749
3750     if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3751       debugAopGet ("  result:", IC_RESULT (ic));
3752       printSymType("     ", OP_SYMBOL(IC_RESULT(ic))->type);
3753 //      pic16_allocDirReg(IC_RESULT(ic));
3754     }
3755
3756
3757     if (POINTER_SET (ic))
3758         debugLog ("  %d - Pointer set\n", __LINE__);
3759
3760
3761     /* if this is an itemp & result of a address of a true sym 
3762        then mark this as rematerialisable   */
3763     if (ic->op == ADDRESS_OF &&
3764         IS_ITEMP (IC_RESULT (ic)) &&
3765         IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3766         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3767         !OP_SYMBOL (IC_LEFT (ic))->onStack)
3768       {
3769
3770         debugLog ("  %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3771
3772         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3773         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3774         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3775
3776       }
3777
3778     /* if straight assignment then carry remat flag if
3779        this is the only definition */
3780     if (ic->op == '=' &&
3781         !POINTER_SET (ic) &&
3782         IS_SYMOP (IC_RIGHT (ic)) &&
3783         OP_SYMBOL (IC_RIGHT (ic))->remat &&
3784         bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3785       {
3786         debugLog ("  %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3787
3788         OP_SYMBOL (IC_RESULT (ic))->remat =
3789           OP_SYMBOL (IC_RIGHT (ic))->remat;
3790         OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3791           OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3792       }
3793
3794     /* if this is a +/- operation with a rematerizable 
3795        then mark this as rematerializable as well */
3796     if ((ic->op == '+' || ic->op == '-') &&
3797         (IS_SYMOP (IC_LEFT (ic)) &&
3798          IS_ITEMP (IC_RESULT (ic)) &&
3799          OP_SYMBOL (IC_LEFT (ic))->remat &&
3800          bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3801          IS_OP_LITERAL (IC_RIGHT (ic))))
3802       {
3803         debugLog ("  %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3804         //int i = 
3805         operandLitValue (IC_RIGHT (ic));
3806         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3807         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3808         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3809       }
3810
3811     /* mark the pointer usages */
3812     if (POINTER_SET (ic))
3813       {
3814         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3815         debugLog ("  marking as a pointer (set) =>");
3816         debugAopGet ("  result:", IC_RESULT (ic));
3817       }
3818     if (POINTER_GET (ic))
3819       {
3820         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3821         debugLog ("  marking as a pointer (get) =>");
3822         debugAopGet ("  left:", IC_LEFT (ic));
3823       }
3824
3825         //debugLog("  %d   %s\n", __LINE__, __FUNCTION__);
3826
3827     if (!SKIP_IC2 (ic))
3828       {
3829         //debugLog("  %d   %s\n", __LINE__, __FUNCTION__ );
3830         /* if we are using a symbol on the stack
3831            then we should say pic16_ptrRegReq */
3832         if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3833           pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3834                                OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3835         else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3836           pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3837                                OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3838         else
3839           {
3840
3841                 //debugLog("   %d   %s\n", __LINE__, __FUNCTION__ );
3842             if (IS_SYMOP (IC_LEFT (ic)))
3843               pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3844                                    OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3845             if (IS_SYMOP (IC_RIGHT (ic)))
3846               pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3847                                    OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3848             if (IS_SYMOP (IC_RESULT (ic)))
3849               pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3850                                    OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3851           }
3852
3853         debugLog ("  %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3854
3855       }
3856
3857     /* if the condition of an if instruction
3858        is defined in the previous instruction then
3859        mark the itemp as a conditional */
3860     if ((IS_CONDITIONAL (ic) ||
3861          ((ic->op == BITWISEAND ||
3862            ic->op == '|' ||
3863            ic->op == '^') &&
3864           isBitwiseOptimizable (ic))) &&
3865         ic->next && ic->next->op == IFX &&
3866         isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3867         OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3868       {
3869
3870         debugLog ("  %d\n", __LINE__);
3871         OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3872         continue;
3873       }
3874
3875         debugLog(" %d\n", __LINE__);
3876
3877 #ifndef NO_packRegsForSupport
3878     /* reduce for support function calls */
3879     if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3880       packRegsForSupport (ic, ebp);
3881 #endif
3882
3883     /* if a parameter is passed, it's in W, so we may not
3884        need to place a copy in a register */
3885     if (ic->op == RECEIVE)
3886       packForReceive (ic, ebp);
3887
3888 #ifndef NO_packRegsForOneuse
3889     /* some cases the redundant moves can
3890        can be eliminated for return statements */
3891     if ((ic->op == RETURN || ic->op == SEND) &&
3892         !isOperandInFarSpace (IC_LEFT (ic)) &&
3893         !options.model)
3894       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3895 #endif
3896
3897 #ifndef NO_packRegsForOneuse
3898     /* if pointer set & left has a size more than
3899        one and right is not in far space */
3900     if (POINTER_SET (ic) &&
3901         !isOperandInFarSpace (IC_RIGHT (ic)) &&
3902         !OP_SYMBOL (IC_RESULT (ic))->remat &&
3903         !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3904         getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3905
3906       packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3907 #endif
3908
3909 #ifndef NO_packRegsForOneuse
3910     /* if pointer get */
3911     if (POINTER_GET (ic) &&
3912         !isOperandInFarSpace (IC_RESULT (ic)) &&
3913         !OP_SYMBOL (IC_LEFT (ic))->remat &&
3914         !IS_OP_RUONLY (IC_RESULT (ic)) &&
3915         getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3916
3917       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3918       debugLog("%d - return from packRegsForOneuse\n", __LINE__);
3919 #endif
3920
3921 #ifndef NO_cast_peep
3922     /* if this is cast for intergral promotion then
3923        check if only use of  the definition of the 
3924        operand being casted/ if yes then replace
3925        the result of that arithmetic operation with 
3926        this result and get rid of the cast */
3927     if (ic->op == CAST) {
3928         
3929       sym_link *fromType = operandType (IC_RIGHT (ic));
3930       sym_link *toType = operandType (IC_LEFT (ic));
3931
3932       debugLog ("  %d - casting\n", __LINE__);
3933
3934       if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3935           getSize (fromType) != getSize (toType)) {
3936             
3937
3938         iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3939         if (dic) {
3940                 
3941           if (IS_ARITHMETIC_OP (dic)) {
3942                     debugLog("   %d   %s\n", __LINE__, __FUNCTION__ );
3943                     
3944             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3945             IC_RESULT (dic) = IC_RESULT (ic);
3946             remiCodeFromeBBlock (ebp, ic);
3947             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3948             hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3949             OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3950             ic = ic->prev;
3951           }  else
3952                 
3953             OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3954         }
3955       } else {
3956
3957         /* if the type from and type to are the same
3958            then if this is the only use then packit */
3959         if (compareType (operandType (IC_RIGHT (ic)),
3960                          operandType (IC_LEFT (ic))) == 1) {
3961                 
3962           iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3963           if (dic) {
3964
3965                    debugLog(" %d\n", __LINE__);
3966
3967             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3968             IC_RESULT (dic) = IC_RESULT (ic);
3969             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3970             remiCodeFromeBBlock (ebp, ic);
3971             hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3972             OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3973             ic = ic->prev;
3974           }
3975         }
3976       }
3977     }
3978 #endif
3979     /* pack for PUSH 
3980        iTempNN := (some variable in farspace) V1
3981        push iTempNN ;
3982        -------------
3983        push V1
3984     */
3985     if (ic->op == IPUSH)
3986       {
3987         packForPush (ic, ebp);
3988       }
3989
3990
3991 #ifndef NO_packRegsForAccUse
3992     /* pack registers for accumulator use, when the
3993        result of an arithmetic or bit wise operation
3994        has only one use, that use is immediately following
3995        the defintion and the using iCode has only one
3996        operand or has two operands but one is literal &
3997        the result of that operation is not on stack then
3998        we can leave the result of this operation in acc:b
3999        combination */
4000     if ((IS_ARITHMETIC_OP (ic)
4001
4002          || IS_BITWISE_OP (ic)
4003
4004          || ic->op == LEFT_OP || ic->op == RIGHT_OP
4005
4006          ) &&
4007         IS_ITEMP (IC_RESULT (ic)) &&
4008         getSize (operandType (IC_RESULT (ic))) <= 1)
4009
4010       packRegsForAccUse (ic);
4011 #endif
4012
4013   }
4014 }
4015
4016 static void
4017 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4018 {
4019   int i;
4020
4021   if (!pic16_ralloc_debug || !debugF)
4022     return;
4023
4024   for (i = 0; i < count; i++)
4025     {
4026       fprintf (debugF, "\n----------------------------------------------------------------\n");
4027       fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4028                ebbs[i]->entryLabel->name,
4029                ebbs[i]->depth,
4030                ebbs[i]->noPath,
4031                ebbs[i]->isLastInLoop);
4032       fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4033                ebbs[i]->dfnum,
4034                ebbs[i]->bbnum,
4035                ebbs[i]->fSeq,
4036                ebbs[i]->lSeq);
4037       fprintf (debugF, "visited %d : hasFcall = %d\n",
4038                ebbs[i]->visited,
4039                ebbs[i]->hasFcall);
4040
4041       fprintf (debugF, "\ndefines bitVector :");
4042       bitVectDebugOn (ebbs[i]->defSet, debugF);
4043       fprintf (debugF, "\nlocal defines bitVector :");
4044       bitVectDebugOn (ebbs[i]->ldefs, debugF);
4045       fprintf (debugF, "\npointers Set bitvector :");
4046       bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4047       fprintf (debugF, "\nin pointers Set bitvector :");
4048       bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4049       fprintf (debugF, "\ninDefs Set bitvector :");
4050       bitVectDebugOn (ebbs[i]->inDefs, debugF);
4051       fprintf (debugF, "\noutDefs Set bitvector :");
4052       bitVectDebugOn (ebbs[i]->outDefs, debugF);
4053       fprintf (debugF, "\nusesDefs Set bitvector :");
4054       bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4055       fprintf (debugF, "\n----------------------------------------------------------------\n");
4056       printiCChain (ebbs[i]->sch, debugF);
4057     }
4058 }
4059 /*-----------------------------------------------------------------*/
4060 /* pic16_assignRegisters - assigns registers to each live range as need  */
4061 /*-----------------------------------------------------------------*/
4062 void
4063 pic16_assignRegisters (eBBlock ** ebbs, int count)
4064 {
4065   iCode *ic;
4066   int i;
4067
4068   debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4069   debugLog ("\nebbs before optimizing:\n");
4070   dumpEbbsToDebug (ebbs, count);
4071
4072   setToNull ((void *) &_G.funcrUsed);
4073   pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4074
4075
4076   /* change assignments this will remove some
4077      live ranges reducing some register pressure */
4078   for (i = 0; i < count; i++)
4079     pic16_packRegisters (ebbs[i]);
4080
4081   {
4082     regs *reg;
4083     int hkey;
4084     int i=0;
4085
4086     debugLog("dir registers allocated so far:\n");
4087     reg = hTabFirstItem(dynDirectRegNames, &hkey);
4088
4089     while(reg) {
4090       debugLog("  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4091 //      fprintf(stderr, "  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4092       reg = hTabNextItem(dynDirectRegNames, &hkey);
4093     }
4094
4095   }
4096
4097   /* liveranges probably changed by register packing
4098      so we compute them again */
4099   recomputeLiveRanges (ebbs, count);
4100
4101   if (options.dump_pack)
4102     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4103
4104   /* first determine for each live range the number of 
4105      registers & the type of registers required for each */
4106   regTypeNum ();
4107
4108   /* and serially allocate registers */
4109   serialRegAssign (ebbs, count);
4110
4111 //  debugLog ("ebbs after serialRegAssign:\n");
4112 //  dumpEbbsToDebug (ebbs, count);
4113
4114
4115   //pic16_freeAllRegs();
4116
4117   /* if stack was extended then tell the user */
4118   if (_G.stackExtend)
4119     {
4120 /*      werror(W_TOOMANY_SPILS,"stack", */
4121 /*             _G.stackExtend,currFunc->name,""); */
4122       _G.stackExtend = 0;
4123     }
4124
4125   if (_G.dataExtend)
4126     {
4127 /*      werror(W_TOOMANY_SPILS,"data space", */
4128 /*             _G.dataExtend,currFunc->name,""); */
4129       _G.dataExtend = 0;
4130     }
4131
4132   /* after that create the register mask
4133      for each of the instruction */
4134   createRegMask (ebbs, count);
4135
4136   /* redo that offsets for stacked automatic variables */
4137   redoStackOffsets ();
4138
4139   if (options.dump_rassgn)
4140     dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4141
4142   /* now get back the chain */
4143   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4144
4145   debugLog ("ebbs after optimizing:\n");
4146   dumpEbbsToDebug (ebbs, count);
4147
4148
4149   genpic16Code (ic);
4150
4151   /* free up any _G.stackSpil locations allocated */
4152   applyToSet (_G.stackSpil, deallocStackSpil);
4153   _G.slocNum = 0;
4154   setToNull ((void *) &_G.stackSpil);
4155   setToNull ((void *) &_G.spiltSet);
4156   /* mark all registers as free */
4157   pic16_freeAllRegs ();
4158
4159   debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
4160   debugLogClose ();
4161   return;
4162 }