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