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