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