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