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