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