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