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