* fixed bug 1045046 - SIGSEGV with really simple code?:
[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                 else {
974                   werror (E_STACK_OUT, "Register");
975                   /* return an existing register just to avoid the SDCC crash */
976                   return regWithIdx ( dynStackRegs, 0x7f, fixed);
977                 }
978                 break;
979         case REG_SFR:
980                 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
981                         debugLog ("Found a Processor Register!\n");
982                         return dReg;
983                 }
984                 
985         case REG_CND:
986         case REG_PTR:
987         default:
988                 break;
989         }
990         
991         
992         return NULL;
993 }
994
995 /*-----------------------------------------------------------------*/
996 /* pic14_regWithIdx - returns pointer to register with index number*/
997 /*-----------------------------------------------------------------*/
998 regs *
999 pic14_regWithIdx (int idx)
1000 {
1001         regs *dReg;
1002         
1003         if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
1004                 return dReg;
1005         
1006         if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
1007                 return dReg;
1008         
1009         return NULL;
1010 }
1011
1012 /*-----------------------------------------------------------------*/
1013 /* pic14_regWithIdx - returns pointer to register with index number       */
1014 /*-----------------------------------------------------------------*/
1015 regs *
1016 pic14_allocWithIdx (int idx)
1017 {
1018         
1019         regs *dReg;
1020         
1021         debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
1022         
1023         if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
1024                 
1025                 debugLog ("Found a Dynamic Register!\n");
1026         } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
1027                 debugLog ("Found a Stack Register!\n");
1028         } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
1029                 debugLog ("Found a Processor Register!\n");
1030         } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
1031                 debugLog ("Found an Internal Register!\n");
1032         } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
1033                 debugLog ("Found an Internal Register!\n");
1034         } else {
1035                 
1036                 debugLog ("Dynamic Register not found\n");
1037                 
1038                 
1039                 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
1040                 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1041                         "regWithIdx not found");
1042                 exit (1);
1043                 
1044         }
1045         
1046         dReg->wasUsed = 1;
1047         dReg->isFree = 0;
1048         
1049         return dReg;
1050 }
1051 /*-----------------------------------------------------------------*/
1052 /*-----------------------------------------------------------------*/
1053 regs *
1054 pic14_findFreeReg(short type)
1055 {
1056         //  int i;
1057         regs* dReg;
1058         
1059         switch (type) {
1060         case REG_GPR:
1061                 if((dReg = regFindFree(dynAllocRegs)) != NULL)
1062                         return dReg;
1063                 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
1064                 
1065         case REG_STK:
1066                 
1067                 if((dReg = regFindFree(dynStackRegs)) != NULL)
1068                         return dReg;
1069                 
1070                 return NULL;
1071                 
1072         case REG_PTR:
1073         case REG_CND:
1074         case REG_SFR:
1075         default:
1076                 return NULL;
1077         }
1078 }
1079 /*-----------------------------------------------------------------*/
1080 /* freeReg - frees a register                                      */
1081 /*-----------------------------------------------------------------*/
1082 static void
1083 freeReg (regs * reg)
1084 {
1085         debugLog ("%s\n", __FUNCTION__);
1086         reg->isFree = 1;
1087 }
1088
1089
1090 /*-----------------------------------------------------------------*/
1091 /* nFreeRegs - returns number of free registers                    */
1092 /*-----------------------------------------------------------------*/
1093 static int
1094 nFreeRegs (int type)
1095 {
1096 /* dynamically allocate as many as we need and worry about
1097         * fitting them into a PIC later */
1098         
1099         return 100;
1100 #if 0
1101         int i;
1102         int nfr = 0;
1103         
1104         debugLog ("%s\n", __FUNCTION__);
1105         for (i = 0; i < pic14_nRegs; i++)
1106                 if (regspic14[i].isFree && regspic14[i].type == type)
1107                         nfr++;
1108                 return nfr;
1109 #endif
1110 }
1111
1112 /*-----------------------------------------------------------------*/
1113 /* nfreeRegsType - free registers with type                         */
1114 /*-----------------------------------------------------------------*/
1115 static int
1116 nfreeRegsType (int type)
1117 {
1118         int nfr;
1119         debugLog ("%s\n", __FUNCTION__);
1120         if (type == REG_PTR)
1121         {
1122                 if ((nfr = nFreeRegs (type)) == 0)
1123                         return nFreeRegs (REG_GPR);
1124         }
1125         
1126         return nFreeRegs (type);
1127 }
1128
1129 void writeSetUsedRegs(FILE *of, set *dRegs)
1130 {
1131         
1132         regs *dReg;
1133         
1134         for (dReg = setFirstItem(dRegs) ; dReg ; 
1135         dReg = setNextItem(dRegs)) {
1136                 
1137                 if(dReg->wasUsed)
1138                         fprintf (of, "\t%s\n",dReg->name);
1139         }
1140         
1141 }
1142 extern void assignFixedRegisters(set *regset);
1143 extern void assignRelocatableRegisters(set *regset,int used);
1144 extern void dump_map(void);
1145 extern void dump_sfr(FILE *of);
1146
1147 void packBits(set *bregs)
1148 {
1149         set *regset;
1150         regs *breg;
1151         regs *bitfield=NULL;
1152         regs *relocbitfield=NULL;
1153         int bit_no=0;
1154         int byte_no=-1;
1155         char buffer[20];
1156         
1157         
1158         for (regset = bregs ; regset ;
1159         regset = regset->next) {
1160                 
1161                 breg = regset->item;
1162                 breg->isBitField = 1;
1163                 //fprintf(stderr,"bit reg: %s\n",breg->name);
1164                 
1165                 if(breg->isFixed) {
1166                         //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1167                         
1168                         bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
1169                         breg->rIdx = breg->address & 7;
1170                         breg->address >>= 3;
1171                         
1172                         if(!bitfield) {
1173                                 //sprintf (buffer, "fbitfield%02x", breg->address);
1174                                 sprintf (buffer, "0x%02x", breg->address);
1175                                 //fprintf(stderr,"new bit field\n");
1176                                 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
1177                                 bitfield->isBitField = 1;
1178                                 bitfield->isFixed = 1;
1179                                 bitfield->address = breg->address;
1180                                 //addSet(&dynDirectRegs,bitfield);
1181                                 addSet(&dynInternalRegs,bitfield);
1182                                 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1183                         } else {
1184                                 //fprintf(stderr,"  which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1185                                 ;
1186                         }
1187                         breg->reg_alias = bitfield;
1188                         bitfield = NULL;
1189                         
1190                 } else {
1191                         if(!relocbitfield || bit_no >7) {
1192                                 byte_no++;
1193                                 bit_no=0;
1194                                 sprintf (buffer, "bitfield%d", byte_no);
1195                                 //fprintf(stderr,"new relocatable bit field\n");
1196                                 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
1197                                 relocbitfield->isBitField = 1;
1198                                 //addSet(&dynDirectRegs,relocbitfield);
1199                                 addSet(&dynInternalRegs,relocbitfield);
1200                                 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1201                                 
1202                         }
1203                         
1204                         breg->reg_alias = relocbitfield;
1205                         breg->address = rDirectIdx;   /* byte_no; */
1206                         breg->rIdx = bit_no++;
1207                 }
1208         }
1209         
1210 }
1211
1212
1213
1214 void bitEQUs(FILE *of, set *bregs)
1215 {
1216         regs *breg,*bytereg;
1217         int bit_no=0;
1218         
1219         //fprintf(stderr," %s\n",__FUNCTION__);
1220         for (breg = setFirstItem(bregs) ; breg ;
1221         breg = setNextItem(bregs)) {
1222                 
1223                 //fprintf(stderr,"bit reg: %s\n",breg->name);
1224                 
1225                 bytereg = breg->reg_alias;
1226                 if(bytereg)
1227                         fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1228                         breg->name,
1229                         bytereg->name,
1230                         breg->rIdx & 0x0007);
1231                 
1232                 else {
1233                         //fprintf(stderr, "bit field is not assigned to a register\n");
1234                         fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1235                                 breg->name,
1236                                 bit_no>>3,
1237                                 bit_no & 0x0007);
1238                         
1239                         bit_no++;
1240                 }
1241         }
1242         
1243 }
1244 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1245 {
1246         regs *reg;
1247         
1248         
1249         for (reg = setFirstItem(fregs) ; reg ;
1250         reg = setNextItem(fregs)) {
1251                 
1252                 //if(!reg->isEmitted && reg->wasUsed) {
1253                 if(reg->wasUsed) {
1254                         if(use_rIdx)
1255                                 fprintf (of, "%s\tEQU\t0x%03x\n",
1256                                 reg->name,
1257                                 reg->rIdx);
1258                         else
1259                                 fprintf (of, "%s\tEQU\t0x%03x\n",
1260                                 reg->name,
1261                                 reg->address);
1262                 }
1263         }
1264         
1265 }
1266
1267 void writeUsedRegs(FILE *of) 
1268 {
1269         packBits(dynDirectBitRegs);
1270         
1271         assignFixedRegisters(dynInternalRegs);
1272         assignFixedRegisters(dynAllocRegs);
1273         assignFixedRegisters(dynStackRegs);
1274         assignFixedRegisters(dynDirectRegs);
1275         
1276         assignRelocatableRegisters(dynInternalRegs,0);
1277         assignRelocatableRegisters(dynAllocRegs,0);
1278         assignRelocatableRegisters(dynStackRegs,0);
1279         
1280         /*
1281         assignRelocatableRegisters(dynDirectRegs,0);
1282         printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
1283         */
1284         //dump_map();
1285         
1286         dump_sfr(of);
1287         bitEQUs(of,dynDirectBitRegs);
1288         /*
1289         aliasEQUs(of,dynAllocRegs,0);
1290         aliasEQUs(of,dynDirectRegs,0);
1291         aliasEQUs(of,dynStackRegs,0);
1292         aliasEQUs(of,dynProcessorRegs,1);
1293         */
1294 }
1295
1296 #if 0
1297 /*-----------------------------------------------------------------*/
1298 /* allDefsOutOfRange - all definitions are out of a range          */
1299 /*-----------------------------------------------------------------*/
1300 static bool
1301 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1302 {
1303         int i;
1304         
1305         debugLog ("%s\n", __FUNCTION__);
1306         if (!defs)
1307                 return TRUE;
1308         
1309         for (i = 0; i < defs->size; i++)
1310         {
1311                 iCode *ic;
1312                 
1313                 if (bitVectBitValue (defs, i) &&
1314                         (ic = hTabItemWithKey (iCodehTab, i)) &&
1315                         (ic->seq >= fseq && ic->seq <= toseq))
1316                         
1317                         return FALSE;
1318                 
1319         }
1320         
1321         return TRUE;
1322 }
1323 #endif
1324
1325 /*-----------------------------------------------------------------*/
1326 /* computeSpillable - given a point find the spillable live ranges */
1327 /*-----------------------------------------------------------------*/
1328 static bitVect *
1329 computeSpillable (iCode * ic)
1330 {
1331         bitVect *spillable;
1332         
1333         debugLog ("%s\n", __FUNCTION__);
1334         /* spillable live ranges are those that are live at this 
1335         point . the following categories need to be subtracted
1336         from this set. 
1337         a) - those that are already spilt
1338         b) - if being used by this one
1339         c) - defined by this one */
1340         
1341         spillable = bitVectCopy (ic->rlive);
1342         spillable =
1343                 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1344         spillable =
1345                 bitVectCplAnd (spillable, ic->uses);    /* used in this one */
1346         bitVectUnSetBit (spillable, ic->defKey);
1347         spillable = bitVectIntersect (spillable, _G.regAssigned);
1348         return spillable;
1349         
1350 }
1351
1352 /*-----------------------------------------------------------------*/
1353 /* noSpilLoc - return true if a variable has no spil location      */
1354 /*-----------------------------------------------------------------*/
1355 static int
1356 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1357 {
1358         debugLog ("%s\n", __FUNCTION__);
1359         return (sym->usl.spillLoc ? 0 : 1);
1360 }
1361
1362 /*-----------------------------------------------------------------*/
1363 /* hasSpilLoc - will return 1 if the symbol has spil location      */
1364 /*-----------------------------------------------------------------*/
1365 static int
1366 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1367 {
1368         debugLog ("%s\n", __FUNCTION__);
1369         return (sym->usl.spillLoc ? 1 : 0);
1370 }
1371
1372 /*-----------------------------------------------------------------*/
1373 /* directSpilLoc - will return 1 if the splilocation is in direct  */
1374 /*-----------------------------------------------------------------*/
1375 static int
1376 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1377 {
1378         debugLog ("%s\n", __FUNCTION__);
1379         if (sym->usl.spillLoc &&
1380                 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1381                 return 1;
1382         else
1383                 return 0;
1384 }
1385
1386 /*-----------------------------------------------------------------*/
1387 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1388 /*                    but is not used as a pointer                 */
1389 /*-----------------------------------------------------------------*/
1390 static int
1391 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1392 {
1393         debugLog ("%s\n", __FUNCTION__);
1394         return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1395 }
1396
1397 /*-----------------------------------------------------------------*/
1398 /* rematable - will return 1 if the remat flag is set              */
1399 /*-----------------------------------------------------------------*/
1400 static int
1401 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1402 {
1403         debugLog ("%s\n", __FUNCTION__);
1404         return sym->remat;
1405 }
1406
1407 /*-----------------------------------------------------------------*/
1408 /* notUsedInRemaining - not used or defined in remain of the block */
1409 /*-----------------------------------------------------------------*/
1410 static int
1411 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1412 {
1413         debugLog ("%s\n", __FUNCTION__);
1414         return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1415                 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1416 }
1417
1418 /*-----------------------------------------------------------------*/
1419 /* allLRs - return true for all                                    */
1420 /*-----------------------------------------------------------------*/
1421 static int
1422 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1423 {
1424         debugLog ("%s\n", __FUNCTION__);
1425         return 1;
1426 }
1427
1428 /*-----------------------------------------------------------------*/
1429 /* liveRangesWith - applies function to a given set of live range  */
1430 /*-----------------------------------------------------------------*/
1431 static set *
1432 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1433                                 eBBlock * ebp, iCode * ic)
1434 {
1435         set *rset = NULL;
1436         int i;
1437         
1438         debugLog ("%s\n", __FUNCTION__);
1439         if (!lrs || !lrs->size)
1440                 return NULL;
1441         
1442         for (i = 1; i < lrs->size; i++)
1443         {
1444                 symbol *sym;
1445                 if (!bitVectBitValue (lrs, i))
1446                         continue;
1447                 
1448                 /* if we don't find it in the live range 
1449                 hash table we are in serious trouble */
1450                 if (!(sym = hTabItemWithKey (liveRanges, i)))
1451                 {
1452                         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1453                                 "liveRangesWith could not find liveRange");
1454                         exit (1);
1455                 }
1456                 
1457                 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1458                         addSetHead (&rset, sym);
1459         }
1460         
1461         return rset;
1462 }
1463
1464
1465 /*-----------------------------------------------------------------*/
1466 /* leastUsedLR - given a set determines which is the least used    */
1467 /*-----------------------------------------------------------------*/
1468 static symbol *
1469 leastUsedLR (set * sset)
1470 {
1471         symbol *sym = NULL, *lsym = NULL;
1472         
1473         debugLog ("%s\n", __FUNCTION__);
1474         sym = lsym = setFirstItem (sset);
1475         
1476         if (!lsym)
1477                 return NULL;
1478         
1479         for (; lsym; lsym = setNextItem (sset))
1480         {
1481                 
1482         /* if usage is the same then prefer
1483                 the spill the smaller of the two */
1484                 if (lsym->used == sym->used)
1485                         if (getSize (lsym->type) < getSize (sym->type))
1486                                 sym = lsym;
1487                         
1488                         /* if less usage */
1489                         if (lsym->used < sym->used)
1490                                 sym = lsym;
1491                         
1492         }
1493         
1494         setToNull ((void *) &sset);
1495         sym->blockSpil = 0;
1496         return sym;
1497 }
1498
1499 /*-----------------------------------------------------------------*/
1500 /* noOverLap - will iterate through the list looking for over lap  */
1501 /*-----------------------------------------------------------------*/
1502 static int
1503 noOverLap (set * itmpStack, symbol * fsym)
1504 {
1505         symbol *sym;
1506         debugLog ("%s\n", __FUNCTION__);
1507         
1508         
1509         for (sym = setFirstItem (itmpStack); sym;
1510         sym = setNextItem (itmpStack))
1511         {
1512                 if (sym->liveTo > fsym->liveFrom)
1513                         return 0;
1514                 
1515         }
1516         
1517         return 1;
1518 }
1519
1520 /*-----------------------------------------------------------------*/
1521 /* isFree - will return 1 if the a free spil location is found     */
1522 /*-----------------------------------------------------------------*/
1523 static
1524 DEFSETFUNC (isFree)
1525 {
1526         symbol *sym = item;
1527         V_ARG (symbol **, sloc);
1528         V_ARG (symbol *, fsym);
1529         
1530         debugLog ("%s\n", __FUNCTION__);
1531         /* if already found */
1532         if (*sloc)
1533                 return 0;
1534         
1535                 /* if it is free && and the itmp assigned to
1536                 this does not have any overlapping live ranges
1537                 with the one currently being assigned and
1538         the size can be accomodated  */
1539         if (sym->isFree &&
1540                 noOverLap (sym->usl.itmpStack, fsym) &&
1541                 getSize (sym->type) >= getSize (fsym->type))
1542         {
1543                 *sloc = sym;
1544                 return 1;
1545         }
1546         
1547         return 0;
1548 }
1549
1550 /*-----------------------------------------------------------------*/
1551 /* spillLRWithPtrReg :- will spil those live ranges which use PTR  */
1552 /*-----------------------------------------------------------------*/
1553 static void
1554 spillLRWithPtrReg (symbol * forSym)
1555 {
1556         symbol *lrsym;
1557         regs *r0, *r1;
1558         int k;
1559         
1560         debugLog ("%s\n", __FUNCTION__);
1561         if (!_G.regAssigned ||
1562                 bitVectIsZero (_G.regAssigned))
1563                 return;
1564         
1565         r0 = pic14_regWithIdx (R0_IDX);
1566         r1 = pic14_regWithIdx (R1_IDX);
1567         
1568         /* for all live ranges */
1569         for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1570         lrsym = hTabNextItem (liveRanges, &k))
1571         {
1572                 int j;
1573                 
1574                 /* if no registers assigned to it or
1575                 spilt */
1576                 /* if it does not overlap with this then 
1577                 not need to spill it */
1578                 
1579                 if (lrsym->isspilt || !lrsym->nRegs ||
1580                         (lrsym->liveTo < forSym->liveFrom))
1581                         continue;
1582                 
1583                         /* go thru the registers : if it is either
1584                 r0 or r1 then spil it */
1585                 for (j = 0; j < lrsym->nRegs; j++)
1586                         if (lrsym->regs[j] == r0 ||
1587                                 lrsym->regs[j] == r1)
1588                         {
1589                                 spillThis (lrsym);
1590                                 break;
1591                         }
1592         }
1593         
1594 }
1595
1596 /*-----------------------------------------------------------------*/
1597 /* createStackSpil - create a location on the stack to spil        */
1598 /*-----------------------------------------------------------------*/
1599 static symbol *
1600 createStackSpil (symbol * sym)
1601 {
1602         symbol *sloc = NULL;
1603         int useXstack, model, noOverlay;
1604         
1605         char slocBuffer[30];
1606         debugLog ("%s\n", __FUNCTION__);
1607         
1608         /* first go try and find a free one that is already 
1609         existing on the stack */
1610         if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1611         {
1612                 /* found a free one : just update & return */
1613                 sym->usl.spillLoc = sloc;
1614                 sym->stackSpil = 1;
1615                 sloc->isFree = 0;
1616                 addSetHead (&sloc->usl.itmpStack, sym);
1617                 return sym;
1618         }
1619         
1620         /* could not then have to create one , this is the hard part
1621         we need to allocate this on the stack : this is really a
1622         hack!! but cannot think of anything better at this time */
1623         
1624         if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1625         {
1626                 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1627                         __FILE__, __LINE__);
1628                 exit (1);
1629         }
1630         
1631         sloc = newiTemp (slocBuffer);
1632         
1633         /* set the type to the spilling symbol */
1634         sloc->type = copyLinkChain (sym->type);
1635         sloc->etype = getSpec (sloc->type);
1636         SPEC_SCLS (sloc->etype) = S_DATA;
1637         SPEC_EXTR (sloc->etype) = 0;
1638         SPEC_STAT (sloc->etype) = 0;
1639         
1640         /* we don't allow it to be allocated`
1641         onto the external stack since : so we
1642         temporarily turn it off ; we also
1643         turn off memory model to prevent
1644         the spil from going to the external storage
1645         and turn off overlaying 
1646         */
1647         
1648         useXstack = options.useXstack;
1649         model = options.model;
1650         noOverlay = options.noOverlay;
1651         options.noOverlay = 1;
1652         options.model = options.useXstack = 0;
1653         
1654         allocLocal (sloc);
1655         
1656         options.useXstack = useXstack;
1657         options.model = model;
1658         options.noOverlay = noOverlay;
1659         sloc->isref = 1;                /* to prevent compiler warning */
1660         
1661         /* if it is on the stack then update the stack */
1662         if (IN_STACK (sloc->etype))
1663         {
1664                 currFunc->stack += getSize (sloc->type);
1665                 _G.stackExtend += getSize (sloc->type);
1666         }
1667         else
1668                 _G.dataExtend += getSize (sloc->type);
1669         
1670         /* add it to the _G.stackSpil set */
1671         addSetHead (&_G.stackSpil, sloc);
1672         sym->usl.spillLoc = sloc;
1673         sym->stackSpil = 1;
1674         
1675         /* add it to the set of itempStack set 
1676         of the spill location */
1677         addSetHead (&sloc->usl.itmpStack, sym);
1678         return sym;
1679 }
1680
1681 /*-----------------------------------------------------------------*/
1682 /* isSpiltOnStack - returns true if the spil location is on stack  */
1683 /*-----------------------------------------------------------------*/
1684 static bool
1685 isSpiltOnStack (symbol * sym)
1686 {
1687         sym_link *etype;
1688         
1689         debugLog ("%s\n", __FUNCTION__);
1690         if (!sym)
1691                 return FALSE;
1692         
1693         if (!sym->isspilt)
1694                 return FALSE;
1695         
1696         /*     if (sym->_G.stackSpil) */
1697         /*      return TRUE; */
1698         
1699         if (!sym->usl.spillLoc)
1700                 return FALSE;
1701         
1702         etype = getSpec (sym->usl.spillLoc->type);
1703         if (IN_STACK (etype))
1704                 return TRUE;
1705         
1706         return FALSE;
1707 }
1708
1709 /*-----------------------------------------------------------------*/
1710 /* spillThis - spils a specific operand                            */
1711 /*-----------------------------------------------------------------*/
1712 static void
1713 spillThis (symbol * sym)
1714 {
1715         int i;
1716         debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1717         
1718         /* if this is rematerializable or has a spillLocation
1719         we are okay, else we need to create a spillLocation
1720         for it */
1721         if (!(sym->remat || sym->usl.spillLoc))
1722                 createStackSpil (sym);
1723         
1724         
1725         /* mark it has spilt & put it in the spilt set */
1726         sym->isspilt = 1;
1727         _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1728         
1729         bitVectUnSetBit (_G.regAssigned, sym->key);
1730         
1731         for (i = 0; i < sym->nRegs; i++)
1732                 
1733                 if (sym->regs[i])
1734                 {
1735                         freeReg (sym->regs[i]);
1736                         sym->regs[i] = NULL;
1737                 }
1738                 
1739                 /* if spilt on stack then free up r0 & r1 
1740                 if they could have been assigned to some
1741                 LIVE ranges */
1742                 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1743                 {
1744                         pic14_ptrRegReq++;
1745                         spillLRWithPtrReg (sym);
1746                 }
1747                 
1748                 if (sym->usl.spillLoc && !sym->remat)
1749                         sym->usl.spillLoc->allocreq = 1;
1750                 return;
1751 }
1752
1753 /*-----------------------------------------------------------------*/
1754 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1755 /*-----------------------------------------------------------------*/
1756 static symbol *
1757 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1758 {
1759         bitVect *lrcs = NULL;
1760         set *selectS;
1761         symbol *sym;
1762         
1763         debugLog ("%s\n", __FUNCTION__);
1764         /* get the spillable live ranges */
1765         lrcs = computeSpillable (ic);
1766         
1767         /* get all live ranges that are rematerizable */
1768         if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1769         {
1770                 
1771                 /* return the least used of these */
1772                 return leastUsedLR (selectS);
1773         }
1774         
1775         /* get live ranges with spillLocations in direct space */
1776         if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1777         {
1778                 sym = leastUsedLR (selectS);
1779                 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1780                         sym->usl.spillLoc->rname :
1781                 sym->usl.spillLoc->name));
1782                 sym->spildir = 1;
1783                 /* mark it as allocation required */
1784                 sym->usl.spillLoc->allocreq = 1;
1785                 return sym;
1786         }
1787         
1788         /* if the symbol is local to the block then */
1789         if (forSym->liveTo < ebp->lSeq)
1790         {
1791                 
1792         /* check if there are any live ranges allocated
1793                 to registers that are not used in this block */
1794                 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1795                 {
1796                         sym = leastUsedLR (selectS);
1797                         /* if this is not rematerializable */
1798                         if (!sym->remat)
1799                         {
1800                                 _G.blockSpil++;
1801                                 sym->blockSpil = 1;
1802                         }
1803                         return sym;
1804                 }
1805                 
1806                 /* check if there are any live ranges that not
1807                 used in the remainder of the block */
1808                 if (!_G.blockSpil &&
1809                     !isiCodeInFunctionCall (ic) &&
1810                     (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1811                 {
1812                         sym = leastUsedLR (selectS);
1813                         if (!sym->remat)
1814                         {
1815                                 sym->remainSpil = 1;
1816                                 _G.blockSpil++;
1817                         }
1818                         return sym;
1819                 }
1820         }
1821         
1822         /* find live ranges with spillocation && not used as pointers */
1823         if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1824         {
1825                 
1826                 sym = leastUsedLR (selectS);
1827                 /* mark this as allocation required */
1828                 sym->usl.spillLoc->allocreq = 1;
1829                 return sym;
1830         }
1831         
1832         /* find live ranges with spillocation */
1833         if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1834         {
1835                 
1836                 sym = leastUsedLR (selectS);
1837                 sym->usl.spillLoc->allocreq = 1;
1838                 return sym;
1839         }
1840         
1841         /* couldn't find then we need to create a spil
1842         location on the stack , for which one? the least
1843         used ofcourse */
1844         if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1845         {
1846                 
1847                 /* return a created spil location */
1848                 sym = createStackSpil (leastUsedLR (selectS));
1849                 sym->usl.spillLoc->allocreq = 1;
1850                 return sym;
1851         }
1852         
1853         /* this is an extreme situation we will spill
1854         this one : happens very rarely but it does happen */
1855         spillThis (forSym);
1856         return forSym;
1857         
1858 }
1859
1860 /*-----------------------------------------------------------------*/
1861 /* spilSomething - spil some variable & mark registers as free     */
1862 /*-----------------------------------------------------------------*/
1863 static bool
1864 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1865 {
1866         symbol *ssym;
1867         int i;
1868         
1869         debugLog ("%s\n", __FUNCTION__);
1870         /* get something we can spil */
1871         ssym = selectSpil (ic, ebp, forSym);
1872         
1873         /* mark it as spilt */
1874         ssym->isspilt = 1;
1875         _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1876         
1877         /* mark it as not register assigned &
1878         take it away from the set */
1879         bitVectUnSetBit (_G.regAssigned, ssym->key);
1880         
1881         /* mark the registers as free */
1882         for (i = 0; i < ssym->nRegs; i++)
1883                 if (ssym->regs[i])
1884                         freeReg (ssym->regs[i]);
1885                 
1886                 /* if spilt on stack then free up r0 & r1 
1887                 if they could have been assigned to as gprs */
1888                 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1889                 {
1890                         pic14_ptrRegReq++;
1891                         spillLRWithPtrReg (ssym);
1892                 }
1893                 
1894                 /* if this was a block level spil then insert push & pop 
1895                 at the start & end of block respectively */
1896                 if (ssym->blockSpil)
1897                 {
1898                         iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1899                         /* add push to the start of the block */
1900                         addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1901                                 ebp->sch->next : ebp->sch));
1902                         nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1903                         /* add pop to the end of the block */
1904                         addiCodeToeBBlock (ebp, nic, NULL);
1905                 }
1906                 
1907                 /* if spilt because not used in the remainder of the
1908                 block then add a push before this instruction and
1909                 a pop at the end of the block */
1910                 if (ssym->remainSpil)
1911                 {
1912                         
1913                         iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1914                         /* add push just before this instruction */
1915                         addiCodeToeBBlock (ebp, nic, ic);
1916                         
1917                         nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1918                         /* add pop to the end of the block */
1919                         addiCodeToeBBlock (ebp, nic, NULL);
1920                 }
1921                 
1922                 if (ssym == forSym)
1923                         return FALSE;
1924                 else
1925                         return TRUE;
1926 }
1927
1928 /*-----------------------------------------------------------------*/
1929 /* getRegPtr - will try for PTR if not a GPR type if not spil      */
1930 /*-----------------------------------------------------------------*/
1931 static regs *
1932 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1933 {
1934         regs *reg;
1935         int j;
1936         
1937         debugLog ("%s\n", __FUNCTION__);
1938 tryAgain:
1939         /* try for a ptr type */
1940         if ((reg = allocReg (REG_PTR)))
1941                 return reg;
1942         
1943         /* try for gpr type */
1944         if ((reg = allocReg (REG_GPR)))
1945                 return reg;
1946         
1947         /* we have to spil */
1948         if (!spilSomething (ic, ebp, sym))
1949                 return NULL;
1950         
1951         /* make sure partially assigned registers aren't reused */
1952         for (j=0; j<=sym->nRegs; j++)
1953                 if (sym->regs[j])
1954                         sym->regs[j]->isFree = 0;
1955                 
1956                         /* this looks like an infinite loop but 
1957                 in really selectSpil will abort  */
1958                 goto tryAgain;
1959 }
1960
1961 /*-----------------------------------------------------------------*/
1962 /* getRegGpr - will try for GPR if not spil                        */
1963 /*-----------------------------------------------------------------*/
1964 static regs *
1965 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1966 {
1967         regs *reg;
1968         int j;
1969         
1970         debugLog ("%s\n", __FUNCTION__);
1971 tryAgain:
1972         /* try for gpr type */
1973         if ((reg = allocReg (REG_GPR)))
1974                 return reg;
1975         
1976         if (!pic14_ptrRegReq)
1977                 if ((reg = allocReg (REG_PTR)))
1978                         return reg;
1979                 
1980                 /* we have to spil */
1981                 if (!spilSomething (ic, ebp, sym))
1982                         return NULL;
1983                 
1984                 /* make sure partially assigned registers aren't reused */
1985                 for (j=0; j<=sym->nRegs; j++)
1986                         if (sym->regs[j])
1987                                 sym->regs[j]->isFree = 0;
1988                         
1989                                 /* this looks like an infinite loop but 
1990                         in really selectSpil will abort  */
1991                         goto tryAgain;
1992 }
1993
1994 /*-----------------------------------------------------------------*/
1995 /* symHasReg - symbol has a given register                         */
1996 /*-----------------------------------------------------------------*/
1997 static bool
1998 symHasReg (symbol * sym, regs * reg)
1999 {
2000         int i;
2001         
2002         debugLog ("%s\n", __FUNCTION__);
2003         for (i = 0; i < sym->nRegs; i++)
2004                 if (sym->regs[i] == reg)
2005                         return TRUE;
2006                 
2007                 return FALSE;
2008 }
2009
2010 /*-----------------------------------------------------------------*/
2011 /* deassignLRs - check the live to and if they have registers & are */
2012 /*               not spilt then free up the registers              */
2013 /*-----------------------------------------------------------------*/
2014 static void
2015 deassignLRs (iCode * ic, eBBlock * ebp)
2016 {
2017         symbol *sym;
2018         int k;
2019         symbol *result;
2020         
2021         debugLog ("%s\n", __FUNCTION__);
2022         for (sym = hTabFirstItem (liveRanges, &k); sym;
2023         sym = hTabNextItem (liveRanges, &k))
2024         {
2025                 
2026                 symbol *psym = NULL;
2027                 /* if it does not end here */
2028                 if (sym->liveTo > ic->seq)
2029                         continue;
2030                 
2031                 /* if it was spilt on stack then we can 
2032                 mark the stack spil location as free */
2033                 if (sym->isspilt)
2034                 {
2035                         if (sym->stackSpil)
2036                         {
2037                                 sym->usl.spillLoc->isFree = 1;
2038                                 sym->stackSpil = 0;
2039                         }
2040                         continue;
2041                 }
2042                 
2043                 if (!bitVectBitValue (_G.regAssigned, sym->key))
2044                         continue;
2045                 
2046                 /* special case check if this is an IFX &
2047                 the privious one was a pop and the 
2048                 previous one was not spilt then keep track
2049                 of the symbol */
2050                 if (ic->op == IFX && ic->prev &&
2051                         ic->prev->op == IPOP &&
2052                         !ic->prev->parmPush &&
2053                         !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2054                         psym = OP_SYMBOL (IC_LEFT (ic->prev));
2055                 
2056                 if (sym->nRegs)
2057                 {
2058                         int i = 0;
2059                         
2060                         bitVectUnSetBit (_G.regAssigned, sym->key);
2061                         
2062                         /* if the result of this one needs registers
2063                         and does not have it then assign it right
2064                         away */
2065                         if (IC_RESULT (ic) &&
2066                                 !(SKIP_IC2 (ic) ||      /* not a special icode */
2067                                 ic->op == JUMPTABLE ||
2068                                 ic->op == IFX ||
2069                                 ic->op == IPUSH ||
2070                                 ic->op == IPOP ||
2071                                 ic->op == RETURN ||
2072                                 POINTER_SET (ic)) &&
2073                                 (result = OP_SYMBOL (IC_RESULT (ic))) &&        /* has a result */
2074                                 result->liveTo > ic->seq &&     /* and will live beyond this */
2075                                 result->liveTo <= ebp->lSeq &&  /* does not go beyond this block */
2076                                 result->liveFrom == ic->seq &&    /* does not start before here */
2077                                 result->regType == sym->regType &&      /* same register types */
2078                                 result->regType == sym->regType &&      /* same register types */
2079                                 result->nRegs &&        /* which needs registers */
2080                                 !result->isspilt &&     /* and does not already have them */
2081                                 !result->remat &&
2082                                 !bitVectBitValue (_G.regAssigned, result->key) &&
2083                                 /* the number of free regs + number of regs in this LR
2084                                 can accomodate the what result Needs */
2085                                 ((nfreeRegsType (result->regType) +
2086                                 sym->nRegs) >= result->nRegs)
2087                                 )
2088                         {
2089                                 
2090                                 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2091                                         if (i < sym->nRegs)
2092                                                 result->regs[i] = sym->regs[i];
2093                                         else
2094                                                 result->regs[i] = getRegGpr (ic, ebp, result);
2095                                         
2096                                         _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2097                                         
2098                         }
2099                         
2100                         /* free the remaining */
2101                         for (; i < sym->nRegs; i++)
2102                         {
2103                                 if (psym)
2104                                 {
2105                                         if (!symHasReg (psym, sym->regs[i]))
2106                                                 freeReg (sym->regs[i]);
2107                                 }
2108                                 else
2109                                         freeReg (sym->regs[i]);
2110                         }
2111                 }
2112         }
2113 }
2114
2115
2116 /*-----------------------------------------------------------------*/
2117 /* reassignLR - reassign this to registers                         */
2118 /*-----------------------------------------------------------------*/
2119 static void
2120 reassignLR (operand * op)
2121 {
2122         symbol *sym = OP_SYMBOL (op);
2123         int i;
2124         
2125         debugLog ("%s\n", __FUNCTION__);
2126         /* not spilt any more */
2127         sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2128         bitVectUnSetBit (_G.spiltSet, sym->key);
2129         
2130         _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2131         
2132         _G.blockSpil--;
2133         
2134         for (i = 0; i < sym->nRegs; i++)
2135                 sym->regs[i]->isFree = 0;
2136 }
2137
2138 /*-----------------------------------------------------------------*/
2139 /* willCauseSpill - determines if allocating will cause a spill    */
2140 /*-----------------------------------------------------------------*/
2141 static int
2142 willCauseSpill (int nr, int rt)
2143 {
2144         debugLog ("%s\n", __FUNCTION__);
2145         /* first check if there are any avlb registers
2146         of te type required */
2147         if (rt == REG_PTR)
2148         {
2149         /* special case for pointer type 
2150         if pointer type not avlb then 
2151                 check for type gpr */
2152                 if (nFreeRegs (rt) >= nr)
2153                         return 0;
2154                 if (nFreeRegs (REG_GPR) >= nr)
2155                         return 0;
2156         }
2157         else
2158         {
2159                 if (pic14_ptrRegReq)
2160                 {
2161                         if (nFreeRegs (rt) >= nr)
2162                                 return 0;
2163                 }
2164                 else
2165                 {
2166                         if (nFreeRegs (REG_PTR) +
2167                                 nFreeRegs (REG_GPR) >= nr)
2168                                 return 0;
2169                 }
2170         }
2171         
2172         debugLog (" ... yep it will (cause a spill)\n");
2173         /* it will cause a spil */
2174         return 1;
2175 }
2176
2177 /*-----------------------------------------------------------------*/
2178 /* positionRegs - the allocator can allocate same registers to res- */
2179 /* ult and operand, if this happens make sure they are in the same */
2180 /* position as the operand otherwise chaos results                 */
2181 /*-----------------------------------------------------------------*/
2182 static void
2183 positionRegs (symbol * result, symbol * opsym, int lineno)
2184 {
2185         int count = min (result->nRegs, opsym->nRegs);
2186         int i, j = 0, shared = 0;
2187         
2188         debugLog ("%s\n", __FUNCTION__);
2189         /* if the result has been spilt then cannot share */
2190         if (opsym->isspilt)
2191                 return;
2192 again:
2193         shared = 0;
2194         /* first make sure that they actually share */
2195         for (i = 0; i < count; i++)
2196         {
2197                 for (j = 0; j < count; j++)
2198                 {
2199                         if (result->regs[i] == opsym->regs[j] && i != j)
2200                         {
2201                                 shared = 1;
2202                                 goto xchgPositions;
2203                         }
2204                 }
2205         }
2206 xchgPositions:
2207         if (shared)
2208         {
2209                 regs *tmp = result->regs[i];
2210                 result->regs[i] = result->regs[j];
2211                 result->regs[j] = tmp;
2212                 goto again;
2213         }
2214 }
2215
2216 /*------------------------------------------------------------------*/
2217 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2218 /* it should either have registers or have beed spilled. Otherwise, */
2219 /* there was an uninitialized variable, so just spill this to get   */
2220 /* the operand in a valid state.                                    */
2221 /*------------------------------------------------------------------*/
2222 static void
2223 verifyRegsAssigned (operand *op, iCode * ic)
2224 {
2225   symbol * sym;
2226   
2227   if (!op) return;
2228   if (!IS_ITEMP (op)) return;
2229   
2230   sym = OP_SYMBOL (op);
2231   if (sym->isspilt) return;
2232   if (!sym->nRegs) return;
2233   if (sym->regs[0]) return;
2234   
2235   werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT, 
2236             sym->prereqv ? sym->prereqv->name : sym->name);
2237   spillThis (sym);
2238 }
2239
2240
2241 /*-----------------------------------------------------------------*/
2242 /* serialRegAssign - serially allocate registers to the variables  */
2243 /*-----------------------------------------------------------------*/
2244 static void
2245 serialRegAssign (eBBlock ** ebbs, int count)
2246 {
2247         int i;
2248         
2249         debugLog ("%s\n", __FUNCTION__);
2250         /* for all blocks */
2251         for (i = 0; i < count; i++)
2252         {
2253                 
2254                 iCode *ic;
2255                 
2256                 if (ebbs[i]->noPath &&
2257                         (ebbs[i]->entryLabel != entryLabel &&
2258                         ebbs[i]->entryLabel != returnLabel))
2259                         continue;
2260                 
2261                 /* of all instructions do */
2262                 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2263                 {
2264                         
2265                         debugLog ("  op: %s\n", decodeOp (ic->op));
2266                         
2267                         /* if this is an ipop that means some live
2268                         range will have to be assigned again */
2269                         if (ic->op == IPOP)
2270                                 reassignLR (IC_LEFT (ic));
2271                         
2272                         /* if result is present && is a true symbol */
2273                         if (IC_RESULT (ic) && ic->op != IFX &&
2274                                 IS_TRUE_SYMOP (IC_RESULT (ic)))
2275                                 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2276                         
2277                         /* take away registers from live
2278                         ranges that end at this instruction */
2279                         deassignLRs (ic, ebbs[i]);
2280                         
2281                         /* some don't need registers */
2282                         if (SKIP_IC2 (ic) ||
2283                                 ic->op == JUMPTABLE ||
2284                                 ic->op == IFX ||
2285                                 ic->op == IPUSH ||
2286                                 ic->op == IPOP ||
2287                                 (IC_RESULT (ic) && POINTER_SET (ic)))
2288                                 continue;
2289                         
2290                         /* now we need to allocate registers
2291                         only for the result */
2292                         if (IC_RESULT (ic))
2293                         {
2294                                 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2295                                 bitVect *spillable;
2296                                 int willCS;
2297                                 int j;
2298                                 int ptrRegSet = 0;
2299
2300                                 /* Make sure any spill location is definately allocated */
2301                                 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2302                                     !sym->usl.spillLoc->allocreq)
2303                                 {
2304                                         sym->usl.spillLoc->allocreq++;
2305                                 }
2306
2307                                 /* if it does not need or is spilt 
2308                                 or is already assigned to registers
2309                                 or will not live beyond this instructions */
2310                                 if (!sym->nRegs ||
2311                                         sym->isspilt ||
2312                                         bitVectBitValue (_G.regAssigned, sym->key) ||
2313                                         sym->liveTo <= ic->seq)
2314                                         continue;
2315                                 
2316                                 /* if some liverange has been spilt at the block level
2317                                 and this one live beyond this block then spil this
2318                                 to be safe */
2319                                 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2320                                 {
2321                                         spillThis (sym);
2322                                         continue;
2323                                 }
2324                                 /* if trying to allocate this will cause
2325                                 a spill and there is nothing to spill 
2326                                 or this one is rematerializable then
2327                                 spill this one */
2328                                 willCS = willCauseSpill (sym->nRegs, sym->regType);
2329                                 spillable = computeSpillable (ic);
2330                                 if (sym->remat ||
2331                                         (willCS && bitVectIsZero (spillable)))
2332                                 {
2333                                         
2334                                         spillThis (sym);
2335                                         continue;
2336                                         
2337                                 }
2338
2339                                 /* If the live range preceeds the point of definition 
2340                                    then ideally we must take into account registers that 
2341                                    have been allocated after sym->liveFrom but freed
2342                                    before ic->seq. This is complicated, so spill this
2343                                    symbol instead and let fillGaps handle the allocation. */
2344                                 if (sym->liveFrom < ic->seq)
2345                                 {
2346                                         spillThis (sym);
2347                                         continue;                     
2348                                 }
2349                                 
2350                                 /* if it has a spillocation & is used less than
2351                                 all other live ranges then spill this */
2352                                 if (willCS) {
2353                                         if (sym->usl.spillLoc) {
2354                                                 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2355                                                         allLRs, ebbs[i], ic));
2356                                                 if (leastUsed && leastUsed->used > sym->used) {
2357                                                         spillThis (sym);
2358                                                         continue;
2359                                                 }
2360                                         } else {
2361                                                 /* if none of the liveRanges have a spillLocation then better
2362                                                 to spill this one than anything else already assigned to registers */
2363                                                 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2364                                                         /* if this is local to this block then we might find a block spil */
2365                                                         if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2366                                                                 spillThis (sym);
2367                                                                 continue;
2368                                                         }
2369                                                 }
2370                                         }
2371                                 }
2372                                 
2373                                 if (ic->op == RECEIVE)
2374                                         debugLog ("When I get clever, I'll optimize the receive logic\n");
2375                                 
2376                                 /* if we need ptr regs for the right side
2377                                 then mark it */
2378                                 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2379                                         <= (unsigned) PTRSIZE)
2380                                 {
2381                                         pic14_ptrRegReq++;
2382                                         ptrRegSet = 1;
2383                                 }
2384                                 /* else we assign registers to it */
2385                                 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2386                                 
2387                                 debugLog ("  %d - \n", __LINE__);
2388                                 if(debugF) 
2389                                         bitVectDebugOn(_G.regAssigned, debugF);
2390                                 for (j = 0; j < sym->nRegs; j++)
2391                                 {
2392                                         if (sym->regType == REG_PTR)
2393                                                 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2394                                         else
2395                                                 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2396                                         
2397                                         /* if the allocation failed which means
2398                                         this was spilt then break */
2399                                         if (!sym->regs[j])
2400                                                 break;
2401                                 }
2402                                 debugLog ("  %d - \n", __LINE__);
2403                                 
2404                                 /* if it shares registers with operands make sure
2405                                 that they are in the same position */
2406                                 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2407                                         OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2408                                         positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2409                                         OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2410                                 /* do the same for the right operand */
2411                                 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2412                                         OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2413                                         positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2414                                         OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2415                                 
2416                                 debugLog ("  %d - \n", __LINE__);
2417                                 if (ptrRegSet)
2418                                 {
2419                                         debugLog ("  %d - \n", __LINE__);
2420                                         pic14_ptrRegReq--;
2421                                         ptrRegSet = 0;
2422                                 }
2423                                 
2424                         }
2425                 }
2426         }
2427
2428     /* Check for and fix any problems with uninitialized operands */
2429     for (i = 0; i < count; i++)
2430         {
2431                 iCode *ic;
2432
2433                 if (ebbs[i]->noPath &&
2434                         (ebbs[i]->entryLabel != entryLabel &&
2435                          ebbs[i]->entryLabel != returnLabel))
2436                         continue;
2437
2438                 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2439                 {
2440                         if (SKIP_IC2 (ic))
2441                           continue;
2442
2443                         if (ic->op == IFX)
2444                         {
2445                                 verifyRegsAssigned (IC_COND (ic), ic);
2446                                 continue;
2447                         }
2448
2449                         if (ic->op == JUMPTABLE)
2450                         {
2451                                 verifyRegsAssigned (IC_JTCOND (ic), ic);
2452                                 continue;
2453                         }
2454
2455                         verifyRegsAssigned (IC_RESULT (ic), ic);
2456                         verifyRegsAssigned (IC_LEFT (ic), ic);
2457                         verifyRegsAssigned (IC_RIGHT (ic), ic);
2458                 }
2459         }
2460
2461 }
2462
2463 /*-----------------------------------------------------------------*/
2464 /* rUmaskForOp :- returns register mask for an operand             */
2465 /*-----------------------------------------------------------------*/
2466 static bitVect *
2467 rUmaskForOp (operand * op)
2468 {
2469         bitVect *rumask;
2470         symbol *sym;
2471         int j;
2472         
2473         debugLog ("%s\n", __FUNCTION__);
2474         /* only temporaries are assigned registers */
2475         if (!IS_ITEMP (op))
2476                 return NULL;
2477         
2478         sym = OP_SYMBOL (op);
2479         
2480         /* if spilt or no registers assigned to it
2481         then nothing */
2482         if (sym->isspilt || !sym->nRegs)
2483                 return NULL;
2484         
2485         rumask = newBitVect (pic14_nRegs);
2486         
2487         for (j = 0; j < sym->nRegs; j++)
2488         {
2489                 rumask = bitVectSetBit (rumask,
2490                         sym->regs[j]->rIdx);
2491         }
2492         
2493         return rumask;
2494 }
2495
2496 /*-----------------------------------------------------------------*/
2497 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2498 /*-----------------------------------------------------------------*/
2499 static bitVect *
2500 regsUsedIniCode (iCode * ic)
2501 {
2502         bitVect *rmask = newBitVect (pic14_nRegs);
2503         
2504         debugLog ("%s\n", __FUNCTION__);
2505         /* do the special cases first */
2506         if (ic->op == IFX)
2507         {
2508                 rmask = bitVectUnion (rmask,
2509                         rUmaskForOp (IC_COND (ic)));
2510                 goto ret;
2511         }
2512         
2513         /* for the jumptable */
2514         if (ic->op == JUMPTABLE)
2515         {
2516                 rmask = bitVectUnion (rmask,
2517                         rUmaskForOp (IC_JTCOND (ic)));
2518                 
2519                 goto ret;
2520         }
2521         
2522         /* of all other cases */
2523         if (IC_LEFT (ic))
2524                 rmask = bitVectUnion (rmask,
2525                 rUmaskForOp (IC_LEFT (ic)));
2526         
2527         
2528         if (IC_RIGHT (ic))
2529                 rmask = bitVectUnion (rmask,
2530                 rUmaskForOp (IC_RIGHT (ic)));
2531         
2532         if (IC_RESULT (ic))
2533                 rmask = bitVectUnion (rmask,
2534                 rUmaskForOp (IC_RESULT (ic)));
2535         
2536 ret:
2537         return rmask;
2538 }
2539
2540 /*-----------------------------------------------------------------*/
2541 /* createRegMask - for each instruction will determine the regsUsed */
2542 /*-----------------------------------------------------------------*/
2543 static void
2544 createRegMask (eBBlock ** ebbs, int count)
2545 {
2546         int i;
2547         
2548         debugLog ("%s\n", __FUNCTION__);
2549         /* for all blocks */
2550         for (i = 0; i < count; i++)
2551         {
2552                 iCode *ic;
2553                 
2554                 if (ebbs[i]->noPath &&
2555                         (ebbs[i]->entryLabel != entryLabel &&
2556                         ebbs[i]->entryLabel != returnLabel))
2557                         continue;
2558                 
2559                 /* for all instructions */
2560                 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2561                 {
2562                         
2563                         int j;
2564                         
2565                         if (SKIP_IC2 (ic) || !ic->rlive)
2566                                 continue;
2567                         
2568                                 /* first mark the registers used in this
2569                         instruction */
2570                         ic->rUsed = regsUsedIniCode (ic);
2571                         _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2572                         
2573                         /* now create the register mask for those 
2574                         registers that are in use : this is a
2575                         super set of ic->rUsed */
2576                         ic->rMask = newBitVect (pic14_nRegs + 1);
2577                         
2578                         /* for all live Ranges alive at this point */
2579                         for (j = 1; j < ic->rlive->size; j++)
2580                         {
2581                                 symbol *sym;
2582                                 int k;
2583                                 
2584                                 /* if not alive then continue */
2585                                 if (!bitVectBitValue (ic->rlive, j))
2586                                         continue;
2587                                 
2588                                 /* find the live range we are interested in */
2589                                 if (!(sym = hTabItemWithKey (liveRanges, j)))
2590                                 {
2591                                         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2592                                                 "createRegMask cannot find live range");
2593                                         exit (0);
2594                                 }
2595                                 
2596                                 /* if no register assigned to it */
2597                                 if (!sym->nRegs || sym->isspilt)
2598                                         continue;
2599                                 
2600                                 /* for all the registers allocated to it */
2601                                 for (k = 0; k < sym->nRegs; k++)
2602                                         if (sym->regs[k])
2603                                                 ic->rMask =
2604                                                 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2605                         }
2606                 }
2607         }
2608 }
2609
2610 /*-----------------------------------------------------------------*/
2611 /* rematStr - returns the rematerialized string for a remat var    */
2612 /*-----------------------------------------------------------------*/
2613 static symbol *
2614 rematStr (symbol * sym)
2615 {
2616         char *s = buffer;
2617         iCode *ic = sym->rematiCode;
2618         symbol *psym = NULL;
2619         
2620         debugLog ("%s\n", __FUNCTION__);
2621         
2622         //printf ("%s\n", s);
2623         
2624         /* if plus or minus print the right hand side */
2625         
2626         if (ic->op == '+' || ic->op == '-') {
2627                 
2628                 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2629                 
2630                 sprintf (s, "(%s %c 0x%04x)",
2631                         OP_SYMBOL (IC_LEFT (ric))->rname,
2632                         ic->op,
2633                         (int) operandLitValue (IC_RIGHT (ic)));
2634                 
2635                 
2636                 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2637                 
2638                 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2639                 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2640                 
2641                 return psym;
2642         }
2643         
2644         sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2645         psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2646         
2647         //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2648         return psym;
2649 }
2650
2651 #if 0
2652 /*-----------------------------------------------------------------*/
2653 /* rematStr - returns the rematerialized string for a remat var    */
2654 /*-----------------------------------------------------------------*/
2655 static char *
2656 rematStr (symbol * sym)
2657 {
2658         char *s = buffer;
2659         iCode *ic = sym->rematiCode;
2660         
2661         debugLog ("%s\n", __FUNCTION__);
2662         while (1)
2663         {
2664                 
2665                 printf ("%s\n", s);
2666                 /* if plus or minus print the right hand side */
2667                 /*
2668                 if (ic->op == '+' || ic->op == '-') {
2669                 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2670                 ic->op );
2671                 s += strlen(s);
2672                 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2673                 continue ;
2674                 }
2675                 */
2676                 if (ic->op == '+' || ic->op == '-')
2677                 {
2678                         iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2679                         sprintf (s, "(%s %c 0x%04x)",
2680                                 OP_SYMBOL (IC_LEFT (ric))->rname,
2681                                 ic->op,
2682                                 (int) operandLitValue (IC_RIGHT (ic)));
2683                         
2684                         //s += strlen(s);
2685                         //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2686                         //continue ;
2687                         //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2688                         return buffer;
2689                 }
2690                 
2691                 /* we reached the end */
2692                 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2693                 break;
2694         }
2695         
2696         printf ("%s\n", buffer);
2697         return buffer;
2698 }
2699 #endif
2700
2701 /*-----------------------------------------------------------------*/
2702 /* regTypeNum - computes the type & number of registers required   */
2703 /*-----------------------------------------------------------------*/
2704 static void
2705 regTypeNum ()
2706 {
2707         symbol *sym;
2708         int k;
2709         iCode *ic;
2710         
2711         debugLog ("%s\n", __FUNCTION__);
2712         /* for each live range do */
2713         for (sym = hTabFirstItem (liveRanges, &k); sym;
2714         sym = hTabNextItem (liveRanges, &k)) {
2715
2716                 debugLog ("  %d - %s\n", __LINE__, sym->rname);
2717                 
2718                 /* if used zero times then no registers needed */
2719                 if ((sym->liveTo - sym->liveFrom) == 0)
2720                         continue;
2721
2722
2723                 /* if the live range is a temporary */
2724                 if (sym->isitmp) {
2725                         
2726                         debugLog ("  %d - itemp register\n", __LINE__);
2727                         
2728                         /* if the type is marked as a conditional */
2729                         if (sym->regType == REG_CND)
2730                                 continue;
2731                         
2732                         /* if used in return only then we don't 
2733                         need registers */
2734                         if (sym->accuse) {
2735                                 if (IS_AGGREGATE (sym->type) || sym->isptr)
2736                                         sym->type = aggrToPtr (sym->type, FALSE);
2737                                 debugLog ("  %d - no reg needed - accumulator used\n", __LINE__);
2738                                 
2739                                 continue;
2740                         }
2741                         
2742                         if (sym->ruonly) {
2743                                 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2744                                 //  sym->type = aggrToPtr (sym->type, FALSE);
2745                                 debugLog ("  %d - used as a return\n", __LINE__);
2746                                 
2747                                 //continue;
2748                         }
2749                         
2750                         /* if the symbol has only one definition &
2751                         that definition is a get_pointer and the
2752                         pointer we are getting is rematerializable and
2753                         in "data" space */
2754                         
2755                         if (bitVectnBitsOn (sym->defs) == 1 &&
2756                             (ic = hTabItemWithKey (iCodehTab,
2757                                                    bitVectFirstBit (sym->defs))) &&
2758                             POINTER_GET (ic) &&
2759                             !IS_BITVAR (sym->etype) &&
2760                             (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2761
2762                                 if (ptrPseudoSymSafe (sym, ic)) {
2763
2764                                         symbol *psym;
2765                                         
2766                                         debugLog ("  %d - \n", __LINE__);
2767                                 
2768                                         /* create a psuedo symbol & force a spil */
2769                                         //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2770                                         psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2771                                         psym->type = sym->type;
2772                                         psym->etype = sym->etype;
2773                                         psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2774                                         strcpy (psym->rname, psym->name);
2775                                         sym->isspilt = 1;
2776                                         sym->usl.spillLoc = psym;
2777                                         continue;
2778                                 }
2779                                 
2780                                 /* if in data space or idata space then try to
2781                                 allocate pointer register */
2782                                 
2783                         }
2784                         
2785                         /* if not then we require registers */
2786                         sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2787                                 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2788                         getSize (sym->type));
2789                         
2790                         
2791                         if(IS_PTR_CONST (sym->type)) {
2792                                 debugLog ("  %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2793                                 sym->nRegs = 2;
2794                         }
2795                         
2796                         if (sym->nRegs > 4) {
2797                                 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2798                                 printTypeChain (sym->type, stderr);
2799                                 fprintf (stderr, "\n");
2800                         }
2801                         
2802                         /* determine the type of register required */
2803                         if (sym->nRegs == 1 &&
2804                                 IS_PTR (sym->type) &&
2805                                 sym->uptr)
2806                                 sym->regType = REG_PTR;
2807                         else
2808                                 sym->regType = REG_GPR;
2809                         
2810                         
2811                         debugLog ("  reg name %s,  reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2812                         
2813                 }
2814                 else
2815                         /* for the first run we don't provide */
2816                         /* registers for true symbols we will */
2817                         /* see how things go                  */
2818                         sym->nRegs = 0;
2819         }
2820   
2821 }
2822 DEFSETFUNC (markRegFree)
2823 {
2824         ((regs *)item)->isFree = 1;
2825         
2826         return 0;
2827 }
2828
2829 DEFSETFUNC (deallocReg)
2830 {
2831         fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2832         ((regs *)item)->isFree = 1;
2833         ((regs *)item)->wasUsed = 0;
2834         
2835         return 0;
2836 }
2837 /*-----------------------------------------------------------------*/
2838 /* freeAllRegs - mark all registers as free                        */
2839 /*-----------------------------------------------------------------*/
2840 void
2841 pic14_freeAllRegs ()
2842 {
2843         //  int i;
2844         
2845         debugLog ("%s\n", __FUNCTION__);
2846         
2847         applyToSet(dynAllocRegs,markRegFree);
2848         applyToSet(dynStackRegs,markRegFree);
2849         
2850         /*
2851         for (i = 0; i < pic14_nRegs; i++)
2852         regspic14[i].isFree = 1;
2853         */
2854 }
2855
2856 /*-----------------------------------------------------------------*/
2857 /*-----------------------------------------------------------------*/
2858 void
2859 pic14_deallocateAllRegs ()
2860 {
2861         //  int i;
2862         
2863         debugLog ("%s\n", __FUNCTION__);
2864         
2865         applyToSet(dynAllocRegs,deallocReg);
2866         
2867         /*
2868         for (i = 0; i < pic14_nRegs; i++) {
2869                 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2870                 regspic14[i].isFree = 1;
2871                 regspic14[i].wasUsed = 0;
2872                 }
2873         }
2874         */
2875 }
2876
2877
2878 /*-----------------------------------------------------------------*/
2879 /* deallocStackSpil - this will set the stack pointer back         */
2880 /*-----------------------------------------------------------------*/
2881 static
2882 DEFSETFUNC (deallocStackSpil)
2883 {
2884         symbol *sym = item;
2885         
2886         debugLog ("%s\n", __FUNCTION__);
2887         deallocLocal (sym);
2888         return 0;
2889 }
2890
2891 /*-----------------------------------------------------------------*/
2892 /* farSpacePackable - returns the packable icode for far variables */
2893 /*-----------------------------------------------------------------*/
2894 static iCode *
2895 farSpacePackable (iCode * ic)
2896 {
2897         iCode *dic;
2898         
2899         debugLog ("%s\n", __FUNCTION__);
2900         /* go thru till we find a definition for the
2901         symbol on the right */
2902         for (dic = ic->prev; dic; dic = dic->prev)
2903         {
2904                 
2905                 /* if the definition is a call then no */
2906                 if ((dic->op == CALL || dic->op == PCALL) &&
2907                         IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2908                 {
2909                         return NULL;
2910                 }
2911                 
2912                 /* if shift by unknown amount then not */
2913                 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2914                         IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2915                         return NULL;
2916                 
2917                 /* if pointer get and size > 1 */
2918                 if (POINTER_GET (dic) &&
2919                         getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2920                         return NULL;
2921                 
2922                 if (POINTER_SET (dic) &&
2923                         getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2924                         return NULL;
2925                 
2926                 /* if any three is a true symbol in far space */
2927                 if (IC_RESULT (dic) &&
2928                         IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2929                         isOperandInFarSpace (IC_RESULT (dic)))
2930                         return NULL;
2931                 
2932                 if (IC_RIGHT (dic) &&
2933                         IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2934                         isOperandInFarSpace (IC_RIGHT (dic)) &&
2935                         !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2936                         return NULL;
2937                 
2938                 if (IC_LEFT (dic) &&
2939                         IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2940                         isOperandInFarSpace (IC_LEFT (dic)) &&
2941                         !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2942                         return NULL;
2943                 
2944                 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2945                 {
2946                         if ((dic->op == LEFT_OP ||
2947                                 dic->op == RIGHT_OP ||
2948                                 dic->op == '-') &&
2949                                 IS_OP_LITERAL (IC_RIGHT (dic)))
2950                                 return NULL;
2951                         else
2952                                 return dic;
2953                 }
2954         }
2955         
2956         return NULL;
2957 }
2958
2959 /*-----------------------------------------------------------------*/
2960 /* packRegsForAssign - register reduction for assignment           */
2961 /*-----------------------------------------------------------------*/
2962 static int
2963 packRegsForAssign (iCode * ic, eBBlock * ebp)
2964 {
2965         
2966         iCode *dic, *sic;
2967         
2968         debugLog ("%s\n", __FUNCTION__);
2969         
2970         debugAopGet ("  result:", IC_RESULT (ic));
2971         debugAopGet ("  left:", IC_LEFT (ic));
2972         debugAopGet ("  right:", IC_RIGHT (ic));
2973         
2974         /* if this is at an absolute address, then get the address. */
2975         if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2976                 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2977                         debugLog ("  %d - found config word declaration\n", __LINE__);
2978                         if(IS_VALOP(IC_RIGHT(ic))) {
2979                                 debugLog ("  setting config word to %x\n", 
2980                                         (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2981                                 assignConfigWordValue(  SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2982                                         (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2983                         }
2984                         
2985                         /* remove the assignment from the iCode chain. */
2986                         
2987                         remiCodeFromeBBlock (ebp, ic);
2988                         bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2989                         hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2990                         
2991                         return 1;
2992                         
2993                 }
2994         }
2995         
2996         if (!IS_ITEMP (IC_RESULT (ic))) {
2997                 allocDirReg(IC_RESULT (ic));
2998                 debugLog ("  %d - result is not temp\n", __LINE__);
2999         }
3000         /*
3001         if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
3002         debugLog ("  %d - left is not temp, allocating\n", __LINE__);
3003         allocDirReg(IC_LEFT (ic));
3004         }
3005         */
3006         
3007         if (!IS_ITEMP (IC_RIGHT (ic))) {
3008                 debugLog ("  %d - not packing - right is not temp\n", __LINE__);
3009                 
3010                 /* only pack if this is not a function pointer */
3011                 if (!IS_REF (IC_RIGHT (ic)))
3012                         allocDirReg(IC_RIGHT (ic));
3013                 return 0;
3014         }
3015         
3016         if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
3017                 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
3018         {
3019                 debugLog ("  %d - not packing - right side fails \n", __LINE__);
3020                 return 0;
3021         }
3022         
3023         /* if the true symbol is defined in far space or on stack
3024         then we should not since this will increase register pressure */
3025         if (isOperandInFarSpace (IC_RESULT (ic)))
3026         {
3027                 if ((dic = farSpacePackable (ic)))
3028                         goto pack;
3029                 else
3030                         return 0;
3031                 
3032         }
3033         /* find the definition of iTempNN scanning backwards if we find a 
3034         a use of the true symbol before we find the definition then 
3035         we cannot pack */
3036         for (dic = ic->prev; dic; dic = dic->prev)
3037         {
3038                 
3039                 /* if there is a function call and this is
3040                 a parameter & not my parameter then don't pack it */
3041                 if ((dic->op == CALL || dic->op == PCALL) &&
3042                         (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3043                         !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3044                 {
3045                         debugLog ("  %d - \n", __LINE__);
3046                         dic = NULL;
3047                         break;
3048                 }
3049                 
3050                 if (SKIP_IC2 (dic))
3051                         continue;
3052                 
3053                 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3054                         IS_OP_VOLATILE (IC_RESULT (dic)))
3055                 {
3056                         debugLog ("  %d - dic is VOLATILE \n", __LINE__);
3057                         dic = NULL;
3058                         break;
3059                 }
3060                 
3061                 if (IS_SYMOP (IC_RESULT (dic)) &&
3062                         IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3063                 {
3064                         /* A previous result was assigned to the same register - we'll our definition */
3065                         debugLog ("  %d - dic result key == ic right key -- pointer set=%c\n",
3066                                 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3067                         if (POINTER_SET (dic))
3068                                 dic = NULL;
3069                         
3070                         break;
3071                 }
3072                 
3073                 if (IS_SYMOP (IC_RIGHT (dic)) &&
3074                         (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3075                         IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3076                 {
3077                         debugLog ("  %d - dic right key == ic rightor result key\n", __LINE__);
3078                         dic = NULL;
3079                         break;
3080                 }
3081                 
3082                 if (IS_SYMOP (IC_LEFT (dic)) &&
3083                         (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3084                         IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3085                 {
3086                         debugLog ("  %d - dic left key == ic rightor result key\n", __LINE__);
3087                         dic = NULL;
3088                         break;
3089                 }
3090                 
3091                 if (POINTER_SET (dic) &&
3092                         IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3093                 {
3094                         debugLog ("  %d - dic result key == ic result key -- pointer set=Y\n",
3095                                 __LINE__);
3096                         dic = NULL;
3097                         break;
3098                 }
3099         }
3100         
3101         if (!dic)
3102                 return 0;                       /* did not find */
3103         
3104         /* if the result is on stack or iaccess then it must be
3105         the same at least one of the operands */
3106         if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3107                 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3108         {
3109                 
3110         /* the operation has only one symbol
3111                 operator then we can pack */
3112                 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3113                         (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3114                         goto pack;
3115                 
3116                 if (!((IC_LEFT (dic) &&
3117                         IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3118                         (IC_RIGHT (dic) &&
3119                         IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3120                         return 0;
3121         }
3122 pack:
3123         debugLog ("  packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3124         debugLog ("  replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3125         /* found the definition */
3126         /* replace the result with the result of */
3127         /* this assignment and remove this assignment */
3128         bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3129         IC_RESULT (dic) = IC_RESULT (ic);
3130         
3131         if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3132         {
3133                 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3134         }
3135         /* delete from liverange table also 
3136         delete from all the points inbetween and the new
3137         one */
3138         for (sic = dic; sic != ic; sic = sic->next)
3139         {
3140                 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3141                 if (IS_ITEMP (IC_RESULT (dic)))
3142                         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3143         }
3144         
3145         remiCodeFromeBBlock (ebp, ic);
3146         bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3147         hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3148         OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3149         return 1;
3150         
3151         
3152 }
3153
3154 /*-----------------------------------------------------------------*/
3155 /* findAssignToSym : scanning backwards looks for first assig found */
3156 /*-----------------------------------------------------------------*/
3157 static iCode *
3158 findAssignToSym (operand * op, iCode * ic)
3159 {
3160         iCode *dic;
3161         
3162         debugLog ("%s\n", __FUNCTION__);
3163         for (dic = ic->prev; dic; dic = dic->prev)
3164         {
3165                 
3166                 /* if definition by assignment */
3167                 if (dic->op == '=' &&
3168                         !POINTER_SET (dic) &&
3169                         IC_RESULT (dic)->key == op->key
3170                         /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3171                         )
3172                 {
3173                         
3174                         /* we are interested only if defined in far space */
3175                         /* or in stack space in case of + & - */
3176                         
3177                         /* if assigned to a non-symbol then return
3178                         true */
3179                         if (!IS_SYMOP (IC_RIGHT (dic)))
3180                                 break;
3181                         
3182                                 /* if the symbol is in far space then
3183                         we should not */
3184                         if (isOperandInFarSpace (IC_RIGHT (dic)))
3185                                 return NULL;
3186                         
3187                                 /* for + & - operations make sure that
3188                                 if it is on the stack it is the same
3189                         as one of the three operands */
3190                         if ((ic->op == '+' || ic->op == '-') &&
3191                                 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3192                         {
3193                                 
3194                                 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3195                                         IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3196                                         IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3197                                         return NULL;
3198                         }
3199                         
3200                         break;
3201                         
3202                 }
3203                 
3204                 /* if we find an usage then we cannot delete it */
3205                 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3206                         return NULL;
3207                 
3208                 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3209                         return NULL;
3210                 
3211                 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3212                         return NULL;
3213         }
3214         
3215         /* now make sure that the right side of dic
3216         is not defined between ic & dic */
3217         if (dic)
3218         {
3219                 iCode *sic = dic->next;
3220                 
3221                 for (; sic != ic; sic = sic->next)
3222                         if (IC_RESULT (sic) &&
3223                                 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3224                                 return NULL;
3225         }
3226         
3227         return dic;
3228         
3229         
3230 }
3231
3232 /*-----------------------------------------------------------------*/
3233 /* packRegsForSupport :- reduce some registers for support calls   */
3234 /*-----------------------------------------------------------------*/
3235 static int
3236 packRegsForSupport (iCode * ic, eBBlock * ebp)
3237 {
3238         int change = 0;
3239         
3240         debugLog ("%s\n", __FUNCTION__);
3241         /* for the left & right operand :- look to see if the
3242         left was assigned a true symbol in far space in that
3243         case replace them */
3244         if (IS_ITEMP (IC_LEFT (ic)) &&
3245                 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3246         {
3247                 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3248                 iCode *sic;
3249                 
3250                 if (!dic)
3251                         goto right;
3252                 
3253                 debugAopGet ("removing left:", IC_LEFT (ic));
3254                 
3255                 /* found it we need to remove it from the
3256                 block */
3257                 for (sic = dic; sic != ic; sic = sic->next)
3258                         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3259                 
3260                 IC_LEFT (ic)->operand.symOperand =
3261                         IC_RIGHT (dic)->operand.symOperand;
3262                 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3263                 remiCodeFromeBBlock (ebp, dic);
3264                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3265                 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3266                 change++;
3267         }
3268         
3269         /* do the same for the right operand */
3270 right:
3271         if (!change &&
3272                 IS_ITEMP (IC_RIGHT (ic)) &&
3273                 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3274         {
3275                 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3276                 iCode *sic;
3277                 
3278                 if (!dic)
3279                         return change;
3280                 
3281                         /* if this is a subtraction & the result
3282                 is a true symbol in far space then don't pack */
3283                 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3284                 {
3285                         sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3286                         if (IN_FARSPACE (SPEC_OCLS (etype)))
3287                                 return change;
3288                 }
3289                 
3290                 debugAopGet ("removing right:", IC_RIGHT (ic));
3291                 
3292                 /* found it we need to remove it from the
3293                 block */
3294                 for (sic = dic; sic != ic; sic = sic->next)
3295                         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3296                 
3297                 IC_RIGHT (ic)->operand.symOperand =
3298                         IC_RIGHT (dic)->operand.symOperand;
3299                 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3300                 
3301                 remiCodeFromeBBlock (ebp, dic);
3302                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3303                 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3304                 change++;
3305         }
3306         
3307         return change;
3308 }
3309
3310 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3311
3312
3313 /*-----------------------------------------------------------------*/
3314 /* packRegsForOneuse : - will reduce some registers for single Use */
3315 /*-----------------------------------------------------------------*/
3316 static iCode *
3317 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3318 {
3319         bitVect *uses;
3320         iCode *dic, *sic;
3321         
3322         debugLog ("%s\n", __FUNCTION__);
3323         /* if returning a literal then do nothing */
3324         if (!IS_SYMOP (op))
3325                 return NULL;
3326         
3327         /* only upto 2 bytes since we cannot predict
3328         the usage of b, & acc */
3329         if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3330                 ic->op != RETURN &&
3331                 ic->op != SEND)
3332                 return NULL;
3333         
3334         /* this routine will mark the a symbol as used in one 
3335         instruction use only && if the definition is local 
3336         (ie. within the basic block) && has only one definition &&
3337         that definition is either a return value from a 
3338         function or does not contain any variables in
3339         far space */
3340         uses = bitVectCopy (OP_USES (op));
3341         bitVectUnSetBit (uses, ic->key);        /* take away this iCode */
3342         if (!bitVectIsZero (uses))      /* has other uses */
3343                 return NULL;
3344         
3345         /* if it has only one defintion */
3346         if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3347                 return NULL;            /* has more than one definition */
3348         
3349         /* get that definition */
3350         if (!(dic =
3351                 hTabItemWithKey (iCodehTab,
3352                 bitVectFirstBit (OP_DEFS (op)))))
3353                 return NULL;
3354         
3355         /* found the definition now check if it is local */
3356         if (dic->seq < ebp->fSeq ||
3357                 dic->seq > ebp->lSeq)
3358                 return NULL;            /* non-local */
3359         
3360                                                         /* now check if it is the return from
3361         a function call */
3362         if (dic->op == CALL || dic->op == PCALL)
3363         {
3364                 if (ic->op != SEND && ic->op != RETURN &&
3365                         !POINTER_SET(ic) && !POINTER_GET(ic))
3366                 {
3367                         OP_SYMBOL (op)->ruonly = 1;
3368                         return dic;
3369                 }
3370                 dic = dic->next;
3371         }
3372         
3373         
3374         /* otherwise check that the definition does
3375         not contain any symbols in far space */
3376         if (isOperandInFarSpace (IC_LEFT (dic)) ||
3377                 isOperandInFarSpace (IC_RIGHT (dic)) ||
3378                 IS_OP_RUONLY (IC_LEFT (ic)) ||
3379                 IS_OP_RUONLY (IC_RIGHT (ic)))
3380         {
3381                 return NULL;
3382         }
3383         
3384         /* if pointer set then make sure the pointer
3385         is one byte */
3386         if (POINTER_SET (dic) &&
3387                 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3388                 return NULL;
3389         
3390         if (POINTER_GET (dic) &&
3391                 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3392                 return NULL;
3393         
3394         sic = dic;
3395         
3396         /* also make sure the intervenening instructions
3397         don't have any thing in far space */
3398         for (dic = dic->next; dic && dic != ic; dic = dic->next)
3399         {
3400                 
3401                 /* if there is an intervening function call then no */
3402                 if (dic->op == CALL || dic->op == PCALL)
3403                         return NULL;
3404                         /* if pointer set then make sure the pointer
3405                 is one byte */
3406                 if (POINTER_SET (dic) &&
3407                         !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3408                         return NULL;
3409                 
3410                 if (POINTER_GET (dic) &&
3411                         !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3412                         return NULL;
3413                 
3414                 /* if address of & the result is remat then okay */
3415                 if (dic->op == ADDRESS_OF &&
3416                         OP_SYMBOL (IC_RESULT (dic))->remat)
3417                         continue;
3418                 
3419                         /* if operand has size of three or more & this
3420                         operation is a '*','/' or '%' then 'b' may
3421                 cause a problem */
3422                 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3423                         getSize (operandType (op)) >= 3)
3424                         return NULL;
3425                 
3426                 /* if left or right or result is in far space */
3427                 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3428                         isOperandInFarSpace (IC_RIGHT (dic)) ||
3429                         isOperandInFarSpace (IC_RESULT (dic)) ||
3430                         IS_OP_RUONLY (IC_LEFT (dic)) ||
3431                         IS_OP_RUONLY (IC_RIGHT (dic)) ||
3432                         IS_OP_RUONLY (IC_RESULT (dic)))
3433                 {
3434                         return NULL;
3435                 }
3436         }
3437         
3438         OP_SYMBOL (op)->ruonly = 1;
3439         return sic;
3440         
3441 }
3442
3443 /*-----------------------------------------------------------------*/
3444 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
3445 /*-----------------------------------------------------------------*/
3446 static bool
3447 isBitwiseOptimizable (iCode * ic)
3448 {
3449         sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3450         sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3451         
3452         debugLog ("%s\n", __FUNCTION__);
3453         /* bitwise operations are considered optimizable
3454         under the following conditions (Jean-Louis VERN) 
3455         
3456           x & lit
3457           bit & bit
3458           bit & x
3459           bit ^ bit
3460           bit ^ x
3461           x   ^ lit
3462           x   | lit
3463           bit | bit
3464           bit | x
3465         */
3466         if (IS_LITERAL (rtype) ||
3467                 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3468                 return TRUE;
3469         else
3470                 return FALSE;
3471 }
3472
3473 /*-----------------------------------------------------------------*/
3474 /* packRegsForAccUse - pack registers for acc use                  */
3475 /*-----------------------------------------------------------------*/
3476 static void
3477 packRegsForAccUse (iCode * ic)
3478 {
3479         iCode *uic;
3480         
3481         debugLog ("%s\n", __FUNCTION__);
3482         
3483         /* if this is an aggregate, e.g. a one byte char array */
3484         if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3485                 return;
3486         }
3487         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3488         
3489         /* if + or - then it has to be one byte result */
3490         if ((ic->op == '+' || ic->op == '-')
3491                 && getSize (operandType (IC_RESULT (ic))) > 1)
3492                 return;
3493         
3494         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3495         /* if shift operation make sure right side is not a literal */
3496         if (ic->op == RIGHT_OP &&
3497                 (isOperandLiteral (IC_RIGHT (ic)) ||
3498                 getSize (operandType (IC_RESULT (ic))) > 1))
3499                 return;
3500         
3501         if (ic->op == LEFT_OP &&
3502                 (isOperandLiteral (IC_RIGHT (ic)) ||
3503                 getSize (operandType (IC_RESULT (ic))) > 1))
3504                 return;
3505         
3506         if (IS_BITWISE_OP (ic) &&
3507                 getSize (operandType (IC_RESULT (ic))) > 1)
3508                 return;
3509         
3510         
3511         /* has only one definition */
3512         if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3513                 return;
3514         
3515         /* has only one use */
3516         if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3517                 return;
3518         
3519         /* and the usage immediately follows this iCode */
3520         if (!(uic = hTabItemWithKey (iCodehTab,
3521                 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3522                 return;
3523         
3524         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3525         if (ic->next != uic)
3526                 return;
3527         
3528         /* if it is a conditional branch then we definitely can */
3529         if (uic->op == IFX)
3530                 goto accuse;
3531         
3532         if (uic->op == JUMPTABLE)
3533                 return;
3534         
3535                 /* if the usage is not is an assignment
3536         or an arithmetic / bitwise / shift operation then not */
3537         if (POINTER_SET (uic) &&
3538                 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3539                 return;
3540         
3541         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3542         if (uic->op != '=' &&
3543                 !IS_ARITHMETIC_OP (uic) &&
3544                 !IS_BITWISE_OP (uic) &&
3545                 uic->op != LEFT_OP &&
3546                 uic->op != RIGHT_OP)
3547                 return;
3548         
3549         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3550         /* if used in ^ operation then make sure right is not a 
3551         literl */
3552         if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3553                 return;
3554         
3555         /* if shift operation make sure right side is not a literal */
3556         if (uic->op == RIGHT_OP &&
3557                 (isOperandLiteral (IC_RIGHT (uic)) ||
3558                 getSize (operandType (IC_RESULT (uic))) > 1))
3559                 return;
3560         
3561         if (uic->op == LEFT_OP &&
3562                 (isOperandLiteral (IC_RIGHT (uic)) ||
3563                 getSize (operandType (IC_RESULT (uic))) > 1))
3564                 return;
3565         
3566                 /* make sure that the result of this icode is not on the
3567         stack, since acc is used to compute stack offset */
3568         if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3569                 OP_SYMBOL (IC_RESULT (uic))->onStack)
3570                 return;
3571         
3572         /* if either one of them in far space then we cannot */
3573         if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3574                 isOperandInFarSpace (IC_LEFT (uic))) ||
3575                 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3576                 isOperandInFarSpace (IC_RIGHT (uic))))
3577                 return;
3578         
3579         /* if the usage has only one operand then we can */
3580         if (IC_LEFT (uic) == NULL ||
3581                 IC_RIGHT (uic) == NULL)
3582                 goto accuse;
3583         
3584                 /* make sure this is on the left side if not
3585         a '+' since '+' is commutative */
3586         if (ic->op != '+' &&
3587                 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3588                 return;
3589         
3590         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3591         /* if one of them is a literal then we can */
3592         if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3593                 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))  &&
3594                 (getSize (operandType (IC_RESULT (uic))) <= 1))
3595         {
3596                 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3597                 return;
3598         }
3599         
3600         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3601         /* if the other one is not on stack then we can */
3602         if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3603                 (IS_ITEMP (IC_RIGHT (uic)) ||
3604                 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3605                 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3606                 goto accuse;
3607         
3608         if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3609                 (IS_ITEMP (IC_LEFT (uic)) ||
3610                 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3611                 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3612                 goto accuse;
3613         
3614         return;
3615         
3616 accuse:
3617         debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3618         OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3619         
3620         
3621 }
3622
3623 /*-----------------------------------------------------------------*/
3624 /* packForPush - hueristics to reduce iCode for pushing            */
3625 /*-----------------------------------------------------------------*/
3626 static void
3627 packForReceive (iCode * ic, eBBlock * ebp)
3628 {
3629         iCode *dic;
3630         
3631         debugLog ("%s\n", __FUNCTION__);
3632         debugAopGet ("  result:", IC_RESULT (ic));
3633         debugAopGet ("  left:", IC_LEFT (ic));
3634         debugAopGet ("  right:", IC_RIGHT (ic));
3635         
3636         if (!ic->next)
3637                 return;
3638         
3639         for (dic = ic->next; dic; dic = dic->next)
3640         {
3641                 
3642                 
3643                 
3644                 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3645                         debugLog ("    used on left\n");
3646                 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3647                         debugLog ("    used on right\n");
3648                 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3649                         debugLog ("    used on result\n");
3650                 
3651                 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3652                         (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3653                         return;
3654                 
3655         }
3656         
3657         debugLog ("  hey we can remove this unnecessary assign\n");
3658 }
3659 /*-----------------------------------------------------------------*/
3660 /* packForPush - hueristics to reduce iCode for pushing            */
3661 /*-----------------------------------------------------------------*/
3662 static void
3663 packForPush (iCode * ic, eBBlock * ebp)
3664 {
3665         iCode *dic;
3666         
3667         debugLog ("%s\n", __FUNCTION__);
3668         if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3669                 return;
3670         
3671         /* must have only definition & one usage */
3672         if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3673                 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3674                 return;
3675         
3676         /* find the definition */
3677         if (!(dic = hTabItemWithKey (iCodehTab,
3678                 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3679                 return;
3680         
3681         if (dic->op != '=' || POINTER_SET (dic))
3682                 return;
3683         
3684                 /* we now we know that it has one & only one def & use
3685         and the that the definition is an assignment */
3686         IC_LEFT (ic) = IC_RIGHT (dic);
3687         
3688         remiCodeFromeBBlock (ebp, dic);
3689         bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3690         hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3691 }
3692
3693 void printSymType(char * str, sym_link *sl)
3694 {
3695         debugLog ("    %s Symbol type: ",str);
3696         printTypeChain( sl, debugF);
3697         debugLog ("\n");
3698         
3699 }
3700
3701 /*-----------------------------------------------------------------*/
3702 /* some debug code to print the symbol S_TYPE. Note that
3703 * the function checkSClass in src/SDCCsymt.c dinks with
3704 * the S_TYPE in ways the PIC port doesn't fully like...*/
3705 /*-----------------------------------------------------------------*/
3706 void isData(sym_link *sl)
3707 {
3708         FILE *of = stderr;
3709         
3710         if(!sl)
3711                 return;
3712         
3713         if(debugF)
3714                 of = debugF;
3715         
3716         for ( ; sl; sl=sl->next) {
3717                 if(!IS_DECL(sl) ) {
3718                         switch (SPEC_SCLS(sl)) {
3719                                 
3720                         case S_DATA: fprintf (of, "data "); break;
3721                         case S_XDATA: fprintf (of, "xdata "); break;
3722                         case S_SFR: fprintf (of, "sfr "); break;
3723                         case S_SBIT: fprintf (of, "sbit "); break;
3724                         case S_CODE: fprintf (of, "code "); break;
3725                         case S_IDATA: fprintf (of, "idata "); break;
3726                         case S_PDATA: fprintf (of, "pdata "); break;
3727                         case S_LITERAL: fprintf (of, "literal "); break;
3728                         case S_STACK: fprintf (of, "stack "); break;
3729                         case S_XSTACK: fprintf (of, "xstack "); break;
3730                         case S_BIT: fprintf (of, "bit "); break;
3731                         case S_EEPROM: fprintf (of, "eeprom "); break;
3732                         default: break;
3733                         }
3734                         
3735                 }
3736                 
3737         }
3738         
3739 }
3740
3741 /*-----------------------------------------------------------------*/
3742 /* packRegisters - does some transformations to reduce register    */
3743 /*                   pressure                                      */
3744 /*-----------------------------------------------------------------*/
3745 static void
3746 packRegisters (eBBlock * ebp)
3747 {
3748         iCode *ic;
3749         int change = 0;
3750         
3751         debugLog ("%s\n", __FUNCTION__);
3752         
3753         while (1) {
3754                 
3755                 change = 0;
3756                 
3757                 /* look for assignments of the form */
3758                 /* iTempNN = TRueSym (someoperation) SomeOperand */
3759                 /*       ....                       */
3760                 /* TrueSym := iTempNN:1             */
3761                 for (ic = ebp->sch; ic; ic = ic->next)
3762                 {
3763                         
3764                         /* find assignment of the form TrueSym := iTempNN:1 */
3765                         if (ic->op == '=' && !POINTER_SET (ic))
3766                                 change += packRegsForAssign (ic, ebp);
3767                         /* debug stuff */
3768                         if (ic->op == '=')
3769                         {
3770                                 if (POINTER_SET (ic))
3771                                         debugLog ("pointer is set\n");
3772                                 debugAopGet ("  result:", IC_RESULT (ic));
3773                                 debugAopGet ("  left:", IC_LEFT (ic));
3774                                 debugAopGet ("  right:", IC_RIGHT (ic));
3775                         }
3776                         
3777                 }
3778                 
3779                 if (!change)
3780                         break;
3781         }
3782         
3783         for (ic = ebp->sch; ic; ic = ic->next) {
3784                 
3785                 if(IS_SYMOP ( IC_LEFT(ic))) {
3786                         sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3787                         
3788                         debugAopGet ("  left:", IC_LEFT (ic));
3789                         if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3790                                 debugLog ("    is a pointer\n");
3791                         
3792                         if(IS_OP_VOLATILE(IC_LEFT(ic)))
3793                                 debugLog ("    is volatile\n");
3794                         
3795                         isData(etype);
3796                         
3797                         printSymType("   ", OP_SYMBOL(IC_LEFT(ic))->type);
3798                 }
3799                 
3800                 if(IS_SYMOP ( IC_RIGHT(ic))) {
3801                         debugAopGet ("  right:", IC_RIGHT (ic));
3802                         printSymType("    ", OP_SYMBOL(IC_RIGHT(ic))->type);
3803                 }
3804                 
3805                 if(IS_SYMOP ( IC_RESULT(ic))) {
3806                         debugAopGet ("  result:", IC_RESULT (ic));
3807                         printSymType("     ", OP_SYMBOL(IC_RESULT(ic))->type);
3808                 }
3809                 
3810                 if (POINTER_SET (ic))
3811                         debugLog ("  %d - Pointer set\n", __LINE__);
3812                 
3813                 
3814                 /* Look for two subsequent iCodes with */
3815                 /*   iTemp := _c;         */
3816                 /*   _c = iTemp & op;     */
3817                 /* and replace them by    */
3818                 /*   iTemp := _c;         */
3819                 /*   _c = _c & op;        */
3820                 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3821                         ic->prev &&
3822                         ic->prev->op == '=' &&
3823                         IS_ITEMP (IC_LEFT (ic)) &&
3824                         IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3825                         isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3826         {
3827                         iCode* ic_prev = ic->prev;
3828                         symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3829                         
3830                         ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3831                         if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3832             {
3833                                 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3834                                 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3835                                         prev_result_sym->liveTo == ic->seq)
3836                 {
3837                                         prev_result_sym->liveTo = ic_prev->seq;
3838                 }
3839             }
3840                         bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3841                         
3842                         bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3843                         
3844                         if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3845             {
3846                                 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3847                                 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3848                                 remiCodeFromeBBlock (ebp, ic_prev);
3849                                 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3850             }
3851         }
3852                 
3853                 /* if this is an itemp & result of a address of a true sym 
3854                 then mark this as rematerialisable   */
3855                 if (ic->op == ADDRESS_OF &&
3856                         IS_ITEMP (IC_RESULT (ic)) &&
3857                         IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3858                         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3859                         !OP_SYMBOL (IC_LEFT (ic))->onStack)
3860                 {
3861                         
3862                         debugLog ("  %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3863                         
3864                         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3865                         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3866                         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3867                         
3868                 }
3869                 
3870                 /* if straight assignment then carry remat flag if
3871                 this is the only definition */
3872                 if (ic->op == '=' &&
3873                         !POINTER_SET (ic) &&
3874                         IS_SYMOP (IC_RIGHT (ic)) &&
3875                         OP_SYMBOL (IC_RIGHT (ic))->remat &&
3876                         bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3877                 {
3878                         debugLog ("  %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3879                         
3880                         OP_SYMBOL (IC_RESULT (ic))->remat =
3881                                 OP_SYMBOL (IC_RIGHT (ic))->remat;
3882                         OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3883                                 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3884                 }
3885                 
3886                 /* if this is a +/- operation with a rematerizable 
3887                 then mark this as rematerializable as well */
3888                 if ((ic->op == '+' || ic->op == '-') &&
3889                         (IS_SYMOP (IC_LEFT (ic)) &&
3890                         IS_ITEMP (IC_RESULT (ic)) &&
3891                         OP_SYMBOL (IC_LEFT (ic))->remat &&
3892                         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3893                         IS_OP_LITERAL (IC_RIGHT (ic))))
3894                 {
3895                         debugLog ("  %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3896                         //int i = 
3897                         operandLitValue (IC_RIGHT (ic));
3898                         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3899                         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3900                         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3901                 }
3902                 
3903                 /* mark the pointer usages */
3904                 if (POINTER_SET (ic))
3905                 {
3906                         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3907                         debugLog ("  marking as a pointer (set) =>");
3908                         debugAopGet ("  result:", IC_RESULT (ic));
3909                 }
3910                 if (POINTER_GET (ic))
3911                 {
3912                         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3913                         debugLog ("  marking as a pointer (get) =>");
3914                         debugAopGet ("  left:", IC_LEFT (ic));
3915                 }
3916                 
3917                 if (!SKIP_IC2 (ic))
3918                 {
3919                         /* if we are using a symbol on the stack
3920                         then we should say pic14_ptrRegReq */
3921                         if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3922                                 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3923                                 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3924                         else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3925                                 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3926                                 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3927                         else
3928                         {
3929                                 if (IS_SYMOP (IC_LEFT (ic)))
3930                                         pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3931                                         OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3932                                 if (IS_SYMOP (IC_RIGHT (ic)))
3933                                         pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3934                                         OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3935                                 if (IS_SYMOP (IC_RESULT (ic)))
3936                                         pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3937                                         OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3938                         }
3939                         
3940                         debugLog ("  %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3941                         
3942                 }
3943                 
3944                 /* if the condition of an if instruction
3945                 is defined in the previous instruction then
3946                 mark the itemp as a conditional */
3947                 if ((IS_CONDITIONAL (ic) ||
3948                         ((ic->op == BITWISEAND ||
3949                         ic->op == '|' ||
3950                         ic->op == '^') &&
3951                         isBitwiseOptimizable (ic))) &&
3952                         ic->next && ic->next->op == IFX &&
3953                         isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3954                         OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3955                 {
3956                         
3957                         debugLog ("  %d\n", __LINE__);
3958                         OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3959                         continue;
3960                 }
3961                 
3962                 /* reduce for support function calls */
3963                 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3964                         packRegsForSupport (ic, ebp);
3965                 
3966                 /* if a parameter is passed, it's in W, so we may not
3967                 need to place a copy in a register */
3968                 if (ic->op == RECEIVE)
3969                         packForReceive (ic, ebp);
3970                 
3971                 /* some cases the redundant moves can
3972                 can be eliminated for return statements */
3973                 if ((ic->op == RETURN || ic->op == SEND) &&
3974                         !isOperandInFarSpace (IC_LEFT (ic)) &&
3975                         !options.model)
3976                         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3977                 
3978                 /* if pointer set & left has a size more than
3979                 one and right is not in far space */
3980                 if (POINTER_SET (ic) &&
3981                         !isOperandInFarSpace (IC_RIGHT (ic)) &&
3982                         !OP_SYMBOL (IC_RESULT (ic))->remat &&
3983                         !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3984                         getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3985                         
3986                         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3987                 
3988                 /* if pointer get */
3989                 if (POINTER_GET (ic) &&
3990                         !isOperandInFarSpace (IC_RESULT (ic)) &&
3991                         !OP_SYMBOL (IC_LEFT (ic))->remat &&
3992                         !IS_OP_RUONLY (IC_RESULT (ic)) &&
3993                         getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3994                         
3995                         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3996                 
3997                 
3998                 /* if this is cast for intergral promotion then
3999                 check if only use of  the definition of the 
4000                 operand being casted/ if yes then replace
4001                 the result of that arithmetic operation with 
4002                 this result and get rid of the cast */
4003                 if (ic->op == CAST) {
4004                         
4005                         sym_link *fromType = operandType (IC_RIGHT (ic));
4006                         sym_link *toType = operandType (IC_LEFT (ic));
4007                         
4008                         debugLog ("  %d - casting\n", __LINE__);
4009                         
4010                         if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4011                                 getSize (fromType) != getSize (toType)) {
4012                                 
4013                                 
4014                                 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4015                                 if (dic) {
4016                                         
4017                                         if (IS_ARITHMETIC_OP (dic)) {
4018                                                 
4019                                                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4020                                                 IC_RESULT (dic) = IC_RESULT (ic);
4021                                                 remiCodeFromeBBlock (ebp, ic);
4022                                                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4023                                                 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4024                                                 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4025                                                 ic = ic->prev;
4026                                         }  else
4027                                                 
4028                                                 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4029                                 }
4030                         } else {
4031                                 
4032                                 /* if the type from and type to are the same
4033                                 then if this is the only use then packit */
4034                                 if (compareType (operandType (IC_RIGHT (ic)),
4035                                         operandType (IC_LEFT (ic))) == 1) {
4036                                         
4037                                         iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4038                                         if (dic) {
4039                                                 
4040                                                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4041                                                 IC_RESULT (dic) = IC_RESULT (ic);
4042                                                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4043                                                 remiCodeFromeBBlock (ebp, ic);
4044                                                 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4045                                                 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4046                                                 ic = ic->prev;
4047                                         }
4048                                 }
4049                         }
4050                 }
4051                 
4052                 /* pack for PUSH 
4053                 iTempNN := (some variable in farspace) V1
4054                 push iTempNN ;
4055                 -------------
4056                 push V1
4057                 */
4058                 if (ic->op == IPUSH)
4059                 {
4060                         packForPush (ic, ebp);
4061                 }
4062                 
4063                 
4064                 /* pack registers for accumulator use, when the
4065                 result of an arithmetic or bit wise operation
4066                 has only one use, that use is immediately following
4067                 the defintion and the using iCode has only one
4068                 operand or has two operands but one is literal &
4069                 the result of that operation is not on stack then
4070                 we can leave the result of this operation in acc:b
4071                 combination */
4072                 if ((IS_ARITHMETIC_OP (ic)
4073                         
4074                         || IS_BITWISE_OP (ic)
4075                         
4076                         || ic->op == LEFT_OP || ic->op == RIGHT_OP
4077                         
4078                         ) &&
4079                         IS_ITEMP (IC_RESULT (ic)) &&
4080                         getSize (operandType (IC_RESULT (ic))) <= 2)
4081                         
4082                         packRegsForAccUse (ic);
4083                 
4084         }
4085 }
4086
4087 static void
4088 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4089 {
4090         int i;
4091         
4092         if (!debug || !debugF)
4093                 return;
4094         
4095         for (i = 0; i < count; i++)
4096         {
4097                 fprintf (debugF, "\n----------------------------------------------------------------\n");
4098                 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4099                         ebbs[i]->entryLabel->name,
4100                         ebbs[i]->depth,
4101                         ebbs[i]->noPath,
4102                         ebbs[i]->isLastInLoop);
4103                 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4104                         ebbs[i]->dfnum,
4105                         ebbs[i]->bbnum,
4106                         ebbs[i]->fSeq,
4107                         ebbs[i]->lSeq);
4108                 fprintf (debugF, "visited %d : hasFcall = %d\n",
4109                         ebbs[i]->visited,
4110                         ebbs[i]->hasFcall);
4111                 
4112                 fprintf (debugF, "\ndefines bitVector :");
4113                 bitVectDebugOn (ebbs[i]->defSet, debugF);
4114                 fprintf (debugF, "\nlocal defines bitVector :");
4115                 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4116                 fprintf (debugF, "\npointers Set bitvector :");
4117                 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4118                 fprintf (debugF, "\nin pointers Set bitvector :");
4119                 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4120                 fprintf (debugF, "\ninDefs Set bitvector :");
4121                 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4122                 fprintf (debugF, "\noutDefs Set bitvector :");
4123                 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4124                 fprintf (debugF, "\nusesDefs Set bitvector :");
4125                 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4126                 fprintf (debugF, "\n----------------------------------------------------------------\n");
4127                 printiCChain (ebbs[i]->sch, debugF);
4128         }
4129 }
4130 /*-----------------------------------------------------------------*/
4131 /* assignRegisters - assigns registers to each live range as need  */
4132 /*-----------------------------------------------------------------*/
4133 void
4134 pic14_assignRegisters (ebbIndex * ebbi)
4135 {
4136         eBBlock ** ebbs = ebbi->bbOrder;
4137         int count = ebbi->count;
4138         iCode *ic;
4139         int i;
4140         
4141         debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4142         debugLog ("\nebbs before optimizing:\n");
4143         dumpEbbsToDebug (ebbs, count);
4144         
4145         setToNull ((void *) &_G.funcrUsed);
4146         pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4147         
4148         
4149         /* change assignments this will remove some
4150         live ranges reducing some register pressure */
4151         for (i = 0; i < count; i++)
4152                 packRegisters (ebbs[i]);
4153         
4154         {
4155                 regs *reg;
4156                 int hkey;
4157                 int i=0;
4158                 
4159                 debugLog("dir registers allocated so far:\n");
4160                 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4161                 
4162                 while(reg) {
4163                         debugLog("  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4164                         reg = hTabNextItem(dynDirectRegNames, &hkey);
4165                 }
4166                 
4167         }
4168         
4169         if (options.dump_pack)
4170                 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4171         
4172         /* first determine for each live range the number of 
4173         registers & the type of registers required for each */
4174         regTypeNum ();
4175         
4176         /* and serially allocate registers */
4177         serialRegAssign (ebbs, count);
4178         
4179         /* if stack was extended then tell the user */
4180         if (_G.stackExtend)
4181         {
4182                 /*      werror(W_TOOMANY_SPILS,"stack", */
4183                 /*             _G.stackExtend,currFunc->name,""); */
4184                 _G.stackExtend = 0;
4185         }
4186         
4187         if (_G.dataExtend)
4188         {
4189                 /*      werror(W_TOOMANY_SPILS,"data space", */
4190                 /*             _G.dataExtend,currFunc->name,""); */
4191                 _G.dataExtend = 0;
4192         }
4193         
4194         /* after that create the register mask
4195         for each of the instruction */
4196         createRegMask (ebbs, count);
4197         
4198         /* redo that offsets for stacked automatic variables */
4199         redoStackOffsets ();
4200         
4201         if (options.dump_rassgn)
4202                 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4203         
4204         /* now get back the chain */
4205         ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4206         
4207         debugLog ("ebbs after optimizing:\n");
4208         dumpEbbsToDebug (ebbs, count);
4209         
4210         
4211         genpic14Code (ic);
4212         
4213         /* free up any _G.stackSpil locations allocated */
4214         applyToSet (_G.stackSpil, deallocStackSpil);
4215         _G.slocNum = 0;
4216         setToNull ((void *) &_G.stackSpil);
4217         setToNull ((void *) &_G.spiltSet);
4218         /* mark all registers as free */
4219         //pic14_freeAllRegs ();
4220         
4221         debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
4222         debugLogClose ();
4223         return;
4224 }