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