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