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