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