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