* src/mcs51/ralloc.c (deassignLR),
[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->liveFrom == ic->seq &&    /* does not start before here */                              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 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2209 /* it should either have registers or have beed spilled. Otherwise, */
2210 /* there was an uninitialized variable, so just spill this to get   */
2211 /* the operand in a valid state.                                    */
2212 /*------------------------------------------------------------------*/
2213 static void
2214 verifyRegsAssigned (operand *op, iCode * ic)
2215 {
2216   symbol * sym;
2217   
2218   if (!op) return;
2219   if (!IS_ITEMP (op)) return;
2220   
2221   sym = OP_SYMBOL (op);
2222   if (sym->isspilt) return;
2223   if (!sym->nRegs) return;
2224   if (sym->regs[0]) return;
2225   
2226   werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT, 
2227             sym->prereqv ? sym->prereqv->name : sym->name);
2228   spillThis (sym);
2229 }
2230
2231
2232 /*-----------------------------------------------------------------*/
2233 /* serialRegAssign - serially allocate registers to the variables  */
2234 /*-----------------------------------------------------------------*/
2235 static void
2236 serialRegAssign (eBBlock ** ebbs, int count)
2237 {
2238         int i;
2239         
2240         debugLog ("%s\n", __FUNCTION__);
2241         /* for all blocks */
2242         for (i = 0; i < count; i++)
2243         {
2244                 
2245                 iCode *ic;
2246                 
2247                 if (ebbs[i]->noPath &&
2248                         (ebbs[i]->entryLabel != entryLabel &&
2249                         ebbs[i]->entryLabel != returnLabel))
2250                         continue;
2251                 
2252                 /* of all instructions do */
2253                 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2254                 {
2255                         
2256                         debugLog ("  op: %s\n", decodeOp (ic->op));
2257                         
2258                         /* if this is an ipop that means some live
2259                         range will have to be assigned again */
2260                         if (ic->op == IPOP)
2261                                 reassignLR (IC_LEFT (ic));
2262                         
2263                         /* if result is present && is a true symbol */
2264                         if (IC_RESULT (ic) && ic->op != IFX &&
2265                                 IS_TRUE_SYMOP (IC_RESULT (ic)))
2266                                 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2267                         
2268                         /* take away registers from live
2269                         ranges that end at this instruction */
2270                         deassignLRs (ic, ebbs[i]);
2271                         
2272                         /* some don't need registers */
2273                         if (SKIP_IC2 (ic) ||
2274                                 ic->op == JUMPTABLE ||
2275                                 ic->op == IFX ||
2276                                 ic->op == IPUSH ||
2277                                 ic->op == IPOP ||
2278                                 (IC_RESULT (ic) && POINTER_SET (ic)))
2279                                 continue;
2280                         
2281                                 /* now we need to allocate registers
2282                         only for the result */
2283                         if (IC_RESULT (ic))
2284                         {
2285                                 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2286                                 bitVect *spillable;
2287                                 int willCS;
2288                                 int j;
2289                                 int ptrRegSet = 0;
2290                                 
2291                                 /* if it does not need or is spilt 
2292                                 or is already assigned to registers
2293                                 or will not live beyond this instructions */
2294                                 if (!sym->nRegs ||
2295                                         sym->isspilt ||
2296                                         bitVectBitValue (_G.regAssigned, sym->key) ||
2297                                         sym->liveTo <= ic->seq)
2298                                         continue;
2299                                 
2300                                         /* if some liverange has been spilt at the block level
2301                                         and this one live beyond this block then spil this
2302                                 to be safe */
2303                                 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2304                                 {
2305                                         spillThis (sym);
2306                                         continue;
2307                                 }
2308                                 /* if trying to allocate this will cause
2309                                 a spill and there is nothing to spill 
2310                                 or this one is rematerializable then
2311                                 spill this one */
2312                                 willCS = willCauseSpill (sym->nRegs, sym->regType);
2313                                 spillable = computeSpillable (ic);
2314                                 if (sym->remat ||
2315                                         (willCS && bitVectIsZero (spillable)))
2316                                 {
2317                                         
2318                                         spillThis (sym);
2319                                         continue;
2320                                         
2321                                 }
2322
2323                                 /* If the live range preceeds the point of definition 
2324                                    then ideally we must take into account registers that 
2325                                    have been allocated after sym->liveFrom but freed
2326                                    before ic->seq. This is complicated, so spill this
2327                                    symbol instead and let fillGaps handle the allocation. */
2328                                 if (sym->liveFrom < ic->seq)
2329                                 {
2330                                         spillThis (sym);
2331                                         continue;                     
2332                                 }
2333                                 
2334                                 /* if it has a spillocation & is used less than
2335                                 all other live ranges then spill this */
2336                                 if (willCS) {
2337                                         if (sym->usl.spillLoc) {
2338                                                 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2339                                                         allLRs, ebbs[i], ic));
2340                                                 if (leastUsed && leastUsed->used > sym->used) {
2341                                                         spillThis (sym);
2342                                                         continue;
2343                                                 }
2344                                         } else {
2345                                         /* if none of the liveRanges have a spillLocation then better
2346                                                 to spill this one than anything else already assigned to registers */
2347                                                 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2348                                                         /* if this is local to this block then we might find a block spil */
2349                                                         if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2350                                                                 spillThis (sym);
2351                                                                 continue;
2352                                                         }
2353                                                 }
2354                                         }
2355                                 }
2356                                 
2357                                 if (ic->op == RECEIVE)
2358                                         debugLog ("When I get clever, I'll optimize the receive logic\n");
2359                                 
2360                                         /* if we need ptr regs for the right side
2361                                 then mark it */
2362                                 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2363                                         <= (unsigned) PTRSIZE)
2364                                 {
2365                                         pic14_ptrRegReq++;
2366                                         ptrRegSet = 1;
2367                                 }
2368                                 /* else we assign registers to it */
2369                                 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2370                                 
2371                                 debugLog ("  %d - \n", __LINE__);
2372                                 if(debugF) 
2373                                         bitVectDebugOn(_G.regAssigned, debugF);
2374                                 for (j = 0; j < sym->nRegs; j++)
2375                                 {
2376                                         if (sym->regType == REG_PTR)
2377                                                 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2378                                         else
2379                                                 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2380                                         
2381                                                 /* if the allocation failed which means
2382                                         this was spilt then break */
2383                                         if (!sym->regs[j])
2384                                                 break;
2385                                 }
2386                                 debugLog ("  %d - \n", __LINE__);
2387                                 
2388                                 /* if it shares registers with operands make sure
2389                                 that they are in the same position */
2390                                 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2391                                         OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2392                                         positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2393                                         OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2394                                 /* do the same for the right operand */
2395                                 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2396                                         OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2397                                         positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2398                                         OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2399                                 
2400                                 debugLog ("  %d - \n", __LINE__);
2401                                 if (ptrRegSet)
2402                                 {
2403                                         debugLog ("  %d - \n", __LINE__);
2404                                         pic14_ptrRegReq--;
2405                                         ptrRegSet = 0;
2406                                 }
2407                                 
2408                         }
2409                 }
2410         }
2411
2412         /* Check for and fix any problems with uninitialized operands */
2413     for (i = 0; i < count; i++)
2414         {
2415                 iCode *ic;
2416                 
2417                 if (ebbs[i]->noPath &&
2418                         (ebbs[i]->entryLabel != entryLabel &&
2419                         ebbs[i]->entryLabel != returnLabel))
2420                         continue;
2421                 
2422                 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2423                 {
2424                         if (SKIP_IC2 (ic))
2425                                 continue;
2426                         
2427                         if (ic->op == IFX)
2428                         {
2429                                 verifyRegsAssigned (IC_COND (ic), ic);
2430                                 continue;
2431                         }
2432                         
2433                         if (ic->op == JUMPTABLE)
2434                         {
2435                                 verifyRegsAssigned (IC_JTCOND (ic), ic);
2436                                 continue;
2437                         }
2438                         
2439                         verifyRegsAssigned (IC_RESULT (ic), ic);
2440                         verifyRegsAssigned (IC_LEFT (ic), ic);
2441                         verifyRegsAssigned (IC_RIGHT (ic), ic);
2442                 }
2443         }
2444         
2445 }
2446
2447 /*-----------------------------------------------------------------*/
2448 /* rUmaskForOp :- returns register mask for an operand             */
2449 /*-----------------------------------------------------------------*/
2450 static bitVect *
2451 rUmaskForOp (operand * op)
2452 {
2453         bitVect *rumask;
2454         symbol *sym;
2455         int j;
2456         
2457         debugLog ("%s\n", __FUNCTION__);
2458         /* only temporaries are assigned registers */
2459         if (!IS_ITEMP (op))
2460                 return NULL;
2461         
2462         sym = OP_SYMBOL (op);
2463         
2464         /* if spilt or no registers assigned to it
2465         then nothing */
2466         if (sym->isspilt || !sym->nRegs)
2467                 return NULL;
2468         
2469         rumask = newBitVect (pic14_nRegs);
2470         
2471         for (j = 0; j < sym->nRegs; j++)
2472         {
2473                 rumask = bitVectSetBit (rumask,
2474                         sym->regs[j]->rIdx);
2475         }
2476         
2477         return rumask;
2478 }
2479
2480 /*-----------------------------------------------------------------*/
2481 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2482 /*-----------------------------------------------------------------*/
2483 static bitVect *
2484 regsUsedIniCode (iCode * ic)
2485 {
2486         bitVect *rmask = newBitVect (pic14_nRegs);
2487         
2488         debugLog ("%s\n", __FUNCTION__);
2489         /* do the special cases first */
2490         if (ic->op == IFX)
2491         {
2492                 rmask = bitVectUnion (rmask,
2493                         rUmaskForOp (IC_COND (ic)));
2494                 goto ret;
2495         }
2496         
2497         /* for the jumptable */
2498         if (ic->op == JUMPTABLE)
2499         {
2500                 rmask = bitVectUnion (rmask,
2501                         rUmaskForOp (IC_JTCOND (ic)));
2502                 
2503                 goto ret;
2504         }
2505         
2506         /* of all other cases */
2507         if (IC_LEFT (ic))
2508                 rmask = bitVectUnion (rmask,
2509                 rUmaskForOp (IC_LEFT (ic)));
2510         
2511         
2512         if (IC_RIGHT (ic))
2513                 rmask = bitVectUnion (rmask,
2514                 rUmaskForOp (IC_RIGHT (ic)));
2515         
2516         if (IC_RESULT (ic))
2517                 rmask = bitVectUnion (rmask,
2518                 rUmaskForOp (IC_RESULT (ic)));
2519         
2520 ret:
2521         return rmask;
2522 }
2523
2524 /*-----------------------------------------------------------------*/
2525 /* createRegMask - for each instruction will determine the regsUsed */
2526 /*-----------------------------------------------------------------*/
2527 static void
2528 createRegMask (eBBlock ** ebbs, int count)
2529 {
2530         int i;
2531         
2532         debugLog ("%s\n", __FUNCTION__);
2533         /* for all blocks */
2534         for (i = 0; i < count; i++)
2535         {
2536                 iCode *ic;
2537                 
2538                 if (ebbs[i]->noPath &&
2539                         (ebbs[i]->entryLabel != entryLabel &&
2540                         ebbs[i]->entryLabel != returnLabel))
2541                         continue;
2542                 
2543                 /* for all instructions */
2544                 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2545                 {
2546                         
2547                         int j;
2548                         
2549                         if (SKIP_IC2 (ic) || !ic->rlive)
2550                                 continue;
2551                         
2552                                 /* first mark the registers used in this
2553                         instruction */
2554                         ic->rUsed = regsUsedIniCode (ic);
2555                         _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2556                         
2557                         /* now create the register mask for those 
2558                         registers that are in use : this is a
2559                         super set of ic->rUsed */
2560                         ic->rMask = newBitVect (pic14_nRegs + 1);
2561                         
2562                         /* for all live Ranges alive at this point */
2563                         for (j = 1; j < ic->rlive->size; j++)
2564                         {
2565                                 symbol *sym;
2566                                 int k;
2567                                 
2568                                 /* if not alive then continue */
2569                                 if (!bitVectBitValue (ic->rlive, j))
2570                                         continue;
2571                                 
2572                                 /* find the live range we are interested in */
2573                                 if (!(sym = hTabItemWithKey (liveRanges, j)))
2574                                 {
2575                                         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2576                                                 "createRegMask cannot find live range");
2577                                         exit (0);
2578                                 }
2579                                 
2580                                 /* if no register assigned to it */
2581                                 if (!sym->nRegs || sym->isspilt)
2582                                         continue;
2583                                 
2584                                 /* for all the registers allocated to it */
2585                                 for (k = 0; k < sym->nRegs; k++)
2586                                         if (sym->regs[k])
2587                                                 ic->rMask =
2588                                                 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2589                         }
2590                 }
2591         }
2592 }
2593
2594 /*-----------------------------------------------------------------*/
2595 /* rematStr - returns the rematerialized string for a remat var    */
2596 /*-----------------------------------------------------------------*/
2597 static symbol *
2598 rematStr (symbol * sym)
2599 {
2600         char *s = buffer;
2601         iCode *ic = sym->rematiCode;
2602         symbol *psym = NULL;
2603         
2604         debugLog ("%s\n", __FUNCTION__);
2605         
2606         //printf ("%s\n", s);
2607         
2608         /* if plus or minus print the right hand side */
2609         
2610         if (ic->op == '+' || ic->op == '-') {
2611                 
2612                 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2613                 
2614                 sprintf (s, "(%s %c 0x%04x)",
2615                         OP_SYMBOL (IC_LEFT (ric))->rname,
2616                         ic->op,
2617                         (int) operandLitValue (IC_RIGHT (ic)));
2618                 
2619                 
2620                 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2621                 
2622                 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2623                 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2624                 
2625                 return psym;
2626         }
2627         
2628         sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2629         psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2630         
2631         //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2632         return psym;
2633 }
2634
2635 #if 0
2636 /*-----------------------------------------------------------------*/
2637 /* rematStr - returns the rematerialized string for a remat var    */
2638 /*-----------------------------------------------------------------*/
2639 static char *
2640 rematStr (symbol * sym)
2641 {
2642         char *s = buffer;
2643         iCode *ic = sym->rematiCode;
2644         
2645         debugLog ("%s\n", __FUNCTION__);
2646         while (1)
2647         {
2648                 
2649                 printf ("%s\n", s);
2650                 /* if plus or minus print the right hand side */
2651                 /*
2652                 if (ic->op == '+' || ic->op == '-') {
2653                 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2654                 ic->op );
2655                 s += strlen(s);
2656                 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2657                 continue ;
2658                 }
2659                 */
2660                 if (ic->op == '+' || ic->op == '-')
2661                 {
2662                         iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2663                         sprintf (s, "(%s %c 0x%04x)",
2664                                 OP_SYMBOL (IC_LEFT (ric))->rname,
2665                                 ic->op,
2666                                 (int) operandLitValue (IC_RIGHT (ic)));
2667                         
2668                         //s += strlen(s);
2669                         //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2670                         //continue ;
2671                         //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2672                         return buffer;
2673                 }
2674                 
2675                 /* we reached the end */
2676                 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2677                 break;
2678         }
2679         
2680         printf ("%s\n", buffer);
2681         return buffer;
2682 }
2683 #endif
2684
2685 /*-----------------------------------------------------------------*/
2686 /* regTypeNum - computes the type & number of registers required   */
2687 /*-----------------------------------------------------------------*/
2688 static void
2689 regTypeNum ()
2690 {
2691         symbol *sym;
2692         int k;
2693         iCode *ic;
2694         
2695         debugLog ("%s\n", __FUNCTION__);
2696         /* for each live range do */
2697         for (sym = hTabFirstItem (liveRanges, &k); sym;
2698         sym = hTabNextItem (liveRanges, &k)) {
2699                 
2700                 debugLog ("  %d - %s\n", __LINE__, sym->rname);
2701                 
2702                 /* if used zero times then no registers needed */
2703                 if ((sym->liveTo - sym->liveFrom) == 0)
2704                         continue;
2705                 
2706                 
2707                 /* if the live range is a temporary */
2708                 if (sym->isitmp) {
2709                         
2710                         debugLog ("  %d - itemp register\n", __LINE__);
2711                         
2712                         /* if the type is marked as a conditional */
2713                         if (sym->regType == REG_CND)
2714                                 continue;
2715                         
2716                                 /* if used in return only then we don't 
2717                         need registers */
2718                         if (sym->accuse) {
2719                                 if (IS_AGGREGATE (sym->type) || sym->isptr)
2720                                         sym->type = aggrToPtr (sym->type, FALSE);
2721                                 debugLog ("  %d - no reg needed - accumulator used\n", __LINE__);
2722                                 
2723                                 continue;
2724                         }
2725                         
2726                         if (sym->ruonly) {
2727                                 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2728                                 //  sym->type = aggrToPtr (sym->type, FALSE);
2729                                 debugLog ("  %d - used as a return\n", __LINE__);
2730                                 
2731                                 //continue;
2732                         }
2733                         
2734                         /* if the symbol has only one definition &
2735                         that definition is a get_pointer and the
2736                         pointer we are getting is rematerializable and
2737                         in "data" space */
2738                         
2739                         if (bitVectnBitsOn (sym->defs) == 1 &&
2740                             (ic = hTabItemWithKey (iCodehTab,
2741                                                    bitVectFirstBit (sym->defs))) &&
2742                             POINTER_GET (ic) &&
2743                             !IS_BITVAR (sym->etype) &&
2744                             (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2745
2746                                 if (ptrPseudoSymSafe (sym, ic)) {
2747
2748                                         symbol *psym;
2749                                         
2750                                         debugLog ("  %d - \n", __LINE__);
2751                                 
2752                                         /* create a psuedo symbol & force a spil */
2753                                         //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2754                                         psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2755                                         psym->type = sym->type;
2756                                         psym->etype = sym->etype;
2757                                         psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2758                                         strcpy (psym->rname, psym->name);
2759                                         sym->isspilt = 1;
2760                                         sym->usl.spillLoc = psym;
2761                                         continue;
2762                                 }
2763                                 
2764                                 /* if in data space or idata space then try to
2765                                 allocate pointer register */
2766                                 
2767                         }
2768                         
2769                         /* if not then we require registers */
2770                         sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2771                                 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2772                         getSize (sym->type));
2773                         
2774                         
2775                         if(IS_PTR_CONST (sym->type)) {
2776                                 debugLog ("  %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2777                                 sym->nRegs = 2;
2778                         }
2779                         
2780                         if (sym->nRegs > 4) {
2781                                 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2782                                 printTypeChain (sym->type, stderr);
2783                                 fprintf (stderr, "\n");
2784                         }
2785                         
2786                         /* determine the type of register required */
2787                         if (sym->nRegs == 1 &&
2788                                 IS_PTR (sym->type) &&
2789                                 sym->uptr)
2790                                 sym->regType = REG_PTR;
2791                         else
2792                                 sym->regType = REG_GPR;
2793                         
2794                         
2795                         debugLog ("  reg name %s,  reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2796                         
2797                 }
2798                 else
2799                         /* for the first run we don't provide */
2800                         /* registers for true symbols we will */
2801                         /* see how things go                  */
2802                         sym->nRegs = 0;
2803   }
2804   
2805 }
2806 DEFSETFUNC (markRegFree)
2807 {
2808         ((regs *)item)->isFree = 1;
2809         
2810         return 0;
2811 }
2812
2813 DEFSETFUNC (deallocReg)
2814 {
2815         fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2816         ((regs *)item)->isFree = 1;
2817         ((regs *)item)->wasUsed = 0;
2818         
2819         return 0;
2820 }
2821 /*-----------------------------------------------------------------*/
2822 /* freeAllRegs - mark all registers as free                        */
2823 /*-----------------------------------------------------------------*/
2824 void
2825 pic14_freeAllRegs ()
2826 {
2827         //  int i;
2828         
2829         debugLog ("%s\n", __FUNCTION__);
2830         
2831         applyToSet(dynAllocRegs,markRegFree);
2832         applyToSet(dynStackRegs,markRegFree);
2833         
2834         /*
2835         for (i = 0; i < pic14_nRegs; i++)
2836         regspic14[i].isFree = 1;
2837         */
2838 }
2839
2840 /*-----------------------------------------------------------------*/
2841 /*-----------------------------------------------------------------*/
2842 void
2843 pic14_deallocateAllRegs ()
2844 {
2845         //  int i;
2846         
2847         debugLog ("%s\n", __FUNCTION__);
2848         
2849         applyToSet(dynAllocRegs,deallocReg);
2850         
2851         /*
2852         for (i = 0; i < pic14_nRegs; i++) {
2853                 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2854                 regspic14[i].isFree = 1;
2855                 regspic14[i].wasUsed = 0;
2856                 }
2857         }
2858         */
2859 }
2860
2861
2862 /*-----------------------------------------------------------------*/
2863 /* deallocStackSpil - this will set the stack pointer back         */
2864 /*-----------------------------------------------------------------*/
2865 static
2866 DEFSETFUNC (deallocStackSpil)
2867 {
2868         symbol *sym = item;
2869         
2870         debugLog ("%s\n", __FUNCTION__);
2871         deallocLocal (sym);
2872         return 0;
2873 }
2874
2875 /*-----------------------------------------------------------------*/
2876 /* farSpacePackable - returns the packable icode for far variables */
2877 /*-----------------------------------------------------------------*/
2878 static iCode *
2879 farSpacePackable (iCode * ic)
2880 {
2881         iCode *dic;
2882         
2883         debugLog ("%s\n", __FUNCTION__);
2884         /* go thru till we find a definition for the
2885         symbol on the right */
2886         for (dic = ic->prev; dic; dic = dic->prev)
2887         {
2888                 
2889                 /* if the definition is a call then no */
2890                 if ((dic->op == CALL || dic->op == PCALL) &&
2891                         IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2892                 {
2893                         return NULL;
2894                 }
2895                 
2896                 /* if shift by unknown amount then not */
2897                 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2898                         IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2899                         return NULL;
2900                 
2901                 /* if pointer get and size > 1 */
2902                 if (POINTER_GET (dic) &&
2903                         getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2904                         return NULL;
2905                 
2906                 if (POINTER_SET (dic) &&
2907                         getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2908                         return NULL;
2909                 
2910                 /* if any three is a true symbol in far space */
2911                 if (IC_RESULT (dic) &&
2912                         IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2913                         isOperandInFarSpace (IC_RESULT (dic)))
2914                         return NULL;
2915                 
2916                 if (IC_RIGHT (dic) &&
2917                         IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2918                         isOperandInFarSpace (IC_RIGHT (dic)) &&
2919                         !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2920                         return NULL;
2921                 
2922                 if (IC_LEFT (dic) &&
2923                         IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2924                         isOperandInFarSpace (IC_LEFT (dic)) &&
2925                         !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2926                         return NULL;
2927                 
2928                 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2929                 {
2930                         if ((dic->op == LEFT_OP ||
2931                                 dic->op == RIGHT_OP ||
2932                                 dic->op == '-') &&
2933                                 IS_OP_LITERAL (IC_RIGHT (dic)))
2934                                 return NULL;
2935                         else
2936                                 return dic;
2937                 }
2938         }
2939         
2940         return NULL;
2941 }
2942
2943 /*-----------------------------------------------------------------*/
2944 /* packRegsForAssign - register reduction for assignment           */
2945 /*-----------------------------------------------------------------*/
2946 static int
2947 packRegsForAssign (iCode * ic, eBBlock * ebp)
2948 {
2949         
2950         iCode *dic, *sic;
2951         
2952         debugLog ("%s\n", __FUNCTION__);
2953         
2954         debugAopGet ("  result:", IC_RESULT (ic));
2955         debugAopGet ("  left:", IC_LEFT (ic));
2956         debugAopGet ("  right:", IC_RIGHT (ic));
2957         
2958         /* if this is at an absolute address, then get the address. */
2959         if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2960                 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2961                         debugLog ("  %d - found config word declaration\n", __LINE__);
2962                         if(IS_VALOP(IC_RIGHT(ic))) {
2963                                 debugLog ("  setting config word to %x\n", 
2964                                         (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2965                                 assignConfigWordValue(  SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2966                                         (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2967                         }
2968                         
2969                         /* remove the assignment from the iCode chain. */
2970                         
2971                         remiCodeFromeBBlock (ebp, ic);
2972                         bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2973                         hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2974                         
2975                         return 1;
2976                         
2977                 }
2978         }
2979         
2980         if (!IS_ITEMP (IC_RESULT (ic))) {
2981                 allocDirReg(IC_RESULT (ic));
2982                 debugLog ("  %d - result is not temp\n", __LINE__);
2983         }
2984         /*
2985         if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2986         debugLog ("  %d - left is not temp, allocating\n", __LINE__);
2987         allocDirReg(IC_LEFT (ic));
2988         }
2989         */
2990         
2991         if (!IS_ITEMP (IC_RIGHT (ic))) {
2992                 debugLog ("  %d - not packing - right is not temp\n", __LINE__);
2993                 
2994                 /* only pack if this is not a function pointer */
2995                 if (!IS_REF (IC_RIGHT (ic)))
2996                         allocDirReg(IC_RIGHT (ic));
2997                 return 0;
2998         }
2999         
3000         if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
3001                 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
3002         {
3003                 debugLog ("  %d - not packing - right side fails \n", __LINE__);
3004                 return 0;
3005         }
3006         
3007         /* if the true symbol is defined in far space or on stack
3008         then we should not since this will increase register pressure */
3009         if (isOperandInFarSpace (IC_RESULT (ic)))
3010         {
3011                 if ((dic = farSpacePackable (ic)))
3012                         goto pack;
3013                 else
3014                         return 0;
3015                 
3016         }
3017         /* find the definition of iTempNN scanning backwards if we find a 
3018         a use of the true symbol before we find the definition then 
3019         we cannot pack */
3020         for (dic = ic->prev; dic; dic = dic->prev)
3021         {
3022                 
3023         /* if there is a function call and this is
3024                 a parameter & not my parameter then don't pack it */
3025                 if ((dic->op == CALL || dic->op == PCALL) &&
3026                         (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3027                         !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3028                 {
3029                         debugLog ("  %d - \n", __LINE__);
3030                         dic = NULL;
3031                         break;
3032                 }
3033                 
3034                 if (SKIP_IC2 (dic))
3035                         continue;
3036                 
3037                 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3038                         IS_OP_VOLATILE (IC_RESULT (dic)))
3039                 {
3040                         debugLog ("  %d - dic is VOLATILE \n", __LINE__);
3041                         dic = NULL;
3042                         break;
3043                 }
3044                 
3045                 if (IS_SYMOP (IC_RESULT (dic)) &&
3046                         IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3047                 {
3048                         /* A previous result was assigned to the same register - we'll our definition */
3049                         debugLog ("  %d - dic result key == ic right key -- pointer set=%c\n",
3050                                 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3051                         if (POINTER_SET (dic))
3052                                 dic = NULL;
3053                         
3054                         break;
3055                 }
3056                 
3057                 if (IS_SYMOP (IC_RIGHT (dic)) &&
3058                         (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3059                         IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3060                 {
3061                         debugLog ("  %d - dic right key == ic rightor result key\n", __LINE__);
3062                         dic = NULL;
3063                         break;
3064                 }
3065                 
3066                 if (IS_SYMOP (IC_LEFT (dic)) &&
3067                         (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3068                         IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3069                 {
3070                         debugLog ("  %d - dic left key == ic rightor result key\n", __LINE__);
3071                         dic = NULL;
3072                         break;
3073                 }
3074                 
3075                 if (POINTER_SET (dic) &&
3076                         IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3077                 {
3078                         debugLog ("  %d - dic result key == ic result key -- pointer set=Y\n",
3079                                 __LINE__);
3080                         dic = NULL;
3081                         break;
3082                 }
3083         }
3084         
3085         if (!dic)
3086                 return 0;                       /* did not find */
3087         
3088                                                         /* if the result is on stack or iaccess then it must be
3089         the same atleast one of the operands */
3090         if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3091                 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3092         {
3093                 
3094         /* the operation has only one symbol
3095                 operator then we can pack */
3096                 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3097                         (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3098                         goto pack;
3099                 
3100                 if (!((IC_LEFT (dic) &&
3101                         IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3102                         (IC_RIGHT (dic) &&
3103                         IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3104                         return 0;
3105         }
3106 pack:
3107         debugLog ("  packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3108         debugLog ("  replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3109         /* found the definition */
3110         /* replace the result with the result of */
3111         /* this assignment and remove this assignment */
3112         bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3113         IC_RESULT (dic) = IC_RESULT (ic);
3114         
3115         if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3116         {
3117                 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3118         }
3119         /* delete from liverange table also 
3120         delete from all the points inbetween and the new
3121         one */
3122         for (sic = dic; sic != ic; sic = sic->next)
3123         {
3124                 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3125                 if (IS_ITEMP (IC_RESULT (dic)))
3126                         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3127         }
3128         
3129         remiCodeFromeBBlock (ebp, ic);
3130         bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3131         hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3132         OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3133         return 1;
3134         
3135         
3136 }
3137
3138 /*-----------------------------------------------------------------*/
3139 /* findAssignToSym : scanning backwards looks for first assig found */
3140 /*-----------------------------------------------------------------*/
3141 static iCode *
3142 findAssignToSym (operand * op, iCode * ic)
3143 {
3144         iCode *dic;
3145         
3146         debugLog ("%s\n", __FUNCTION__);
3147         for (dic = ic->prev; dic; dic = dic->prev)
3148         {
3149                 
3150                 /* if definition by assignment */
3151                 if (dic->op == '=' &&
3152                         !POINTER_SET (dic) &&
3153                         IC_RESULT (dic)->key == op->key
3154                         /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3155                         )
3156                 {
3157                         
3158                         /* we are interested only if defined in far space */
3159                         /* or in stack space in case of + & - */
3160                         
3161                         /* if assigned to a non-symbol then return
3162                         true */
3163                         if (!IS_SYMOP (IC_RIGHT (dic)))
3164                                 break;
3165                         
3166                                 /* if the symbol is in far space then
3167                         we should not */
3168                         if (isOperandInFarSpace (IC_RIGHT (dic)))
3169                                 return NULL;
3170                         
3171                                 /* for + & - operations make sure that
3172                                 if it is on the stack it is the same
3173                         as one of the three operands */
3174                         if ((ic->op == '+' || ic->op == '-') &&
3175                                 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3176                         {
3177                                 
3178                                 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3179                                         IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3180                                         IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3181                                         return NULL;
3182                         }
3183                         
3184                         break;
3185                         
3186                 }
3187                 
3188                 /* if we find an usage then we cannot delete it */
3189                 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3190                         return NULL;
3191                 
3192                 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3193                         return NULL;
3194                 
3195                 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3196                         return NULL;
3197         }
3198         
3199         /* now make sure that the right side of dic
3200         is not defined between ic & dic */
3201         if (dic)
3202         {
3203                 iCode *sic = dic->next;
3204                 
3205                 for (; sic != ic; sic = sic->next)
3206                         if (IC_RESULT (sic) &&
3207                                 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3208                                 return NULL;
3209         }
3210         
3211         return dic;
3212         
3213         
3214 }
3215
3216 /*-----------------------------------------------------------------*/
3217 /* packRegsForSupport :- reduce some registers for support calls   */
3218 /*-----------------------------------------------------------------*/
3219 static int
3220 packRegsForSupport (iCode * ic, eBBlock * ebp)
3221 {
3222         int change = 0;
3223         
3224         debugLog ("%s\n", __FUNCTION__);
3225         /* for the left & right operand :- look to see if the
3226         left was assigned a true symbol in far space in that
3227         case replace them */
3228         if (IS_ITEMP (IC_LEFT (ic)) &&
3229                 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3230         {
3231                 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3232                 iCode *sic;
3233                 
3234                 if (!dic)
3235                         goto right;
3236                 
3237                 debugAopGet ("removing left:", IC_LEFT (ic));
3238                 
3239                 /* found it we need to remove it from the
3240                 block */
3241                 for (sic = dic; sic != ic; sic = sic->next)
3242                         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3243                 
3244                 IC_LEFT (ic)->operand.symOperand =
3245                         IC_RIGHT (dic)->operand.symOperand;
3246                 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3247                 remiCodeFromeBBlock (ebp, dic);
3248                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3249                 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3250                 change++;
3251         }
3252         
3253         /* do the same for the right operand */
3254 right:
3255         if (!change &&
3256                 IS_ITEMP (IC_RIGHT (ic)) &&
3257                 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3258         {
3259                 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3260                 iCode *sic;
3261                 
3262                 if (!dic)
3263                         return change;
3264                 
3265                         /* if this is a subtraction & the result
3266                 is a true symbol in far space then don't pack */
3267                 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3268                 {
3269                         sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3270                         if (IN_FARSPACE (SPEC_OCLS (etype)))
3271                                 return change;
3272                 }
3273                 
3274                 debugAopGet ("removing right:", IC_RIGHT (ic));
3275                 
3276                 /* found it we need to remove it from the
3277                 block */
3278                 for (sic = dic; sic != ic; sic = sic->next)
3279                         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3280                 
3281                 IC_RIGHT (ic)->operand.symOperand =
3282                         IC_RIGHT (dic)->operand.symOperand;
3283                 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3284                 
3285                 remiCodeFromeBBlock (ebp, dic);
3286                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3287                 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3288                 change++;
3289         }
3290         
3291         return change;
3292 }
3293
3294 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3295
3296
3297 /*-----------------------------------------------------------------*/
3298 /* packRegsForOneuse : - will reduce some registers for single Use */
3299 /*-----------------------------------------------------------------*/
3300 static iCode *
3301 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3302 {
3303         bitVect *uses;
3304         iCode *dic, *sic;
3305         
3306         debugLog ("%s\n", __FUNCTION__);
3307         /* if returning a literal then do nothing */
3308         if (!IS_SYMOP (op))
3309                 return NULL;
3310         
3311                 /* only upto 2 bytes since we cannot predict
3312         the usage of b, & acc */
3313         if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3314                 ic->op != RETURN &&
3315                 ic->op != SEND)
3316                 return NULL;
3317         
3318                 /* this routine will mark the a symbol as used in one 
3319                 instruction use only && if the definition is local 
3320                 (ie. within the basic block) && has only one definition &&
3321                 that definition is either a return value from a 
3322                 function or does not contain any variables in
3323         far space */
3324         uses = bitVectCopy (OP_USES (op));
3325         bitVectUnSetBit (uses, ic->key);        /* take away this iCode */
3326         if (!bitVectIsZero (uses))      /* has other uses */
3327                 return NULL;
3328         
3329         /* if it has only one defintion */
3330         if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3331                 return NULL;            /* has more than one definition */
3332         
3333         /* get that definition */
3334         if (!(dic =
3335                 hTabItemWithKey (iCodehTab,
3336                 bitVectFirstBit (OP_DEFS (op)))))
3337                 return NULL;
3338         
3339         /* found the definition now check if it is local */
3340         if (dic->seq < ebp->fSeq ||
3341                 dic->seq > ebp->lSeq)
3342                 return NULL;            /* non-local */
3343         
3344                                                         /* now check if it is the return from
3345         a function call */
3346         if (dic->op == CALL || dic->op == PCALL)
3347         {
3348                 if (ic->op != SEND && ic->op != RETURN &&
3349                         !POINTER_SET(ic) && !POINTER_GET(ic))
3350                 {
3351                         OP_SYMBOL (op)->ruonly = 1;
3352                         return dic;
3353                 }
3354                 dic = dic->next;
3355         }
3356         
3357         
3358         /* otherwise check that the definition does
3359         not contain any symbols in far space */
3360         if (isOperandInFarSpace (IC_LEFT (dic)) ||
3361                 isOperandInFarSpace (IC_RIGHT (dic)) ||
3362                 IS_OP_RUONLY (IC_LEFT (ic)) ||
3363                 IS_OP_RUONLY (IC_RIGHT (ic)))
3364         {
3365                 return NULL;
3366         }
3367         
3368         /* if pointer set then make sure the pointer
3369         is one byte */
3370         if (POINTER_SET (dic) &&
3371                 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3372                 return NULL;
3373         
3374         if (POINTER_GET (dic) &&
3375                 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3376                 return NULL;
3377         
3378         sic = dic;
3379         
3380         /* also make sure the intervenening instructions
3381         don't have any thing in far space */
3382         for (dic = dic->next; dic && dic != ic; dic = dic->next)
3383         {
3384                 
3385                 /* if there is an intervening function call then no */
3386                 if (dic->op == CALL || dic->op == PCALL)
3387                         return NULL;
3388                         /* if pointer set then make sure the pointer
3389                 is one byte */
3390                 if (POINTER_SET (dic) &&
3391                         !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3392                         return NULL;
3393                 
3394                 if (POINTER_GET (dic) &&
3395                         !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3396                         return NULL;
3397                 
3398                 /* if address of & the result is remat then okay */
3399                 if (dic->op == ADDRESS_OF &&
3400                         OP_SYMBOL (IC_RESULT (dic))->remat)
3401                         continue;
3402                 
3403                         /* if operand has size of three or more & this
3404                         operation is a '*','/' or '%' then 'b' may
3405                 cause a problem */
3406                 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3407                         getSize (operandType (op)) >= 3)
3408                         return NULL;
3409                 
3410                 /* if left or right or result is in far space */
3411                 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3412                         isOperandInFarSpace (IC_RIGHT (dic)) ||
3413                         isOperandInFarSpace (IC_RESULT (dic)) ||
3414                         IS_OP_RUONLY (IC_LEFT (dic)) ||
3415                         IS_OP_RUONLY (IC_RIGHT (dic)) ||
3416                         IS_OP_RUONLY (IC_RESULT (dic)))
3417                 {
3418                         return NULL;
3419                 }
3420         }
3421         
3422         OP_SYMBOL (op)->ruonly = 1;
3423         return sic;
3424         
3425 }
3426
3427 /*-----------------------------------------------------------------*/
3428 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
3429 /*-----------------------------------------------------------------*/
3430 static bool
3431 isBitwiseOptimizable (iCode * ic)
3432 {
3433         sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3434         sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3435         
3436         debugLog ("%s\n", __FUNCTION__);
3437         /* bitwise operations are considered optimizable
3438         under the following conditions (Jean-Louis VERN) 
3439         
3440           x & lit
3441           bit & bit
3442           bit & x
3443           bit ^ bit
3444           bit ^ x
3445           x   ^ lit
3446           x   | lit
3447           bit | bit
3448           bit | x
3449         */
3450         if (IS_LITERAL (rtype) ||
3451                 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3452                 return TRUE;
3453         else
3454                 return FALSE;
3455 }
3456
3457 /*-----------------------------------------------------------------*/
3458 /* packRegsForAccUse - pack registers for acc use                  */
3459 /*-----------------------------------------------------------------*/
3460 static void
3461 packRegsForAccUse (iCode * ic)
3462 {
3463         iCode *uic;
3464         
3465         debugLog ("%s\n", __FUNCTION__);
3466         
3467         /* if this is an aggregate, e.g. a one byte char array */
3468         if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3469                 return;
3470         }
3471         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3472         
3473         /* if + or - then it has to be one byte result */
3474         if ((ic->op == '+' || ic->op == '-')
3475                 && getSize (operandType (IC_RESULT (ic))) > 1)
3476                 return;
3477         
3478         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3479         /* if shift operation make sure right side is not a literal */
3480         if (ic->op == RIGHT_OP &&
3481                 (isOperandLiteral (IC_RIGHT (ic)) ||
3482                 getSize (operandType (IC_RESULT (ic))) > 1))
3483                 return;
3484         
3485         if (ic->op == LEFT_OP &&
3486                 (isOperandLiteral (IC_RIGHT (ic)) ||
3487                 getSize (operandType (IC_RESULT (ic))) > 1))
3488                 return;
3489         
3490         if (IS_BITWISE_OP (ic) &&
3491                 getSize (operandType (IC_RESULT (ic))) > 1)
3492                 return;
3493         
3494         
3495         /* has only one definition */
3496         if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3497                 return;
3498         
3499         /* has only one use */
3500         if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3501                 return;
3502         
3503         /* and the usage immediately follows this iCode */
3504         if (!(uic = hTabItemWithKey (iCodehTab,
3505                 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3506                 return;
3507         
3508         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3509         if (ic->next != uic)
3510                 return;
3511         
3512         /* if it is a conditional branch then we definitely can */
3513         if (uic->op == IFX)
3514                 goto accuse;
3515         
3516         if (uic->op == JUMPTABLE)
3517                 return;
3518         
3519                 /* if the usage is not is an assignment
3520         or an arithmetic / bitwise / shift operation then not */
3521         if (POINTER_SET (uic) &&
3522                 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3523                 return;
3524         
3525         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3526         if (uic->op != '=' &&
3527                 !IS_ARITHMETIC_OP (uic) &&
3528                 !IS_BITWISE_OP (uic) &&
3529                 uic->op != LEFT_OP &&
3530                 uic->op != RIGHT_OP)
3531                 return;
3532         
3533         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3534         /* if used in ^ operation then make sure right is not a 
3535         literl */
3536         if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3537                 return;
3538         
3539         /* if shift operation make sure right side is not a literal */
3540         if (uic->op == RIGHT_OP &&
3541                 (isOperandLiteral (IC_RIGHT (uic)) ||
3542                 getSize (operandType (IC_RESULT (uic))) > 1))
3543                 return;
3544         
3545         if (uic->op == LEFT_OP &&
3546                 (isOperandLiteral (IC_RIGHT (uic)) ||
3547                 getSize (operandType (IC_RESULT (uic))) > 1))
3548                 return;
3549         
3550                 /* make sure that the result of this icode is not on the
3551         stack, since acc is used to compute stack offset */
3552         if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3553                 OP_SYMBOL (IC_RESULT (uic))->onStack)
3554                 return;
3555         
3556         /* if either one of them in far space then we cannot */
3557         if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3558                 isOperandInFarSpace (IC_LEFT (uic))) ||
3559                 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3560                 isOperandInFarSpace (IC_RIGHT (uic))))
3561                 return;
3562         
3563         /* if the usage has only one operand then we can */
3564         if (IC_LEFT (uic) == NULL ||
3565                 IC_RIGHT (uic) == NULL)
3566                 goto accuse;
3567         
3568                 /* make sure this is on the left side if not
3569         a '+' since '+' is commutative */
3570         if (ic->op != '+' &&
3571                 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3572                 return;
3573         
3574         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3575         /* if one of them is a literal then we can */
3576         if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3577                 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))  &&
3578                 (getSize (operandType (IC_RESULT (uic))) <= 1))
3579         {
3580                 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3581                 return;
3582         }
3583         
3584         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3585         /* if the other one is not on stack then we can */
3586         if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3587                 (IS_ITEMP (IC_RIGHT (uic)) ||
3588                 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3589                 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3590                 goto accuse;
3591         
3592         if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3593                 (IS_ITEMP (IC_LEFT (uic)) ||
3594                 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3595                 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3596                 goto accuse;
3597         
3598         return;
3599         
3600 accuse:
3601         debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3602         OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3603         
3604         
3605 }
3606
3607 /*-----------------------------------------------------------------*/
3608 /* packForPush - hueristics to reduce iCode for pushing            */
3609 /*-----------------------------------------------------------------*/
3610 static void
3611 packForReceive (iCode * ic, eBBlock * ebp)
3612 {
3613         iCode *dic;
3614         
3615         debugLog ("%s\n", __FUNCTION__);
3616         debugAopGet ("  result:", IC_RESULT (ic));
3617         debugAopGet ("  left:", IC_LEFT (ic));
3618         debugAopGet ("  right:", IC_RIGHT (ic));
3619         
3620         if (!ic->next)
3621                 return;
3622         
3623         for (dic = ic->next; dic; dic = dic->next)
3624         {
3625                 
3626                 
3627                 
3628                 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3629                         debugLog ("    used on left\n");
3630                 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3631                         debugLog ("    used on right\n");
3632                 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3633                         debugLog ("    used on result\n");
3634                 
3635                 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3636                         (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3637                         return;
3638                 
3639         }
3640         
3641         debugLog ("  hey we can remove this unnecessary assign\n");
3642 }
3643 /*-----------------------------------------------------------------*/
3644 /* packForPush - hueristics to reduce iCode for pushing            */
3645 /*-----------------------------------------------------------------*/
3646 static void
3647 packForPush (iCode * ic, eBBlock * ebp)
3648 {
3649         iCode *dic;
3650         
3651         debugLog ("%s\n", __FUNCTION__);
3652         if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3653                 return;
3654         
3655         /* must have only definition & one usage */
3656         if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3657                 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3658                 return;
3659         
3660         /* find the definition */
3661         if (!(dic = hTabItemWithKey (iCodehTab,
3662                 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3663                 return;
3664         
3665         if (dic->op != '=' || POINTER_SET (dic))
3666                 return;
3667         
3668                 /* we now we know that it has one & only one def & use
3669         and the that the definition is an assignment */
3670         IC_LEFT (ic) = IC_RIGHT (dic);
3671         
3672         remiCodeFromeBBlock (ebp, dic);
3673         bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3674         hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3675 }
3676
3677 void printSymType(char * str, sym_link *sl)
3678 {
3679         debugLog ("    %s Symbol type: ",str);
3680         printTypeChain( sl, debugF);
3681         debugLog ("\n");
3682         
3683 }
3684
3685 /*-----------------------------------------------------------------*/
3686 /* some debug code to print the symbol S_TYPE. Note that
3687 * the function checkSClass in src/SDCCsymt.c dinks with
3688 * the S_TYPE in ways the PIC port doesn't fully like...*/
3689 /*-----------------------------------------------------------------*/
3690 void isData(sym_link *sl)
3691 {
3692         FILE *of = stderr;
3693         
3694         if(!sl)
3695                 return;
3696         
3697         if(debugF)
3698                 of = debugF;
3699         
3700         for ( ; sl; sl=sl->next) {
3701                 if(!IS_DECL(sl) ) {
3702                         switch (SPEC_SCLS(sl)) {
3703                                 
3704                         case S_DATA: fprintf (of, "data "); break;
3705                         case S_XDATA: fprintf (of, "xdata "); break;
3706                         case S_SFR: fprintf (of, "sfr "); break;
3707                         case S_SBIT: fprintf (of, "sbit "); break;
3708                         case S_CODE: fprintf (of, "code "); break;
3709                         case S_IDATA: fprintf (of, "idata "); break;
3710                         case S_PDATA: fprintf (of, "pdata "); break;
3711                         case S_LITERAL: fprintf (of, "literal "); break;
3712                         case S_STACK: fprintf (of, "stack "); break;
3713                         case S_XSTACK: fprintf (of, "xstack "); break;
3714                         case S_BIT: fprintf (of, "bit "); break;
3715                         case S_EEPROM: fprintf (of, "eeprom "); break;
3716                         default: break;
3717                         }
3718                         
3719                 }
3720                 
3721         }
3722         
3723 }
3724 /*-----------------------------------------------------------------*/
3725 /* packRegisters - does some transformations to reduce register    */
3726 /*                   pressure                                      */
3727 /*-----------------------------------------------------------------*/
3728 static void
3729 packRegisters (eBBlock * ebp)
3730 {
3731         iCode *ic;
3732         int change = 0;
3733         
3734         debugLog ("%s\n", __FUNCTION__);
3735         
3736         while (1) {
3737                 
3738                 change = 0;
3739                 
3740                 /* look for assignments of the form */
3741                 /* iTempNN = TRueSym (someoperation) SomeOperand */
3742                 /*       ....                       */
3743                 /* TrueSym := iTempNN:1             */
3744                 for (ic = ebp->sch; ic; ic = ic->next)
3745                 {
3746                         
3747                         /* find assignment of the form TrueSym := iTempNN:1 */
3748                         if (ic->op == '=' && !POINTER_SET (ic))
3749                                 change += packRegsForAssign (ic, ebp);
3750                         /* debug stuff */
3751                         if (ic->op == '=')
3752                         {
3753                                 if (POINTER_SET (ic))
3754                                         debugLog ("pointer is set\n");
3755                                 debugAopGet ("  result:", IC_RESULT (ic));
3756                                 debugAopGet ("  left:", IC_LEFT (ic));
3757                                 debugAopGet ("  right:", IC_RIGHT (ic));
3758                         }
3759                         
3760                 }
3761                 
3762                 if (!change)
3763                         break;
3764         }
3765         
3766         for (ic = ebp->sch; ic; ic = ic->next) {
3767                 
3768                 if(IS_SYMOP ( IC_LEFT(ic))) {
3769                         sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3770                         
3771                         debugAopGet ("  left:", IC_LEFT (ic));
3772                         if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3773                                 debugLog ("    is a pointer\n");
3774                         
3775                         if(IS_OP_VOLATILE(IC_LEFT(ic)))
3776                                 debugLog ("    is volatile\n");
3777                         
3778                         isData(etype);
3779                         
3780                         printSymType("   ", OP_SYMBOL(IC_LEFT(ic))->type);
3781                 }
3782                 
3783                 if(IS_SYMOP ( IC_RIGHT(ic))) {
3784                         debugAopGet ("  right:", IC_RIGHT (ic));
3785                         printSymType("    ", OP_SYMBOL(IC_RIGHT(ic))->type);
3786                 }
3787                 
3788                 if(IS_SYMOP ( IC_RESULT(ic))) {
3789                         debugAopGet ("  result:", IC_RESULT (ic));
3790                         printSymType("     ", OP_SYMBOL(IC_RESULT(ic))->type);
3791                 }
3792                 
3793                 if (POINTER_SET (ic))
3794                         debugLog ("  %d - Pointer set\n", __LINE__);
3795                 
3796                 
3797                         /* if this is an itemp & result of a address of a true sym 
3798                 then mark this as rematerialisable   */
3799                 if (ic->op == ADDRESS_OF &&
3800                         IS_ITEMP (IC_RESULT (ic)) &&
3801                         IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3802                         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3803                         !OP_SYMBOL (IC_LEFT (ic))->onStack)
3804                 {
3805                         
3806                         debugLog ("  %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3807                         
3808                         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3809                         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3810                         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3811                         
3812                 }
3813                 
3814                 /* if straight assignment then carry remat flag if
3815                 this is the only definition */
3816                 if (ic->op == '=' &&
3817                         !POINTER_SET (ic) &&
3818                         IS_SYMOP (IC_RIGHT (ic)) &&
3819                         OP_SYMBOL (IC_RIGHT (ic))->remat &&
3820                         bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3821                 {
3822                         debugLog ("  %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3823                         
3824                         OP_SYMBOL (IC_RESULT (ic))->remat =
3825                                 OP_SYMBOL (IC_RIGHT (ic))->remat;
3826                         OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3827                                 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3828                 }
3829                 
3830                 /* if this is a +/- operation with a rematerizable 
3831                 then mark this as rematerializable as well */
3832                 if ((ic->op == '+' || ic->op == '-') &&
3833                         (IS_SYMOP (IC_LEFT (ic)) &&
3834                         IS_ITEMP (IC_RESULT (ic)) &&
3835                         OP_SYMBOL (IC_LEFT (ic))->remat &&
3836                         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3837                         IS_OP_LITERAL (IC_RIGHT (ic))))
3838                 {
3839                         debugLog ("  %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3840                         //int i = 
3841                         operandLitValue (IC_RIGHT (ic));
3842                         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3843                         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3844                         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3845                 }
3846                 
3847                 /* mark the pointer usages */
3848                 if (POINTER_SET (ic))
3849                 {
3850                         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3851                         debugLog ("  marking as a pointer (set) =>");
3852                         debugAopGet ("  result:", IC_RESULT (ic));
3853                 }
3854                 if (POINTER_GET (ic))
3855                 {
3856                         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3857                         debugLog ("  marking as a pointer (get) =>");
3858                         debugAopGet ("  left:", IC_LEFT (ic));
3859                 }
3860                 
3861                 if (!SKIP_IC2 (ic))
3862                 {
3863                 /* if we are using a symbol on the stack
3864                         then we should say pic14_ptrRegReq */
3865                         if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3866                                 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3867                                 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3868                         else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3869                                 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3870                                 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3871                         else
3872                         {
3873                                 if (IS_SYMOP (IC_LEFT (ic)))
3874                                         pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3875                                         OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3876                                 if (IS_SYMOP (IC_RIGHT (ic)))
3877                                         pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3878                                         OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3879                                 if (IS_SYMOP (IC_RESULT (ic)))
3880                                         pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3881                                         OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3882                         }
3883                         
3884                         debugLog ("  %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3885                         
3886                 }
3887                 
3888                 /* if the condition of an if instruction
3889                 is defined in the previous instruction then
3890                 mark the itemp as a conditional */
3891                 if ((IS_CONDITIONAL (ic) ||
3892                         ((ic->op == BITWISEAND ||
3893                         ic->op == '|' ||
3894                         ic->op == '^') &&
3895                         isBitwiseOptimizable (ic))) &&
3896                         ic->next && ic->next->op == IFX &&
3897                         isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3898                         OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3899                 {
3900                         
3901                         debugLog ("  %d\n", __LINE__);
3902                         OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3903                         continue;
3904                 }
3905                 
3906                 /* reduce for support function calls */
3907                 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3908                         packRegsForSupport (ic, ebp);
3909                 
3910                 /* if a parameter is passed, it's in W, so we may not
3911                 need to place a copy in a register */
3912                 if (ic->op == RECEIVE)
3913                         packForReceive (ic, ebp);
3914                 
3915                 /* some cases the redundant moves can
3916                 can be eliminated for return statements */
3917                 if ((ic->op == RETURN || ic->op == SEND) &&
3918                         !isOperandInFarSpace (IC_LEFT (ic)) &&
3919                         !options.model)
3920                         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3921                 
3922                 /* if pointer set & left has a size more than
3923                 one and right is not in far space */
3924                 if (POINTER_SET (ic) &&
3925                         !isOperandInFarSpace (IC_RIGHT (ic)) &&
3926                         !OP_SYMBOL (IC_RESULT (ic))->remat &&
3927                         !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3928                         getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3929                         
3930                         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3931                 
3932                 /* if pointer get */
3933                 if (POINTER_GET (ic) &&
3934                         !isOperandInFarSpace (IC_RESULT (ic)) &&
3935                         !OP_SYMBOL (IC_LEFT (ic))->remat &&
3936                         !IS_OP_RUONLY (IC_RESULT (ic)) &&
3937                         getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3938                         
3939                         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3940                 
3941                 
3942                         /* if this is cast for intergral promotion then
3943                         check if only use of  the definition of the 
3944                         operand being casted/ if yes then replace
3945                         the result of that arithmetic operation with 
3946                 this result and get rid of the cast */
3947                 if (ic->op == CAST) {
3948                         
3949                         sym_link *fromType = operandType (IC_RIGHT (ic));
3950                         sym_link *toType = operandType (IC_LEFT (ic));
3951                         
3952                         debugLog ("  %d - casting\n", __LINE__);
3953                         
3954                         if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3955                                 getSize (fromType) != getSize (toType)) {
3956                                 
3957                                 
3958                                 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3959                                 if (dic) {
3960                                         
3961                                         if (IS_ARITHMETIC_OP (dic)) {
3962                                                 
3963                                                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3964                                                 IC_RESULT (dic) = IC_RESULT (ic);
3965                                                 remiCodeFromeBBlock (ebp, ic);
3966                                                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3967                                                 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3968                                                 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3969                                                 ic = ic->prev;
3970                                         }  else
3971                                                 
3972                                                 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3973                                 }
3974                         } else {
3975                                 
3976                         /* if the type from and type to are the same
3977                                 then if this is the only use then packit */
3978                                 if (compareType (operandType (IC_RIGHT (ic)),
3979                                         operandType (IC_LEFT (ic))) == 1) {
3980                                         
3981                                         iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3982                                         if (dic) {
3983                                                 
3984                                                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3985                                                 IC_RESULT (dic) = IC_RESULT (ic);
3986                                                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3987                                                 remiCodeFromeBBlock (ebp, ic);
3988                                                 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3989                                                 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3990                                                 ic = ic->prev;
3991                                         }
3992                                 }
3993                         }
3994                 }
3995                 
3996                 /* pack for PUSH 
3997                 iTempNN := (some variable in farspace) V1
3998                 push iTempNN ;
3999                 -------------
4000                 push V1
4001                 */
4002                 if (ic->op == IPUSH)
4003                 {
4004                         packForPush (ic, ebp);
4005                 }
4006                 
4007                 
4008                 /* pack registers for accumulator use, when the
4009                 result of an arithmetic or bit wise operation
4010                 has only one use, that use is immediately following
4011                 the defintion and the using iCode has only one
4012                 operand or has two operands but one is literal &
4013                 the result of that operation is not on stack then
4014                 we can leave the result of this operation in acc:b
4015                 combination */
4016                 if ((IS_ARITHMETIC_OP (ic)
4017                         
4018                         || IS_BITWISE_OP (ic)
4019                         
4020                         || ic->op == LEFT_OP || ic->op == RIGHT_OP
4021                         
4022                         ) &&
4023                         IS_ITEMP (IC_RESULT (ic)) &&
4024                         getSize (operandType (IC_RESULT (ic))) <= 2)
4025                         
4026                         packRegsForAccUse (ic);
4027                 
4028   }
4029 }
4030
4031 static void
4032 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4033 {
4034         int i;
4035         
4036         if (!debug || !debugF)
4037                 return;
4038         
4039         for (i = 0; i < count; i++)
4040         {
4041                 fprintf (debugF, "\n----------------------------------------------------------------\n");
4042                 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4043                         ebbs[i]->entryLabel->name,
4044                         ebbs[i]->depth,
4045                         ebbs[i]->noPath,
4046                         ebbs[i]->isLastInLoop);
4047                 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4048                         ebbs[i]->dfnum,
4049                         ebbs[i]->bbnum,
4050                         ebbs[i]->fSeq,
4051                         ebbs[i]->lSeq);
4052                 fprintf (debugF, "visited %d : hasFcall = %d\n",
4053                         ebbs[i]->visited,
4054                         ebbs[i]->hasFcall);
4055                 
4056                 fprintf (debugF, "\ndefines bitVector :");
4057                 bitVectDebugOn (ebbs[i]->defSet, debugF);
4058                 fprintf (debugF, "\nlocal defines bitVector :");
4059                 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4060                 fprintf (debugF, "\npointers Set bitvector :");
4061                 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4062                 fprintf (debugF, "\nin pointers Set bitvector :");
4063                 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4064                 fprintf (debugF, "\ninDefs Set bitvector :");
4065                 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4066                 fprintf (debugF, "\noutDefs Set bitvector :");
4067                 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4068                 fprintf (debugF, "\nusesDefs Set bitvector :");
4069                 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4070                 fprintf (debugF, "\n----------------------------------------------------------------\n");
4071                 printiCChain (ebbs[i]->sch, debugF);
4072         }
4073 }
4074 /*-----------------------------------------------------------------*/
4075 /* assignRegisters - assigns registers to each live range as need  */
4076 /*-----------------------------------------------------------------*/
4077 void
4078 pic14_assignRegisters (eBBlock ** ebbs, int count)
4079 {
4080         iCode *ic;
4081         int i;
4082         
4083         debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4084         debugLog ("\nebbs before optimizing:\n");
4085         dumpEbbsToDebug (ebbs, count);
4086         
4087         setToNull ((void *) &_G.funcrUsed);
4088         pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4089         
4090         
4091         /* change assignments this will remove some
4092         live ranges reducing some register pressure */
4093         for (i = 0; i < count; i++)
4094                 packRegisters (ebbs[i]);
4095         
4096         {
4097                 regs *reg;
4098                 int hkey;
4099                 int i=0;
4100                 
4101                 debugLog("dir registers allocated so far:\n");
4102                 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4103                 
4104                 while(reg) {
4105                         debugLog("  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4106                         reg = hTabNextItem(dynDirectRegNames, &hkey);
4107                 }
4108                 
4109         }
4110         
4111         if (options.dump_pack)
4112                 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
4113         
4114         /* first determine for each live range the number of 
4115         registers & the type of registers required for each */
4116         regTypeNum ();
4117         
4118         /* and serially allocate registers */
4119         serialRegAssign (ebbs, count);
4120         
4121         /* if stack was extended then tell the user */
4122         if (_G.stackExtend)
4123         {
4124                 /*      werror(W_TOOMANY_SPILS,"stack", */
4125                 /*             _G.stackExtend,currFunc->name,""); */
4126                 _G.stackExtend = 0;
4127         }
4128         
4129         if (_G.dataExtend)
4130         {
4131                 /*      werror(W_TOOMANY_SPILS,"data space", */
4132                 /*             _G.dataExtend,currFunc->name,""); */
4133                 _G.dataExtend = 0;
4134         }
4135         
4136         /* after that create the register mask
4137         for each of the instruction */
4138         createRegMask (ebbs, count);
4139         
4140         /* redo that offsets for stacked automatic variables */
4141         redoStackOffsets ();
4142         
4143         if (options.dump_rassgn)
4144                 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4145         
4146         /* now get back the chain */
4147         ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4148         
4149         debugLog ("ebbs after optimizing:\n");
4150         dumpEbbsToDebug (ebbs, count);
4151         
4152         
4153         genpic14Code (ic);
4154         
4155         /* free up any _G.stackSpil locations allocated */
4156         applyToSet (_G.stackSpil, deallocStackSpil);
4157         _G.slocNum = 0;
4158         setToNull ((void *) &_G.stackSpil);
4159         setToNull ((void *) &_G.spiltSet);
4160         /* mark all registers as free */
4161         //pic14_freeAllRegs ();
4162         
4163         debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
4164         debugLogClose ();
4165         return;
4166 }