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