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