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