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