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