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