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