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