* support/Utils/dbuf_string.[ch]: added dbuf_chomp(),
[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->usl.spillLoc ? 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->usl.spillLoc ? 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->usl.spillLoc &&
1404       (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->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->usl.spillLoc && !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->usl.spillLoc = 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->usl.spillLoc = 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->usl.spillLoc)
1724     return FALSE;
1725
1726   etype = getSpec (sym->usl.spillLoc->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->usl.spillLoc))
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->usl.spillLoc && !sym->remat)
1773     sym->usl.spillLoc->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->usl.spillLoc->rname[0] ?
1804                            sym->usl.spillLoc->rname :
1805                            sym->usl.spillLoc->name));
1806       sym->spildir = 1;
1807       /* mark it as allocation required */
1808       sym->usl.spillLoc->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->usl.spillLoc->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->usl.spillLoc->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->usl.spillLoc->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->usl.spillLoc->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->usl.spillLoc &&
2344                   !sym->usl.spillLoc->allocreq)
2345                 {
2346                   sym->usl.spillLoc->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->usl.spillLoc) {
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   char *s = buffer;
2677   iCode *ic = sym->rematiCode;
2678   symbol *psym = NULL;
2679
2680   debugLog ("%s\n", __FUNCTION__);
2681
2682   //printf ("%s\n", s);
2683
2684   /* if plus or minus print the right hand side */
2685
2686   if (ic->op == '+' || ic->op == '-') {
2687
2688     iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2689
2690     sprintf (s, "(%s %c 0x%04x)",
2691              OP_SYMBOL (IC_LEFT (ric))->rname,
2692              ic->op,
2693              (int) operandLitValue (IC_RIGHT (ic)));
2694
2695
2696     //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2697
2698     psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2699     psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2700
2701     return psym;
2702   }
2703
2704   sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2705   psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2706
2707   //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2708   return psym;
2709 }
2710
2711 #if 0
2712 /*-----------------------------------------------------------------*/
2713 /* rematStr - returns the rematerialized string for a remat var    */
2714 /*-----------------------------------------------------------------*/
2715 static char *
2716 rematStr (symbol * sym)
2717 {
2718   char *s = buffer;
2719   iCode *ic = sym->rematiCode;
2720
2721   debugLog ("%s\n", __FUNCTION__);
2722   while (1)
2723     {
2724
2725       printf ("%s\n", s);
2726       /* if plus or minus print the right hand side */
2727 /*
2728    if (ic->op == '+' || ic->op == '-') {
2729    sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2730    ic->op );
2731    s += strlen(s);
2732    ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2733    continue ;
2734    }
2735  */
2736       if (ic->op == '+' || ic->op == '-')
2737         {
2738           iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2739           sprintf (s, "(%s %c 0x%04x)",
2740                    OP_SYMBOL (IC_LEFT (ric))->rname,
2741                    ic->op,
2742                    (int) operandLitValue (IC_RIGHT (ic)));
2743
2744           //s += strlen(s);
2745           //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2746           //continue ;
2747           //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2748           return buffer;
2749         }
2750
2751       /* we reached the end */
2752       sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2753       break;
2754     }
2755
2756   printf ("%s\n", buffer);
2757   return buffer;
2758 }
2759 #endif
2760
2761 /*-----------------------------------------------------------------*/
2762 /* regTypeNum - computes the type & number of registers required   */
2763 /*-----------------------------------------------------------------*/
2764 static void
2765 regTypeNum ()
2766 {
2767   symbol *sym;
2768   int k;
2769   iCode *ic;
2770
2771   debugLog ("%s\n", __FUNCTION__);
2772   /* for each live range do */
2773   for (sym = hTabFirstItem (liveRanges, &k); sym;
2774        sym = hTabNextItem (liveRanges, &k)) {
2775
2776     debugLog ("  %d - %s\n", __LINE__, sym->rname);
2777     //fprintf(stderr,"  %d - %s\n", __LINE__, sym->rname);
2778
2779     /* if used zero times then no registers needed */
2780     if ((sym->liveTo - sym->liveFrom) == 0)
2781       continue;
2782
2783
2784     /* if the live range is a temporary */
2785     if (sym->isitmp) {
2786
2787       debugLog ("  %d - itemp register\n", __LINE__);
2788
2789       /* if the type is marked as a conditional */
2790       if (sym->regType == REG_CND)
2791         continue;
2792
2793       /* if used in return only then we don't
2794          need registers */
2795       if (sym->ruonly || sym->accuse) {
2796         if (IS_AGGREGATE (sym->type) || sym->isptr)
2797           sym->type = aggrToPtr (sym->type, FALSE);
2798         debugLog ("  %d - no reg needed - used as a return\n", __LINE__);
2799         continue;
2800       }
2801
2802       /* if the symbol has only one definition &
2803          that definition is a get_pointer and the
2804          pointer we are getting is rematerializable and
2805          in "data" space */
2806
2807       if (bitVectnBitsOn (sym->defs) == 1 &&
2808           (ic = hTabItemWithKey (iCodehTab,
2809                                  bitVectFirstBit (sym->defs))) &&
2810           POINTER_GET (ic) &&
2811           !IS_BITVAR (sym->etype) &&
2812           (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2813
2814 //        continue;       /* FIXME -- VR */
2815         if (ptrPseudoSymSafe (sym, ic)) {
2816
2817           symbol *psym;
2818
2819           debugLog ("  %d - \n", __LINE__);
2820
2821           /* create a psuedo symbol & force a spil */
2822           //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2823           psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2824           psym->type = sym->type;
2825           psym->etype = sym->etype;
2826           psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2827           strcpy (psym->rname, psym->name);
2828           sym->isspilt = 1;
2829           sym->usl.spillLoc = psym;
2830           continue;
2831         }
2832
2833         /* if in data space or idata space then try to
2834            allocate pointer register */
2835
2836       }
2837
2838       /* if not then we require registers */
2839       sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2840                     getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2841                     getSize (sym->type));
2842
2843
2844 #if 0
2845     if(IS_PTR_CONST (sym->type)) {
2846 #else
2847     if(IS_CODEPTR (sym->type)) {
2848 #endif
2849       // what IS this ???? (HJD)
2850       debugLog ("  %d const pointer type requires %d registers, changing to 3\n",__LINE__,sym->nRegs); // patch 14
2851       sym->nRegs = 3; // patch 14
2852     }
2853
2854       if (sym->nRegs > 4) {
2855         fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2856         printTypeChain (sym->type, stderr);
2857         fprintf (stderr, "\n");
2858       }
2859
2860       /* determine the type of register required */
2861       if (sym->nRegs == 1 &&
2862           IS_PTR (sym->type) &&
2863           sym->uptr)
2864         sym->regType = REG_PTR;
2865       else
2866         sym->regType = REG_GPR;
2867
2868
2869       debugLog ("  reg name %s,  reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2870
2871     }
2872     else
2873       /* for the first run we don't provide */
2874       /* registers for true symbols we will */
2875       /* see how things go                  */
2876       sym->nRegs = 0;
2877
2878   }
2879
2880 }
2881 static DEFSETFUNC (markRegFree)
2882 {
2883   ((regs *)item)->isFree = 1;
2884 //  ((regs *)item)->wasUsed = 0;
2885
2886   return 0;
2887 }
2888
2889 DEFSETFUNC (pic16_deallocReg)
2890 {
2891   fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2892   ((regs *)item)->isFree = 1;
2893   ((regs *)item)->wasUsed = 0;
2894
2895   return 0;
2896 }
2897 /*-----------------------------------------------------------------*/
2898 /* freeAllRegs - mark all registers as free                        */
2899 /*-----------------------------------------------------------------*/
2900 void
2901 pic16_freeAllRegs ()
2902 {
2903   debugLog ("%s\n", __FUNCTION__);
2904
2905   applyToSet(pic16_dynAllocRegs,markRegFree);
2906   applyToSet(pic16_dynStackRegs,markRegFree);
2907 }
2908
2909 /*-----------------------------------------------------------------*/
2910 /*-----------------------------------------------------------------*/
2911 void
2912 pic16_deallocateAllRegs ()
2913 {
2914   debugLog ("%s\n", __FUNCTION__);
2915
2916   applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2917 }
2918
2919
2920 /*-----------------------------------------------------------------*/
2921 /* deallocStackSpil - this will set the stack pointer back         */
2922 /*-----------------------------------------------------------------*/
2923 static
2924 DEFSETFUNC (deallocStackSpil)
2925 {
2926   symbol *sym = item;
2927
2928   debugLog ("%s\n", __FUNCTION__);
2929   deallocLocal (sym);
2930   return 0;
2931 }
2932
2933 /*-----------------------------------------------------------------*/
2934 /* farSpacePackable - returns the packable icode for far variables */
2935 /*-----------------------------------------------------------------*/
2936 static iCode *
2937 farSpacePackable (iCode * ic)
2938 {
2939   iCode *dic;
2940
2941   debugLog ("%s\n", __FUNCTION__);
2942   /* go thru till we find a definition for the
2943      symbol on the right */
2944   for (dic = ic->prev; dic; dic = dic->prev)
2945     {
2946
2947       /* if the definition is a call then no */
2948       if ((dic->op == CALL || dic->op == PCALL) &&
2949           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2950         {
2951           return NULL;
2952         }
2953
2954       /* if shift by unknown amount then not */
2955       if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2956           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2957         return NULL;
2958
2959       /* if pointer get and size > 1 */
2960       if (POINTER_GET (dic) &&
2961           getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2962         return NULL;
2963
2964       if (POINTER_SET (dic) &&
2965           getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2966         return NULL;
2967
2968       /* if any three is a true symbol in far space */
2969       if (IC_RESULT (dic) &&
2970           IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2971           isOperandInFarSpace (IC_RESULT (dic)))
2972         return NULL;
2973
2974       if (IC_RIGHT (dic) &&
2975           IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2976           isOperandInFarSpace (IC_RIGHT (dic)) &&
2977           !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2978         return NULL;
2979
2980       if (IC_LEFT (dic) &&
2981           IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2982           isOperandInFarSpace (IC_LEFT (dic)) &&
2983           !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2984         return NULL;
2985
2986       if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2987         {
2988           if ((dic->op == LEFT_OP ||
2989                dic->op == RIGHT_OP ||
2990                dic->op == '-') &&
2991               IS_OP_LITERAL (IC_RIGHT (dic)))
2992             return NULL;
2993           else
2994             return dic;
2995         }
2996     }
2997
2998   return NULL;
2999 }
3000
3001 #if 0
3002 static int packRegsForPointerGet(iCode *ic, eBBlock *ebp)
3003 {
3004   iCode *dic, *sic;
3005
3006     debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
3007     debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
3008     debugAopGet ("  result:", IC_RESULT (ic));
3009     debugAopGet ("  left:", IC_LEFT (ic));
3010     debugAopGet ("  right:", IC_RIGHT (ic));
3011
3012     dic = ic->prev;
3013     if((dic->op == '=')
3014       && (
3015 }
3016 #endif
3017
3018
3019 void replaceOperandWithOperand(eBBlock *ebp, iCode *ic, operand *src, iCode *dic, operand *dst);
3020
3021 /*-----------------------------------------------------------------*/
3022 /* packRegsForAssign - register reduction for assignment           */
3023 /*-----------------------------------------------------------------*/
3024 static int
3025 packRegsForAssign (iCode * ic, eBBlock * ebp)
3026 {
3027   iCode *dic, *sic;
3028
3029   debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
3030   debugLog ("ic->op = %s\n", pic16_decodeOp( ic->op ) );
3031   debugAopGet ("  result:", IC_RESULT (ic));
3032   debugAopGet ("  left:", IC_LEFT (ic));
3033   debugAopGet ("  right:", IC_RIGHT (ic));
3034
3035 //      fprintf(stderr, "%s:%d symbol = %s\n", __FILE__, __LINE__, OP_SYMBOL( IC_RESULT(ic))->name);
3036
3037         debugLog(" %d - actuall processing\n", __LINE__ );
3038
3039   if (!IS_ITEMP (IC_RESULT (ic))) {
3040     pic16_allocDirReg(IC_RESULT (ic));
3041     debugLog ("  %d - result is not temp\n", __LINE__);
3042   }
3043
3044 //  if(IS_VALOP(IC_RIGHT(ic)))return 0;
3045
3046 /* See BUGLOG0001 - VR */
3047 #if 1
3048   if (!IS_ITEMP (IC_RIGHT (ic)) /*&& (!IS_PARM(IC_RESULT(ic)))*/) {
3049     debugLog ("  %d - not packing - right is not temp\n", __LINE__);
3050     pic16_allocDirReg(IC_RIGHT (ic));
3051     return 0;
3052   }
3053 #endif
3054
3055   if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
3056       OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
3057     {
3058       debugLog ("  %d - not packing - right side fails \n", __LINE__);
3059       return 0;
3060     }
3061
3062   /* if the true symbol is defined in far space or on stack
3063      then we should not since this will increase register pressure */
3064   if (isOperandInFarSpace (IC_RESULT (ic)))
3065     {
3066       if ((dic = farSpacePackable (ic)))
3067         goto pack;
3068       else
3069         return 0;
3070
3071     }
3072
3073   /* find the definition of iTempNN scanning backwards if we find a
3074      a use of the true symbol before we find the definition then
3075      we cannot pack */
3076   for (dic = ic->prev; dic; dic = dic->prev)
3077     {
3078
3079       /* if there is a function call and this is
3080          a parameter & not my parameter then don't pack it */
3081       if ((dic->op == CALL || dic->op == PCALL) &&
3082           (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3083            !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3084         {
3085           debugLog ("  %d - \n", __LINE__);
3086           dic = NULL;
3087           break;
3088         }
3089
3090
3091       if (SKIP_IC2 (dic))
3092         continue;
3093
3094         debugLog("%d\tSearching for iTempNN\n", __LINE__);
3095
3096       if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3097           IS_OP_VOLATILE (IC_RESULT (dic)))
3098         {
3099           debugLog ("  %d - dic is VOLATILE \n", __LINE__);
3100           dic = NULL;
3101           break;
3102         }
3103
3104 #if 1
3105       if( IS_SYMOP( IC_RESULT(dic)) &&
3106         IS_BITFIELD( OP_SYMBOL(IC_RESULT(dic))->etype ) ) {
3107
3108           debugLog (" %d - result is bitfield\n", __LINE__);
3109           dic = NULL;
3110           break;
3111         }
3112 #endif
3113
3114       if (IS_SYMOP (IC_RESULT (dic)) &&
3115           IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3116         {
3117           /* A previous result was assigned to the same register - we'll our definition */
3118           debugLog ("  %d - dic result key == ic right key -- pointer set=%c\n",
3119                     __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3120           if (POINTER_SET (dic))
3121             dic = NULL;
3122
3123           break;
3124         }
3125
3126       if (IS_SYMOP (IC_RIGHT (dic)) &&
3127           (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3128            IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3129         {
3130           debugLog ("  %d - dic right key == ic rightor result key\n", __LINE__);
3131           dic = NULL;
3132           break;
3133         }
3134
3135       if (IS_SYMOP (IC_LEFT (dic)) &&
3136           (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3137            IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3138         {
3139           debugLog ("  %d - dic left key == ic rightor result key\n", __LINE__);
3140           dic = NULL;
3141           break;
3142         }
3143
3144       if (POINTER_SET (dic) &&
3145           IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3146         {
3147           debugLog ("  %d - dic result key == ic result key -- pointer set=Y\n",
3148                     __LINE__);
3149           dic = NULL;
3150           break;
3151         }
3152     }
3153
3154   if (!dic)
3155     return 0;                   /* did not find */
3156
3157 #if 1
3158         /* This code is taken from the hc08 port. Do not know
3159          * if it fits for pic16, but I leave it here just in case */
3160
3161         /* if assignment then check that right is not a bit */
3162         if (ASSIGNMENT (ic) && !POINTER_SET (ic)) {
3163           sym_link *etype = operandType (IC_RESULT (dic));
3164
3165                 if (IS_BITFIELD (etype)) {
3166                         /* if result is a bit too then it's ok */
3167                         etype = operandType (IC_RESULT (ic));
3168                         if (!IS_BITFIELD (etype)) {
3169                                 debugLog(" %d bitfields\n");
3170                           return 0;
3171                         }
3172                 }
3173         }
3174 #endif
3175
3176   /* if the result is on stack or iaccess then it must be
3177      the same atleast one of the operands */
3178   if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3179       OP_SYMBOL (IC_RESULT (ic))->iaccess)
3180     {
3181       /* the operation has only one symbol
3182          operator then we can pack */
3183       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3184           (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3185         goto pack;
3186
3187       if (!((IC_LEFT (dic) &&
3188              IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3189             (IC_RIGHT (dic) &&
3190              IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3191         return 0;
3192     }
3193 pack:
3194   debugLog ("  packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3195   debugLog ("  replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3196   /* found the definition */
3197   /* replace the result with the result of */
3198   /* this assignment and remove this assignment */
3199
3200
3201     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3202     IC_RESULT (dic) = IC_RESULT (ic);
3203
3204     if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3205       {
3206         OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3207       }
3208     /* delete from liverange table also
3209        delete from all the points inbetween and the new
3210        one */
3211     for (sic = dic; sic != ic; sic = sic->next)
3212       {
3213         bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3214         if (IS_ITEMP (IC_RESULT (dic)))
3215           bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3216       }
3217
3218     remiCodeFromeBBlock (ebp, ic);
3219     bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3220
3221     debugLog("  %d\n", __LINE__ );
3222     hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3223     OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3224     return 1;
3225 }
3226
3227
3228 #if 1
3229
3230 #define NO_packRegsForAccUse
3231 #define NO_packRegsForSupport
3232 #define NO_packRegsForOneuse
3233 #define NO_cast_peep
3234
3235 #endif
3236
3237
3238 #ifndef NO_packRegsForSupport
3239 /*-----------------------------------------------------------------*/
3240 /* findAssignToSym : scanning backwards looks for first assig found */
3241 /*-----------------------------------------------------------------*/
3242 static iCode *
3243 findAssignToSym (operand * op, iCode * ic)
3244 {
3245   iCode *dic;
3246
3247   debugLog ("%s\n", __FUNCTION__);
3248   for (dic = ic->prev; dic; dic = dic->prev)
3249     {
3250
3251       /* if definition by assignment */
3252       if (dic->op == '=' &&
3253           !POINTER_SET (dic) &&
3254           IC_RESULT (dic)->key == op->key
3255 /*          &&  IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3256         )
3257         {
3258
3259           /* we are interested only if defined in far space */
3260           /* or in stack space in case of + & - */
3261
3262           /* if assigned to a non-symbol then return
3263              true */
3264           if (!IS_SYMOP (IC_RIGHT (dic)))
3265             break;
3266
3267           /* if the symbol is in far space then
3268              we should not */
3269           if (isOperandInFarSpace (IC_RIGHT (dic)))
3270             return NULL;
3271
3272           /* for + & - operations make sure that
3273              if it is on the stack it is the same
3274              as one of the three operands */
3275           if ((ic->op == '+' || ic->op == '-') &&
3276               OP_SYMBOL (IC_RIGHT (dic))->onStack)
3277             {
3278               if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3279                   IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3280                   IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3281                 return NULL;
3282             }
3283
3284           break;
3285
3286         }
3287
3288       /* if we find an usage then we cannot delete it */
3289       if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3290         return NULL;
3291
3292       if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3293         return NULL;
3294
3295       if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3296         return NULL;
3297     }
3298
3299   /* now make sure that the right side of dic
3300      is not defined between ic & dic */
3301   if (dic)
3302     {
3303       iCode *sic = dic->next;
3304
3305       for (; sic != ic; sic = sic->next)
3306         if (IC_RESULT (sic) &&
3307             IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3308           return NULL;
3309     }
3310
3311   return dic;
3312
3313
3314 }
3315 #endif
3316
3317
3318 #ifndef NO_packRegsForSupport
3319 /*-----------------------------------------------------------------*/
3320 /* packRegsForSupport :- reduce some registers for support calls   */
3321 /*-----------------------------------------------------------------*/
3322 static int
3323 packRegsForSupport (iCode * ic, eBBlock * ebp)
3324 {
3325   int change = 0;
3326
3327   debugLog ("%s\n", __FUNCTION__);
3328   /* for the left & right operand :- look to see if the
3329      left was assigned a true symbol in far space in that
3330      case replace them */
3331   if (IS_ITEMP (IC_LEFT (ic)) &&
3332       OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3333     {
3334       iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3335       iCode *sic;
3336
3337       if (!dic)
3338         goto right;
3339
3340       debugAopGet ("removing left:", IC_LEFT (ic));
3341
3342       /* found it we need to remove it from the
3343          block */
3344       for (sic = dic; sic != ic; sic = sic->next)
3345         bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3346
3347       IC_LEFT (ic)->operand.symOperand =
3348         IC_RIGHT (dic)->operand.symOperand;
3349       IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3350       remiCodeFromeBBlock (ebp, dic);
3351       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3352       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3353       change++;
3354     }
3355
3356   /* do the same for the right operand */
3357 right:
3358   if (!change &&
3359       IS_ITEMP (IC_RIGHT (ic)) &&
3360       OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3361     {
3362       iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3363       iCode *sic;
3364
3365       if (!dic)
3366         return change;
3367
3368       /* if this is a subtraction & the result
3369          is a true symbol in far space then don't pack */
3370       if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3371         {
3372           sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3373           if (IN_FARSPACE (SPEC_OCLS (etype)))
3374             return change;
3375         }
3376
3377       debugAopGet ("removing right:", IC_RIGHT (ic));
3378
3379       /* found it we need to remove it from the
3380          block */
3381       for (sic = dic; sic != ic; sic = sic->next)
3382         bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3383
3384       IC_RIGHT (ic)->operand.symOperand =
3385         IC_RIGHT (dic)->operand.symOperand;
3386       IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3387
3388       remiCodeFromeBBlock (ebp, dic);
3389       bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3390       hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3391       change++;
3392     }
3393
3394   return change;
3395 }
3396 #endif
3397
3398
3399 #ifndef NO_packRegsForOneuse
3400 /*-----------------------------------------------------------------*/
3401 /* packRegsForOneuse : - will reduce some registers for single Use */
3402 /*-----------------------------------------------------------------*/
3403 static iCode *
3404 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3405 {
3406   bitVect *uses;
3407   iCode *dic, *sic;
3408
3409   return NULL;
3410
3411   debugLog ("%s\n", __FUNCTION__);
3412   /* if returning a literal then do nothing */
3413   if (!IS_SYMOP (op))
3414     return NULL;
3415
3416   if(OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly)
3417     return NULL;
3418
3419   /* only upto 2 bytes since we cannot predict
3420      the usage of b, & acc */
3421   if (getSize (operandType (op)) > (pic16_fReturnSizePic - 1)
3422       && ic->op != RETURN
3423       && ic->op != SEND
3424       && !POINTER_SET(ic)
3425       && !POINTER_GET(ic)
3426       )
3427     return NULL;
3428
3429   /* this routine will mark the a symbol as used in one
3430      instruction use only && if the definition is local
3431      (ie. within the basic block) && has only one definition &&
3432      that definition is either a return value from a
3433      function or does not contain any variables in
3434      far space */
3435
3436 #if 0
3437   uses = bitVectCopy (OP_USES (op));
3438   bitVectUnSetBit (uses, ic->key);      /* take away this iCode */
3439   if (!bitVectIsZero (uses))    /* has other uses */
3440     return NULL;
3441 #endif
3442
3443 #if 1
3444   if (bitVectnBitsOn (OP_USES (op)) > 1)
3445     return NULL;
3446 #endif
3447
3448   /* if it has only one defintion */
3449   if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3450     return NULL;                /* has more than one definition */
3451
3452   /* get that definition */
3453   if (!(dic =
3454         hTabItemWithKey (iCodehTab,
3455                          bitVectFirstBit (OP_DEFS (op)))))
3456     return NULL;
3457
3458   /* found the definition now check if it is local */
3459   if (dic->seq < ebp->fSeq ||
3460       dic->seq > ebp->lSeq)
3461     return NULL;                /* non-local */
3462
3463   /* now check if it is the return from
3464      a function call */
3465   if (dic->op == CALL || dic->op == PCALL)
3466     {
3467       if (ic->op != SEND && ic->op != RETURN &&
3468           !POINTER_SET(ic) && !POINTER_GET(ic))
3469         {
3470           OP_SYMBOL (op)->ruonly = 1;
3471           return dic;
3472         }
3473       dic = dic->next;
3474     }
3475   else
3476     {
3477
3478
3479   /* otherwise check that the definition does
3480      not contain any symbols in far space */
3481   if (isOperandInFarSpace (IC_LEFT (dic)) ||
3482       isOperandInFarSpace (IC_RIGHT (dic)) ||
3483       IS_OP_RUONLY (IC_LEFT (ic)) ||
3484       IS_OP_RUONLY (IC_RIGHT (ic)))
3485     {
3486       return NULL;
3487     }
3488
3489   /* if pointer set then make sure the pointer
3490      is one byte */
3491   if (POINTER_SET (dic) &&
3492       !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3493     return NULL;
3494
3495   if (POINTER_GET (dic) &&
3496       !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3497     return NULL;
3498     }
3499
3500   sic = dic;
3501
3502   /* also make sure the intervenening instructions
3503      don't have any thing in far space */
3504   for (dic = dic->next; dic && dic != ic; dic = dic->next)
3505     {
3506
3507       /* if there is an intervening function call then no */
3508       if (dic->op == CALL || dic->op == PCALL)
3509         return NULL;
3510       /* if pointer set then make sure the pointer
3511          is one byte */
3512       if (POINTER_SET (dic) &&
3513           !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3514         return NULL;
3515
3516       if (POINTER_GET (dic) &&
3517           !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3518         return NULL;
3519
3520       /* if address of & the result is remat then okay */
3521       if (dic->op == ADDRESS_OF &&
3522           OP_SYMBOL (IC_RESULT (dic))->remat)
3523         continue;
3524
3525       /* if operand has size of three or more & this
3526          operation is a '*','/' or '%' then 'b' may
3527          cause a problem */
3528       if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3529           getSize (operandType (op)) >= 2)
3530         return NULL;
3531
3532       /* if left or right or result is in far space */
3533       if (isOperandInFarSpace (IC_LEFT (dic)) ||
3534           isOperandInFarSpace (IC_RIGHT (dic)) ||
3535           isOperandInFarSpace (IC_RESULT (dic)) ||
3536           IS_OP_RUONLY (IC_LEFT (dic)) ||
3537           IS_OP_RUONLY (IC_RIGHT (dic)) ||
3538           IS_OP_RUONLY (IC_RESULT (dic)))
3539         {
3540           return NULL;
3541         }
3542     }
3543
3544   OP_SYMBOL (op)->ruonly = 1;
3545   return sic;
3546
3547 }
3548 #endif
3549
3550
3551 /*-----------------------------------------------------------------*/
3552 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN          */
3553 /*-----------------------------------------------------------------*/
3554 static bool
3555 isBitwiseOptimizable (iCode * ic)
3556 {
3557   sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3558   sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3559
3560   debugLog ("%s\n", __FUNCTION__);
3561   /* bitwise operations are considered optimizable
3562      under the following conditions (Jean-Louis VERN)
3563
3564      x & lit
3565      bit & bit
3566      bit & x
3567      bit ^ bit
3568      bit ^ x
3569      x   ^ lit
3570      x   | lit
3571      bit | bit
3572      bit | x
3573    */
3574   if (IS_LITERAL (rtype) ||
3575       (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3576     return TRUE;
3577   else
3578     return FALSE;
3579 }
3580
3581
3582 #ifndef NO_packRegsForAccUse
3583
3584 /*-----------------------------------------------------------------*/
3585 /* packRegsForAccUse - pack registers for acc use                  */
3586 /*-----------------------------------------------------------------*/
3587 static void
3588 packRegsForAccUse (iCode * ic)
3589 {
3590   iCode *uic;
3591
3592   debugLog ("%s\n", __FUNCTION__);
3593
3594   /* if this is an aggregate, e.g. a one byte char array */
3595   if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3596     return;
3597   }
3598   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3599
3600   /* if + or - then it has to be one byte result */
3601   if ((ic->op == '+' || ic->op == '-')
3602       && getSize (operandType (IC_RESULT (ic))) > 1)
3603     return;
3604
3605   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3606   /* if shift operation make sure right side is not a literal */
3607   if (ic->op == RIGHT_OP &&
3608       (isOperandLiteral (IC_RIGHT (ic)) ||
3609        getSize (operandType (IC_RESULT (ic))) > 1))
3610     return;
3611
3612   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3613   if (ic->op == LEFT_OP &&
3614       (isOperandLiteral (IC_RIGHT (ic)) ||
3615        getSize (operandType (IC_RESULT (ic))) > 1))
3616     return;
3617
3618   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3619   if (IS_BITWISE_OP (ic) &&
3620       getSize (operandType (IC_RESULT (ic))) > 1)
3621     return;
3622
3623
3624   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3625   /* has only one definition */
3626   if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3627     return;
3628
3629   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3630   /* has only one use */
3631   if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3632     return;
3633
3634   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3635   /* and the usage immediately follows this iCode */
3636   if (!(uic = hTabItemWithKey (iCodehTab,
3637                                bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3638     return;
3639
3640   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3641   if (ic->next != uic)
3642     return;
3643
3644   /* if it is a conditional branch then we definitely can */
3645   if (uic->op == IFX)
3646     goto accuse;
3647
3648   if (uic->op == JUMPTABLE)
3649     return;
3650
3651   /* if the usage is not is an assignment
3652      or an arithmetic / bitwise / shift operation then not */
3653   if (POINTER_SET (uic) &&
3654       getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3655     return;
3656
3657   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3658   if (uic->op != '=' &&
3659       !IS_ARITHMETIC_OP (uic) &&
3660       !IS_BITWISE_OP (uic) &&
3661       uic->op != LEFT_OP &&
3662       uic->op != RIGHT_OP)
3663     return;
3664
3665   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3666   /* if used in ^ operation then make sure right is not a
3667      literl */
3668   if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3669     return;
3670
3671   /* if shift operation make sure right side is not a literal */
3672   if (uic->op == RIGHT_OP &&
3673       (isOperandLiteral (IC_RIGHT (uic)) ||
3674        getSize (operandType (IC_RESULT (uic))) > 1))
3675     return;
3676
3677   if (uic->op == LEFT_OP &&
3678       (isOperandLiteral (IC_RIGHT (uic)) ||
3679        getSize (operandType (IC_RESULT (uic))) > 1))
3680     return;
3681
3682   /* make sure that the result of this icode is not on the
3683      stack, since acc is used to compute stack offset */
3684   if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3685       OP_SYMBOL (IC_RESULT (uic))->onStack)
3686     return;
3687
3688   /* if either one of them in far space then we cannot */
3689   if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3690        isOperandInFarSpace (IC_LEFT (uic))) ||
3691       (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3692        isOperandInFarSpace (IC_RIGHT (uic))))
3693     return;
3694
3695   /* if the usage has only one operand then we can */
3696   if (IC_LEFT (uic) == NULL ||
3697       IC_RIGHT (uic) == NULL)
3698     goto accuse;
3699
3700   /* make sure this is on the left side if not
3701      a '+' since '+' is commutative */
3702   if (ic->op != '+' &&
3703       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3704     return;
3705
3706 #if 1
3707   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3708   /* if one of them is a literal then we can */
3709   if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3710         (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))  &&
3711        (getSize (operandType (IC_RESULT (uic))) <= 1))
3712     {
3713       OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3714       return;
3715     }
3716 #endif
3717
3718   debugLog ("  %s:%d\n", __FUNCTION__,__LINE__);
3719   /* if the other one is not on stack then we can */
3720   if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3721       (IS_ITEMP (IC_RIGHT (uic)) ||
3722        (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3723         !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3724     goto accuse;
3725
3726   if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3727       (IS_ITEMP (IC_LEFT (uic)) ||
3728        (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3729         !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3730     goto accuse;
3731
3732   return;
3733
3734 accuse:
3735   debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3736   OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3737
3738
3739 }
3740 #endif
3741
3742
3743 /*-----------------------------------------------------------------*/
3744 /* packForPush - hueristics to reduce iCode for pushing            */
3745 /*-----------------------------------------------------------------*/
3746 static void
3747 packForReceive (iCode * ic, eBBlock * ebp)
3748 {
3749   iCode *dic;
3750
3751   debugLog ("%s\n", __FUNCTION__);
3752   debugAopGet ("  result:", IC_RESULT (ic));
3753   debugAopGet ("  left:", IC_LEFT (ic));
3754   debugAopGet ("  right:", IC_RIGHT (ic));
3755
3756   if (!ic->next)
3757     return;
3758
3759   for (dic = ic->next; dic; dic = dic->next)
3760     {
3761       if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3762         debugLog ("    used on left\n");
3763       if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3764         debugLog ("    used on right\n");
3765       if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3766         debugLog ("    used on result\n");
3767
3768       if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3769         (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3770         return;
3771     }
3772
3773   debugLog ("  hey we can remove this unnecessary assign\n");
3774 }
3775 /*-----------------------------------------------------------------*/
3776 /* packForPush - hueristics to reduce iCode for pushing            */
3777 /*-----------------------------------------------------------------*/
3778 static void
3779 packForPush (iCode * ic, eBBlock * ebp)
3780 {
3781   iCode *dic;
3782   const char *iLine;
3783
3784   debugLog ("%s\n", __FUNCTION__);
3785   if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3786     return;
3787
3788 #if 0
3789   {
3790     int n1, n2;
3791
3792     n1 = bitVectnBitsOn( OP_DEFS(IC_LEFT(ic)));
3793     n2 = bitVectnBitsOn( OP_USES(IC_LEFT(ic)));
3794     iLine = printILine(ic);
3795     debugf3("defs: %d\tuses: %d\t%s\n", n1, n2, printILine(ic));
3796     dbuf_free(iLine);
3797     debugf2("IC_LEFT(ic): from %d to %d\n", OP_LIVEFROM(IC_LEFT(ic)), OP_LIVETO(IC_LEFT(ic)));
3798   }
3799 #endif
3800
3801   /* must have only definition & one usage */
3802   if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3803       bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3804     return;
3805
3806   /* find the definition */
3807   if (!(dic = hTabItemWithKey (iCodehTab,
3808                                bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3809     return;
3810
3811   /* if definition is not assignment,
3812    * or is not pointer (because pointer might have changed) */
3813   if (dic->op != '=' || POINTER_SET (dic))
3814     return;
3815
3816   /* we must ensure that we can use the delete the assignment,
3817    * because the source might have been modified in between.
3818    * Until I know how to fix this, I'll use the adhoc fix
3819    * to check the liveranges */
3820   if((OP_LIVEFROM(IC_RIGHT(dic))==0) || (OP_LIVETO(IC_RIGHT(dic))==0))
3821     return;
3822 //  debugf2("IC_RIGHT(dic): from %d to %d\n", OP_LIVEFROM(IC_RIGHT(dic)), OP_LIVETO(IC_RIGHT(dic)));
3823
3824
3825
3826   /* we now we know that it has one & only one def & use
3827      and the that the definition is an assignment */
3828   IC_LEFT (ic) = IC_RIGHT (dic);
3829
3830   iLine = printILine(dic);
3831   debugf("remiCodeFromeBBlock: %s\n", iLine);
3832   dbuf_free(iLine);
3833
3834   remiCodeFromeBBlock (ebp, dic);
3835   bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3836   hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3837 }
3838
3839 static void printSymType(char * str, sym_link *sl)
3840 {
3841         if(!pic16_ralloc_debug)return;
3842
3843         debugLog ("    %s Symbol type: ",str);
3844         printTypeChain (sl, debugF);
3845         debugLog ("\n");
3846 }
3847
3848 /*-----------------------------------------------------------------*/
3849 /* some debug code to print the symbol S_TYPE. Note that
3850  * the function checkSClass in src/SDCCsymt.c dinks with
3851  * the S_TYPE in ways the PIC port doesn't fully like...*/
3852 /*-----------------------------------------------------------------*/
3853 static void isData(sym_link *sl)
3854 {
3855   FILE *of = stderr;
3856
3857     if(!pic16_ralloc_debug)return;
3858
3859     if(!sl)return;
3860
3861     if(debugF)
3862       of = debugF;
3863
3864     for ( ; sl; sl=sl->next) {
3865       if(!IS_DECL(sl) ) {
3866         switch (SPEC_SCLS(sl)) {
3867           case S_DATA: fprintf (of, "data "); break;
3868           case S_XDATA: fprintf (of, "xdata "); break;
3869           case S_SFR: fprintf (of, "sfr "); break;
3870           case S_SBIT: fprintf (of, "sbit "); break;
3871           case S_CODE: fprintf (of, "code "); break;
3872           case S_IDATA: fprintf (of, "idata "); break;
3873           case S_PDATA: fprintf (of, "pdata "); break;
3874           case S_LITERAL: fprintf (of, "literal "); break;
3875           case S_STACK: fprintf (of, "stack "); break;
3876           case S_XSTACK: fprintf (of, "xstack "); break;
3877           case S_BIT: fprintf (of, "bit "); break;
3878           case S_EEPROM: fprintf (of, "eeprom "); break;
3879           default: break;
3880         }
3881       }
3882     }
3883 }
3884
3885
3886 /*--------------------------------------------------------------------*/
3887 /* pic16_packRegisters - does some transformations to reduce          */
3888 /*                   register pressure                                */
3889 /*                                                                    */
3890 /*--------------------------------------------------------------------*/
3891 static void
3892 pic16_packRegisters (eBBlock * ebp)
3893 {
3894   iCode *ic;
3895   int change = 0;
3896
3897   debugLog ("%s\n", __FUNCTION__);
3898
3899   while (1) {
3900
3901     change = 0;
3902
3903     /* look for assignments of the form */
3904     /* iTempNN = TRueSym (someoperation) SomeOperand */
3905     /*       ....                       */
3906     /* TrueSym := iTempNN:1             */
3907     for (ic = ebp->sch; ic; ic = ic->next)
3908       {
3909 //              debugLog("%d\n", __LINE__);
3910         /* find assignment of the form TrueSym := iTempNN:1 */
3911         if ( (ic->op == '=') && !POINTER_SET (ic) ) // patch 11
3912           change += packRegsForAssign (ic, ebp);
3913         /* debug stuff */
3914         if (ic->op == '=')
3915           {
3916             if (POINTER_SET (ic))
3917               debugLog ("pointer is set\n");
3918             debugAopGet ("  result:", IC_RESULT (ic));
3919             debugAopGet ("  left:", IC_LEFT (ic));
3920             debugAopGet ("  right:", IC_RIGHT (ic));
3921           }
3922
3923       }
3924
3925     if (!change)
3926       break;
3927   }
3928
3929   for (ic = ebp->sch; ic; ic = ic->next) {
3930
3931     if(IS_SYMOP ( IC_LEFT(ic))) {
3932       sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3933
3934       debugAopGet ("x  left:", IC_LEFT (ic));
3935 #if 0
3936       if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3937 #else
3938       if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3939 #endif
3940         debugLog ("    is a pointer\n");
3941
3942       if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3943         debugLog ("    is a ptr\n");
3944
3945       if(IS_OP_VOLATILE(IC_LEFT(ic)))
3946         debugLog ("    is volatile\n");
3947
3948       isData(etype);
3949
3950         if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3951             debugLog ("  %d - left is not temp, allocating\n", __LINE__);
3952             pic16_allocDirReg(IC_LEFT (ic));
3953         }
3954
3955       printSymType("c  ", OP_SYMBOL(IC_LEFT(ic))->type);
3956     }
3957
3958     if(IS_SYMOP ( IC_RIGHT(ic))) {
3959       debugAopGet ("  right:", IC_RIGHT (ic));
3960       printSymType("    ", OP_SYMBOL(IC_RIGHT(ic))->type);
3961     }
3962
3963     if(IS_SYMOP ( IC_RESULT(ic))) {
3964       debugAopGet ("  result:", IC_RESULT (ic));
3965       printSymType("     ", OP_SYMBOL(IC_RESULT(ic))->type);
3966     }
3967
3968     if(IS_TRUE_SYMOP ( IC_RIGHT(ic))) {
3969       debugAopGet ("  right:", IC_RIGHT (ic));
3970       printSymType("    ", OP_SYMBOL(IC_RIGHT(ic))->type);
3971 //      pic16_allocDirReg(IC_RIGHT(ic));
3972     }
3973
3974     if(IS_TRUE_SYMOP ( IC_RESULT(ic))) {
3975       debugAopGet ("  result:", IC_RESULT (ic));
3976       printSymType("     ", OP_SYMBOL(IC_RESULT(ic))->type);
3977 //      pic16_allocDirReg(IC_RESULT(ic));
3978     }
3979
3980
3981     if (POINTER_SET (ic))
3982       debugLog ("  %d - Pointer set\n", __LINE__);
3983
3984       /* Look for two subsequent iCodes with */
3985       /*   iTemp := _c;         */
3986       /*   _c = iTemp & op;     */
3987       /* and replace them by    */
3988       /*   iTemp := _c;         */
3989       /*   _c = _c & op;        */
3990       if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^')
3991         && ic->prev
3992         && ic->prev->op == '='
3993         && IS_ITEMP (IC_LEFT (ic))
3994         && IC_LEFT (ic) == IC_RESULT (ic->prev)
3995         && isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3996         {
3997           iCode* ic_prev = ic->prev;
3998           symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3999
4000           ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
4001           if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) {
4002             bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
4003             if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
4004               prev_result_sym->liveTo == ic->seq)
4005             {
4006               prev_result_sym->liveTo = ic_prev->seq;
4007             }
4008           }
4009           bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
4010
4011           bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
4012
4013           if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) {
4014             bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
4015             bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
4016             remiCodeFromeBBlock (ebp, ic_prev);
4017             hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
4018           }
4019         }
4020
4021     /* if this is an itemp & result of a address of a true sym
4022        then mark this as rematerialisable   */
4023     if (ic->op == ADDRESS_OF &&
4024         IS_ITEMP (IC_RESULT (ic)) &&
4025         IS_TRUE_SYMOP (IC_LEFT (ic)) &&
4026         bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4027         !OP_SYMBOL (IC_LEFT (ic))->onStack)
4028       {
4029
4030         debugLog ("  %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
4031
4032         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
4033         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
4034         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
4035
4036       }
4037
4038     /* if straight assignment then carry remat flag if
4039        this is the only definition */
4040     if (ic->op == '=' &&
4041         !POINTER_SET (ic) &&
4042         IS_SYMOP (IC_RIGHT (ic)) &&
4043         OP_SYMBOL (IC_RIGHT (ic))->remat &&
4044         bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
4045       {
4046         debugLog ("  %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
4047
4048         OP_SYMBOL (IC_RESULT (ic))->remat =
4049           OP_SYMBOL (IC_RIGHT (ic))->remat;
4050         OP_SYMBOL (IC_RESULT (ic))->rematiCode =
4051           OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
4052       }
4053
4054     /* if this is a +/- operation with a rematerizable
4055        then mark this as rematerializable as well */
4056     if ((ic->op == '+' || ic->op == '-') &&
4057         (IS_SYMOP (IC_LEFT (ic)) &&
4058          IS_ITEMP (IC_RESULT (ic)) &&
4059          OP_SYMBOL (IC_LEFT (ic))->remat &&
4060          bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
4061          IS_OP_LITERAL (IC_RIGHT (ic))))
4062       {
4063         debugLog ("  %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
4064         //int i =
4065         operandLitValue (IC_RIGHT (ic));
4066         OP_SYMBOL (IC_RESULT (ic))->remat = 1;
4067         OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
4068         OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
4069       }
4070
4071
4072 #if 0
4073     /* try to optimize FSR0 usage when reading data memory pointers */
4074
4075     if(getenv("OPTIMIZE_NEAR_POINTER_GET")) {
4076           static int fsr0usage=0;
4077           static iCode *usic;
4078
4079                 if(POINTER_GET(ic)                              /* this is a memory read */
4080                         && ic->loop                                     /* this is in a loop */
4081                 ) {
4082                         fprintf(stderr, "might optimize FSR0 usage\n");
4083                 }
4084     }
4085 #endif
4086
4087     /* mark the pointer usages */
4088     if (POINTER_SET (ic))
4089       {
4090         OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
4091         debugLog ("  marking as a pointer (set) =>");
4092         debugAopGet ("  result:", IC_RESULT (ic));
4093
4094       }
4095
4096     if (POINTER_GET (ic))
4097       {
4098         if(IS_SYMOP(IC_LEFT(ic))) {
4099           OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
4100           debugLog ("  marking as a pointer (get) =>");
4101           debugAopGet ("  left:", IC_LEFT (ic));
4102         }
4103
4104         if(getenv("OPTIMIZE_BITFIELD_POINTER_GET")) {
4105           if(IS_ITEMP(IC_LEFT(ic)) && IS_BITFIELD(OP_SYM_ETYPE(IC_LEFT(ic)))) {
4106             iCode *dic = ic->prev;
4107
4108             fprintf(stderr, "%s:%d might give opt POINTER_GET && IS_BITFIELD(IC_LEFT)\n", __FILE__, __LINE__);
4109
4110             if(dic && dic->op == '='
4111               && isOperandEqual(IC_RESULT(dic), IC_LEFT(ic))) {
4112
4113                 fprintf(stderr, "%s:%d && prev is '=' && prev->result == ic->left\n", __FILE__, __LINE__);
4114
4115
4116                 /* replace prev->left with ic->left */
4117                 IC_LEFT(ic) = IC_RIGHT(dic);
4118                 IC_RIGHT(ic->prev) = NULL;
4119
4120                 /* remove ic->prev iCode (assignment) */
4121                 remiCodeFromeBBlock (ebp, dic);
4122                 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,ic->key);
4123
4124
4125                 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
4126             }
4127           }
4128         }
4129       }
4130
4131         //debugLog("  %d   %s\n", __LINE__, __FUNCTION__);
4132
4133     if (!SKIP_IC2 (ic))
4134       {
4135         //debugLog("  %d   %s\n", __LINE__, __FUNCTION__ );
4136         /* if we are using a symbol on the stack
4137            then we should say pic16_ptrRegReq */
4138         if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
4139           pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
4140                                OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
4141         else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
4142           pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
4143                                OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
4144         else
4145           {
4146
4147                 //debugLog("   %d   %s\n", __LINE__, __FUNCTION__ );
4148             if (IS_SYMOP (IC_LEFT (ic)))
4149               pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
4150                                    OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
4151             if (IS_SYMOP (IC_RIGHT (ic)))
4152               pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
4153                                    OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
4154             if (IS_SYMOP (IC_RESULT (ic)))
4155               pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
4156                                    OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
4157           }
4158
4159         debugLog ("  %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
4160
4161       }
4162
4163     /* if the condition of an if instruction
4164        is defined in the previous instruction then
4165        mark the itemp as a conditional */
4166     if ((IS_CONDITIONAL (ic) ||
4167          ((ic->op == BITWISEAND ||
4168            ic->op == '|' ||
4169            ic->op == '^') &&
4170           isBitwiseOptimizable (ic))) &&
4171         ic->next && ic->next->op == IFX &&
4172         isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
4173         OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
4174       {
4175
4176         debugLog ("  %d\n", __LINE__);
4177         OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
4178         continue;
4179       }
4180
4181         debugLog(" %d\n", __LINE__);
4182
4183 #ifndef NO_packRegsForSupport
4184     /* reduce for support function calls */
4185     if (ic->supportRtn || ic->op == '+' || ic->op == '-')
4186       packRegsForSupport (ic, ebp);
4187 #endif
4188
4189     /* if a parameter is passed, it's in W, so we may not
4190        need to place a copy in a register */
4191     if (ic->op == RECEIVE)
4192       packForReceive (ic, ebp);
4193
4194 #ifndef NO_packRegsForOneuse
4195     /* some cases the redundant moves can
4196        can be eliminated for return statements */
4197     if ((ic->op == RETURN || ic->op == SEND) &&
4198         !isOperandInFarSpace (IC_LEFT (ic)) &&
4199         !options.model)
4200       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4201 #endif
4202
4203 #ifndef NO_packRegsForOneuse
4204     /* if pointer set & left has a size more than
4205        one and right is not in far space */
4206     if (POINTER_SET (ic) &&
4207         !isOperandInFarSpace (IC_RIGHT (ic)) &&
4208         !OP_SYMBOL (IC_RESULT (ic))->remat &&
4209         !IS_OP_RUONLY (IC_RIGHT (ic)) &&
4210         getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
4211
4212       packRegsForOneuse (ic, IC_RESULT (ic), ebp);
4213 #endif
4214
4215 #ifndef NO_packRegsForOneuse
4216     /* if pointer get */
4217     if (POINTER_GET (ic) &&
4218         !isOperandInFarSpace (IC_RESULT (ic)) &&
4219         !OP_SYMBOL (IC_LEFT (ic))->remat &&
4220         !IS_OP_RUONLY (IC_RESULT (ic)) &&
4221         getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
4222
4223       packRegsForOneuse (ic, IC_LEFT (ic), ebp);
4224       debugLog("%d - return from packRegsForOneuse\n", __LINE__);
4225 #endif
4226
4227 #ifndef NO_cast_peep
4228     /* if this is cast for intergral promotion then
4229        check if only use of  the definition of the
4230        operand being casted/ if yes then replace
4231        the result of that arithmetic operation with
4232        this result and get rid of the cast */
4233     if (ic->op == CAST) {
4234
4235       sym_link *fromType = operandType (IC_RIGHT (ic));
4236       sym_link *toType = operandType (IC_LEFT (ic));
4237
4238       debugLog ("  %d - casting\n", __LINE__);
4239
4240       if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4241           getSize (fromType) != getSize (toType)) {
4242
4243
4244         iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4245         if (dic) {
4246
4247           if (IS_ARITHMETIC_OP (dic)) {
4248                     debugLog("   %d   %s\n", __LINE__, __FUNCTION__ );
4249
4250             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4251             IC_RESULT (dic) = IC_RESULT (ic);
4252             remiCodeFromeBBlock (ebp, ic);
4253             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4254             hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4255             OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4256             ic = ic->prev;
4257           }  else
4258
4259             OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4260         }
4261       } else {
4262
4263         /* if the type from and type to are the same
4264            then if this is the only use then packit */
4265         if (compareType (operandType (IC_RIGHT (ic)),
4266                          operandType (IC_LEFT (ic))) == 1) {
4267
4268           iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4269           if (dic) {
4270
4271                    debugLog(" %d\n", __LINE__);
4272
4273             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4274             IC_RESULT (dic) = IC_RESULT (ic);
4275             bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4276             remiCodeFromeBBlock (ebp, ic);
4277             hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4278             OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4279             ic = ic->prev;
4280           }
4281         }
4282       }
4283     }
4284 #endif
4285
4286 #if 1
4287     /* there are some problems with packing variables
4288      * it seems that the live range estimator doesn't
4289      * estimate correctly the liveranges of some symbols */
4290
4291     /* pack for PUSH
4292        iTempNN := (some variable in farspace) V1
4293        push iTempNN ;
4294        -------------
4295        push V1
4296     */
4297     if (ic->op == IPUSH)
4298       {
4299         packForPush (ic, ebp);
4300       }
4301 #endif
4302
4303 #ifndef NO_packRegsForAccUse
4304     /* pack registers for accumulator use, when the
4305        result of an arithmetic or bit wise operation
4306        has only one use, that use is immediately following
4307        the defintion and the using iCode has only one
4308        operand or has two operands but one is literal &
4309        the result of that operation is not on stack then
4310        we can leave the result of this operation in acc:b
4311        combination */
4312     if ((IS_ARITHMETIC_OP (ic)
4313
4314          || IS_BITWISE_OP (ic)
4315
4316          || ic->op == LEFT_OP || ic->op == RIGHT_OP
4317
4318          ) &&
4319         IS_ITEMP (IC_RESULT (ic)) &&
4320         getSize (operandType (IC_RESULT (ic))) <= 1)
4321
4322       packRegsForAccUse (ic);
4323 #endif
4324
4325   }
4326 }
4327
4328 static void
4329 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4330 {
4331   int i;
4332
4333   if (!pic16_ralloc_debug || !debugF)
4334     return;
4335
4336   for (i = 0; i < count; i++)
4337     {
4338       fprintf (debugF, "\n----------------------------------------------------------------\n");
4339       fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4340                ebbs[i]->entryLabel->name,
4341                ebbs[i]->depth,
4342                ebbs[i]->noPath,
4343                ebbs[i]->isLastInLoop);
4344       fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4345                ebbs[i]->dfnum,
4346                ebbs[i]->bbnum,
4347                ebbs[i]->fSeq,
4348                ebbs[i]->lSeq);
4349       fprintf (debugF, "visited %d : hasFcall = %d\n",
4350                ebbs[i]->visited,
4351                ebbs[i]->hasFcall);
4352
4353       fprintf (debugF, "\ndefines bitVector :");
4354       bitVectDebugOn (ebbs[i]->defSet, debugF);
4355       fprintf (debugF, "\nlocal defines bitVector :");
4356       bitVectDebugOn (ebbs[i]->ldefs, debugF);
4357       fprintf (debugF, "\npointers Set bitvector :");
4358       bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4359       fprintf (debugF, "\nin pointers Set bitvector :");
4360       bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4361       fprintf (debugF, "\ninDefs Set bitvector :");
4362       bitVectDebugOn (ebbs[i]->inDefs, debugF);
4363       fprintf (debugF, "\noutDefs Set bitvector :");
4364       bitVectDebugOn (ebbs[i]->outDefs, debugF);
4365       fprintf (debugF, "\nusesDefs Set bitvector :");
4366       bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4367       fprintf (debugF, "\n----------------------------------------------------------------\n");
4368       printiCChain (ebbs[i]->sch, debugF);
4369     }
4370 }
4371
4372 void dbg_dumpregusage(void);
4373
4374 /*-----------------------------------------------------------------*/
4375 /* pic16_assignRegisters - assigns registers to each live range as need  */
4376 /*-----------------------------------------------------------------*/
4377 void
4378 pic16_assignRegisters (ebbIndex * ebbi)
4379 {
4380   eBBlock ** ebbs = ebbi->bbOrder;
4381   int count = ebbi->count;
4382   iCode *ic;
4383   int i;
4384
4385   debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4386   debugLog ("\nebbs before optimizing:\n");
4387   dumpEbbsToDebug (ebbs, count);
4388
4389   _inRegAllocator = 1;
4390
4391   pic16_freeAllRegs();
4392 #if 0
4393         dbg_dumpregusage();
4394         /* clear whats left over from peephole parser */
4395         pic16_dynAllocRegs= newSet();   //NULL;
4396 //      pic16_dynStackRegs= newSet();   //NULL;
4397 //      pic16_dynProcessorRegs=newSet();        //NULL;
4398 //      pic16_dynDirectRegs=newSet();           //NULL;
4399 //      pic16_dynDirectBitRegs=newSet();        //NULL;
4400 //      pic16_dynInternalRegs=newSet();         //NULL;
4401 //      pic16_dynAccessRegs=newSet();           //NULL;
4402
4403 //      dynDirectRegNames=NULL;
4404         dynAllocRegNames=NULL;
4405 //      dynProcRegNames=NULL;
4406 //      dynAccessRegNames=NULL;
4407 #endif
4408
4409   setToNull ((void *) &_G.funcrUsed);
4410   pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4411
4412
4413   /* change assignments this will remove some
4414      live ranges reducing some register pressure */
4415   for (i = 0; i < count; i++)
4416     pic16_packRegisters (ebbs[i]);
4417
4418
4419   {
4420     regs *reg;
4421     int hkey;
4422
4423     debugLog("dir registers allocated so far:\n");
4424     reg = hTabFirstItem(dynDirectRegNames, &hkey);
4425
4426 #if 0
4427     while(reg) {
4428       debugLog("  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4429 //      fprintf(stderr, "  -- #%d reg = %s  key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4430       reg = hTabNextItem(dynDirectRegNames, &hkey);
4431     }
4432 #endif
4433
4434   }
4435
4436   /* liveranges probably changed by register packing
4437      so we compute them again */
4438   recomputeLiveRanges (ebbs, count);
4439
4440   if (options.dump_pack)
4441     dumpEbbsToFileExt (DUMP_PACK, ebbi);
4442
4443   /* first determine for each live range the number of
4444      registers & the type of registers required for each */
4445   regTypeNum ();
4446
4447   /* start counting function temporary registers from zero */
4448   /* XXX: Resetting dynrIdx breaks register allocation,
4449    *      see #1489055, #1483693 (?), and #1445850! */
4450   //dynrIdx = 0;
4451
4452   /* and serially allocate registers */
4453   serialRegAssign (ebbs, count);
4454
4455 #if 0
4456   debugLog ("ebbs after serialRegAssign:\n");
4457   dumpEbbsToDebug (ebbs, count);
4458 #endif
4459
4460   //pic16_freeAllRegs();
4461
4462   /* if stack was extended then tell the user */
4463   if (_G.stackExtend)
4464     {
4465 /*      werror(W_TOOMANY_SPILS,"stack", */
4466 /*             _G.stackExtend,currFunc->name,""); */
4467       _G.stackExtend = 0;
4468     }
4469
4470   if (_G.dataExtend)
4471     {
4472 /*      werror(W_TOOMANY_SPILS,"data space", */
4473 /*             _G.dataExtend,currFunc->name,""); */
4474       _G.dataExtend = 0;
4475     }
4476
4477   /* after that create the register mask
4478      for each of the instruction */
4479   createRegMask (ebbs, count);
4480
4481   /* redo that offsets for stacked automatic variables */
4482   redoStackOffsets ();
4483
4484   if (options.dump_rassgn)
4485     dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4486
4487 //  dumpLR(ebbs, count);
4488
4489   /* now get back the chain */
4490   ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4491
4492   debugLog ("ebbs after optimizing:\n");
4493   dumpEbbsToDebug (ebbs, count);
4494
4495
4496   _inRegAllocator = 0;
4497
4498   genpic16Code (ic);
4499
4500   /* free up any _G.stackSpil locations allocated */
4501   applyToSet (_G.stackSpil, deallocStackSpil);
4502   _G.slocNum = 0;
4503   setToNull ((void *) &_G.stackSpil);
4504   setToNull ((void *) &_G.spiltSet);
4505   /* mark all registers as free */
4506   pic16_freeAllRegs ();
4507
4508
4509   debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");
4510   debugLogClose ();
4511   return;
4512 }