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