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