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