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