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