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