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