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