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