* src/pic/device.c (dump_sfr): replaced register declaration with
[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                 /* HACK: result and addr must be disjoint for POINTER_GET */
1949                 if (sym->liveTo == ic->seq && POINTER_GET(ic))
1950                 {
1951                         //piCode (ic, stderr); fprintf (stderr, " -- registers NOT deallocated\n");
1952                         continue;
1953                 }
1954                 
1955                 /* if it was spilt on stack then we can 
1956                 mark the stack spil location as free */
1957                 if (sym->isspilt)
1958                 {
1959                         if (sym->stackSpil)
1960                         {
1961                                 sym->usl.spillLoc->isFree = 1;
1962                                 sym->stackSpil = 0;
1963                         }
1964                         continue;
1965                 }
1966                 
1967                 if (!bitVectBitValue (_G.regAssigned, sym->key))
1968                         continue;
1969                 /* special case check if this is an IFX &
1970                 the privious one was a pop and the 
1971                 previous one was not spilt then keep track
1972                 of the symbol */
1973                 if (ic->op == IFX && ic->prev &&
1974                         ic->prev->op == IPOP &&
1975                         !ic->prev->parmPush &&
1976                         IS_SYMOP(IC_LEFT (ic->prev)) &&
1977                         !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1978                         psym = OP_SYMBOL (IC_LEFT (ic->prev));
1979                 
1980                 if (sym->nRegs)
1981                 {
1982                         int i = 0;
1983                         
1984                         bitVectUnSetBit (_G.regAssigned, sym->key);
1985                         
1986                         /* if the result of this one needs registers
1987                         and does not have it then assign it right
1988                         away */
1989                         if (IC_RESULT (ic) &&
1990                                 !(SKIP_IC2 (ic) ||      /* not a special icode */
1991                                 ic->op == JUMPTABLE ||
1992                                 ic->op == IFX ||
1993                                 ic->op == IPUSH ||
1994                                 ic->op == IPOP ||
1995                                 ic->op == RETURN ||
1996                                 POINTER_SET (ic)) &&
1997                                 IS_SYMOP (IC_RESULT (ic)) &&
1998                                 (result = OP_SYMBOL (IC_RESULT (ic))) &&        /* has a result */
1999                                 result->liveTo > ic->seq &&     /* and will live beyond this */
2000                                 result->liveTo <= ebp->lSeq &&  /* does not go beyond this block */
2001                                 result->liveFrom == ic->seq &&    /* does not start before here */
2002                                 result->regType == sym->regType &&      /* same register types */
2003                                 result->regType == sym->regType &&      /* same register types */
2004                                 result->nRegs &&        /* which needs registers */
2005                                 !result->isspilt &&     /* and does not already have them */
2006                                 !result->remat &&
2007                                 !bitVectBitValue (_G.regAssigned, result->key) &&
2008                                 /* the number of free regs + number of regs in this LR
2009                                 can accomodate the what result Needs */
2010                                 ((nfreeRegsType (result->regType) +
2011                                 sym->nRegs) >= result->nRegs)
2012                                 )
2013                         {
2014                                 
2015                                 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2016                                         if (i < sym->nRegs)
2017                                                 result->regs[i] = sym->regs[i];
2018                                         else
2019                                                 result->regs[i] = getRegGpr (ic, ebp, result);
2020                                         
2021                                         _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2022                                         
2023                         }
2024
2025                         /* free the remaining */
2026                         for (; i < sym->nRegs; i++)
2027                         {
2028                                 if (psym)
2029                                 {
2030                                         if (!symHasReg (psym, sym->regs[i]))
2031                                                 freeReg (sym->regs[i]);
2032                                 }
2033                                 else
2034                                         freeReg (sym->regs[i]);
2035                         }
2036                 }
2037         }
2038 }
2039
2040
2041 /*-----------------------------------------------------------------*/
2042 /* reassignLR - reassign this to registers                         */
2043 /*-----------------------------------------------------------------*/
2044 static void
2045 reassignLR (operand * op)
2046 {
2047         symbol *sym = OP_SYMBOL (op);
2048         int i;
2049         
2050         debugLog ("%s\n", __FUNCTION__);
2051         /* not spilt any more */
2052         sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2053         bitVectUnSetBit (_G.spiltSet, sym->key);
2054         
2055         _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2056         
2057         _G.blockSpil--;
2058         
2059         for (i = 0; i < sym->nRegs; i++)
2060                 sym->regs[i]->isFree = 0;
2061 }
2062
2063 /*-----------------------------------------------------------------*/
2064 /* willCauseSpill - determines if allocating will cause a spill    */
2065 /*-----------------------------------------------------------------*/
2066 static int
2067 willCauseSpill (int nr, int rt)
2068 {
2069         debugLog ("%s\n", __FUNCTION__);
2070         /* first check if there are any avlb registers
2071         of te type required */
2072         if (rt == REG_PTR)
2073         {
2074         /* special case for pointer type 
2075         if pointer type not avlb then 
2076                 check for type gpr */
2077                 if (nFreeRegs (rt) >= nr)
2078                         return 0;
2079                 if (nFreeRegs (REG_GPR) >= nr)
2080                         return 0;
2081         }
2082         else
2083         {
2084                 if (pic14_ptrRegReq)
2085                 {
2086                         if (nFreeRegs (rt) >= nr)
2087                                 return 0;
2088                 }
2089                 else
2090                 {
2091                         if (nFreeRegs (REG_PTR) +
2092                                 nFreeRegs (REG_GPR) >= nr)
2093                                 return 0;
2094                 }
2095         }
2096         
2097         debugLog (" ... yep it will (cause a spill)\n");
2098         /* it will cause a spil */
2099         return 1;
2100 }
2101
2102 /*-----------------------------------------------------------------*/
2103 /* positionRegs - the allocator can allocate same registers to res- */
2104 /* ult and operand, if this happens make sure they are in the same */
2105 /* position as the operand otherwise chaos results                 */
2106 /*-----------------------------------------------------------------*/
2107 static void
2108 positionRegs (symbol * result, symbol * opsym, int lineno)
2109 {
2110         int count = min (result->nRegs, opsym->nRegs);
2111         int i, j = 0, shared = 0;
2112         
2113         debugLog ("%s\n", __FUNCTION__);
2114         /* if the result has been spilt then cannot share */
2115         if (opsym->isspilt)
2116                 return;
2117 again:
2118         shared = 0;
2119         /* first make sure that they actually share */
2120         for (i = 0; i < count; i++)
2121         {
2122                 for (j = 0; j < count; j++)
2123                 {
2124                         if (result->regs[i] == opsym->regs[j] && i != j)
2125                         {
2126                                 shared = 1;
2127                                 goto xchgPositions;
2128                         }
2129                 }
2130         }
2131 xchgPositions:
2132         if (shared)
2133         {
2134                 regs *tmp = result->regs[i];
2135                 result->regs[i] = result->regs[j];
2136                 result->regs[j] = tmp;
2137                 goto again;
2138         }
2139 }
2140
2141 /*------------------------------------------------------------------*/
2142 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2143 /* it should either have registers or have beed spilled. Otherwise, */
2144 /* there was an uninitialized variable, so just spill this to get   */
2145 /* the operand in a valid state.                                    */
2146 /*------------------------------------------------------------------*/
2147 static void
2148 verifyRegsAssigned (operand *op, iCode * ic)
2149 {
2150   symbol * sym;
2151   
2152   if (!op) return;
2153   if (!IS_ITEMP (op)) return;
2154   
2155   sym = OP_SYMBOL (op);
2156   if (sym->isspilt) return;
2157   if (!sym->nRegs) return;
2158   if (sym->regs[0]) return;
2159   
2160   werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT, 
2161             sym->prereqv ? sym->prereqv->name : sym->name);
2162   spillThis (sym);
2163 }
2164
2165
2166 /*-----------------------------------------------------------------*/
2167 /* serialRegAssign - serially allocate registers to the variables  */
2168 /*-----------------------------------------------------------------*/
2169 static void
2170 serialRegAssign (eBBlock ** ebbs, int count)
2171 {
2172         int i;
2173         
2174         debugLog ("%s\n", __FUNCTION__);
2175         /* for all blocks */
2176         for (i = 0; i < count; i++)
2177         {
2178                 
2179                 iCode *ic;
2180                 
2181                 if (ebbs[i]->noPath &&
2182                         (ebbs[i]->entryLabel != entryLabel &&
2183                         ebbs[i]->entryLabel != returnLabel))
2184                         continue;
2185                 
2186                 /* of all instructions do */
2187                 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2188                 {
2189                         debugLog ("  op: %s\n", decodeOp (ic->op));
2190                         
2191                         /* if this is an ipop that means some live
2192                         range will have to be assigned again */
2193                         if (ic->op == IPOP)
2194                                 reassignLR (IC_LEFT (ic));
2195                         
2196                         /* if result is present && is a true symbol */
2197                         if (IC_RESULT (ic) && ic->op != IFX &&
2198                                 IS_TRUE_SYMOP (IC_RESULT (ic)))
2199                                 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2200                         
2201                         /* take away registers from live
2202                         ranges that end at this instruction */
2203                         deassignLRs (ic, ebbs[i]);
2204                         
2205                         /* some don't need registers */
2206                         if (SKIP_IC2 (ic) ||
2207                                 ic->op == JUMPTABLE ||
2208                                 ic->op == IFX ||
2209                                 ic->op == IPUSH ||
2210                                 ic->op == IPOP ||
2211                                 (IC_RESULT (ic) && POINTER_SET (ic)))
2212                                 continue;
2213                         
2214                         /* now we need to allocate registers
2215                         only for the result */
2216                         if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
2217                         {
2218                                 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2219                                 bitVect *spillable;
2220                                 int willCS;
2221                                 int j;
2222                                 int ptrRegSet = 0;
2223
2224                                 /* Make sure any spill location is definately allocated */
2225                                 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2226                                     !sym->usl.spillLoc->allocreq)
2227                                 {
2228                                         sym->usl.spillLoc->allocreq++;
2229                                 }
2230
2231                                 /* if it does not need or is spilt 
2232                                 or is already assigned to registers
2233                                 or will not live beyond this instructions */
2234                                 if (!sym->nRegs ||
2235                                         sym->isspilt ||
2236                                         bitVectBitValue (_G.regAssigned, sym->key) ||
2237                                         sym->liveTo <= ic->seq)
2238                                         continue;
2239                                 
2240                                 /* if some liverange has been spilt at the block level
2241                                 and this one live beyond this block then spil this
2242                                 to be safe */
2243                                 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2244                                 {
2245                                         spillThis (sym);
2246                                         continue;
2247                                 }
2248                                 /* if trying to allocate this will cause
2249                                 a spill and there is nothing to spill 
2250                                 or this one is rematerializable then
2251                                 spill this one */
2252                                 willCS = willCauseSpill (sym->nRegs, sym->regType);
2253                                 spillable = computeSpillable (ic);
2254                                 if (sym->remat ||
2255                                         (willCS && bitVectIsZero (spillable)))
2256                                 {
2257                                         
2258                                         spillThis (sym);
2259                                         continue;
2260                                         
2261                                 }
2262
2263                                 /* If the live range preceeds the point of definition 
2264                                    then ideally we must take into account registers that 
2265                                    have been allocated after sym->liveFrom but freed
2266                                    before ic->seq. This is complicated, so spill this
2267                                    symbol instead and let fillGaps handle the allocation. */
2268                                 if (sym->liveFrom < ic->seq)
2269                                 {
2270                                         spillThis (sym);
2271                                         continue;                     
2272                                 }
2273                                 
2274                                 /* if it has a spillocation & is used less than
2275                                 all other live ranges then spill this */
2276                                 if (willCS) {
2277                                         if (sym->usl.spillLoc) {
2278                                                 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2279                                                         allLRs, ebbs[i], ic));
2280                                                 if (leastUsed && leastUsed->used > sym->used) {
2281                                                         spillThis (sym);
2282                                                         continue;
2283                                                 }
2284                                         } else {
2285                                                 /* if none of the liveRanges have a spillLocation then better
2286                                                 to spill this one than anything else already assigned to registers */
2287                                                 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2288                                                         /* if this is local to this block then we might find a block spil */
2289                                                         if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2290                                                                 spillThis (sym);
2291                                                                 continue;
2292                                                         }
2293                                                 }
2294                                         }
2295                                 }
2296                                 
2297                                 if (ic->op == RECEIVE)
2298                                         debugLog ("When I get clever, I'll optimize the receive logic\n");
2299                                 
2300                                 /* if we need ptr regs for the right side
2301                                 then mark it */
2302                                 if (POINTER_GET (ic)
2303                                         && IS_SYMOP(IC_LEFT(ic))
2304                                         && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2305                                                 <= (unsigned) PTRSIZE)
2306                                 {
2307                                         pic14_ptrRegReq++;
2308                                         ptrRegSet = 1;
2309                                 }
2310                                 /* else we assign registers to it */
2311                                 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2312                                 
2313                                 debugLog ("  %d - \n", __LINE__);
2314                                 if(debugF) 
2315                                         bitVectDebugOn(_G.regAssigned, debugF);
2316                                 for (j = 0; j < sym->nRegs; j++)
2317                                 {
2318                                         if (sym->regType == REG_PTR)
2319                                                 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2320                                         else
2321                                                 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2322                                         
2323                                         /* if the allocation failed which means
2324                                         this was spilt then break */
2325                                         if (!sym->regs[j])
2326                                                 break;
2327                                 }
2328                                 debugLog ("  %d - \n", __LINE__);
2329                                 
2330                                 /* if it shares registers with operands make sure
2331                                 that they are in the same position */
2332                                 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2333                                         IS_SYMOP(IC_RESULT(ic)) &&
2334                                         OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2335                                         positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2336                                         OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2337                                 /* do the same for the right operand */
2338                                 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2339                                         IS_SYMOP(IC_RESULT(ic)) &&
2340                                         OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2341                                         positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2342                                         OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2343                                 
2344                                 debugLog ("  %d - \n", __LINE__);
2345                                 if (ptrRegSet)
2346                                 {
2347                                         debugLog ("  %d - \n", __LINE__);
2348                                         pic14_ptrRegReq--;
2349                                         ptrRegSet = 0;
2350                                 }
2351                                 
2352                         }
2353                 }
2354         }
2355
2356     /* Check for and fix any problems with uninitialized operands */
2357     for (i = 0; i < count; i++)
2358         {
2359                 iCode *ic;
2360
2361                 if (ebbs[i]->noPath &&
2362                         (ebbs[i]->entryLabel != entryLabel &&
2363                          ebbs[i]->entryLabel != returnLabel))
2364                         continue;
2365
2366                 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2367                 {
2368                         if (SKIP_IC2 (ic))
2369                           continue;
2370
2371                         if (ic->op == IFX)
2372                         {
2373                                 verifyRegsAssigned (IC_COND (ic), ic);
2374                                 continue;
2375                         }
2376
2377                         if (ic->op == JUMPTABLE)
2378                         {
2379                                 verifyRegsAssigned (IC_JTCOND (ic), ic);
2380                                 continue;
2381                         }
2382
2383                         verifyRegsAssigned (IC_RESULT (ic), ic);
2384                         verifyRegsAssigned (IC_LEFT (ic), ic);
2385                         verifyRegsAssigned (IC_RIGHT (ic), ic);
2386                 }
2387         }
2388
2389 }
2390
2391 /*-----------------------------------------------------------------*/
2392 /* rUmaskForOp :- returns register mask for an operand             */
2393 /*-----------------------------------------------------------------*/
2394 static bitVect *
2395 rUmaskForOp (operand * op)
2396 {
2397         bitVect *rumask;
2398         symbol *sym;
2399         int j;
2400         
2401         debugLog ("%s\n", __FUNCTION__);
2402         /* only temporaries are assigned registers */
2403         if (!IS_ITEMP (op))
2404                 return NULL;
2405         
2406         sym = OP_SYMBOL (op);
2407         
2408         /* if spilt or no registers assigned to it
2409         then nothing */
2410         if (sym->isspilt || !sym->nRegs)
2411                 return NULL;
2412         
2413         rumask = newBitVect (pic14_nRegs);
2414         
2415         for (j = 0; j < sym->nRegs; j++)
2416         {
2417                 rumask = bitVectSetBit (rumask,
2418                         sym->regs[j]->rIdx);
2419         }
2420         
2421         return rumask;
2422 }
2423
2424 /*-----------------------------------------------------------------*/
2425 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2426 /*-----------------------------------------------------------------*/
2427 static bitVect *
2428 regsUsedIniCode (iCode * ic)
2429 {
2430         bitVect *rmask = newBitVect (pic14_nRegs);
2431         
2432         debugLog ("%s\n", __FUNCTION__);
2433         /* do the special cases first */
2434         if (ic->op == IFX)
2435         {
2436                 rmask = bitVectUnion (rmask,
2437                         rUmaskForOp (IC_COND (ic)));
2438                 goto ret;
2439         }
2440         
2441         /* for the jumptable */
2442         if (ic->op == JUMPTABLE)
2443         {
2444                 rmask = bitVectUnion (rmask,
2445                         rUmaskForOp (IC_JTCOND (ic)));
2446                 
2447                 goto ret;
2448         }
2449         
2450         /* of all other cases */
2451         if (IC_LEFT (ic))
2452                 rmask = bitVectUnion (rmask,
2453                 rUmaskForOp (IC_LEFT (ic)));
2454         
2455         
2456         if (IC_RIGHT (ic))
2457                 rmask = bitVectUnion (rmask,
2458                 rUmaskForOp (IC_RIGHT (ic)));
2459         
2460         if (IC_RESULT (ic))
2461                 rmask = bitVectUnion (rmask,
2462                 rUmaskForOp (IC_RESULT (ic)));
2463         
2464 ret:
2465         return rmask;
2466 }
2467
2468 /*-----------------------------------------------------------------*/
2469 /* createRegMask - for each instruction will determine the regsUsed */
2470 /*-----------------------------------------------------------------*/
2471 static void
2472 createRegMask (eBBlock ** ebbs, int count)
2473 {
2474         int i;
2475         
2476         debugLog ("%s\n", __FUNCTION__);
2477         /* for all blocks */
2478         for (i = 0; i < count; i++)
2479         {
2480                 iCode *ic;
2481                 
2482                 if (ebbs[i]->noPath &&
2483                         (ebbs[i]->entryLabel != entryLabel &&
2484                         ebbs[i]->entryLabel != returnLabel))
2485                         continue;
2486                 
2487                 /* for all instructions */
2488                 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2489                 {
2490                         
2491                         int j;
2492                         
2493                         if (SKIP_IC2 (ic) || !ic->rlive)
2494                                 continue;
2495                         
2496                                 /* first mark the registers used in this
2497                         instruction */
2498                         ic->rUsed = regsUsedIniCode (ic);
2499                         _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2500                         
2501                         /* now create the register mask for those 
2502                         registers that are in use : this is a
2503                         super set of ic->rUsed */
2504                         ic->rMask = newBitVect (pic14_nRegs + 1);
2505                         
2506                         /* for all live Ranges alive at this point */
2507                         for (j = 1; j < ic->rlive->size; j++)
2508                         {
2509                                 symbol *sym;
2510                                 int k;
2511                                 
2512                                 /* if not alive then continue */
2513                                 if (!bitVectBitValue (ic->rlive, j))
2514                                         continue;
2515                                 
2516                                 /* find the live range we are interested in */
2517                                 if (!(sym = hTabItemWithKey (liveRanges, j)))
2518                                 {
2519                                         werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2520                                                 "createRegMask cannot find live range");
2521                                         exit (0);
2522                                 }
2523                                 
2524                                 /* if no register assigned to it */
2525                                 if (!sym->nRegs || sym->isspilt)
2526                                         continue;
2527                                 
2528                                 /* for all the registers allocated to it */
2529                                 for (k = 0; k < sym->nRegs; k++)
2530                                         if (sym->regs[k])
2531                                                 ic->rMask =
2532                                                 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2533                         }
2534                 }
2535         }
2536 }
2537 #if 0
2538 /* This was the active version */
2539 /*-----------------------------------------------------------------*/
2540 /* rematStr - returns the rematerialized string for a remat var    */
2541 /*-----------------------------------------------------------------*/
2542 static symbol *
2543 rematStr (symbol * sym)
2544 {
2545         char *s = buffer;
2546         iCode *ic = sym->rematiCode;
2547         symbol *psym = NULL;
2548         
2549         debugLog ("%s\n", __FUNCTION__);
2550         
2551         //printf ("%s\n", s);
2552         
2553         /* if plus or minus print the right hand side */
2554         
2555         if (ic->op == '+' || ic->op == '-') {
2556                 
2557                 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2558                 
2559                 sprintf (s, "(%s %c 0x%04x)",
2560                         OP_SYMBOL (IC_LEFT (ric))->rname,
2561                         ic->op,
2562                         (int) operandLitValue (IC_RIGHT (ic)));
2563                 
2564                 
2565                 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2566                 
2567                 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2568                 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2569                 
2570                 return psym;
2571         }
2572         
2573         sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2574         psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2575         
2576         //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2577         return psym;
2578 }
2579 #endif
2580
2581 #if 0
2582 /* deprecated version */
2583 /*-----------------------------------------------------------------*/
2584 /* rematStr - returns the rematerialized string for a remat var    */
2585 /*-----------------------------------------------------------------*/
2586 static char *
2587 rematStr (symbol * sym)
2588 {
2589         char *s = buffer;
2590         iCode *ic = sym->rematiCode;
2591         
2592         debugLog ("%s\n", __FUNCTION__);
2593         while (1)
2594         {
2595                 
2596                 printf ("%s\n", s);
2597                 /* if plus or minus print the right hand side */
2598                 /*
2599                 if (ic->op == '+' || ic->op == '-') {
2600                 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2601                 ic->op );
2602                 s += strlen(s);
2603                 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2604                 continue ;
2605                 }
2606                 */
2607                 if (ic->op == '+' || ic->op == '-')
2608                 {
2609                         iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2610                         sprintf (s, "(%s %c 0x%04x)",
2611                                 OP_SYMBOL (IC_LEFT (ric))->rname,
2612                                 ic->op,
2613                                 (int) operandLitValue (IC_RIGHT (ic)));
2614                         
2615                         //s += strlen(s);
2616                         //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2617                         //continue ;
2618                         //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2619                         return buffer;
2620                 }
2621                 
2622                 /* we reached the end */
2623                 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2624                 break;
2625         }
2626         
2627         printf ("%s\n", buffer);
2628         return buffer;
2629 }
2630 #endif
2631
2632 /*-----------------------------------------------------------------*/
2633 /* regTypeNum - computes the type & number of registers required   */
2634 /*-----------------------------------------------------------------*/
2635 static void
2636 regTypeNum ()
2637 {
2638         symbol *sym;
2639         int k;
2640         //iCode *ic;
2641         
2642         debugLog ("%s\n", __FUNCTION__);
2643         /* for each live range do */
2644         for (sym = hTabFirstItem (liveRanges, &k); sym;
2645         sym = hTabNextItem (liveRanges, &k)) {
2646
2647                 debugLog ("  %d - %s\n", __LINE__, sym->rname);
2648                 
2649                 /* if used zero times then no registers needed */
2650                 if ((sym->liveTo - sym->liveFrom) == 0)
2651                         continue;
2652
2653
2654                 /* if the live range is a temporary */
2655                 if (sym->isitmp) {
2656                         
2657                         debugLog ("  %d - itemp register\n", __LINE__);
2658                         
2659                         /* if the type is marked as a conditional */
2660                         if (sym->regType == REG_CND)
2661                                 continue;
2662                         
2663                         /* if used in return only then we don't 
2664                         need registers */
2665                         if (sym->accuse) {
2666                                 if (IS_AGGREGATE (sym->type) || sym->isptr)
2667                                         sym->type = aggrToPtr (sym->type, FALSE);
2668                                 debugLog ("  %d - no reg needed - accumulator used\n", __LINE__);
2669                                 
2670                                 continue;
2671                         }
2672                         
2673                         if (sym->ruonly) {
2674                                 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2675                                 //  sym->type = aggrToPtr (sym->type, FALSE);
2676                                 debugLog ("  %d - used as a return\n", __LINE__);
2677                                 
2678                                 //continue;
2679                         }
2680                         
2681                         /* if the symbol has only one definition &
2682                         that definition is a get_pointer and the
2683                         pointer we are getting is rematerializable and
2684                         in "data" space */
2685                         
2686 #if 0
2687                         if (bitVectnBitsOn (sym->defs) == 1 &&
2688                             (ic = hTabItemWithKey (iCodehTab,
2689                                                    bitVectFirstBit (sym->defs))) &&
2690                             POINTER_GET (ic) &&
2691                             !IS_BITVAR (sym->etype) &&
2692                             (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2693
2694                                 if (ptrPseudoSymSafe (sym, ic)) {
2695
2696                                         symbol *psym;
2697                                         
2698                                         debugLog ("  %d - \n", __LINE__);
2699                                 
2700                                         /* create a psuedo symbol & force a spil */
2701                                         //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2702                                         psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2703                                         psym->type = sym->type;
2704                                         psym->etype = sym->etype;
2705                                         psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2706                                         strcpy (psym->rname, psym->name);
2707                                         sym->isspilt = 1;
2708                                         sym->usl.spillLoc = psym;
2709                                         continue;
2710                                 }
2711                                 
2712                                 /* if in data space or idata space then try to
2713                                 allocate pointer register */
2714                                 
2715                         }
2716 #endif
2717                         
2718                         /* if not then we require registers */
2719                         sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2720                                 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2721                         getSize (sym->type));
2722                         
2723                         
2724                         if(IS_PTR_CONST (sym->type)) {
2725                                 debugLog ("  %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2726                                 sym->nRegs = 2;
2727                         }
2728                         
2729                         if (sym->nRegs > 4) {
2730                                 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2731                                 printTypeChain (sym->type, stderr);
2732                                 fprintf (stderr, "\n");
2733                         }
2734                         
2735                         /* determine the type of register required */
2736                         if (sym->nRegs == 1 &&
2737                                 IS_PTR (sym->type) &&
2738                                 sym->uptr)
2739                                 sym->regType = REG_PTR;
2740                         else
2741                                 sym->regType = REG_GPR;
2742                         
2743                         
2744                         debugLog ("  reg name %s,  reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2745                         
2746                 }
2747                 else
2748                         /* for the first run we don't provide */
2749                         /* registers for true symbols we will */
2750                         /* see how things go                  */
2751                         sym->nRegs = 0;
2752         }
2753   
2754 }
2755 DEFSETFUNC (markRegFree)
2756 {
2757         ((regs *)item)->isFree = 1;
2758         
2759         return 0;
2760 }
2761
2762 DEFSETFUNC (deallocReg)
2763 {
2764         fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2765         ((regs *)item)->isFree = 1;
2766         ((regs *)item)->wasUsed = 0;
2767         
2768         return 0;
2769 }
2770 /*-----------------------------------------------------------------*/
2771 /* freeAllRegs - mark all registers as free                        */
2772 /*-----------------------------------------------------------------*/
2773 void
2774 pic14_freeAllRegs ()
2775 {
2776         //  int i;
2777         
2778         debugLog ("%s\n", __FUNCTION__);
2779         
2780         applyToSet(dynAllocRegs,markRegFree);
2781         applyToSet(dynStackRegs,markRegFree);
2782         
2783         /*
2784         for (i = 0; i < pic14_nRegs; i++)
2785         regspic14[i].isFree = 1;
2786         */
2787 }
2788
2789 /*-----------------------------------------------------------------*/
2790 /*-----------------------------------------------------------------*/
2791 void
2792 pic14_deallocateAllRegs ()
2793 {
2794         //  int i;
2795         
2796         debugLog ("%s\n", __FUNCTION__);
2797         
2798         applyToSet(dynAllocRegs,deallocReg);
2799         
2800         /*
2801         for (i = 0; i < pic14_nRegs; i++) {
2802                 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2803                 regspic14[i].isFree = 1;
2804                 regspic14[i].wasUsed = 0;
2805                 }
2806         }
2807         */
2808 }
2809
2810
2811 /*-----------------------------------------------------------------*/
2812 /* deallocStackSpil - this will set the stack pointer back         */
2813 /*-----------------------------------------------------------------*/
2814 static
2815 DEFSETFUNC (deallocStackSpil)
2816 {
2817         symbol *sym = item;
2818         
2819         debugLog ("%s\n", __FUNCTION__);
2820         deallocLocal (sym);
2821         return 0;
2822 }
2823
2824 /*-----------------------------------------------------------------*/
2825 /* farSpacePackable - returns the packable icode for far variables */
2826 /*-----------------------------------------------------------------*/
2827 static iCode *
2828 farSpacePackable (iCode * ic)
2829 {
2830         iCode *dic;
2831         
2832         debugLog ("%s\n", __FUNCTION__);
2833         /* go thru till we find a definition for the
2834         symbol on the right */
2835         for (dic = ic->prev; dic; dic = dic->prev)
2836         {
2837                 
2838                 /* if the definition is a call then no */
2839                 if ((dic->op == CALL || dic->op == PCALL) &&
2840                         IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2841                 {
2842                         return NULL;
2843                 }
2844                 
2845                 /* if shift by unknown amount then not */
2846                 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2847                         IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2848                         return NULL;
2849                 
2850                 /* if pointer get and size > 1 */
2851                 if (POINTER_GET (dic) &&
2852                         getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2853                         return NULL;
2854                 
2855                 if (POINTER_SET (dic) &&
2856                         getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2857                         return NULL;
2858                 
2859                 /* if any three is a true symbol in far space */
2860                 if (IC_RESULT (dic) &&
2861                         IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2862                         isOperandInFarSpace (IC_RESULT (dic)))
2863                         return NULL;
2864                 
2865                 if (IC_RIGHT (dic) &&
2866                         IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2867                         isOperandInFarSpace (IC_RIGHT (dic)) &&
2868                         !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2869                         return NULL;
2870                 
2871                 if (IC_LEFT (dic) &&
2872                         IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2873                         isOperandInFarSpace (IC_LEFT (dic)) &&
2874                         !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2875                         return NULL;
2876                 
2877                 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2878                 {
2879                         if ((dic->op == LEFT_OP ||
2880                                 dic->op == RIGHT_OP ||
2881                                 dic->op == '-') &&
2882                                 IS_OP_LITERAL (IC_RIGHT (dic)))
2883                                 return NULL;
2884                         else
2885                                 return dic;
2886                 }
2887         }
2888         
2889         return NULL;
2890 }
2891
2892 /*-----------------------------------------------------------------*/
2893 /* packRegsForAssign - register reduction for assignment           */
2894 /*-----------------------------------------------------------------*/
2895 static int
2896 packRegsForAssign (iCode * ic, eBBlock * ebp)
2897 {
2898         
2899         iCode *dic, *sic;
2900         
2901         debugLog ("%s\n", __FUNCTION__);
2902         
2903         debugAopGet ("  result:", IC_RESULT (ic));
2904         debugAopGet ("  left:", IC_LEFT (ic));
2905         debugAopGet ("  right:", IC_RIGHT (ic));
2906         
2907         /* if this is at an absolute address, then get the address. */
2908         if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2909                 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2910                         debugLog ("  %d - found config word declaration\n", __LINE__);
2911                         if(IS_VALOP(IC_RIGHT(ic))) {
2912                                 debugLog ("  setting config word to %x\n", 
2913                                         (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2914                                 assignConfigWordValue(  SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2915                                         (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2916                         }
2917                         
2918                         /* remove the assignment from the iCode chain. */
2919                         
2920                         remiCodeFromeBBlock (ebp, ic);
2921                         bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2922                         hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2923                         
2924                         return 1;
2925                         
2926                 }
2927         }
2928         
2929         if (!IS_ITEMP (IC_RESULT (ic))) {
2930                 allocDirReg(IC_RESULT (ic));
2931                 debugLog ("  %d - result is not temp\n", __LINE__);
2932         }
2933         /*
2934         if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2935         debugLog ("  %d - left is not temp, allocating\n", __LINE__);
2936         allocDirReg(IC_LEFT (ic));
2937         }
2938         */
2939         
2940         if (!IS_ITEMP (IC_RIGHT (ic))) {
2941                 debugLog ("  %d - not packing - right is not temp\n", __LINE__);
2942                 
2943                 /* only pack if this is not a function pointer */
2944                 if (!IS_REF (IC_RIGHT (ic)))
2945                         allocDirReg(IC_RIGHT (ic));
2946                 return 0;
2947         }
2948         
2949         if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2950                 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2951         {
2952                 debugLog ("  %d - not packing - right side fails \n", __LINE__);
2953                 return 0;
2954         }
2955         
2956         /* if the true symbol is defined in far space or on stack
2957         then we should not since this will increase register pressure */
2958         if (isOperandInFarSpace (IC_RESULT (ic)))
2959         {
2960                 if ((dic = farSpacePackable (ic)))
2961                         goto pack;
2962                 else
2963                         return 0;
2964                 
2965         }
2966         /* find the definition of iTempNN scanning backwards if we find a 
2967         a use of the true symbol before we find the definition then 
2968         we cannot pack */
2969         for (dic = ic->prev; dic; dic = dic->prev)
2970         {
2971                 
2972                 /* if there is a function call and this is
2973                 a parameter & not my parameter then don't pack it */
2974                 if ((dic->op == CALL || dic->op == PCALL) &&
2975                         (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2976                         !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2977                 {
2978                         debugLog ("  %d - \n", __LINE__);
2979                         dic = NULL;
2980                         break;
2981                 }
2982                 
2983                 if (SKIP_IC2 (dic))
2984                         continue;
2985                 
2986                 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2987                         IS_OP_VOLATILE (IC_RESULT (dic)))
2988                 {
2989                         debugLog ("  %d - dic is VOLATILE \n", __LINE__);
2990                         dic = NULL;
2991                         break;
2992                 }
2993                 
2994                 if (IS_SYMOP (IC_RESULT (dic)) &&
2995                         IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2996                 {
2997                         /* A previous result was assigned to the same register - we'll our definition */
2998                         debugLog ("  %d - dic result key == ic right key -- pointer set=%c\n",
2999                                 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3000                         if (POINTER_SET (dic))
3001                                 dic = NULL;
3002                         
3003                         break;
3004                 }
3005                 
3006                 if (IS_SYMOP (IC_RIGHT (dic)) &&
3007                         (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3008                         IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3009                 {
3010                         debugLog ("  %d - dic right key == ic rightor result key\n", __LINE__);
3011                         dic = NULL;
3012                         break;
3013                 }
3014                 
3015                 if (IS_SYMOP (IC_LEFT (dic)) &&
3016                         (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3017                         IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3018                 {
3019                         debugLog ("  %d - dic left key == ic rightor result key\n", __LINE__);
3020                         dic = NULL;
3021                         break;
3022                 }
3023                 
3024                 if (POINTER_SET (dic) &&
3025                         IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3026                 {
3027                         debugLog ("  %d - dic result key == ic result key -- pointer set=Y\n",
3028                                 __LINE__);
3029                         dic = NULL;
3030                         break;
3031                 }
3032         }
3033         
3034         if (!dic)
3035                 return 0;                       /* did not find */
3036         
3037         /* if the result is on stack or iaccess then it must be
3038         the same at least one of the operands */
3039         if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3040                 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3041         {
3042                 
3043         /* the operation has only one symbol
3044                 operator then we can pack */
3045                 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3046                         (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3047                         goto pack;
3048                 
3049                 if (!((IC_LEFT (dic) &&
3050                         IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3051                         (IC_RIGHT (dic) &&
3052                         IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3053                         return 0;
3054         }
3055 pack:
3056         debugLog ("  packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3057         debugLog ("  replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3058         /* found the definition */
3059         /* replace the result with the result of */
3060         /* this assignment and remove this assignment */
3061         bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3062         IC_RESULT (dic) = IC_RESULT (ic);
3063         
3064         if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3065         {
3066                 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3067         }
3068         /* delete from liverange table also 
3069         delete from all the points inbetween and the new
3070         one */
3071         for (sic = dic; sic != ic; sic = sic->next)
3072         {
3073                 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3074                 if (IS_ITEMP (IC_RESULT (dic)))
3075                         bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3076         }
3077         
3078         remiCodeFromeBBlock (ebp, ic);
3079         bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3080         hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3081         OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3082         return 1;
3083         
3084         
3085 }
3086
3087 /*-----------------------------------------------------------------*/
3088 /* findAssignToSym : scanning backwards looks for first assig found */
3089 /*-----------------------------------------------------------------*/
3090 static iCode *
3091 findAssignToSym (operand * op, iCode * ic)
3092 {
3093         iCode *dic;
3094         
3095         debugLog ("%s\n", __FUNCTION__);
3096         for (dic = ic->prev; dic; dic = dic->prev)
3097         {
3098                 
3099                 /* if definition by assignment */
3100                 if (dic->op == '=' &&
3101                         !POINTER_SET (dic) &&
3102                         IC_RESULT (dic)->key == op->key
3103                         /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3104                         )
3105                 {
3106                         
3107                         /* we are interested only if defined in far space */
3108                         /* or in stack space in case of + & - */
3109                         
3110                         /* if assigned to a non-symbol then return
3111                         true */
3112                         if (!IS_SYMOP (IC_RIGHT (dic)))
3113                                 break;
3114                         
3115                                 /* if the symbol is in far space then
3116                         we should not */
3117                         if (isOperandInFarSpace (IC_RIGHT (dic)))
3118                                 return NULL;
3119                         
3120                                 /* for + & - operations make sure that
3121                                 if it is on the stack it is the same
3122                         as one of the three operands */
3123                         if ((ic->op == '+' || ic->op == '-') &&
3124                                 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3125                         {
3126                                 
3127                                 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3128                                         IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3129                                         IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3130                                         return NULL;
3131                         }
3132                         
3133                         break;
3134                         
3135                 }
3136                 
3137                 /* if we find an usage then we cannot delete it */
3138                 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3139                         return NULL;
3140                 
3141                 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3142                         return NULL;
3143                 
3144                 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3145                         return NULL;
3146         }
3147         
3148         /* now make sure that the right side of dic
3149         is not defined between ic & dic */
3150         if (dic)
3151         {
3152                 iCode *sic = dic->next;
3153                 
3154                 for (; sic != ic; sic = sic->next)
3155                         if (IC_RESULT (sic) &&
3156                                 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3157                                 return NULL;
3158         }
3159         
3160         return dic;
3161         
3162         
3163 }
3164
3165 /*-----------------------------------------------------------------*/
3166 /* packRegsForSupport :- reduce some registers for support calls   */
3167 /*-----------------------------------------------------------------*/
3168 static int
3169 packRegsForSupport (iCode * ic, eBBlock * ebp)
3170 {
3171         int change = 0;
3172         
3173         debugLog ("%s\n", __FUNCTION__);
3174         /* for the left & right operand :- look to see if the
3175         left was assigned a true symbol in far space in that
3176         case replace them */
3177         if (IS_ITEMP (IC_LEFT (ic)) &&
3178                 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3179         {
3180                 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3181                 iCode *sic;
3182                 
3183                 if (!dic)
3184                         goto right;
3185                 
3186                 debugAopGet ("removing left:", IC_LEFT (ic));
3187                 
3188                 /* found it we need to remove it from the
3189                 block */
3190                 for (sic = dic; sic != ic; sic = sic->next)
3191                         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3192                 
3193                 IC_LEFT (ic)->operand.symOperand =
3194                         IC_RIGHT (dic)->operand.symOperand;
3195                 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3196                 remiCodeFromeBBlock (ebp, dic);
3197                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3198                 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3199                 change++;
3200         }
3201         
3202         /* do the same for the right operand */
3203 right:
3204         if (!change &&
3205                 IS_ITEMP (IC_RIGHT (ic)) &&
3206                 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3207         {
3208                 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3209                 iCode *sic;
3210                 
3211                 if (!dic)
3212                         return change;
3213                 
3214                         /* if this is a subtraction & the result
3215                 is a true symbol in far space then don't pack */
3216                 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3217                 {
3218                         sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3219                         if (IN_FARSPACE (SPEC_OCLS (etype)))
3220                                 return change;
3221                 }
3222                 
3223                 debugAopGet ("removing right:", IC_RIGHT (ic));
3224                 
3225                 /* found it we need to remove it from the
3226                 block */
3227                 for (sic = dic; sic != ic; sic = sic->next)
3228                         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3229                 
3230                 IC_RIGHT (ic)->operand.symOperand =
3231                         IC_RIGHT (dic)->operand.symOperand;
3232                 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3233                 
3234                 remiCodeFromeBBlock (ebp, dic);
3235                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3236                 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3237                 change++;
3238         }
3239         
3240         return change;
3241 }
3242
3243 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3244
3245
3246 /*-----------------------------------------------------------------*/
3247 /* packRegsForOneuse : - will reduce some registers for single Use */
3248 /*-----------------------------------------------------------------*/
3249 static iCode *
3250 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3251 {
3252         bitVect *uses;
3253         iCode *dic, *sic;
3254         
3255         debugLog ("%s\n", __FUNCTION__);
3256         /* if returning a literal then do nothing */
3257         if (!IS_SYMOP (op))
3258                 return NULL;
3259         
3260         /* only upto 2 bytes since we cannot predict
3261         the usage of b, & acc */
3262         if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3263                 ic->op != RETURN &&
3264                 ic->op != SEND)
3265                 return NULL;
3266         
3267         /* this routine will mark the a symbol as used in one 
3268         instruction use only && if the definition is local 
3269         (ie. within the basic block) && has only one definition &&
3270         that definition is either a return value from a 
3271         function or does not contain any variables in
3272         far space */
3273         uses = bitVectCopy (OP_USES (op));
3274         bitVectUnSetBit (uses, ic->key);        /* take away this iCode */
3275         if (!bitVectIsZero (uses))      /* has other uses */
3276                 return NULL;
3277         
3278         /* if it has only one defintion */
3279         if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3280                 return NULL;            /* has more than one definition */
3281         
3282         /* get that definition */
3283         if (!(dic =
3284                 hTabItemWithKey (iCodehTab,
3285                 bitVectFirstBit (OP_DEFS (op)))))
3286                 return NULL;
3287         
3288         /* found the definition now check if it is local */
3289         if (dic->seq < ebp->fSeq ||
3290                 dic->seq > ebp->lSeq)
3291                 return NULL;            /* non-local */
3292         
3293                                                         /* now check if it is the return from
3294         a function call */
3295         if (dic->op == CALL || dic->op == PCALL)
3296         {
3297                 if (ic->op != SEND && ic->op != RETURN &&
3298                         !POINTER_SET(ic) && !POINTER_GET(ic))
3299                 {
3300                         OP_SYMBOL (op)->ruonly = 1;
3301                         return dic;
3302                 }
3303                 dic = dic->next;
3304         }
3305         
3306         
3307         /* otherwise check that the definition does
3308         not contain any symbols in far space */
3309         if (isOperandInFarSpace (IC_LEFT (dic)) ||
3310                 isOperandInFarSpace (IC_RIGHT (dic)) ||
3311                 IS_OP_RUONLY (IC_LEFT (ic)) ||
3312                 IS_OP_RUONLY (IC_RIGHT (ic)))
3313         {
3314                 return NULL;
3315         }
3316         
3317         /* if pointer set then make sure the pointer
3318         is one byte */
3319         if (POINTER_SET (dic) &&
3320                 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3321                 return NULL;
3322         
3323         if (POINTER_GET (dic) &&
3324                 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3325                 return NULL;
3326         
3327         sic = dic;
3328         
3329         /* also make sure the intervenening instructions
3330         don't have any thing in far space */
3331         for (dic = dic->next; dic && dic != ic; dic = dic->next)
3332         {
3333                 
3334                 /* if there is an intervening function call then no */
3335                 if (dic->op == CALL || dic->op == PCALL)
3336                         return NULL;
3337                         /* if pointer set then make sure the pointer
3338                 is one byte */
3339                 if (POINTER_SET (dic) &&
3340                         !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3341                         return NULL;
3342                 
3343                 if (POINTER_GET (dic) &&
3344                         !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3345                         return NULL;
3346                 
3347                 /* if address of & the result is remat then okay */
3348                 if (dic->op == ADDRESS_OF &&
3349                         OP_SYMBOL (IC_RESULT (dic))->remat)
3350                         continue;
3351                 
3352                         /* if operand has size of three or more & this
3353                         operation is a '*','/' or '%' then 'b' may
3354                 cause a problem */
3355                 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3356                         getSize (operandType (op)) >= 3)
3357                         return NULL;
3358                 
3359                 /* if left or right or result is in far space */
3360                 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3361                         isOperandInFarSpace (IC_RIGHT (dic)) ||
3362                         isOperandInFarSpace (IC_RESULT (dic)) ||
3363                         IS_OP_RUONLY (IC_LEFT (dic)) ||
3364                         IS_OP_RUONLY (IC_RIGHT (dic)) ||
3365                         IS_OP_RUONLY (IC_RESULT (dic)))
3366                 {
3367                         return NULL;
3368                 }
3369         }
3370         
3371         OP_SYMBOL (op)->ruonly = 1;
3372         return sic;
3373         
3374 }
3375
3376 /*-----------------------------------------------------------------*/
3377 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
3378 /*-----------------------------------------------------------------*/
3379 static bool
3380 isBitwiseOptimizable (iCode * ic)
3381 {
3382         sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3383         sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3384         
3385         debugLog ("%s\n", __FUNCTION__);
3386         /* bitwise operations are considered optimizable
3387         under the following conditions (Jean-Louis VERN) 
3388         
3389           x & lit
3390           bit & bit
3391           bit & x
3392           bit ^ bit
3393           bit ^ x
3394           x   ^ lit
3395           x   | lit
3396           bit | bit
3397           bit | x
3398         */
3399         if (IS_LITERAL (rtype) ||
3400                 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3401                 return TRUE;
3402         else
3403                 return FALSE;
3404 }
3405
3406 /*-----------------------------------------------------------------*/
3407 /* packRegsForAccUse - pack registers for acc use                  */
3408 /*-----------------------------------------------------------------*/
3409 static void
3410 packRegsForAccUse (iCode * ic)
3411 {
3412         //iCode *uic;
3413         
3414         debugLog ("%s\n", __FUNCTION__);
3415
3416         /* result too large for WREG? */
3417         if (getSize (operandType (IC_RESULT (ic))) > 1)
3418           return;
3419         
3420         /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
3421          * is never used as an operand to an instruction that
3422          * cannot have WREG as an operand (e.g. BTFSx cannot
3423          * operate on WREG...
3424          * For now, store all results into proper registers. */
3425         return;
3426
3427 #if 0
3428         /* if this is an aggregate, e.g. a one byte char array */
3429         if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3430                 return;
3431         }
3432         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3433         
3434         /* if + or - then it has to be one byte result */
3435         if ((ic->op == '+' || ic->op == '-')
3436                 && getSize (operandType (IC_RESULT (ic))) > 1)
3437                 return;
3438         
3439         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3440         /* if shift operation make sure right side is not a literal */
3441         if (ic->op == RIGHT_OP &&
3442                 (isOperandLiteral (IC_RIGHT (ic)) ||
3443                 getSize (operandType (IC_RESULT (ic))) > 1))
3444                 return;
3445         
3446         if (ic->op == LEFT_OP &&
3447                 (isOperandLiteral (IC_RIGHT (ic)) ||
3448                 getSize (operandType (IC_RESULT (ic))) > 1))
3449                 return;
3450         
3451         if (IS_BITWISE_OP (ic) &&
3452                 getSize (operandType (IC_RESULT (ic))) > 1)
3453                 return;
3454         
3455         
3456         /* has only one definition */
3457         if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3458                 return;
3459         
3460         /* has only one use */
3461         if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3462                 return;
3463         
3464         /* and the usage immediately follows this iCode */
3465         if (!(uic = hTabItemWithKey (iCodehTab,
3466                 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3467                 return;
3468         
3469         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3470         if (ic->next != uic)
3471                 return;
3472         
3473         /* if it is a conditional branch then we definitely can */
3474         if (uic->op == IFX)
3475                 goto accuse;
3476         
3477         if (uic->op == JUMPTABLE)
3478                 return;
3479         
3480                 /* if the usage is not is an assignment
3481         or an arithmetic / bitwise / shift operation then not */
3482         if (POINTER_SET (uic) &&
3483                 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3484                 return;
3485         
3486         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3487         if (uic->op != '=' &&
3488                 !IS_ARITHMETIC_OP (uic) &&
3489                 !IS_BITWISE_OP (uic) &&
3490                 uic->op != LEFT_OP &&
3491                 uic->op != RIGHT_OP)
3492                 return;
3493         
3494         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3495         /* if used in ^ operation then make sure right is not a 
3496         literl */
3497         if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3498                 return;
3499         
3500         /* if shift operation make sure right side is not a literal */
3501         if (uic->op == RIGHT_OP &&
3502                 (isOperandLiteral (IC_RIGHT (uic)) ||
3503                 getSize (operandType (IC_RESULT (uic))) > 1))
3504                 return;
3505         
3506         if (uic->op == LEFT_OP &&
3507                 (isOperandLiteral (IC_RIGHT (uic)) ||
3508                 getSize (operandType (IC_RESULT (uic))) > 1))
3509                 return;
3510         
3511                 /* make sure that the result of this icode is not on the
3512         stack, since acc is used to compute stack offset */
3513         if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3514                 OP_SYMBOL (IC_RESULT (uic))->onStack)
3515                 return;
3516         
3517         /* if either one of them in far space then we cannot */
3518         if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3519                 isOperandInFarSpace (IC_LEFT (uic))) ||
3520                 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3521                 isOperandInFarSpace (IC_RIGHT (uic))))
3522                 return;
3523         
3524         /* if the usage has only one operand then we can */
3525         if (IC_LEFT (uic) == NULL ||
3526                 IC_RIGHT (uic) == NULL)
3527                 goto accuse;
3528         
3529                 /* make sure this is on the left side if not
3530         a '+' since '+' is commutative */
3531         if (ic->op != '+' &&
3532                 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3533                 return;
3534         
3535         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3536         /* if one of them is a literal then we can */
3537         if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3538                 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))  &&
3539                 (getSize (operandType (IC_RESULT (uic))) <= 1))
3540         {
3541                 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3542                 return;
3543         }
3544         
3545         debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3546         /* if the other one is not on stack then we can */
3547         if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3548                 (IS_ITEMP (IC_RIGHT (uic)) ||
3549                 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3550                 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3551                 goto accuse;
3552         
3553         if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3554                 (IS_ITEMP (IC_LEFT (uic)) ||
3555                 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3556                 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3557                 goto accuse;
3558         
3559         return;
3560         
3561 accuse:
3562         debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3563         OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3564 #endif  
3565 }
3566
3567 /*-----------------------------------------------------------------*/
3568 /* packForPush - hueristics to reduce iCode for pushing            */
3569 /*-----------------------------------------------------------------*/
3570 static void
3571 packForReceive (iCode * ic, eBBlock * ebp)
3572 {
3573         iCode *dic;
3574         
3575         debugLog ("%s\n", __FUNCTION__);
3576         debugAopGet ("  result:", IC_RESULT (ic));
3577         debugAopGet ("  left:", IC_LEFT (ic));
3578         debugAopGet ("  right:", IC_RIGHT (ic));
3579         
3580         if (!ic->next)
3581                 return;
3582         
3583         for (dic = ic->next; dic; dic = dic->next)
3584         {
3585                 
3586                 
3587                 
3588                 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3589                         debugLog ("    used on left\n");
3590                 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3591                         debugLog ("    used on right\n");
3592                 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3593                         debugLog ("    used on result\n");
3594                 
3595                 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3596                         (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3597                         return;
3598                 
3599         }
3600         
3601         debugLog ("  hey we can remove this unnecessary assign\n");
3602 }
3603 /*-----------------------------------------------------------------*/
3604 /* packForPush - hueristics to reduce iCode for pushing            */
3605 /*-----------------------------------------------------------------*/
3606 static void
3607 packForPush (iCode * ic, eBBlock * ebp)
3608 {
3609         iCode *dic;
3610         
3611         debugLog ("%s\n", __FUNCTION__);
3612         if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3613                 return;
3614         
3615         /* must have only definition & one usage */
3616         if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3617                 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3618                 return;
3619         
3620         /* find the definition */
3621         if (!(dic = hTabItemWithKey (iCodehTab,
3622                 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3623                 return;
3624         
3625         if (dic->op != '=' || POINTER_SET (dic))
3626                 return;
3627         
3628                 /* we now we know that it has one & only one def & use
3629         and the that the definition is an assignment */
3630         IC_LEFT (ic) = IC_RIGHT (dic);
3631         
3632         remiCodeFromeBBlock (ebp, dic);
3633         bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3634         hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3635 }
3636
3637 void printSymType(char * str, sym_link *sl)
3638 {
3639         debugLog ("    %s Symbol type: ",str);
3640         printTypeChain( sl, debugF);
3641         debugLog ("\n");
3642         
3643 }
3644
3645 /*-----------------------------------------------------------------*/
3646 /* some debug code to print the symbol S_TYPE. Note that
3647 * the function checkSClass in src/SDCCsymt.c dinks with
3648 * the S_TYPE in ways the PIC port doesn't fully like...*/
3649 /*-----------------------------------------------------------------*/
3650 void isData(sym_link *sl)
3651 {
3652         FILE *of = stderr;
3653         
3654         if(!sl)
3655                 return;
3656         
3657         if(debugF)
3658                 of = debugF;
3659         
3660         for ( ; sl; sl=sl->next) {
3661                 if(!IS_DECL(sl) ) {
3662                         switch (SPEC_SCLS(sl)) {
3663                                 
3664                         case S_DATA: fprintf (of, "data "); break;
3665                         case S_XDATA: fprintf (of, "xdata "); break;
3666                         case S_SFR: fprintf (of, "sfr "); break;
3667                         case S_SBIT: fprintf (of, "sbit "); break;
3668                         case S_CODE: fprintf (of, "code "); break;
3669                         case S_IDATA: fprintf (of, "idata "); break;
3670                         case S_PDATA: fprintf (of, "pdata "); break;
3671                         case S_LITERAL: fprintf (of, "literal "); break;
3672                         case S_STACK: fprintf (of, "stack "); break;
3673                         case S_XSTACK: fprintf (of, "xstack "); break;
3674                         case S_BIT: fprintf (of, "bit "); break;
3675                         case S_EEPROM: fprintf (of, "eeprom "); break;
3676                         default: break;
3677                         }
3678                         
3679                 }
3680                 
3681         }
3682         
3683 }
3684
3685 /*-----------------------------------------------------------------*/
3686 /* packRegisters - does some transformations to reduce register    */
3687 /*                   pressure                                      */
3688 /*-----------------------------------------------------------------*/
3689 static void
3690 packRegisters (eBBlock * ebp)
3691 {
3692         iCode *ic;
3693         int change = 0;
3694         
3695         debugLog ("%s\n", __FUNCTION__);
3696         
3697         while (1) {
3698                 
3699                 change = 0;
3700                 
3701                 /* look for assignments of the form */
3702                 /* iTempNN = TRueSym (someoperation) SomeOperand */
3703                 /*       ....                       */
3704                 /* TrueSym := iTempNN:1             */
3705                 for (ic = ebp->sch; ic; ic = ic->next)
3706                 {
3707                         
3708                         /* find assignment of the form TrueSym := iTempNN:1 */
3709                         if (ic->op == '=' && !POINTER_SET (ic))
3710                                 change += packRegsForAssign (ic, ebp);
3711                         /* debug stuff */
3712                         if (ic->op == '=')
3713                         {
3714                                 if (POINTER_SET (ic))
3715                                         debugLog ("pointer is set\n");
3716                                 debugAopGet ("  result:", IC_RESULT (ic));
3717                                 debugAopGet ("  left:", IC_LEFT (ic));
3718                                 debugAopGet ("  right:", IC_RIGHT (ic));
3719                         }
3720                         
3721                 }
3722                 
3723                 if (!change)
3724                         break;
3725         }
3726         
3727         for (ic = ebp->sch; ic; ic = ic->next) {
3728                 
3729                 if(IS_SYMOP ( IC_LEFT(ic))) {
3730                         sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3731                         
3732                         debugAopGet ("  left:", IC_LEFT (ic));
3733                         if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3734                                 debugLog ("    is a pointer\n");
3735                         
3736                         if(IS_OP_VOLATILE(IC_LEFT(ic)))
3737                                 debugLog ("    is volatile\n");
3738                         
3739                         isData(etype);
3740                         
3741                         printSymType("   ", OP_SYMBOL(IC_LEFT(ic))->type);
3742                 }
3743                 
3744                 if(IS_SYMOP ( IC_RIGHT(ic))) {
3745                         debugAopGet ("  right:", IC_RIGHT (ic));
3746                         printSymType("    ", OP_SYMBOL(IC_RIGHT(ic))->type);
3747                 }
3748                 
3749                 if(IS_SYMOP ( IC_RESULT(ic))) {
3750                         debugAopGet ("  result:", IC_RESULT (ic));
3751                         printSymType("     ", OP_SYMBOL(IC_RESULT(ic))->type);
3752                 }
3753                 
3754                 if (POINTER_SET (ic))
3755                         debugLog ("  %d - Pointer set\n", __LINE__);
3756                 
3757                 
3758                 /* Look for two subsequent iCodes with */
3759                 /*   iTemp := _c;         */
3760                 /*   _c = iTemp & op;     */
3761                 /* and replace them by    */
3762                 /*   iTemp := _c;         */
3763                 /*   _c = _c & op;        */
3764                 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3765                         ic->prev &&
3766                         ic->prev->op == '=' &&
3767                         IS_ITEMP (IC_LEFT (ic)) &&
3768                         IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3769                         isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3770         {
3771                         iCode* ic_prev = ic->prev;
3772                         symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3773                         
3774                         ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3775                         if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3776             {
3777                                 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3778                                 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3779                                         prev_result_sym->liveTo == ic->seq)
3780                 {
3781                                         prev_result_sym->liveTo = ic_prev->seq;
3782                 }
3783             }
3784                         bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3785                         
3786                         bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3787                         
3788                         if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3789             {
3790                                 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3791                                 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3792                                 remiCodeFromeBBlock (ebp, ic_prev);
3793                                 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3794             }
3795         }
3796                 
3797                 /* if this is an itemp & result of a address of a true sym 
3798                 then mark this as rematerialisable   */
3799                 if (ic->op == ADDRESS_OF &&
3800                         IS_ITEMP (IC_RESULT (ic)) &&
3801                         IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3802                         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3803                         !OP_SYMBOL (IC_LEFT (ic))->onStack)
3804                 {
3805                         
3806                         debugLog ("  %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3807                         
3808                         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3809                         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3810                         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3811                         
3812                 }
3813                 
3814                 /* if straight assignment then carry remat flag if
3815                 this is the only definition */
3816                 if (ic->op == '=' &&
3817                         !POINTER_SET (ic) &&
3818                         IS_SYMOP (IC_RIGHT (ic)) &&
3819                         OP_SYMBOL (IC_RIGHT (ic))->remat &&
3820                         bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3821                 {
3822                         debugLog ("  %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3823                         
3824                         OP_SYMBOL (IC_RESULT (ic))->remat =
3825                                 OP_SYMBOL (IC_RIGHT (ic))->remat;
3826                         OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3827                                 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3828                 }
3829                 
3830                 /* if this is a +/- operation with a rematerizable 
3831                 then mark this as rematerializable as well */
3832                 if ((ic->op == '+' || ic->op == '-') &&
3833                         (IS_SYMOP (IC_LEFT (ic)) &&
3834                         IS_ITEMP (IC_RESULT (ic)) &&
3835                         OP_SYMBOL (IC_LEFT (ic))->remat &&
3836                         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3837                         IS_OP_LITERAL (IC_RIGHT (ic))))
3838                 {
3839                         debugLog ("  %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3840                         //int i = 
3841                         operandLitValue (IC_RIGHT (ic));
3842                         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3843                         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3844                         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3845                 }
3846                 
3847                 /* mark the pointer usages */
3848                 if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
3849                 {
3850                         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3851                         debugLog ("  marking as a pointer (set) =>");
3852                         debugAopGet ("  result:", IC_RESULT (ic));
3853                 }
3854                 if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
3855                 {
3856                         OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3857                         debugLog ("  marking as a pointer (get) =>");
3858                         debugAopGet ("  left:", IC_LEFT (ic));
3859                 }
3860                 
3861                 if (!SKIP_IC2 (ic))
3862                 {
3863                         /* if we are using a symbol on the stack
3864                         then we should say pic14_ptrRegReq */
3865                         if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3866                                 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3867                                 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3868                         else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3869                                 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3870                                 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3871                         else
3872                         {
3873                                 if (IS_SYMOP (IC_LEFT (ic)))
3874                                         pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3875                                         OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3876                                 if (IS_SYMOP (IC_RIGHT (ic)))
3877                                         pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3878                                         OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3879                                 if (IS_SYMOP (IC_RESULT (ic)))
3880                                         pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3881                                         OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3882                         }
3883                         
3884                         debugLog ("  %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3885                         
3886                 }
3887                 
3888                 /* if the condition of an if instruction
3889                 is defined in the previous instruction then
3890                 mark the itemp as a conditional */
3891                 if ((IS_CONDITIONAL (ic) ||
3892                         ((ic->op == BITWISEAND ||
3893                         ic->op == '|' ||
3894                         ic->op == '^') &&
3895                         isBitwiseOptimizable (ic))) &&
3896                         ic->next && ic->next->op == IFX &&
3897                         isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3898                         OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3899                 {
3900                         
3901                         debugLog ("  %d\n", __LINE__);
3902                         OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3903                         continue;
3904                 }
3905                 
3906                 /* reduce for support function calls */
3907                 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3908                         packRegsForSupport (ic, ebp);
3909                 
3910                 /* if a parameter is passed, it's in W, so we may not
3911                 need to place a copy in a register */
3912                 if (ic->op == RECEIVE)
3913                         packForReceive (ic, ebp);
3914                 
3915                 /* some cases the redundant moves can
3916                 can be eliminated for return statements */
3917                 if ((ic->op == RETURN || ic->op == SEND) &&
3918                         !isOperandInFarSpace (IC_LEFT (ic)) &&
3919                         !options.model)
3920                         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3921                 
3922                 /* if pointer set & left has a size more than
3923                 one and right is not in far space */
3924                 if (POINTER_SET (ic) &&
3925                         !isOperandInFarSpace (IC_RIGHT (ic)) &&
3926                         IS_SYMOP(IC_RESULT(ic)) &&
3927                         !OP_SYMBOL (IC_RESULT (ic))->remat &&
3928                         !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3929                         getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3930                         
3931                         packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3932                 
3933                 /* if pointer get */
3934                 if (POINTER_GET (ic) &&
3935                         !isOperandInFarSpace (IC_RESULT (ic)) &&
3936                         IS_SYMOP(IC_LEFT(ic)) &&
3937                         !OP_SYMBOL (IC_LEFT (ic))->remat &&
3938                         !IS_OP_RUONLY (IC_RESULT (ic)) &&
3939                         getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3940                         
3941                         packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3942                 
3943                 
3944                 /* if this is cast for intergral promotion then
3945                 check if only use of  the definition of the 
3946                 operand being casted/ if yes then replace
3947                 the result of that arithmetic operation with 
3948                 this result and get rid of the cast */
3949                 if (ic->op == CAST) {
3950                         
3951                         sym_link *fromType = operandType (IC_RIGHT (ic));
3952                         sym_link *toType = operandType (IC_LEFT (ic));
3953                         
3954                         debugLog ("  %d - casting\n", __LINE__);
3955                         
3956                         if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3957                                 getSize (fromType) != getSize (toType)) {
3958                                 
3959                                 
3960                                 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3961                                 if (dic) {
3962                                         
3963                                         if (IS_ARITHMETIC_OP (dic)) {
3964                                                 
3965                                                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3966                                                 IC_RESULT (dic) = IC_RESULT (ic);
3967                                                 remiCodeFromeBBlock (ebp, ic);
3968                                                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3969                                                 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3970                                                 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3971                                                 ic = ic->prev;
3972                                         }  else
3973                                                 
3974                                                 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3975                                 }
3976                         } else {
3977                                 
3978                                 /* if the type from and type to are the same
3979                                 then if this is the only use then packit */
3980                                 if (compareType (operandType (IC_RIGHT (ic)),
3981                                         operandType (IC_LEFT (ic))) == 1) {
3982                                         
3983                                         iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3984                                         if (dic) {
3985                                                 
3986                                                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3987                                                 IC_RESULT (dic) = IC_RESULT (ic);
3988                                                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3989                                                 remiCodeFromeBBlock (ebp, ic);
3990                                                 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3991                                                 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3992                                                 ic = ic->prev;
3993                                         }
3994                                 }
3995                         }
3996                 }
3997                 
3998                 /* pack for PUSH 
3999                 iTempNN := (some variable in farspace) V1
4000                 push iTempNN ;
4001                 -------------
4002                 push V1
4003                 */
4004                 if (ic->op == IPUSH)
4005                 {
4006                         packForPush (ic, ebp);
4007                 }
4008                 
4009                 
4010                 /* pack registers for accumulator use, when the
4011                 result of an arithmetic or bit wise operation
4012                 has only one use, that use is immediately following
4013                 the defintion and the using iCode has only one
4014                 operand or has two operands but one is literal &
4015                 the result of that operation is not on stack then
4016                 we can leave the result of this operation in acc:b
4017                 combination */
4018                 if ((IS_ARITHMETIC_OP (ic)
4019                         
4020                         || IS_BITWISE_OP (ic)
4021                         
4022                         || ic->op == LEFT_OP || ic->op == RIGHT_OP
4023                         
4024                         ) &&
4025                         IS_ITEMP (IC_RESULT (ic)) &&
4026                         getSize (operandType (IC_RESULT (ic))) <= 2)
4027                         
4028                         packRegsForAccUse (ic);
4029                 
4030         }
4031 }
4032
4033 static void
4034 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4035 {
4036         int i;
4037         
4038         if (!debug || !debugF)
4039                 return;
4040         
4041         for (i = 0; i < count; i++)
4042         {
4043                 fprintf (debugF, "\n----------------------------------------------------------------\n");
4044                 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4045                         ebbs[i]->entryLabel->name,
4046                         ebbs[i]->depth,
4047                         ebbs[i]->noPath,
4048                         ebbs[i]->isLastInLoop);
4049                 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4050                         ebbs[i]->dfnum,
4051                         ebbs[i]->bbnum,
4052                         ebbs[i]->fSeq,
4053                         ebbs[i]->lSeq);
4054                 fprintf (debugF, "visited %d : hasFcall = %d\n",
4055                         ebbs[i]->visited,
4056                         ebbs[i]->hasFcall);
4057                 
4058                 fprintf (debugF, "\ndefines bitVector :");
4059                 bitVectDebugOn (ebbs[i]->defSet, debugF);
4060                 fprintf (debugF, "\nlocal defines bitVector :");
4061                 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4062                 fprintf (debugF, "\npointers Set bitvector :");
4063                 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4064                 fprintf (debugF, "\nin pointers Set bitvector :");
4065                 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4066                 fprintf (debugF, "\ninDefs Set bitvector :");
4067                 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4068                 fprintf (debugF, "\noutDefs Set bitvector :");
4069                 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4070                 fprintf (debugF, "\nusesDefs Set bitvector :");
4071                 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4072                 fprintf (debugF, "\n----------------------------------------------------------------\n");
4073                 printiCChain (ebbs[i]->sch, debugF);
4074         }
4075 }
4076 /*-----------------------------------------------------------------*/
4077 /* assignRegisters - assigns registers to each live range as need  */
4078 /*-----------------------------------------------------------------*/
4079 void
4080 pic14_assignRegisters (ebbIndex * ebbi)
4081 {
4082         eBBlock ** ebbs = ebbi->bbOrder;
4083         int count = ebbi->count;
4084         iCode *ic;
4085         int i;
4086         
4087         debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4088         debugLog ("\nebbs before optimizing:\n");
4089         dumpEbbsToDebug (ebbs, count);
4090         
4091         setToNull ((void *) &_G.funcrUsed);
4092         pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4093         
4094         
4095         /* change assignments this will remove some
4096         live ranges reducing some register pressure */
4097         for (i = 0; i < count; i++)
4098                 packRegisters (ebbs[i]);
4099         
4100         {
4101                 regs *reg;
4102                 int hkey;
4103                 int i=0;
4104                 
4105                 debugLog("dir registers allocated so far:\n");
4106                 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4107                 
4108                 while(reg) {
4109                         debugLog("  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4110                         reg = hTabNextItem(dynDirectRegNames, &hkey);
4111                 }
4112                 
4113         }
4114         
4115         if (options.dump_pack)
4116                 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4117         
4118         /* first determine for each live range the number of 
4119         registers & the type of registers required for each */
4120         regTypeNum ();
4121         
4122         /* and serially allocate registers */
4123         serialRegAssign (ebbs, count);
4124         
4125         /* if stack was extended then tell the user */
4126         if (_G.stackExtend)
4127         {
4128                 /*      werror(W_TOOMANY_SPILS,"stack", */
4129                 /*             _G.stackExtend,currFunc->name,""); */
4130                 _G.stackExtend = 0;
4131         }
4132         
4133         if (_G.dataExtend)
4134         {
4135                 /*      werror(W_TOOMANY_SPILS,"data space", */
4136                 /*             _G.dataExtend,currFunc->name,""); */
4137                 _G.dataExtend = 0;
4138         }
4139         
4140         /* after that create the register mask
4141         for each of the instruction */
4142         createRegMask (ebbs, count);
4143         
4144         /* redo that offsets for stacked automatic variables */
4145         redoStackOffsets ();
4146         
4147         if (options.dump_rassgn)
4148                 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4149         
4150         /* now get back the chain */
4151         ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4152         
4153         debugLog ("ebbs after optimizing:\n");
4154         dumpEbbsToDebug (ebbs, count);
4155         
4156         
4157         genpic14Code (ic);
4158         
4159         /* free up any _G.stackSpil locations allocated */
4160         applyToSet (_G.stackSpil, deallocStackSpil);
4161         _G.slocNum = 0;
4162         setToNull ((void *) &_G.stackSpil);
4163         setToNull ((void *) &_G.spiltSet);
4164         /* mark all registers as free */
4165         //pic14_freeAllRegs ();
4166         
4167         debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
4168         debugLogClose ();
4169         return;
4170 }