Version 1.18 was a copy of ralloc.h(1.7). So this version is the same as version...
[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   int j;
1738
1739   debugLog ("%s\n", __FUNCTION__);
1740 tryAgain:
1741   /* try for a ptr type */
1742   if ((reg = allocReg (REG_PTR)))
1743     return reg;
1744
1745   /* try for gpr type */
1746   if ((reg = allocReg (REG_GPR)))
1747     return reg;
1748
1749   /* we have to spil */
1750   if (!spilSomething (ic, ebp, sym))
1751     return NULL;
1752
1753   /* make sure partially assigned registers aren't reused */
1754   for (j=0; j<=sym->nRegs; j++)
1755     if (sym->regs[j])
1756       sym->regs[j]->isFree = 0;
1757       
1758   /* this looks like an infinite loop but 
1759      in really selectSpil will abort  */
1760   goto tryAgain;
1761 }
1762
1763 /*-----------------------------------------------------------------*/
1764 /* getRegGpr - will try for GPR if not spil                        */
1765 /*-----------------------------------------------------------------*/
1766 static regs *
1767 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1768 {
1769   regs *reg;
1770   int j;
1771
1772   debugLog ("%s\n", __FUNCTION__);
1773 tryAgain:
1774   /* try for gpr type */
1775   if ((reg = allocReg (REG_GPR)))
1776     return reg;
1777
1778   if (!pic16_ptrRegReq)
1779     if ((reg = allocReg (REG_PTR)))
1780       return reg;
1781
1782   /* we have to spil */
1783   if (!spilSomething (ic, ebp, sym))
1784     return NULL;
1785
1786   /* make sure partially assigned registers aren't reused */
1787   for (j=0; j<=sym->nRegs; j++)
1788     if (sym->regs[j])
1789       sym->regs[j]->isFree = 0;
1790       
1791   /* this looks like an infinite loop but 
1792      in really selectSpil will abort  */
1793   goto tryAgain;
1794 }
1795
1796 /*-----------------------------------------------------------------*/
1797 /* symHasReg - symbol has a given register                         */
1798 /*-----------------------------------------------------------------*/
1799 static bool
1800 symHasReg (symbol * sym, regs * reg)
1801 {
1802   int i;
1803
1804   debugLog ("%s\n", __FUNCTION__);
1805   for (i = 0; i < sym->nRegs; i++)
1806     if (sym->regs[i] == reg)
1807       return TRUE;
1808
1809   return FALSE;
1810 }
1811
1812 /*-----------------------------------------------------------------*/
1813 /* deassignLRs - check the live to and if they have registers & are */
1814 /*               not spilt then free up the registers              */
1815 /*-----------------------------------------------------------------*/
1816 static void
1817 deassignLRs (iCode * ic, eBBlock * ebp)
1818 {
1819   symbol *sym;
1820   int k;
1821   symbol *result;
1822
1823   debugLog ("%s\n", __FUNCTION__);
1824   for (sym = hTabFirstItem (liveRanges, &k); sym;
1825        sym = hTabNextItem (liveRanges, &k))
1826     {
1827
1828       symbol *psym = NULL;
1829       /* if it does not end here */
1830       if (sym->liveTo > ic->seq)
1831         continue;
1832
1833       /* if it was spilt on stack then we can 
1834          mark the stack spil location as free */
1835       if (sym->isspilt)
1836         {
1837           if (sym->stackSpil)
1838             {
1839               sym->usl.spillLoc->isFree = 1;
1840               sym->stackSpil = 0;
1841             }
1842           continue;
1843         }
1844
1845       if (!bitVectBitValue (_G.regAssigned, sym->key))
1846         continue;
1847
1848       /* special case check if this is an IFX &
1849          the privious one was a pop and the 
1850          previous one was not spilt then keep track
1851          of the symbol */
1852       if (ic->op == IFX && ic->prev &&
1853           ic->prev->op == IPOP &&
1854           !ic->prev->parmPush &&
1855           !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1856         psym = OP_SYMBOL (IC_LEFT (ic->prev));
1857
1858       if (sym->nRegs)
1859         {
1860           int i = 0;
1861
1862           bitVectUnSetBit (_G.regAssigned, sym->key);
1863
1864           /* if the result of this one needs registers
1865              and does not have it then assign it right
1866              away */
1867           if (IC_RESULT (ic) &&
1868               !(SKIP_IC2 (ic) ||        /* not a special icode */
1869                 ic->op == JUMPTABLE ||
1870                 ic->op == IFX ||
1871                 ic->op == IPUSH ||
1872                 ic->op == IPOP ||
1873                 ic->op == RETURN ||
1874                 POINTER_SET (ic)) &&
1875               (result = OP_SYMBOL (IC_RESULT (ic))) &&  /* has a result */
1876               result->liveTo > ic->seq &&       /* and will live beyond this */
1877               result->liveTo <= ebp->lSeq &&    /* does not go beyond this block */
1878               result->regType == sym->regType &&        /* same register types */
1879               result->nRegs &&  /* which needs registers */
1880               !result->isspilt &&       /* and does not already have them */
1881               !result->remat &&
1882               !bitVectBitValue (_G.regAssigned, result->key) &&
1883           /* the number of free regs + number of regs in this LR
1884              can accomodate the what result Needs */
1885               ((nfreeRegsType (result->regType) +
1886                 sym->nRegs) >= result->nRegs)
1887             )
1888             {
1889
1890               for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1891                 if (i < sym->nRegs)
1892                   result->regs[i] = sym->regs[i];
1893                 else
1894                   result->regs[i] = getRegGpr (ic, ebp, result);
1895
1896               _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1897
1898             }
1899
1900           /* free the remaining */
1901           for (; i < sym->nRegs; i++)
1902             {
1903               if (psym)
1904                 {
1905                   if (!symHasReg (psym, sym->regs[i]))
1906                     freeReg (sym->regs[i]);
1907                 }
1908               else
1909                 freeReg (sym->regs[i]);
1910             }
1911         }
1912     }
1913 }
1914
1915
1916 /*-----------------------------------------------------------------*/
1917 /* reassignLR - reassign this to registers                         */
1918 /*-----------------------------------------------------------------*/
1919 static void
1920 reassignLR (operand * op)
1921 {
1922   symbol *sym = OP_SYMBOL (op);
1923   int i;
1924
1925   debugLog ("%s\n", __FUNCTION__);
1926   /* not spilt any more */
1927   sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1928   bitVectUnSetBit (_G.spiltSet, sym->key);
1929
1930   _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1931
1932   _G.blockSpil--;
1933
1934   for (i = 0; i < sym->nRegs; i++)
1935     sym->regs[i]->isFree = 0;
1936 }
1937
1938 /*-----------------------------------------------------------------*/
1939 /* willCauseSpill - determines if allocating will cause a spill    */
1940 /*-----------------------------------------------------------------*/
1941 static int
1942 willCauseSpill (int nr, int rt)
1943 {
1944   debugLog ("%s\n", __FUNCTION__);
1945   /* first check if there are any avlb registers
1946      of te type required */
1947   if (rt == REG_PTR)
1948     {
1949       /* special case for pointer type 
1950          if pointer type not avlb then 
1951          check for type gpr */
1952       if (nFreeRegs (rt) >= nr)
1953         return 0;
1954       if (nFreeRegs (REG_GPR) >= nr)
1955         return 0;
1956     }
1957   else
1958     {
1959       if (pic16_ptrRegReq)
1960         {
1961           if (nFreeRegs (rt) >= nr)
1962             return 0;
1963         }
1964       else
1965         {
1966           if (nFreeRegs (REG_PTR) +
1967               nFreeRegs (REG_GPR) >= nr)
1968             return 0;
1969         }
1970     }
1971
1972   debugLog (" ... yep it will (cause a spill)\n");
1973   /* it will cause a spil */
1974   return 1;
1975 }
1976
1977 /*-----------------------------------------------------------------*/
1978 /* positionRegs - the allocator can allocate same registers to res- */
1979 /* ult and operand, if this happens make sure they are in the same */
1980 /* position as the operand otherwise chaos results                 */
1981 /*-----------------------------------------------------------------*/
1982 static void
1983 positionRegs (symbol * result, symbol * opsym, int lineno)
1984 {
1985   int count = min (result->nRegs, opsym->nRegs);
1986   int i, j = 0, shared = 0;
1987
1988   debugLog ("%s\n", __FUNCTION__);
1989   /* if the result has been spilt then cannot share */
1990   if (opsym->isspilt)
1991     return;
1992 again:
1993   shared = 0;
1994   /* first make sure that they actually share */
1995   for (i = 0; i < count; i++)
1996     {
1997       for (j = 0; j < count; j++)
1998         {
1999           if (result->regs[i] == opsym->regs[j] && i != j)
2000             {
2001               shared = 1;
2002               goto xchgPositions;
2003             }
2004         }
2005     }
2006 xchgPositions:
2007   if (shared)
2008     {
2009       regs *tmp = result->regs[i];
2010       result->regs[i] = result->regs[j];
2011       result->regs[j] = tmp;
2012       goto again;
2013     }
2014 }
2015
2016 /*------------------------------------------------------------------*/
2017 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2018 /* it should either have registers or have beed spilled. Otherwise, */
2019 /* there was an uninitialized variable, so just spill this to get   */
2020 /* the operand in a valid state.                                    */
2021 /*------------------------------------------------------------------*/
2022 static void
2023 verifyRegsAssigned (operand *op, iCode * ic)
2024 {
2025   symbol * sym;
2026   
2027   if (!op) return;
2028   if (!IS_ITEMP (op)) return;
2029   
2030   sym = OP_SYMBOL (op);
2031   if (sym->isspilt) return;
2032   if (!sym->nRegs) return;
2033   if (sym->regs[0]) return;
2034   
2035   werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT, 
2036             sym->prereqv ? sym->prereqv->name : sym->name);
2037   spillThis (sym);
2038 }
2039
2040
2041 /*-----------------------------------------------------------------*/
2042 /* serialRegAssign - serially allocate registers to the variables  */
2043 /*-----------------------------------------------------------------*/
2044 static void
2045 serialRegAssign (eBBlock ** ebbs, int count)
2046 {
2047   int i;
2048
2049   debugLog ("%s\n", __FUNCTION__);
2050   /* for all blocks */
2051   for (i = 0; i < count; i++)
2052     {
2053
2054       iCode *ic;
2055
2056       if (ebbs[i]->noPath &&
2057           (ebbs[i]->entryLabel != entryLabel &&
2058            ebbs[i]->entryLabel != returnLabel))
2059         continue;
2060
2061       /* of all instructions do */
2062       for (ic = ebbs[i]->sch; ic; ic = ic->next)
2063         {
2064
2065           debugLog ("  op: %s\n", decodeOp (ic->op));
2066
2067           /* if this is an ipop that means some live
2068              range will have to be assigned again */
2069           if (ic->op == IPOP)
2070             reassignLR (IC_LEFT (ic));
2071
2072           /* if result is present && is a true symbol */
2073           if (IC_RESULT (ic) && ic->op != IFX &&
2074               IS_TRUE_SYMOP (IC_RESULT (ic)))
2075             OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2076
2077           /* take away registers from live
2078              ranges that end at this instruction */
2079           deassignLRs (ic, ebbs[i]);
2080
2081           /* some don't need registers */
2082           if (SKIP_IC2 (ic) ||
2083               ic->op == JUMPTABLE ||
2084               ic->op == IFX ||
2085               ic->op == IPUSH ||
2086               ic->op == IPOP ||
2087               (IC_RESULT (ic) && POINTER_SET (ic)))
2088             continue;
2089
2090           /* now we need to allocate registers
2091              only for the result */
2092           if (IC_RESULT (ic))
2093             {
2094               symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2095               bitVect *spillable;
2096               int willCS;
2097               int j;
2098               int ptrRegSet = 0;
2099
2100               /* if it does not need or is spilt 
2101                  or is already assigned to registers
2102                  or will not live beyond this instructions */
2103               if (!sym->nRegs ||
2104                   sym->isspilt ||
2105                   bitVectBitValue (_G.regAssigned, sym->key) ||
2106                   sym->liveTo <= ic->seq)
2107                 continue;
2108
2109               /* if some liverange has been spilt at the block level
2110                  and this one live beyond this block then spil this
2111                  to be safe */
2112               if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2113                 {
2114                   spillThis (sym);
2115                   continue;
2116                 }
2117               /* if trying to allocate this will cause
2118                  a spill and there is nothing to spill 
2119                  or this one is rematerializable then
2120                  spill this one */
2121               willCS = willCauseSpill (sym->nRegs, sym->regType);
2122               spillable = computeSpillable (ic);
2123               if (sym->remat ||
2124                   (willCS && bitVectIsZero (spillable)))
2125                 {
2126
2127                   spillThis (sym);
2128                   continue;
2129
2130                 }
2131
2132               /* if it has a spillocation & is used less than
2133                  all other live ranges then spill this */
2134                 if (willCS) {
2135                     if (sym->usl.spillLoc) {
2136                         symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2137                                                                          allLRs, ebbs[i], ic));
2138                         if (leastUsed && leastUsed->used > sym->used) {
2139                             spillThis (sym);
2140                             continue;
2141                         }
2142                     } else {
2143                         /* if none of the liveRanges have a spillLocation then better
2144                            to spill this one than anything else already assigned to registers */
2145                         if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2146                             /* if this is local to this block then we might find a block spil */
2147                             if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2148                                 spillThis (sym);
2149                                 continue;
2150                             }
2151                         }
2152                     }
2153                 }
2154
2155               if (ic->op == RECEIVE)
2156                 debugLog ("When I get clever, I'll optimize the receive logic\n");
2157
2158               /* if we need ptr regs for the right side
2159                  then mark it */
2160               if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2161                   <= (unsigned) PTRSIZE)
2162                 {
2163                   pic16_ptrRegReq++;
2164                   ptrRegSet = 1;
2165                 }
2166               /* else we assign registers to it */
2167               _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2168
2169               debugLog ("  %d - \n", __LINE__);
2170               if(debugF) 
2171                 bitVectDebugOn(_G.regAssigned, debugF);
2172
2173               for (j = 0; j < sym->nRegs; j++)
2174                 {
2175                   if (sym->regType == REG_PTR)
2176                     sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2177                   else
2178                     sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2179
2180                   /* if the allocation falied which means
2181                      this was spilt then break */
2182                   if (!sym->regs[j])
2183                     break;
2184                 }
2185               debugLog ("  %d - \n", __LINE__);
2186
2187               /* if it shares registers with operands make sure
2188                  that they are in the same position */
2189               if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2190                   OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2191                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2192                               OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2193               /* do the same for the right operand */
2194               if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2195                   OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2196                 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2197                               OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2198
2199               debugLog ("  %d - \n", __LINE__);
2200               if (ptrRegSet)
2201                 {
2202                   debugLog ("  %d - \n", __LINE__);
2203                   pic16_ptrRegReq--;
2204                   ptrRegSet = 0;
2205                 }
2206
2207             }
2208         }
2209     }
2210
2211     /* Check for and fix any problems with uninitialized operands */
2212     for (i = 0; i < count; i++)
2213       {
2214         iCode *ic;
2215
2216         if (ebbs[i]->noPath &&
2217             (ebbs[i]->entryLabel != entryLabel &&
2218              ebbs[i]->entryLabel != returnLabel))
2219             continue;
2220
2221         for (ic = ebbs[i]->sch; ic; ic = ic->next)
2222           {
2223             if (SKIP_IC2 (ic))
2224               continue;
2225
2226             if (ic->op == IFX)
2227               {
2228                 verifyRegsAssigned (IC_COND (ic), ic);
2229                 continue;
2230               }
2231
2232             if (ic->op == JUMPTABLE)
2233               {
2234                 verifyRegsAssigned (IC_JTCOND (ic), ic);
2235                 continue;
2236               }
2237
2238             verifyRegsAssigned (IC_RESULT (ic), ic);
2239             verifyRegsAssigned (IC_LEFT (ic), ic);
2240             verifyRegsAssigned (IC_RIGHT (ic), ic);
2241           }
2242       }    
2243     
2244 }
2245
2246 /*-----------------------------------------------------------------*/
2247 /* rUmaskForOp :- returns register mask for an operand             */
2248 /*-----------------------------------------------------------------*/
2249 static bitVect *
2250 rUmaskForOp (operand * op)
2251 {
2252   bitVect *rumask;
2253   symbol *sym;
2254   int j;
2255
2256   debugLog ("%s\n", __FUNCTION__);
2257   /* only temporaries are assigned registers */
2258   if (!IS_ITEMP (op))
2259     return NULL;
2260
2261   sym = OP_SYMBOL (op);
2262
2263   /* if spilt or no registers assigned to it
2264      then nothing */
2265   if (sym->isspilt || !sym->nRegs)
2266     return NULL;
2267
2268   rumask = newBitVect (pic16_nRegs);
2269
2270   for (j = 0; j < sym->nRegs; j++)
2271     {
2272       rumask = bitVectSetBit (rumask,
2273                               sym->regs[j]->rIdx);
2274     }
2275
2276   return rumask;
2277 }
2278
2279 /*-----------------------------------------------------------------*/
2280 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2281 /*-----------------------------------------------------------------*/
2282 static bitVect *
2283 regsUsedIniCode (iCode * ic)
2284 {
2285   bitVect *rmask = newBitVect (pic16_nRegs);
2286
2287   debugLog ("%s\n", __FUNCTION__);
2288   /* do the special cases first */
2289   if (ic->op == IFX)
2290     {
2291       rmask = bitVectUnion (rmask,
2292                             rUmaskForOp (IC_COND (ic)));
2293       goto ret;
2294     }
2295
2296   /* for the jumptable */
2297   if (ic->op == JUMPTABLE)
2298     {
2299       rmask = bitVectUnion (rmask,
2300                             rUmaskForOp (IC_JTCOND (ic)));
2301
2302       goto ret;
2303     }
2304
2305   /* of all other cases */
2306   if (IC_LEFT (ic))
2307     rmask = bitVectUnion (rmask,
2308                           rUmaskForOp (IC_LEFT (ic)));
2309
2310
2311   if (IC_RIGHT (ic))
2312     rmask = bitVectUnion (rmask,
2313                           rUmaskForOp (IC_RIGHT (ic)));
2314
2315   if (IC_RESULT (ic))
2316     rmask = bitVectUnion (rmask,
2317                           rUmaskForOp (IC_RESULT (ic)));
2318
2319 ret:
2320   return rmask;
2321 }
2322
2323 /*-----------------------------------------------------------------*/
2324 /* createRegMask - for each instruction will determine the regsUsed */
2325 /*-----------------------------------------------------------------*/
2326 static void
2327 createRegMask (eBBlock ** ebbs, int count)
2328 {
2329   int i;
2330
2331   debugLog ("%s\n", __FUNCTION__);
2332   /* for all blocks */
2333   for (i = 0; i < count; i++)
2334     {
2335       iCode *ic;
2336
2337       if (ebbs[i]->noPath &&
2338           (ebbs[i]->entryLabel != entryLabel &&
2339            ebbs[i]->entryLabel != returnLabel))
2340         continue;
2341
2342       /* for all instructions */
2343       for (ic = ebbs[i]->sch; ic; ic = ic->next)
2344         {
2345
2346           int j;
2347
2348           if (SKIP_IC2 (ic) || !ic->rlive)
2349             continue;
2350
2351           /* first mark the registers used in this
2352              instruction */
2353           ic->rUsed = regsUsedIniCode (ic);
2354           _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2355
2356           /* now create the register mask for those 
2357              registers that are in use : this is a
2358              super set of ic->rUsed */
2359           ic->rMask = newBitVect (pic16_nRegs + 1);
2360
2361           /* for all live Ranges alive at this point */
2362           for (j = 1; j < ic->rlive->size; j++)
2363             {
2364               symbol *sym;
2365               int k;
2366
2367               /* if not alive then continue */
2368               if (!bitVectBitValue (ic->rlive, j))
2369                 continue;
2370
2371               /* find the live range we are interested in */
2372               if (!(sym = hTabItemWithKey (liveRanges, j)))
2373                 {
2374                   werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2375                           "createRegMask cannot find live range");
2376                   exit (0);
2377                 }
2378
2379               /* if no register assigned to it */
2380               if (!sym->nRegs || sym->isspilt)
2381                 continue;
2382
2383               /* for all the registers allocated to it */
2384               for (k = 0; k < sym->nRegs; k++)
2385                 if (sym->regs[k])
2386                   ic->rMask =
2387                     bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2388             }
2389         }
2390     }
2391 }
2392
2393 /*-----------------------------------------------------------------*/
2394 /* rematStr - returns the rematerialized string for a remat var    */
2395 /*-----------------------------------------------------------------*/
2396 static symbol *
2397 rematStr (symbol * sym)
2398 {
2399   char *s = buffer;
2400   iCode *ic = sym->rematiCode;
2401   symbol *psym = NULL;
2402
2403   debugLog ("%s\n", __FUNCTION__);
2404
2405   //printf ("%s\n", s);
2406
2407   /* if plus or minus print the right hand side */
2408
2409   if (ic->op == '+' || ic->op == '-') {
2410         
2411     iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2412
2413     sprintf (s, "(%s %c 0x%04x)",
2414              OP_SYMBOL (IC_LEFT (ric))->rname,
2415              ic->op,
2416              (int) operandLitValue (IC_RIGHT (ic)));
2417
2418
2419     //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2420
2421     psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2422     psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2423
2424     return psym;
2425   }
2426
2427   sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2428   psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2429
2430   //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2431   return psym;
2432 }
2433
2434 #if 0
2435 /*-----------------------------------------------------------------*/
2436 /* rematStr - returns the rematerialized string for a remat var    */
2437 /*-----------------------------------------------------------------*/
2438 static char *
2439 rematStr (symbol * sym)
2440 {
2441   char *s = buffer;
2442   iCode *ic = sym->rematiCode;
2443
2444   debugLog ("%s\n", __FUNCTION__);
2445   while (1)
2446     {
2447
2448       printf ("%s\n", s);
2449       /* if plus or minus print the right hand side */
2450 /*
2451    if (ic->op == '+' || ic->op == '-') {
2452    sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2453    ic->op );
2454    s += strlen(s);
2455    ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2456    continue ;
2457    }
2458  */
2459       if (ic->op == '+' || ic->op == '-')
2460         {
2461           iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2462           sprintf (s, "(%s %c 0x%04x)",
2463                    OP_SYMBOL (IC_LEFT (ric))->rname,
2464                    ic->op,
2465                    (int) operandLitValue (IC_RIGHT (ic)));
2466
2467           //s += strlen(s);
2468           //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2469           //continue ;
2470           //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2471           return buffer;
2472         }
2473
2474       /* we reached the end */
2475       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2476       break;
2477     }
2478
2479   printf ("%s\n", buffer);
2480   return buffer;
2481 }
2482 #endif
2483
2484 /*-----------------------------------------------------------------*/
2485 /* regTypeNum - computes the type & number of registers required   */
2486 /*-----------------------------------------------------------------*/
2487 static void
2488 regTypeNum ()
2489 {
2490   symbol *sym;
2491   int k;
2492   iCode *ic;
2493
2494   debugLog ("%s\n", __FUNCTION__);
2495   /* for each live range do */
2496   for (sym = hTabFirstItem (liveRanges, &k); sym;
2497        sym = hTabNextItem (liveRanges, &k)) {
2498
2499     debugLog ("  %d - %s\n", __LINE__, sym->rname);
2500     //fprintf(stderr,"  %d - %s\n", __LINE__, sym->rname);
2501
2502     /* if used zero times then no registers needed */
2503     if ((sym->liveTo - sym->liveFrom) == 0)
2504       continue;
2505
2506
2507     /* if the live range is a temporary */
2508     if (sym->isitmp) {
2509
2510       debugLog ("  %d - itemp register\n", __LINE__);
2511
2512       /* if the type is marked as a conditional */
2513       if (sym->regType == REG_CND)
2514         continue;
2515
2516       /* if used in return only then we don't 
2517          need registers */
2518       if (sym->ruonly || sym->accuse) {
2519         if (IS_AGGREGATE (sym->type) || sym->isptr)
2520           sym->type = aggrToPtr (sym->type, FALSE);
2521         debugLog ("  %d - no reg needed - used as a return\n", __LINE__);
2522
2523         continue;
2524       }
2525
2526       /* if the symbol has only one definition &
2527          that definition is a get_pointer and the
2528          pointer we are getting is rematerializable and
2529          in "data" space */
2530
2531       if (bitVectnBitsOn (sym->defs) == 1 &&
2532           (ic = hTabItemWithKey (iCodehTab,
2533                                  bitVectFirstBit (sym->defs))) &&
2534           POINTER_GET (ic) &&
2535           !sym->noSpilLoc &&
2536           !IS_BITVAR (sym->etype)) {
2537         
2538
2539         debugLog ("  %d - \n", __LINE__);
2540
2541         /* if remat in data space */
2542         if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2543             DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2544
2545           /* create a psuedo symbol & force a spil */
2546           //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2547           symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2548           psym->type = sym->type;
2549           psym->etype = sym->etype;
2550           strcpy (psym->rname, psym->name);
2551           sym->isspilt = 1;
2552           sym->usl.spillLoc = psym;
2553           continue;
2554         }
2555
2556         /* if in data space or idata space then try to
2557            allocate pointer register */
2558
2559       }
2560
2561       /* if not then we require registers */
2562       sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2563                     getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2564                     getSize (sym->type));
2565
2566
2567 #if 0
2568     if(IS_PTR_CONST (sym->type)) {
2569 #else
2570     if(IS_CODEPTR (sym->type)) {
2571 #endif
2572       debugLog ("  %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2573       sym->nRegs = 2;
2574     }
2575
2576       if (sym->nRegs > 4) {
2577         fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2578         printTypeChain (sym->type, stderr);
2579         fprintf (stderr, "\n");
2580       }
2581
2582       /* determine the type of register required */
2583       if (sym->nRegs == 1 &&
2584           IS_PTR (sym->type) &&
2585           sym->uptr)
2586         sym->regType = REG_PTR;
2587       else
2588         sym->regType = REG_GPR;
2589
2590
2591       debugLog ("  reg name %s,  reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2592
2593     }
2594     else
2595       /* for the first run we don't provide */
2596       /* registers for true symbols we will */
2597       /* see how things go                  */
2598       sym->nRegs = 0;
2599   }
2600
2601 }
2602 static DEFSETFUNC (markRegFree)
2603 {
2604   ((regs *)item)->isFree = 1;
2605
2606   return 0;
2607 }
2608
2609 DEFSETFUNC (pic16_deallocReg)
2610 {
2611   fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2612   ((regs *)item)->isFree = 1;
2613   ((regs *)item)->wasUsed = 0;
2614
2615   return 0;
2616 }
2617 /*-----------------------------------------------------------------*/
2618 /* freeAllRegs - mark all registers as free                        */
2619 /*-----------------------------------------------------------------*/
2620 void
2621 pic16_freeAllRegs ()
2622 {
2623   debugLog ("%s\n", __FUNCTION__);
2624
2625   applyToSet(pic16_dynAllocRegs,markRegFree);
2626   applyToSet(pic16_dynStackRegs,markRegFree);
2627 }
2628
2629 /*-----------------------------------------------------------------*/
2630 /*-----------------------------------------------------------------*/
2631 void
2632 pic16_deallocateAllRegs ()
2633 {
2634   debugLog ("%s\n", __FUNCTION__);
2635
2636   applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2637 }
2638
2639
2640 /*-----------------------------------------------------------------*/
2641 /* deallocStackSpil - this will set the stack pointer back         */
2642 /*-----------------------------------------------------------------*/
2643 static
2644 DEFSETFUNC (deallocStackSpil)
2645 {
2646   symbol *sym = item;
2647
2648   debugLog ("%s\n", __FUNCTION__);
2649   deallocLocal (sym);
2650   return 0;
2651 }
2652
2653 /*-----------------------------------------------------------------*/
2654 /* farSpacePackable - returns the packable icode for far variables */
2655 /*-----------------------------------------------------------------*/
2656 static iCode *
2657 farSpacePackable (iCode * ic)
2658 {
2659   iCode *dic;
2660
2661   debugLog ("%s\n", __FUNCTION__);
2662   /* go thru till we find a definition for the
2663      symbol on the right */
2664   for (dic = ic->prev; dic; dic = dic->prev)
2665     {
2666
2667       /* if the definition is a call then no */
2668       if ((dic->op == CALL || dic->op == PCALL) &&
2669           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2670         {
2671           return NULL;
2672         }
2673
2674       /* if shift by unknown amount then not */
2675       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2676           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2677         return NULL;
2678
2679       /* if pointer get and size > 1 */
2680       if (POINTER_GET (dic) &&
2681           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2682         return NULL;
2683
2684       if (POINTER_SET (dic) &&
2685           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2686         return NULL;
2687
2688       /* if any three is a true symbol in far space */
2689       if (IC_RESULT (dic) &&
2690           IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2691           isOperandInFarSpace (IC_RESULT (dic)))
2692         return NULL;
2693
2694       if (IC_RIGHT (dic) &&
2695           IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2696           isOperandInFarSpace (IC_RIGHT (dic)) &&
2697           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2698         return NULL;
2699
2700       if (IC_LEFT (dic) &&
2701           IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2702           isOperandInFarSpace (IC_LEFT (dic)) &&
2703           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2704         return NULL;
2705
2706       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2707         {
2708           if ((dic->op == LEFT_OP ||
2709                dic->op == RIGHT_OP ||
2710                dic->op == '-') &&
2711               IS_OP_LITERAL (IC_RIGHT (dic)))
2712             return NULL;
2713           else
2714             return dic;
2715         }
2716     }
2717
2718   return NULL;
2719 }
2720
2721 /*-----------------------------------------------------------------*/
2722 /* packRegsForAssign - register reduction for assignment           */
2723 /*-----------------------------------------------------------------*/
2724 static int
2725 packRegsForAssign (iCode * ic, eBBlock * ebp)
2726 {
2727
2728   iCode *dic, *sic;
2729
2730   debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2731   debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2732   debugAopGet ("  result:", IC_RESULT (ic));
2733   debugAopGet ("  left:", IC_LEFT (ic));
2734   debugAopGet ("  right:", IC_RIGHT (ic));
2735
2736   /* if this is at an absolute address, then get the address. */
2737   if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2738     if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2739       debugLog ("  %d - found config word declaration\n", __LINE__);
2740       if(IS_VALOP(IC_RIGHT(ic))) {
2741         debugLog ("  setting config word to %x\n", 
2742                   (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2743         fprintf(stderr, "  setting config word to %x\n", 
2744                   (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2745         pic16_assignConfigWordValue(  SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2746                                 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2747       }
2748
2749
2750         debugLog(" %d\n", __LINE__);
2751
2752       /* remove the assignment from the iCode chain. */
2753
2754       remiCodeFromeBBlock (ebp, ic);
2755       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2756       hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2757
2758       return 1;
2759
2760     }
2761   }
2762         debugLog(" %d - actuall processing\n", __LINE__ );
2763
2764   if (!IS_ITEMP (IC_RESULT (ic))) {
2765     pic16_allocDirReg(IC_RESULT (ic));
2766     debugLog ("  %d - result is not temp\n", __LINE__);
2767   }
2768
2769 #if 0
2770   if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2771     debugLog ("  %d - left is not temp, allocating\n", __LINE__);
2772     pic16_allocDirReg(IC_LEFT (ic));
2773   }
2774 #endif
2775
2776 /* See BUGLOG0001 - VR */
2777 #if 1
2778   if (!IS_ITEMP (IC_RIGHT (ic))) {
2779     debugLog ("  %d - not packing - right is not temp\n", __LINE__);
2780     pic16_allocDirReg(IC_RIGHT (ic));
2781     return 0;
2782   }
2783 #endif
2784
2785   if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2786       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2787     {
2788       debugLog ("  %d - not packing - right side fails \n", __LINE__);
2789       return 0;
2790     }
2791
2792   /* if the true symbol is defined in far space or on stack
2793      then we should not since this will increase register pressure */
2794   if (isOperandInFarSpace (IC_RESULT (ic)))
2795     {
2796       if ((dic = farSpacePackable (ic)))
2797         goto pack;
2798       else
2799         return 0;
2800
2801     }
2802
2803 #if 0
2804         if(ic->op == CALL || ic->op == PCALL) {
2805                 addSet(&pic16_builtin_functions, OP_SYMBOL( IC_LEFT(ic)));
2806                 debugLog ("%d This is a call, function: %s\n", __LINE__, OP_SYMBOL(IC_LEFT(ic))->name);
2807                 return 0;
2808         }
2809 #endif
2810
2811   /* find the definition of iTempNN scanning backwards if we find a 
2812      a use of the true symbol before we find the definition then 
2813      we cannot pack */
2814   for (dic = ic->prev; dic; dic = dic->prev)
2815     {
2816
2817       /* if there is a function call and this is
2818          a parameter & not my parameter then don't pack it */
2819       if ((dic->op == CALL || dic->op == PCALL) &&
2820           (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2821            !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2822         {
2823           debugLog ("  %d - \n", __LINE__);
2824           dic = NULL;
2825           break;
2826         }
2827
2828
2829       if (SKIP_IC2 (dic))
2830         continue;
2831
2832         debugLog("%d\tSearching for iTempNN\n", __LINE__);
2833
2834 #if 0
2835         if(IS_TRUE_SYMOP( IC_RESULT(dic))) {
2836                 debugLog("%d - dic result is a TRUE_SYMOP\n", __LINE__);
2837                 debugAopGet(" result is ", IC_RESULT(dic));
2838         }
2839         if(IS_TRUE_SYMOP( IC_LEFT(dic))) {
2840                 debugLog("%d - dic left is a SYMOP\n", __LINE__);
2841                 debugAopGet("   left is ", IC_LEFT(dic));
2842         }
2843         if(IS_TRUE_SYMOP( IC_RIGHT(dic))) {
2844                 debugLog("%d - dic right is a SYMOP\n", __LINE__);
2845                 debugAopGet("  right is ", IC_RIGHT(dic));
2846         }
2847 #endif
2848
2849       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2850           IS_OP_VOLATILE (IC_RESULT (dic)))
2851         {
2852           debugLog ("  %d - dic is VOLATILE \n", __LINE__);
2853           dic = NULL;
2854           break;
2855         }
2856
2857 #if 0
2858       if (IS_TRUE_SYMOP( IC_RIGHT (dic)) &&
2859                 IS_OP_VOLATILE (IC_RIGHT(dic)))
2860         {
2861           debugLog ("  %d - dic right is VOLATILE\n", __LINE__);
2862           dic = NULL;
2863           break;
2864         }
2865 #endif
2866
2867 #if 0
2868       if (IS_TRUE_SYMOP( IC_LEFT (dic)) &&
2869                 IS_OP_VOLATILE (IC_LEFT(dic)))
2870         {
2871           debugLog ("  %d - dic left is VOLATILE\n", __LINE__);
2872           dic = NULL;
2873           break;
2874         }
2875 #endif
2876
2877       if (IS_SYMOP (IC_RESULT (dic)) &&
2878           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2879         {
2880           /* A previous result was assigned to the same register - we'll our definition */
2881           debugLog ("  %d - dic result key == ic right key -- pointer set=%c\n",
2882                     __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2883           if (POINTER_SET (dic))
2884             dic = NULL;
2885
2886           break;
2887         }
2888
2889       if (IS_SYMOP (IC_RIGHT (dic)) &&
2890           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2891            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2892         {
2893           debugLog ("  %d - dic right key == ic rightor result key\n", __LINE__);
2894           dic = NULL;
2895           break;
2896         }
2897
2898       if (IS_SYMOP (IC_LEFT (dic)) &&
2899           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2900            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2901         {
2902           debugLog ("  %d - dic left key == ic rightor result key\n", __LINE__);
2903           dic = NULL;
2904           break;
2905         }
2906
2907       if (POINTER_SET (dic) &&
2908           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2909         {
2910           debugLog ("  %d - dic result key == ic result key -- pointer set=Y\n",
2911                     __LINE__);
2912           dic = NULL;
2913           break;
2914         }
2915     }
2916
2917   if (!dic)
2918     return 0;                   /* did not find */
2919
2920   /* if the result is on stack or iaccess then it must be
2921      the same atleast one of the operands */
2922   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2923       OP_SYMBOL (IC_RESULT (ic))->iaccess)
2924     {
2925
2926       /* the operation has only one symbol
2927          operator then we can pack */
2928       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2929           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2930         goto pack;
2931
2932       if (!((IC_LEFT (dic) &&
2933              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2934             (IC_RIGHT (dic) &&
2935              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2936         return 0;
2937     }
2938 pack:
2939   debugLog ("  packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2940   debugLog ("  replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2941   /* found the definition */
2942   /* replace the result with the result of */
2943   /* this assignment and remove this assignment */
2944   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2945   IC_RESULT (dic) = IC_RESULT (ic);
2946
2947   if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2948     {
2949       OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2950     }
2951   /* delete from liverange table also 
2952      delete from all the points inbetween and the new
2953      one */
2954   for (sic = dic; sic != ic; sic = sic->next)
2955     {
2956       bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2957       if (IS_ITEMP (IC_RESULT (dic)))
2958         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2959     }
2960
2961   remiCodeFromeBBlock (ebp, ic);
2962   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2963
2964         debugLog("  %d\n", __LINE__ );
2965   hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2966   OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2967   return 1;
2968
2969
2970 }
2971
2972 /*-----------------------------------------------------------------*/
2973 /* findAssignToSym : scanning backwards looks for first assig found */
2974 /*-----------------------------------------------------------------*/
2975 static iCode *
2976 findAssignToSym (operand * op, iCode * ic)
2977 {
2978   iCode *dic;
2979
2980   debugLog ("%s\n", __FUNCTION__);
2981   for (dic = ic->prev; dic; dic = dic->prev)
2982     {
2983
2984       /* if definition by assignment */
2985       if (dic->op == '=' &&
2986           !POINTER_SET (dic) &&
2987           IC_RESULT (dic)->key == op->key
2988 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2989         )
2990         {
2991
2992           /* we are interested only if defined in far space */
2993           /* or in stack space in case of + & - */
2994
2995           /* if assigned to a non-symbol then return
2996              true */
2997           if (!IS_SYMOP (IC_RIGHT (dic)))
2998             break;
2999
3000           /* if the symbol is in far space then
3001              we should not */
3002           if (isOperandInFarSpace (IC_RIGHT (dic)))
3003             return NULL;
3004
3005           /* for + & - operations make sure that
3006              if it is on the stack it is the same
3007              as one of the three operands */
3008           if ((ic->op == '+' || ic->op == '-') &&
3009               OP_SYMBOL (IC_RIGHT (dic))->onStack)
3010             {
3011
3012               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3013                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3014                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3015                 return NULL;
3016             }
3017
3018           break;
3019
3020         }
3021
3022       /* if we find an usage then we cannot delete it */
3023       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3024         return NULL;
3025
3026       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3027         return NULL;
3028
3029       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3030         return NULL;
3031     }
3032
3033   /* now make sure that the right side of dic
3034      is not defined between ic & dic */
3035   if (dic)
3036     {
3037       iCode *sic = dic->next;
3038
3039       for (; sic != ic; sic = sic->next)
3040         if (IC_RESULT (sic) &&
3041             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3042           return NULL;
3043     }
3044
3045   return dic;
3046
3047
3048 }
3049
3050 /*-----------------------------------------------------------------*/
3051 /* packRegsForSupport :- reduce some registers for support calls   */
3052 /*-----------------------------------------------------------------*/
3053 static int
3054 packRegsForSupport (iCode * ic, eBBlock * ebp)
3055 {
3056   int change = 0;
3057
3058   debugLog ("%s\n", __FUNCTION__);
3059   /* for the left & right operand :- look to see if the
3060      left was assigned a true symbol in far space in that
3061      case replace them */
3062   if (IS_ITEMP (IC_LEFT (ic)) &&
3063       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3064     {
3065       iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3066       iCode *sic;
3067
3068       if (!dic)
3069         goto right;
3070
3071       debugAopGet ("removing left:", IC_LEFT (ic));
3072
3073       /* found it we need to remove it from the
3074          block */
3075       for (sic = dic; sic != ic; sic = sic->next)
3076         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3077
3078       IC_LEFT (ic)->operand.symOperand =
3079         IC_RIGHT (dic)->operand.symOperand;
3080       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3081       remiCodeFromeBBlock (ebp, dic);
3082       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3083       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3084       change++;
3085     }
3086
3087   /* do the same for the right operand */
3088 right:
3089   if (!change &&
3090       IS_ITEMP (IC_RIGHT (ic)) &&
3091       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3092     {
3093       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3094       iCode *sic;
3095
3096       if (!dic)
3097         return change;
3098
3099       /* if this is a subtraction & the result
3100          is a true symbol in far space then don't pack */
3101       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3102         {
3103           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3104           if (IN_FARSPACE (SPEC_OCLS (etype)))
3105             return change;
3106         }
3107
3108       debugAopGet ("removing right:", IC_RIGHT (ic));
3109
3110       /* found it we need to remove it from the
3111          block */
3112       for (sic = dic; sic != ic; sic = sic->next)
3113         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3114
3115       IC_RIGHT (ic)->operand.symOperand =
3116         IC_RIGHT (dic)->operand.symOperand;
3117       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3118
3119       remiCodeFromeBBlock (ebp, dic);
3120       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3121       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3122       change++;
3123     }
3124
3125   return change;
3126 }
3127
3128 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3129
3130
3131 /*-----------------------------------------------------------------*/
3132 /* packRegsForOneuse : - will reduce some registers for single Use */
3133 /*-----------------------------------------------------------------*/
3134 static iCode *
3135 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3136 {
3137   bitVect *uses;
3138   iCode *dic, *sic;
3139
3140   debugLog ("%s\n", __FUNCTION__);
3141   /* if returning a literal then do nothing */
3142   if (!IS_SYMOP (op))
3143     return NULL;
3144
3145   /* only upto 2 bytes since we cannot predict
3146      the usage of b, & acc */
3147   if (getSize (operandType (op)) > (pic16_fReturnSizePic - 2) &&
3148       ic->op != RETURN &&
3149       ic->op != SEND)
3150     return NULL;
3151
3152   /* this routine will mark the a symbol as used in one 
3153      instruction use only && if the definition is local 
3154      (ie. within the basic block) && has only one definition &&
3155      that definition is either a return value from a 
3156      function or does not contain any variables in
3157      far space */
3158   uses = bitVectCopy (OP_USES (op));
3159   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
3160   if (!bitVectIsZero (uses))    /* has other uses */
3161     return NULL;
3162
3163   /* if it has only one defintion */
3164   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3165     return NULL;                /* has more than one definition */
3166
3167   /* get that definition */
3168   if (!(dic =
3169         hTabItemWithKey (iCodehTab,
3170                          bitVectFirstBit (OP_DEFS (op)))))
3171     return NULL;
3172
3173   /* found the definition now check if it is local */
3174   if (dic->seq < ebp->fSeq ||
3175       dic->seq > ebp->lSeq)
3176     return NULL;                /* non-local */
3177
3178   /* now check if it is the return from
3179      a function call */
3180   if (dic->op == CALL || dic->op == PCALL)
3181     {
3182       if (ic->op != SEND && ic->op != RETURN &&
3183           !POINTER_SET(ic) && !POINTER_GET(ic))
3184         {
3185           OP_SYMBOL (op)->ruonly = 1;
3186           return dic;
3187         }
3188       dic = dic->next;
3189     }
3190
3191
3192   /* otherwise check that the definition does
3193      not contain any symbols in far space */
3194   if (isOperandInFarSpace (IC_LEFT (dic)) ||
3195       isOperandInFarSpace (IC_RIGHT (dic)) ||
3196       IS_OP_RUONLY (IC_LEFT (ic)) ||
3197       IS_OP_RUONLY (IC_RIGHT (ic)))
3198     {
3199       return NULL;
3200     }
3201
3202   /* if pointer set then make sure the pointer
3203      is one byte */
3204   if (POINTER_SET (dic) &&
3205       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3206     return NULL;
3207
3208   if (POINTER_GET (dic) &&
3209       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3210     return NULL;
3211
3212   sic = dic;
3213
3214   /* also make sure the intervenening instructions
3215      don't have any thing in far space */
3216   for (dic = dic->next; dic && dic != ic; dic = dic->next)
3217     {
3218
3219       /* if there is an intervening function call then no */
3220       if (dic->op == CALL || dic->op == PCALL)
3221         return NULL;
3222       /* if pointer set then make sure the pointer
3223          is one byte */
3224       if (POINTER_SET (dic) &&
3225           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3226         return NULL;
3227
3228       if (POINTER_GET (dic) &&
3229           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3230         return NULL;
3231
3232       /* if address of & the result is remat then okay */
3233       if (dic->op == ADDRESS_OF &&
3234           OP_SYMBOL (IC_RESULT (dic))->remat)
3235         continue;
3236
3237       /* if operand has size of three or more & this
3238          operation is a '*','/' or '%' then 'b' may
3239          cause a problem */
3240       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3241           getSize (operandType (op)) >= 3)
3242         return NULL;
3243
3244       /* if left or right or result is in far space */
3245       if (isOperandInFarSpace (IC_LEFT (dic)) ||
3246           isOperandInFarSpace (IC_RIGHT (dic)) ||
3247           isOperandInFarSpace (IC_RESULT (dic)) ||
3248           IS_OP_RUONLY (IC_LEFT (dic)) ||
3249           IS_OP_RUONLY (IC_RIGHT (dic)) ||
3250           IS_OP_RUONLY (IC_RESULT (dic)))
3251         {
3252           return NULL;
3253         }
3254     }
3255
3256   OP_SYMBOL (op)->ruonly = 1;
3257   return sic;
3258
3259 }
3260
3261 /*-----------------------------------------------------------------*/
3262 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
3263 /*-----------------------------------------------------------------*/
3264 static bool
3265 isBitwiseOptimizable (iCode * ic)
3266 {
3267   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3268   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3269
3270   debugLog ("%s\n", __FUNCTION__);
3271   /* bitwise operations are considered optimizable
3272      under the following conditions (Jean-Louis VERN) 
3273
3274      x & lit
3275      bit & bit
3276      bit & x
3277      bit ^ bit
3278      bit ^ x
3279      x   ^ lit
3280      x   | lit
3281      bit | bit
3282      bit | x
3283    */
3284   if (IS_LITERAL (rtype) ||
3285       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3286     return TRUE;
3287   else
3288     return FALSE;
3289 }
3290
3291 /*-----------------------------------------------------------------*/
3292 /* packRegsForAccUse - pack registers for acc use                  */
3293 /*-----------------------------------------------------------------*/
3294 static void
3295 packRegsForAccUse (iCode * ic)
3296 {
3297   iCode *uic;
3298
3299   debugLog ("%s\n", __FUNCTION__);
3300
3301   /* if this is an aggregate, e.g. a one byte char array */
3302   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3303     return;
3304   }
3305   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3306
3307   /* if + or - then it has to be one byte result */
3308   if ((ic->op == '+' || ic->op == '-')
3309       && getSize (operandType (IC_RESULT (ic))) > 1)
3310     return;
3311
3312   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3313   /* if shift operation make sure right side is not a literal */
3314   if (ic->op == RIGHT_OP &&
3315       (isOperandLiteral (IC_RIGHT (ic)) ||
3316        getSize (operandType (IC_RESULT (ic))) > 1))
3317     return;
3318
3319   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3320   if (ic->op == LEFT_OP &&
3321       (isOperandLiteral (IC_RIGHT (ic)) ||
3322        getSize (operandType (IC_RESULT (ic))) > 1))
3323     return;
3324
3325   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3326   if (IS_BITWISE_OP (ic) &&
3327       getSize (operandType (IC_RESULT (ic))) > 1)
3328     return;
3329
3330
3331   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3332   /* has only one definition */
3333   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3334     return;
3335
3336   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3337   /* has only one use */
3338   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3339     return;
3340
3341   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3342   /* and the usage immediately follows this iCode */
3343   if (!(uic = hTabItemWithKey (iCodehTab,
3344                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3345     return;
3346
3347   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3348   if (ic->next != uic)
3349     return;
3350
3351   /* if it is a conditional branch then we definitely can */
3352   if (uic->op == IFX)
3353     goto accuse;
3354
3355   if (uic->op == JUMPTABLE)
3356     return;
3357
3358   /* if the usage is not is an assignment
3359      or an arithmetic / bitwise / shift operation then not */
3360   if (POINTER_SET (uic) &&
3361       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3362     return;
3363
3364   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3365   if (uic->op != '=' &&
3366       !IS_ARITHMETIC_OP (uic) &&
3367       !IS_BITWISE_OP (uic) &&
3368       uic->op != LEFT_OP &&
3369       uic->op != RIGHT_OP)
3370     return;
3371
3372   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3373   /* if used in ^ operation then make sure right is not a 
3374      literl */
3375   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3376     return;
3377
3378   /* if shift operation make sure right side is not a literal */
3379   if (uic->op == RIGHT_OP &&
3380       (isOperandLiteral (IC_RIGHT (uic)) ||
3381        getSize (operandType (IC_RESULT (uic))) > 1))
3382     return;
3383
3384   if (uic->op == LEFT_OP &&
3385       (isOperandLiteral (IC_RIGHT (uic)) ||
3386        getSize (operandType (IC_RESULT (uic))) > 1))
3387     return;
3388
3389   /* make sure that the result of this icode is not on the
3390      stack, since acc is used to compute stack offset */
3391   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3392       OP_SYMBOL (IC_RESULT (uic))->onStack)
3393     return;
3394
3395   /* if either one of them in far space then we cannot */
3396   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3397        isOperandInFarSpace (IC_LEFT (uic))) ||
3398       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3399        isOperandInFarSpace (IC_RIGHT (uic))))
3400     return;
3401
3402   /* if the usage has only one operand then we can */
3403   if (IC_LEFT (uic) == NULL ||
3404       IC_RIGHT (uic) == NULL)
3405     goto accuse;
3406
3407   /* make sure this is on the left side if not
3408      a '+' since '+' is commutative */
3409   if (ic->op != '+' &&
3410       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3411     return;
3412
3413   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3414   /* if one of them is a literal then we can */
3415   if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3416         (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))  &&
3417        (getSize (operandType (IC_RESULT (uic))) <= 1))
3418     {
3419       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3420       return;
3421     }
3422
3423   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3424   /* if the other one is not on stack then we can */
3425   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3426       (IS_ITEMP (IC_RIGHT (uic)) ||
3427        (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3428         !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3429     goto accuse;
3430
3431   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3432       (IS_ITEMP (IC_LEFT (uic)) ||
3433        (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3434         !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3435     goto accuse;
3436
3437   return;
3438
3439 accuse:
3440   debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3441   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3442
3443
3444 }
3445
3446 /*-----------------------------------------------------------------*/
3447 /* packForPush - hueristics to reduce iCode for pushing            */
3448 /*-----------------------------------------------------------------*/
3449 static void
3450 packForReceive (iCode * ic, eBBlock * ebp)
3451 {
3452   iCode *dic;
3453
3454   debugLog ("%s\n", __FUNCTION__);
3455   debugAopGet ("  result:", IC_RESULT (ic));
3456   debugAopGet ("  left:", IC_LEFT (ic));
3457   debugAopGet ("  right:", IC_RIGHT (ic));
3458
3459   if (!ic->next)
3460     return;
3461
3462   for (dic = ic->next; dic; dic = dic->next)
3463     {
3464
3465
3466
3467       if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3468         debugLog ("    used on left\n");
3469       if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3470         debugLog ("    used on right\n");
3471       if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3472         debugLog ("    used on result\n");
3473
3474       if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3475           (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3476         return;
3477
3478     }
3479
3480   debugLog ("  hey we can remove this unnecessary assign\n");
3481 }
3482 /*-----------------------------------------------------------------*/
3483 /* packForPush - hueristics to reduce iCode for pushing            */
3484 /*-----------------------------------------------------------------*/
3485 static void
3486 packForPush (iCode * ic, eBBlock * ebp)
3487 {
3488   iCode *dic;
3489
3490   debugLog ("%s\n", __FUNCTION__);
3491   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3492     return;
3493
3494   /* must have only definition & one usage */
3495   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3496       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3497     return;
3498
3499   /* find the definition */
3500   if (!(dic = hTabItemWithKey (iCodehTab,
3501                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3502     return;
3503
3504   if (dic->op != '=' || POINTER_SET (dic))
3505     return;
3506
3507   /* we now we know that it has one & only one def & use
3508      and the that the definition is an assignment */
3509   IC_LEFT (ic) = IC_RIGHT (dic);
3510
3511   remiCodeFromeBBlock (ebp, dic);
3512   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3513   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3514 }
3515
3516 static void printSymType(char * str, sym_link *sl)
3517 {
3518         if(!pic16_ralloc_debug)return;
3519         
3520         debugLog ("    %s Symbol type: ",str);
3521         printTypeChain( sl, debugF);
3522         debugLog ("\n");
3523 }
3524
3525 /*-----------------------------------------------------------------*/
3526 /* some debug code to print the symbol S_TYPE. Note that
3527  * the function checkSClass in src/SDCCsymt.c dinks with
3528  * the S_TYPE in ways the PIC port doesn't fully like...*/
3529 /*-----------------------------------------------------------------*/
3530 static void isData(sym_link *sl)
3531 {
3532   FILE *of = stderr;
3533
3534         if(!pic16_ralloc_debug)return;
3535         
3536         if(!sl)return;
3537
3538         if(debugF)
3539                 of = debugF;
3540
3541         for ( ; sl; sl=sl->next) {
3542                 if(!IS_DECL(sl) ) {
3543                         switch (SPEC_SCLS(sl)) {
3544                                 case S_DATA: fprintf (of, "data "); break;
3545                                 case S_XDATA: fprintf (of, "xdata "); break;
3546                                 case S_SFR: fprintf (of, "sfr "); break;
3547                                 case S_SBIT: fprintf (of, "sbit "); break;
3548                                 case S_CODE: fprintf (of, "code "); break;
3549                                 case S_IDATA: fprintf (of, "idata "); break;
3550                                 case S_PDATA: fprintf (of, "pdata "); break;
3551                                 case S_LITERAL: fprintf (of, "literal "); break;
3552                                 case S_STACK: fprintf (of, "stack "); break;
3553                                 case S_XSTACK: fprintf (of, "xstack "); break;
3554                                 case S_BIT: fprintf (of, "bit "); break;
3555                                 case S_EEPROM: fprintf (of, "eeprom "); break;
3556                                 default: break;
3557                         }
3558
3559                 }
3560         }
3561 }
3562
3563 #define NO_packRegsForSupport   1
3564 #define NO_packRegsForAccUse    1
3565 #define NO_packRegsForOneuse    1
3566 #define NO_cast_peep            1
3567
3568 /*--------------------------------------------------------------------*/
3569 /* pic16_packRegisters - does some transformations to reduce          */
3570 /*                   register pressure                                */
3571 /*                                                                    */
3572 /*--------------------------------------------------------------------*/
3573 static void
3574 pic16_packRegisters (eBBlock * ebp)
3575 {
3576   iCode *ic;
3577   int change = 0;
3578
3579   debugLog ("%s\n", __FUNCTION__);
3580
3581   while (1) {
3582
3583     change = 0;
3584
3585     /* look for assignments of the form */
3586     /* iTempNN = TRueSym (someoperation) SomeOperand */
3587     /*       ....                       */
3588     /* TrueSym := iTempNN:1             */
3589     for (ic = ebp->sch; ic; ic = ic->next)
3590       {
3591 //              debugLog("%d\n", __LINE__);
3592         /* find assignment of the form TrueSym := iTempNN:1 */
3593         /* see BUGLOG0001 for workaround with the CAST - VR */
3594         if ((ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic))
3595           change += packRegsForAssign (ic, ebp);
3596         /* debug stuff */
3597         if (ic->op == '=')
3598           {
3599             if (POINTER_SET (ic))
3600               debugLog ("pointer is set\n");
3601             debugAopGet ("  result:", IC_RESULT (ic));
3602             debugAopGet ("  left:", IC_LEFT (ic));
3603             debugAopGet ("  right:", IC_RIGHT (ic));
3604           }
3605
3606       }
3607
3608     if (!change)
3609       break;
3610   }
3611
3612   for (ic = ebp->sch; ic; ic = ic->next) {
3613
3614     if(IS_SYMOP ( IC_LEFT(ic))) {
3615       sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3616
3617       debugAopGet ("x  left:", IC_LEFT (ic));
3618 #if 0
3619       if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3620 #else
3621       if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3622 #endif
3623         debugLog ("    is a pointer\n");
3624
3625       if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3626         debugLog ("    is a ptr\n");
3627
3628       if(IS_OP_VOLATILE(IC_LEFT(ic)))
3629         debugLog ("    is volatile\n");
3630
3631       isData(etype);
3632
3633         if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3634             debugLog ("  %d - left is not temp, allocating\n", __LINE__);
3635             pic16_allocDirReg(IC_LEFT (ic));
3636         }
3637
3638       printSymType("c  ", OP_SYMBOL(IC_LEFT(ic))->type);
3639     }
3640
3641     if(IS_SYMOP ( IC_RIGHT(ic))) {
3642       debugAopGet ("  right:", IC_RIGHT (ic));
3643       printSymType("    ", OP_SYMBOL(IC_RIGHT(ic))->type);
3644     }
3645
3646     if(IS_SYMOP ( IC_RESULT(ic))) {
3647       debugAopGet ("  result:", IC_RESULT (ic));
3648       printSymType("     ", OP_SYMBOL(IC_RESULT(ic))->type);
3649     }
3650
3651     if (POINTER_SET (ic))
3652         debugLog ("  %d - Pointer set\n", __LINE__);
3653
3654
3655     /* if this is an itemp & result of a address of a true sym 
3656        then mark this as rematerialisable   */
3657     if (ic->op == ADDRESS_OF &&
3658         IS_ITEMP (IC_RESULT (ic)) &&
3659         IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3660         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3661         !OP_SYMBOL (IC_LEFT (ic))->onStack)
3662       {
3663
3664         debugLog ("  %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3665
3666         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3667         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3668         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3669
3670       }
3671
3672     /* if straight assignment then carry remat flag if
3673        this is the only definition */
3674     if (ic->op == '=' &&
3675         !POINTER_SET (ic) &&
3676         IS_SYMOP (IC_RIGHT (ic)) &&
3677         OP_SYMBOL (IC_RIGHT (ic))->remat &&
3678         bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3679       {
3680         debugLog ("  %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3681
3682         OP_SYMBOL (IC_RESULT (ic))->remat =
3683           OP_SYMBOL (IC_RIGHT (ic))->remat;
3684         OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3685           OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3686       }
3687
3688     /* if this is a +/- operation with a rematerizable 
3689        then mark this as rematerializable as well */
3690     if ((ic->op == '+' || ic->op == '-') &&
3691         (IS_SYMOP (IC_LEFT (ic)) &&
3692          IS_ITEMP (IC_RESULT (ic)) &&
3693          OP_SYMBOL (IC_LEFT (ic))->remat &&
3694          bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3695          IS_OP_LITERAL (IC_RIGHT (ic))))
3696       {
3697         debugLog ("  %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3698         //int i = 
3699         operandLitValue (IC_RIGHT (ic));
3700         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3701         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3702         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3703       }
3704
3705     /* mark the pointer usages */
3706     if (POINTER_SET (ic))
3707       {
3708         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3709         debugLog ("  marking as a pointer (set) =>");
3710         debugAopGet ("  result:", IC_RESULT (ic));
3711       }
3712     if (POINTER_GET (ic))
3713       {
3714         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3715         debugLog ("  marking as a pointer (get) =>");
3716         debugAopGet ("  left:", IC_LEFT (ic));
3717       }
3718
3719         //debugLog("  %d   %s\n", __LINE__, __FUNCTION__);
3720
3721     if (!SKIP_IC2 (ic))
3722       {
3723         //debugLog("  %d   %s\n", __LINE__, __FUNCTION__ );
3724         /* if we are using a symbol on the stack
3725            then we should say pic16_ptrRegReq */
3726         if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3727           pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3728                                OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3729         else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3730           pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3731                                OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3732         else
3733           {
3734
3735                 //debugLog("   %d   %s\n", __LINE__, __FUNCTION__ );
3736             if (IS_SYMOP (IC_LEFT (ic)))
3737               pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3738                                    OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3739             if (IS_SYMOP (IC_RIGHT (ic)))
3740               pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3741                                    OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3742             if (IS_SYMOP (IC_RESULT (ic)))
3743               pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3744                                    OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3745           }
3746
3747         debugLog ("  %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3748
3749       }
3750
3751     /* if the condition of an if instruction
3752        is defined in the previous instruction then
3753        mark the itemp as a conditional */
3754     if ((IS_CONDITIONAL (ic) ||
3755          ((ic->op == BITWISEAND ||
3756            ic->op == '|' ||
3757            ic->op == '^') &&
3758           isBitwiseOptimizable (ic))) &&
3759         ic->next && ic->next->op == IFX &&
3760         isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3761         OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3762       {
3763
3764         debugLog ("  %d\n", __LINE__);
3765         OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3766         continue;
3767       }
3768
3769         debugLog(" %d\n", __LINE__);
3770
3771 #if NO_packRegsForSupport
3772     /* reduce for support function calls */
3773     if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3774       packRegsForSupport (ic, ebp);
3775 #endif
3776
3777     /* if a parameter is passed, it's in W, so we may not
3778        need to place a copy in a register */
3779     if (ic->op == RECEIVE)
3780       packForReceive (ic, ebp);
3781
3782 #if NO_packRegsForOneuse
3783     /* some cases the redundant moves can
3784        can be eliminated for return statements */
3785     if ((ic->op == RETURN || ic->op == SEND) &&
3786         !isOperandInFarSpace (IC_LEFT (ic)) &&
3787         !options.model)
3788       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3789 #endif
3790
3791 #if NO_packRegsForOneuse
3792     /* if pointer set & left has a size more than
3793        one and right is not in far space */
3794     if (POINTER_SET (ic) &&
3795         !isOperandInFarSpace (IC_RIGHT (ic)) &&
3796         !OP_SYMBOL (IC_RESULT (ic))->remat &&
3797         !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3798         getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3799
3800       packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3801 #endif
3802
3803 #if NO_packRegsForOneuse
3804     /* if pointer get */
3805     if (POINTER_GET (ic) &&
3806         !isOperandInFarSpace (IC_RESULT (ic)) &&
3807         !OP_SYMBOL (IC_LEFT (ic))->remat &&
3808         !IS_OP_RUONLY (IC_RESULT (ic)) &&
3809         getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3810
3811       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3812       debugLog("%d - return from packRegsForOneuse\n", __LINE__);
3813 #endif
3814
3815 #if NO_cast_peep
3816     /* if this is cast for intergral promotion then
3817        check if only use of  the definition of the 
3818        operand being casted/ if yes then replace
3819        the result of that arithmetic operation with 
3820        this result and get rid of the cast */
3821     if (ic->op == CAST) {
3822         
3823       sym_link *fromType = operandType (IC_RIGHT (ic));
3824       sym_link *toType = operandType (IC_LEFT (ic));
3825
3826       debugLog ("  %d - casting\n", __LINE__);
3827
3828       if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3829           getSize (fromType) != getSize (toType)) {
3830             
3831
3832         iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3833         if (dic) {
3834                 
3835           if (IS_ARITHMETIC_OP (dic)) {
3836                     debugLog("   %d   %s\n", __LINE__, __FUNCTION__ );
3837                     
3838             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3839             IC_RESULT (dic) = IC_RESULT (ic);
3840             remiCodeFromeBBlock (ebp, ic);
3841             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3842             hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3843             OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3844             ic = ic->prev;
3845           }  else
3846                 
3847             OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3848         }
3849       } else {
3850
3851         /* if the type from and type to are the same
3852            then if this is the only use then packit */
3853         if (compareType (operandType (IC_RIGHT (ic)),
3854                          operandType (IC_LEFT (ic))) == 1) {
3855                 
3856           iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3857           if (dic) {
3858
3859                    debugLog(" %d\n", __LINE__);
3860
3861             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3862             IC_RESULT (dic) = IC_RESULT (ic);
3863             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3864             remiCodeFromeBBlock (ebp, ic);
3865             hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3866             OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3867             ic = ic->prev;
3868           }
3869         }
3870       }
3871     }
3872 #endif
3873     /* pack for PUSH 
3874        iTempNN := (some variable in farspace) V1
3875        push iTempNN ;
3876        -------------
3877        push V1
3878     */
3879     if (ic->op == IPUSH)
3880       {
3881         packForPush (ic, ebp);
3882       }
3883
3884
3885 #if NO_packRegsForAccUse
3886     /* pack registers for accumulator use, when the
3887        result of an arithmetic or bit wise operation
3888        has only one use, that use is immediately following
3889        the defintion and the using iCode has only one
3890        operand or has two operands but one is literal &
3891        the result of that operation is not on stack then
3892        we can leave the result of this operation in acc:b
3893        combination */
3894     if ((IS_ARITHMETIC_OP (ic)
3895
3896          || IS_BITWISE_OP (ic)
3897
3898          || ic->op == LEFT_OP || ic->op == RIGHT_OP
3899
3900          ) &&
3901         IS_ITEMP (IC_RESULT (ic)) &&
3902         getSize (operandType (IC_RESULT (ic))) <= 2)
3903
3904       packRegsForAccUse (ic);
3905 #endif
3906
3907   }
3908 }
3909
3910 static void
3911 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3912 {
3913   int i;
3914
3915   if (!pic16_ralloc_debug || !debugF)
3916     return;
3917
3918   for (i = 0; i < count; i++)
3919     {
3920       fprintf (debugF, "\n----------------------------------------------------------------\n");
3921       fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3922                ebbs[i]->entryLabel->name,
3923                ebbs[i]->depth,
3924                ebbs[i]->noPath,
3925                ebbs[i]->isLastInLoop);
3926       fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3927                ebbs[i]->dfnum,
3928                ebbs[i]->bbnum,
3929                ebbs[i]->fSeq,
3930                ebbs[i]->lSeq);
3931       fprintf (debugF, "visited %d : hasFcall = %d\n",
3932                ebbs[i]->visited,
3933                ebbs[i]->hasFcall);
3934
3935       fprintf (debugF, "\ndefines bitVector :");
3936       bitVectDebugOn (ebbs[i]->defSet, debugF);
3937       fprintf (debugF, "\nlocal defines bitVector :");
3938       bitVectDebugOn (ebbs[i]->ldefs, debugF);
3939       fprintf (debugF, "\npointers Set bitvector :");
3940       bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3941       fprintf (debugF, "\nin pointers Set bitvector :");
3942       bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3943       fprintf (debugF, "\ninDefs Set bitvector :");
3944       bitVectDebugOn (ebbs[i]->inDefs, debugF);
3945       fprintf (debugF, "\noutDefs Set bitvector :");
3946       bitVectDebugOn (ebbs[i]->outDefs, debugF);
3947       fprintf (debugF, "\nusesDefs Set bitvector :");
3948       bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3949       fprintf (debugF, "\n----------------------------------------------------------------\n");
3950       printiCChain (ebbs[i]->sch, debugF);
3951     }
3952 }
3953 /*-----------------------------------------------------------------*/
3954 /* pic16_assignRegisters - assigns registers to each live range as need  */
3955 /*-----------------------------------------------------------------*/
3956 void
3957 pic16_assignRegisters (eBBlock ** ebbs, int count)
3958 {
3959   iCode *ic;
3960   int i;
3961
3962   debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3963   debugLog ("\nebbs before optimizing:\n");
3964   dumpEbbsToDebug (ebbs, count);
3965
3966   setToNull ((void *) &_G.funcrUsed);
3967   pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3968
3969
3970   /* change assignments this will remove some
3971      live ranges reducing some register pressure */
3972   for (i = 0; i < count; i++)
3973     pic16_packRegisters (ebbs[i]);
3974
3975   {
3976     regs *reg;
3977     int hkey;
3978     int i=0;
3979
3980     debugLog("dir registers allocated so far:\n");
3981     reg = hTabFirstItem(dynDirectRegNames, &hkey);
3982
3983     while(reg) {
3984       debugLog("  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3985 //      fprintf(stderr, "  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3986       reg = hTabNextItem(dynDirectRegNames, &hkey);
3987     }
3988
3989   }
3990
3991   /* liveranges probably changed by register packing
3992      so we compute them again */
3993   recomputeLiveRanges (ebbs, count);
3994
3995   if (options.dump_pack)
3996     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3997
3998   /* first determine for each live range the number of 
3999      registers & the type of registers required for each */
4000   regTypeNum ();
4001
4002   /* and serially allocate registers */
4003   serialRegAssign (ebbs, count);
4004
4005   //pic16_freeAllRegs();
4006
4007   /* if stack was extended then tell the user */
4008   if (_G.stackExtend)
4009     {
4010 /*      werror(W_TOOMANY_SPILS,"stack", */
4011 /*             _G.stackExtend,currFunc->name,""); */
4012       _G.stackExtend = 0;
4013     }
4014
4015   if (_G.dataExtend)
4016     {
4017 /*      werror(W_TOOMANY_SPILS,"data space", */
4018 /*             _G.dataExtend,currFunc->name,""); */
4019       _G.dataExtend = 0;
4020     }
4021
4022   /* after that create the register mask
4023      for each of the instruction */
4024   createRegMask (ebbs, count);
4025
4026   /* redo that offsets for stacked automatic variables */
4027   redoStackOffsets ();
4028
4029   if (options.dump_rassgn)
4030     dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4031
4032   /* now get back the chain */
4033   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4034
4035   debugLog ("ebbs after optimizing:\n");
4036   dumpEbbsToDebug (ebbs, count);
4037
4038
4039   genpic16Code (ic);
4040
4041   /* free up any _G.stackSpil locations allocated */
4042   applyToSet (_G.stackSpil, deallocStackSpil);
4043   _G.slocNum = 0;
4044   setToNull ((void *) &_G.stackSpil);
4045   setToNull ((void *) &_G.spiltSet);
4046   /* mark all registers as free */
4047   pic16_freeAllRegs ();
4048
4049   debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
4050   debugLogClose ();
4051   return;
4052 }