1 /*------------------------------------------------------------------------
3 SDCCralloc.c - source file for register allocation. (8051) specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
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
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.
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.
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 -------------------------------------------------------------------------*/
33 #if defined(__BORLANDC__) || defined(_MSC_VER)
34 #define STRCASECMP stricmp
35 #define FENTRY2 1 ? (void)0 : printf
37 #define STRCASECMP strcasecmp
38 //#define FENTRY2(fmt,...) do { fprintf (stderr, "%s:%d: called.\n", __FUNCTION__, __LINE__); fprintf (stderr, fmt, ## __VA_ARGS__); } while (0)
39 #define FENTRY2 1 ? (void)0 : printf
42 /* this should go in SDCCicode.h, but it doesn't. */
43 #define IS_REF(op) (IS_SYMOP(op) && op->operand.symOperand->isref == 1)
45 /*-----------------------------------------------------------------*/
46 /* At this point we start getting processor specific although */
47 /* some routines are non-processor specific & can be reused when */
48 /* targetting other processors. The decision for this will have */
49 /* to be made on a routine by routine basis */
50 /* routines used to pack registers are most definitely not reusable */
51 /* since the pack the registers depending strictly on the MCU */
52 /*-----------------------------------------------------------------*/
54 extern void genpic14Code (iCode *);
55 extern void assignConfigWordValue(int address, int value);
65 bitVect *funcrUsed; /* registers used in a function */
71 /* Shared with gen.c */
72 int pic14_ptrRegReq; /* one byte pointer register required */
75 set *dynAllocRegs=NULL;
76 set *dynStackRegs=NULL;
77 set *dynProcessorRegs=NULL;
78 set *dynDirectRegs=NULL;
79 set *dynDirectBitRegs=NULL;
80 set *dynInternalRegs=NULL;
82 static hTab *dynDirectRegNames= NULL;
83 // static hTab *regHash = NULL; /* a hash table containing ALL registers */
85 static int dynrIdx=0x20;
86 static int rDirectIdx=0;
88 int pic14_nRegs = 128; // = sizeof (regspic14) / sizeof (regs);
90 int Gstack_base_addr=0; /* The starting address of registers that
91 * are used to pass and return parameters */
97 static void spillThis (symbol *);
99 static FILE *debugF = NULL;
100 /*-----------------------------------------------------------------*/
101 /* debugLog - open a file for debugging information */
102 /*-----------------------------------------------------------------*/
103 //static void debugLog(char *inst,char *fmt, ...)
105 debugLog (char *fmt,...)
107 static int append = 0; // First time through, open the file without append.
110 //char *bufferP=buffer;
113 if (!debug || !dstFileName)
119 /* create the file name */
120 strcpy (buffer, dstFileName);
121 strcat (buffer, ".d");
123 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
125 werror (E_FILE_OPEN_ERR, buffer);
128 append = 1; // Next time debubLog is called, we'll append the debug info
134 vsprintf (buffer, fmt, ap);
136 fprintf (debugF, "%s", buffer);
138 while (isspace((unsigned char)*bufferP)) bufferP++;
140 if (bufferP && *bufferP)
141 lineCurr = (lineCurr ?
142 connectLine(lineCurr,newLineNode(lb)) :
143 (lineHead = newLineNode(lb)));
144 lineCurr->isInline = _G.inLine;
145 lineCurr->isDebug = _G.debugLine;
155 fputc ('\n', debugF);
157 /*-----------------------------------------------------------------*/
158 /* debugLogClose - closes the debug log file (if opened) */
159 /*-----------------------------------------------------------------*/
169 #define AOP(op) op->aop
172 debugAopGet (char *str, operand * op)
177 printOperand (op, debugF);
185 decodeOp (unsigned int op)
188 if (op < 128 && op > ' ')
190 buffer[0] = (op & 0xff);
197 case IDENTIFIER: return "IDENTIFIER";
198 case TYPE_NAME: return "TYPE_NAME";
199 case CONSTANT: return "CONSTANT";
200 case STRING_LITERAL: return "STRING_LITERAL";
201 case SIZEOF: return "SIZEOF";
202 case PTR_OP: return "PTR_OP";
203 case INC_OP: return "INC_OP";
204 case DEC_OP: return "DEC_OP";
205 case LEFT_OP: return "LEFT_OP";
206 case RIGHT_OP: return "RIGHT_OP";
207 case LE_OP: return "LE_OP";
208 case GE_OP: return "GE_OP";
209 case EQ_OP: return "EQ_OP";
210 case NE_OP: return "NE_OP";
211 case AND_OP: return "AND_OP";
212 case OR_OP: return "OR_OP";
213 case MUL_ASSIGN: return "MUL_ASSIGN";
214 case DIV_ASSIGN: return "DIV_ASSIGN";
215 case MOD_ASSIGN: return "MOD_ASSIGN";
216 case ADD_ASSIGN: return "ADD_ASSIGN";
217 case SUB_ASSIGN: return "SUB_ASSIGN";
218 case LEFT_ASSIGN: return "LEFT_ASSIGN";
219 case RIGHT_ASSIGN: return "RIGHT_ASSIGN";
220 case AND_ASSIGN: return "AND_ASSIGN";
221 case XOR_ASSIGN: return "XOR_ASSIGN";
222 case OR_ASSIGN: return "OR_ASSIGN";
223 case TYPEDEF: return "TYPEDEF";
224 case EXTERN: return "EXTERN";
225 case STATIC: return "STATIC";
226 case AUTO: return "AUTO";
227 case REGISTER: return "REGISTER";
228 case CODE: return "CODE";
229 case EEPROM: return "EEPROM";
230 case INTERRUPT: return "INTERRUPT";
231 case SFR: return "SFR";
232 case AT: return "AT";
233 case SBIT: return "SBIT";
234 case REENTRANT: return "REENTRANT";
235 case USING: return "USING";
236 case XDATA: return "XDATA";
237 case DATA: return "DATA";
238 case IDATA: return "IDATA";
239 case PDATA: return "PDATA";
240 case VAR_ARGS: return "VAR_ARGS";
241 case CRITICAL: return "CRITICAL";
242 case NONBANKED: return "NONBANKED";
243 case BANKED: return "BANKED";
244 case CHAR: return "CHAR";
245 case SHORT: return "SHORT";
246 case INT: return "INT";
247 case LONG: return "LONG";
248 case SIGNED: return "SIGNED";
249 case UNSIGNED: return "UNSIGNED";
250 case FLOAT: return "FLOAT";
251 case DOUBLE: return "DOUBLE";
252 case CONST: return "CONST";
253 case VOLATILE: return "VOLATILE";
254 case VOID: return "VOID";
255 case BIT: return "BIT";
256 case STRUCT: return "STRUCT";
257 case UNION: return "UNION";
258 case ENUM: return "ENUM";
259 case ELIPSIS: return "ELIPSIS";
260 case RANGE: return "RANGE";
261 case FAR: return "FAR";
262 case CASE: return "CASE";
263 case DEFAULT: return "DEFAULT";
264 case IF: return "IF";
265 case ELSE: return "ELSE";
266 case SWITCH: return "SWITCH";
267 case WHILE: return "WHILE";
268 case DO: return "DO";
269 case FOR: return "FOR";
270 case GOTO: return "GOTO";
271 case CONTINUE: return "CONTINUE";
272 case BREAK: return "BREAK";
273 case RETURN: return "RETURN";
274 case INLINEASM: return "INLINEASM";
275 case IFX: return "IFX";
276 case ADDRESS_OF: return "ADDRESS_OF";
277 case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS";
278 case SPIL: return "SPIL";
279 case UNSPIL: return "UNSPIL";
280 case GETHBIT: return "GETHBIT";
281 case BITWISEAND: return "BITWISEAND";
282 case UNARYMINUS: return "UNARYMINUS";
283 case IPUSH: return "IPUSH";
284 case IPOP: return "IPOP";
285 case PCALL: return "PCALL";
286 case ENDFUNCTION: return "ENDFUNCTION";
287 case JUMPTABLE: return "JUMPTABLE";
288 case RRC: return "RRC";
289 case RLC: return "RLC";
290 case CAST: return "CAST";
291 case CALL: return "CALL";
292 case PARAM: return "PARAM ";
293 case NULLOP: return "NULLOP";
294 case BLOCK: return "BLOCK";
295 case LABEL: return "LABEL";
296 case RECEIVE: return "RECEIVE";
297 case SEND: return "SEND";
299 sprintf (buffer, "unknown op %d %c", op, op & 0xff);
302 /*-----------------------------------------------------------------*/
303 /*-----------------------------------------------------------------*/
305 debugLogRegType (short type)
310 case REG_GPR: return "REG_GPR";
311 case REG_PTR: return "REG_PTR";
312 case REG_CND: return "REG_CND";
315 sprintf (buffer, "unknown reg type %d", type);
319 /*-----------------------------------------------------------------*/
320 /*-----------------------------------------------------------------*/
321 static int regname2key(char const *name)
330 key += (*name++) + 1;
334 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
338 static regs *regWithIdx (set *dRegs, int idx, int fixed);
339 /*-----------------------------------------------------------------*/
340 /* newReg - allocate and init memory for a new register */
341 /*-----------------------------------------------------------------*/
342 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias)
347 /* check whether a matching register already exists */
348 dReg = dirregWithName( name );
350 //printf( "%s: already present: %s\n", __FUNCTION__, name );
353 dReg = regWithIdx( dynDirectRegs, rIdx, 0 );
354 if (!dReg) dReg = regWithIdx( dynDirectRegs, rIdx, 1 );
357 //printf( "%s: already present %s (idx:%d/%x)", __FUNCTION__, name, rIdx, rIdx );
361 dReg = Safe_calloc(1,sizeof(regs));
363 dReg->pc_type = pc_type;
366 dReg->name = Safe_strdup(name);
368 sprintf(buffer,"r0x%02X", dReg->rIdx);
369 dReg->name = Safe_strdup(buffer);
385 dReg->reg_alias = NULL;
386 dReg->reglives.usedpFlows = newSet();
387 dReg->reglives.assignedpFlows = newSet();
389 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
394 /*-----------------------------------------------------------------*/
395 /* regWithIdx - Search through a set of registers that matches idx */
396 /*-----------------------------------------------------------------*/
398 regWithIdx (set *dRegs, int idx, int fixed)
402 for (dReg = setFirstItem(dRegs) ; dReg ;
403 dReg = setNextItem(dRegs)) {
405 if(idx == dReg->rIdx && (fixed == (int)dReg->isFixed)) {
413 /*-----------------------------------------------------------------*/
414 /* regWithName - Search through a set of registers that matches name */
415 /*-----------------------------------------------------------------*/
417 regWithName (set *dRegs, const char *name)
421 for (dReg = setFirstItem(dRegs) ; dReg ;
422 dReg = setNextItem(dRegs)) {
424 if((strcmp(name,dReg->name)==0)) {
432 /*-----------------------------------------------------------------*/
433 /* regWithName - Search for a registers that matches name */
434 /*-----------------------------------------------------------------*/
436 regFindWithName (const char *name)
440 if( (dReg = regWithName ( dynDirectRegs, name)) != NULL ) {
441 debugLog ("Found a Direct Register!\n");
444 if( (dReg = regWithName ( dynDirectBitRegs, name)) != NULL) {
445 debugLog ("Found a Direct Bit Register!\n");
449 if (*name=='_') name++; // Step passed '_'
451 if( (dReg = regWithName ( dynAllocRegs, name)) != NULL) {
452 debugLog ("Found a Dynamic Register!\n");
455 if( (dReg = regWithName ( dynProcessorRegs, name)) != NULL) {
456 debugLog ("Found a Processor Register!\n");
459 if( (dReg = regWithName ( dynInternalRegs, name)) != NULL) {
460 debugLog ("Found an Internal Register!\n");
463 if( (dReg = regWithName ( dynStackRegs, name)) != NULL) {
464 debugLog ("Found an Stack Register!\n");
471 /*-----------------------------------------------------------------*/
472 /* regFindFree - Search for a free register in a set of registers */
473 /*-----------------------------------------------------------------*/
475 regFindFree (set *dRegs)
479 for (dReg = setFirstItem(dRegs) ; dReg ;
480 dReg = setNextItem(dRegs)) {
488 /*-----------------------------------------------------------------*/
489 /* initStack - allocate registers for a psuedo stack */
490 /*-----------------------------------------------------------------*/
491 void initStack(int base_address, int size)
496 Gstack_base_addr = base_address;
498 //fprintf(stderr,"initStack [base:0x%02x, size:%d]\n", base_address, size);
500 for(i = 0; i<size; i++) {
503 SNPRINTF(&buffer[0], 16, "STK%02d", i);
504 r = newReg(REG_STK, PO_GPR_TEMP,base_address,buffer,1,0);
505 r->address = base_address; // Pseudo stack needs a fixed location that can be known by all modules
509 r->alias = 0x180; // Using shared memory for pseudo stack
510 addSet(&dynStackRegs,r);
515 /*-----------------------------------------------------------------*
516 *-----------------------------------------------------------------*/
518 allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
521 //fprintf(stderr,"allocProcessorRegister %s addr =0x%x\n",name,rIdx);
522 return addSet(&dynProcessorRegs,newReg(REG_SFR, po_type, rIdx, name,1,alias));
525 /*-----------------------------------------------------------------*
526 *-----------------------------------------------------------------*/
529 allocInternalRegister(int rIdx, char * name, short po_type, int alias)
531 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias);
533 //fprintf(stderr,"allocInternalRegister %s addr =0x%x\n",name,rIdx);
536 return addSet(&dynInternalRegs,reg);
541 /*-----------------------------------------------------------------*/
542 /* allocReg - allocates register of given type */
543 /*-----------------------------------------------------------------*/
545 allocReg (short type)
549 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
550 //fprintf(stderr,"allocReg\n");
552 reg = pic14_findFreeReg (type);
560 //return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
565 /*-----------------------------------------------------------------*/
566 /* dirregWithName - search for register by name */
567 /*-----------------------------------------------------------------*/
569 dirregWithName (char *name)
577 /* hash the name to get a key */
579 hkey = regname2key(name);
581 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
585 if(STRCASECMP(reg->name, name) == 0) {
589 reg = hTabNextItemWK (dynDirectRegNames);
593 return NULL; // name wasn't found in the hash table
596 int IS_CONFIG_ADDRESS(int address)
599 return address == 0x2007;
602 /*-----------------------------------------------------------------*/
603 /* allocNewDirReg - allocates a new register of given type */
604 /*-----------------------------------------------------------------*/
606 allocNewDirReg (sym_link *symlnk,const char *name)
610 sym_link *spec = getSpec (symlnk);
612 /* if this is at an absolute address, then get the address. */
613 if (SPEC_ABSA (spec) ) {
614 address = SPEC_ADDR (spec);
615 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
618 /* Register wasn't found in hash, so let's create
619 * a new one and put it in the hash table AND in the
620 * dynDirectRegNames set */
621 if (IS_CONFIG_ADDRESS(address)) {
622 debugLog (" -- %s is declared at address 0x2007\n",name);
627 if (IS_BITVAR (spec))
634 reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
635 debugLog (" -- added %s to hash, size = %d\n", (char*)name,reg->size);
637 if (SPEC_ABSA (spec) ) {
641 if (IS_BITVAR (spec)) {
642 addSet(&dynDirectBitRegs, reg);
645 addSet(&dynDirectRegs, reg);
647 if (!IS_STATIC (spec)) {
650 if (IS_EXTERN (spec)) {
656 if (address && reg) {
658 reg->address = address;
659 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
665 /*-----------------------------------------------------------------*/
666 /* allocDirReg - allocates register of given type */
667 /*-----------------------------------------------------------------*/
669 allocDirReg (operand *op )
676 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
680 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
682 /* If the symbol is at a fixed address, then remove the leading underscore
683 * from the name. This is hack to allow the .asm include file named registers
684 * to match the .c declared register names */
686 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
689 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
691 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
692 debugLog(" %d const char\n",__LINE__);
693 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
696 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
697 if (IS_CODE ( OP_SYM_ETYPE(op)) )
698 debugLog(" %d code space\n",__LINE__);
700 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
701 debugLog(" %d integral\n",__LINE__);
702 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
703 debugLog(" %d literal\n",__LINE__);
704 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
705 debugLog(" %d specifier\n",__LINE__);
706 debugAopGet(NULL, op);
709 if (IS_CODE ( OP_SYM_ETYPE(op)) )
712 /* First, search the hash table to see if there is a register with this name */
713 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
714 reg = regWithIdx (dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
717 fprintf(stderr,"ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
718 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
720 fprintf(stderr,"ralloc %s at fixed address has already been declared, addr=0x%x\n",
721 name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
724 //fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
726 reg = dirregWithName(name);
733 /* if this is at an absolute address, then get the address. */
734 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
735 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
736 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
739 /* Register wasn't found in hash, so let's create
740 * a new one and put it in the hash table AND in the
741 * dynDirectRegNames set */
742 if(!IS_CONFIG_ADDRESS(address)) {
743 //fprintf(stderr,"allocating new reg %s\n",name);
745 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0 );
746 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
748 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
750 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
752 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
756 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
757 addSet(&dynDirectBitRegs, reg);
760 addSet(&dynDirectRegs, reg);
762 if (!IS_STATIC (OP_SYM_ETYPE(op))) {
765 if (IS_EXTERN (OP_SYM_ETYPE(op))) {
771 debugLog (" -- %s is declared at address 0x2007\n",name);
776 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
778 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
779 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
784 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
786 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
787 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
790 allocNewDirReg (OP_SYM_TYPE(op),name);
797 /*-----------------------------------------------------------------*/
798 /* allocRegByName - allocates register with given name */
799 /*-----------------------------------------------------------------*/
801 allocRegByName (char *name, int size)
807 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
811 /* First, search the hash table to see if there is a register with this name */
812 reg = dirregWithName(name);
818 /* Register wasn't found in hash, so let's create
819 * a new one and put it in the hash table AND in the
820 * dynDirectRegNames set */
821 //fprintf (stderr,"%s symbol name %s, size:%d\n", __FUNCTION__,name,size);
822 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
823 for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
824 if (strcmp(reg->name+1,sym->name)==0) {
825 unsigned a = SPEC_ADDR(sym->etype);
829 if (!IS_STATIC (sym->etype)) {
832 if (IS_EXTERN (sym->etype)) {
835 if (IS_BITVAR (sym->etype))
842 for (sym = setFirstItem(data->syms); sym; sym = setNextItem(data->syms)) {
843 if (strcmp(reg->name+1,sym->name)==0) {
844 unsigned a = SPEC_ADDR(sym->etype);
846 if (!IS_STATIC (sym->etype)) {
849 if (IS_EXTERN (sym->etype)) {
852 if (IS_BITVAR (sym->etype))
860 debugLog (" -- added %s to hash, size = %d\n", name,reg->size);
862 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg);
863 if (reg->isBitField) {
864 addSet(&dynDirectBitRegs, reg);
866 addSet(&dynDirectRegs, reg);
872 /*-----------------------------------------------------------------*/
873 /* RegWithIdx - returns pointer to register with index number */
874 /*-----------------------------------------------------------------*/
876 typeRegWithIdx (int idx, int type, int fixed)
881 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
886 if( (dReg = regWithIdx ( dynAllocRegs, idx, fixed)) != NULL) {
888 debugLog ("Found a Dynamic Register!\n");
891 if( (dReg = regWithIdx ( dynDirectRegs, idx, fixed)) != NULL ) {
892 debugLog ("Found a Direct Register!\n");
898 if( (dReg = regWithIdx ( dynStackRegs, idx, fixed)) != NULL ) {
899 debugLog ("Found a Stack Register!\n");
903 werror (E_STACK_OUT, "Register");
904 /* return an existing register just to avoid the SDCC crash */
905 return regWithIdx ( dynStackRegs, 0x7f, fixed);
909 if( (dReg = regWithIdx ( dynProcessorRegs, idx, fixed)) != NULL ) {
910 debugLog ("Found a Processor Register!\n");
924 /*-----------------------------------------------------------------*/
925 /* pic14_regWithIdx - returns pointer to register with index number*/
926 /*-----------------------------------------------------------------*/
928 pic14_regWithIdx (int idx)
932 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
935 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
941 /*-----------------------------------------------------------------*/
942 /* pic14_regWithIdx - returns pointer to register with index number */
943 /*-----------------------------------------------------------------*/
945 pic14_allocWithIdx (int idx)
950 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
952 if( (dReg = regWithIdx ( dynAllocRegs, idx,0)) != NULL) {
954 debugLog ("Found a Dynamic Register!\n");
955 } else if( (dReg = regWithIdx ( dynStackRegs, idx,0)) != NULL ) {
956 debugLog ("Found a Stack Register!\n");
957 } else if( (dReg = regWithIdx ( dynProcessorRegs, idx,0)) != NULL ) {
958 debugLog ("Found a Processor Register!\n");
959 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,0)) != NULL ) {
960 debugLog ("Found an Internal Register!\n");
961 } else if( (dReg = regWithIdx ( dynInternalRegs, idx,1)) != NULL ) {
962 debugLog ("Found an Internal Register!\n");
965 debugLog ("Dynamic Register not found\n");
968 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
969 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
970 "regWithIdx not found");
980 /*-----------------------------------------------------------------*/
981 /*-----------------------------------------------------------------*/
983 pic14_findFreeReg(short type)
990 if((dReg = regFindFree(dynAllocRegs)) != NULL)
992 return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
996 if((dReg = regFindFree(dynStackRegs)) != NULL)
1008 /*-----------------------------------------------------------------*/
1009 /* freeReg - frees a register */
1010 /*-----------------------------------------------------------------*/
1012 freeReg (regs * reg)
1014 debugLog ("%s\n", __FUNCTION__);
1019 /*-----------------------------------------------------------------*/
1020 /* nFreeRegs - returns number of free registers */
1021 /*-----------------------------------------------------------------*/
1023 nFreeRegs (int type)
1025 /* dynamically allocate as many as we need and worry about
1026 * fitting them into a PIC later */
1033 debugLog ("%s\n", __FUNCTION__);
1034 for (i = 0; i < pic14_nRegs; i++)
1035 if (regspic14[i].isFree && regspic14[i].type == type)
1041 /*-----------------------------------------------------------------*/
1042 /* nfreeRegsType - free registers with type */
1043 /*-----------------------------------------------------------------*/
1045 nfreeRegsType (int type)
1048 debugLog ("%s\n", __FUNCTION__);
1049 if (type == REG_PTR)
1051 if ((nfr = nFreeRegs (type)) == 0)
1052 return nFreeRegs (REG_GPR);
1055 return nFreeRegs (type);
1058 void writeSetUsedRegs(FILE *of, set *dRegs)
1063 for (dReg = setFirstItem(dRegs) ; dReg ;
1064 dReg = setNextItem(dRegs)) {
1067 fprintf (of, "\t%s\n",dReg->name);
1071 extern void assignFixedRegisters(set *regset);
1072 extern void assignRelocatableRegisters(set *regset,int used);
1073 extern void dump_map(void);
1074 extern void dump_sfr(FILE *of);
1076 void packBits(set *bregs)
1080 regs *bitfield=NULL;
1081 regs *relocbitfield=NULL;
1087 for (regset = bregs ; regset ;
1088 regset = regset->next) {
1090 breg = regset->item;
1091 breg->isBitField = 1;
1092 //fprintf(stderr,"bit reg: %s\n",breg->name);
1095 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1097 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
1098 breg->rIdx = breg->address & 7;
1099 breg->address >>= 3;
1102 //sprintf (buffer, "fbitfield%02x", breg->address);
1103 sprintf (buffer, "0x%02x", breg->address);
1104 //fprintf(stderr,"new bit field\n");
1105 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0);
1106 bitfield->isBitField = 1;
1107 bitfield->isFixed = 1;
1108 bitfield->address = breg->address;
1109 //addSet(&dynDirectRegs,bitfield);
1110 addSet(&dynInternalRegs,bitfield);
1111 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1113 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1116 breg->reg_alias = bitfield;
1120 if(!relocbitfield || bit_no >7) {
1123 sprintf (buffer, "bitfield%d", byte_no);
1124 //fprintf(stderr,"new relocatable bit field\n");
1125 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0);
1126 relocbitfield->isBitField = 1;
1127 //addSet(&dynDirectRegs,relocbitfield);
1128 addSet(&dynInternalRegs,relocbitfield);
1129 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1133 breg->reg_alias = relocbitfield;
1134 breg->address = rDirectIdx; /* byte_no; */
1135 breg->rIdx = bit_no++;
1143 void bitEQUs(FILE *of, set *bregs)
1145 regs *breg,*bytereg;
1148 //fprintf(stderr," %s\n",__FUNCTION__);
1149 for (breg = setFirstItem(bregs) ; breg ;
1150 breg = setNextItem(bregs)) {
1152 //fprintf(stderr,"bit reg: %s\n",breg->name);
1154 bytereg = breg->reg_alias;
1156 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1159 breg->rIdx & 0x0007);
1162 //fprintf(stderr, "bit field is not assigned to a register\n");
1163 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1173 void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1178 for (reg = setFirstItem(fregs) ; reg ;
1179 reg = setNextItem(fregs)) {
1181 //if(!reg->isEmitted && reg->wasUsed) {
1184 fprintf (of, "%s\tEQU\t0x%03x\n",
1188 fprintf (of, "%s\tEQU\t0x%03x\n",
1196 void writeUsedRegs(FILE *of)
1198 packBits(dynDirectBitRegs);
1200 assignFixedRegisters(dynInternalRegs);
1201 assignFixedRegisters(dynAllocRegs);
1202 assignFixedRegisters(dynStackRegs);
1203 assignFixedRegisters(dynDirectRegs);
1205 assignRelocatableRegisters(dynInternalRegs,0);
1206 assignRelocatableRegisters(dynAllocRegs,0);
1207 assignRelocatableRegisters(dynStackRegs,0);
1209 assignRelocatableRegisters(dynDirectRegs,0);
1211 assignRelocatableRegisters(dynDirectRegs,0);
1212 printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
1217 bitEQUs(of,dynDirectBitRegs);
1219 aliasEQUs(of,dynAllocRegs,0);
1220 aliasEQUs(of,dynDirectRegs,0);
1221 aliasEQUs(of,dynStackRegs,0);
1222 aliasEQUs(of,dynProcessorRegs,1);
1227 /*-----------------------------------------------------------------*/
1228 /* allDefsOutOfRange - all definitions are out of a range */
1229 /*-----------------------------------------------------------------*/
1231 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1235 debugLog ("%s\n", __FUNCTION__);
1239 for (i = 0; i < defs->size; i++)
1243 if (bitVectBitValue (defs, i) &&
1244 (ic = hTabItemWithKey (iCodehTab, i)) &&
1245 (ic->seq >= fseq && ic->seq <= toseq))
1255 /*-----------------------------------------------------------------*/
1256 /* computeSpillable - given a point find the spillable live ranges */
1257 /*-----------------------------------------------------------------*/
1259 computeSpillable (iCode * ic)
1263 debugLog ("%s\n", __FUNCTION__);
1264 /* spillable live ranges are those that are live at this
1265 point . the following categories need to be subtracted
1267 a) - those that are already spilt
1268 b) - if being used by this one
1269 c) - defined by this one */
1271 spillable = bitVectCopy (ic->rlive);
1273 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1275 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1276 bitVectUnSetBit (spillable, ic->defKey);
1277 spillable = bitVectIntersect (spillable, _G.regAssigned);
1282 /*-----------------------------------------------------------------*/
1283 /* noSpilLoc - return true if a variable has no spil location */
1284 /*-----------------------------------------------------------------*/
1286 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1288 debugLog ("%s\n", __FUNCTION__);
1289 return (sym->usl.spillLoc ? 0 : 1);
1292 /*-----------------------------------------------------------------*/
1293 /* hasSpilLoc - will return 1 if the symbol has spil location */
1294 /*-----------------------------------------------------------------*/
1296 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1298 debugLog ("%s\n", __FUNCTION__);
1299 return (sym->usl.spillLoc ? 1 : 0);
1302 /*-----------------------------------------------------------------*/
1303 /* directSpilLoc - will return 1 if the splilocation is in direct */
1304 /*-----------------------------------------------------------------*/
1306 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1308 debugLog ("%s\n", __FUNCTION__);
1309 if (sym->usl.spillLoc &&
1310 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1316 /*-----------------------------------------------------------------*/
1317 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1318 /* but is not used as a pointer */
1319 /*-----------------------------------------------------------------*/
1321 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1323 debugLog ("%s\n", __FUNCTION__);
1324 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1327 /*-----------------------------------------------------------------*/
1328 /* rematable - will return 1 if the remat flag is set */
1329 /*-----------------------------------------------------------------*/
1331 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1333 debugLog ("%s\n", __FUNCTION__);
1337 /*-----------------------------------------------------------------*/
1338 /* notUsedInRemaining - not used or defined in remain of the block */
1339 /*-----------------------------------------------------------------*/
1341 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1343 debugLog ("%s\n", __FUNCTION__);
1344 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1345 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1348 /*-----------------------------------------------------------------*/
1349 /* allLRs - return true for all */
1350 /*-----------------------------------------------------------------*/
1352 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1354 debugLog ("%s\n", __FUNCTION__);
1358 /*-----------------------------------------------------------------*/
1359 /* liveRangesWith - applies function to a given set of live range */
1360 /*-----------------------------------------------------------------*/
1362 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1363 eBBlock * ebp, iCode * ic)
1368 debugLog ("%s\n", __FUNCTION__);
1369 if (!lrs || !lrs->size)
1372 for (i = 1; i < lrs->size; i++)
1375 if (!bitVectBitValue (lrs, i))
1378 /* if we don't find it in the live range
1379 hash table we are in serious trouble */
1380 if (!(sym = hTabItemWithKey (liveRanges, i)))
1382 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1383 "liveRangesWith could not find liveRange");
1387 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1388 addSetHead (&rset, sym);
1395 /*-----------------------------------------------------------------*/
1396 /* leastUsedLR - given a set determines which is the least used */
1397 /*-----------------------------------------------------------------*/
1399 leastUsedLR (set * sset)
1401 symbol *sym = NULL, *lsym = NULL;
1403 debugLog ("%s\n", __FUNCTION__);
1404 sym = lsym = setFirstItem (sset);
1409 for (; lsym; lsym = setNextItem (sset))
1412 /* if usage is the same then prefer
1413 the spill the smaller of the two */
1414 if (lsym->used == sym->used)
1415 if (getSize (lsym->type) < getSize (sym->type))
1419 if (lsym->used < sym->used)
1424 setToNull ((void *) &sset);
1429 /*-----------------------------------------------------------------*/
1430 /* noOverLap - will iterate through the list looking for over lap */
1431 /*-----------------------------------------------------------------*/
1433 noOverLap (set * itmpStack, symbol * fsym)
1436 debugLog ("%s\n", __FUNCTION__);
1439 for (sym = setFirstItem (itmpStack); sym;
1440 sym = setNextItem (itmpStack))
1442 if (sym->liveTo > fsym->liveFrom)
1450 /*-----------------------------------------------------------------*/
1451 /* isFree - will return 1 if the a free spil location is found */
1452 /*-----------------------------------------------------------------*/
1457 V_ARG (symbol **, sloc);
1458 V_ARG (symbol *, fsym);
1460 debugLog ("%s\n", __FUNCTION__);
1461 /* if already found */
1465 /* if it is free && and the itmp assigned to
1466 this does not have any overlapping live ranges
1467 with the one currently being assigned and
1468 the size can be accomodated */
1470 noOverLap (sym->usl.itmpStack, fsym) &&
1471 getSize (sym->type) >= getSize (fsym->type))
1480 /*-----------------------------------------------------------------*/
1481 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1482 /*-----------------------------------------------------------------*/
1484 spillLRWithPtrReg (symbol * forSym)
1490 debugLog ("%s\n", __FUNCTION__);
1491 if (!_G.regAssigned ||
1492 bitVectIsZero (_G.regAssigned))
1495 r0 = pic14_regWithIdx (R0_IDX);
1496 r1 = pic14_regWithIdx (R1_IDX);
1498 /* for all live ranges */
1499 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1500 lrsym = hTabNextItem (liveRanges, &k))
1504 /* if no registers assigned to it or
1506 /* if it does not overlap with this then
1507 not need to spill it */
1509 if (lrsym->isspilt || !lrsym->nRegs ||
1510 (lrsym->liveTo < forSym->liveFrom))
1513 /* go thru the registers : if it is either
1514 r0 or r1 then spil it */
1515 for (j = 0; j < lrsym->nRegs; j++)
1516 if (lrsym->regs[j] == r0 ||
1517 lrsym->regs[j] == r1)
1526 /*-----------------------------------------------------------------*/
1527 /* createStackSpil - create a location on the stack to spil */
1528 /*-----------------------------------------------------------------*/
1530 createStackSpil (symbol * sym)
1532 symbol *sloc = NULL;
1533 int useXstack, model, noOverlay;
1535 char slocBuffer[30];
1536 debugLog ("%s\n", __FUNCTION__);
1540 /* first go try and find a free one that is already
1541 existing on the stack */
1542 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1544 /* found a free one : just update & return */
1545 sym->usl.spillLoc = sloc;
1548 addSetHead (&sloc->usl.itmpStack, sym);
1552 /* could not then have to create one , this is the hard part
1553 we need to allocate this on the stack : this is really a
1554 hack!! but cannot think of anything better at this time */
1556 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1558 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1559 __FILE__, __LINE__);
1563 sloc = newiTemp (slocBuffer);
1565 /* set the type to the spilling symbol */
1566 sloc->type = copyLinkChain (sym->type);
1567 sloc->etype = getSpec (sloc->type);
1568 SPEC_SCLS (sloc->etype) = S_DATA;
1569 SPEC_EXTR (sloc->etype) = 0;
1570 SPEC_STAT (sloc->etype) = 0;
1572 /* we don't allow it to be allocated`
1573 onto the external stack since : so we
1574 temporarily turn it off ; we also
1575 turn off memory model to prevent
1576 the spil from going to the external storage
1577 and turn off overlaying
1580 useXstack = options.useXstack;
1581 model = options.model;
1582 noOverlay = options.noOverlay;
1583 options.noOverlay = 1;
1584 options.model = options.useXstack = 0;
1588 options.useXstack = useXstack;
1589 options.model = model;
1590 options.noOverlay = noOverlay;
1591 sloc->isref = 1; /* to prevent compiler warning */
1593 /* if it is on the stack then update the stack */
1594 if (IN_STACK (sloc->etype))
1596 currFunc->stack += getSize (sloc->type);
1597 _G.stackExtend += getSize (sloc->type);
1600 _G.dataExtend += getSize (sloc->type);
1602 /* add it to the _G.stackSpil set */
1603 addSetHead (&_G.stackSpil, sloc);
1604 sym->usl.spillLoc = sloc;
1607 /* add it to the set of itempStack set
1608 of the spill location */
1609 addSetHead (&sloc->usl.itmpStack, sym);
1613 /*-----------------------------------------------------------------*/
1614 /* isSpiltOnStack - returns true if the spil location is on stack */
1615 /*-----------------------------------------------------------------*/
1617 isSpiltOnStack (symbol * sym)
1621 debugLog ("%s\n", __FUNCTION__);
1630 /* if (sym->_G.stackSpil) */
1633 if (!sym->usl.spillLoc)
1636 etype = getSpec (sym->usl.spillLoc->type);
1637 if (IN_STACK (etype))
1643 /*-----------------------------------------------------------------*/
1644 /* spillThis - spils a specific operand */
1645 /*-----------------------------------------------------------------*/
1647 spillThis (symbol * sym)
1650 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1651 FENTRY2("sym: %s, spillLoc:%p (%s)\n", sym->rname, sym->usl.spillLoc, sym->usl.spillLoc ? sym->usl.spillLoc->rname : "<unknown>");
1653 /* if this is rematerializable or has a spillLocation
1654 we are okay, else we need to create a spillLocation
1656 if (!(sym->remat || sym->usl.spillLoc))
1657 createStackSpil (sym);
1660 /* mark it has spilt & put it in the spilt set */
1662 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1664 bitVectUnSetBit (_G.regAssigned, sym->key);
1666 for (i = 0; i < sym->nRegs; i++)
1670 freeReg (sym->regs[i]);
1671 sym->regs[i] = NULL;
1675 /* if spilt on stack then free up r0 & r1
1676 if they could have been assigned to some
1678 if (!pic14_ptrRegReq && isSpiltOnStack (sym))
1681 spillLRWithPtrReg (sym);
1684 if (sym->usl.spillLoc && !sym->remat)
1685 sym->usl.spillLoc->allocreq = 1;
1690 /*-----------------------------------------------------------------*/
1691 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1692 /*-----------------------------------------------------------------*/
1694 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1696 bitVect *lrcs = NULL;
1700 debugLog ("%s\n", __FUNCTION__);
1702 /* get the spillable live ranges */
1703 lrcs = computeSpillable (ic);
1706 /* get all live ranges that are rematerizable */
1707 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1709 /* return the least used of these */
1710 return leastUsedLR (selectS);
1713 /* get live ranges with spillLocations in direct space */
1714 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1716 sym = leastUsedLR (selectS);
1717 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1718 sym->usl.spillLoc->rname :
1719 sym->usl.spillLoc->name));
1721 /* mark it as allocation required */
1722 sym->usl.spillLoc->allocreq = 1;
1726 /* if the symbol is local to the block then */
1727 if (forSym->liveTo < ebp->lSeq)
1730 /* check if there are any live ranges allocated
1731 to registers that are not used in this block */
1732 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1734 sym = leastUsedLR (selectS);
1735 /* if this is not rematerializable */
1744 /* check if there are any live ranges that not
1745 used in the remainder of the block */
1746 if (!_G.blockSpil &&
1747 !isiCodeInFunctionCall (ic) &&
1748 (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1750 sym = leastUsedLR (selectS);
1753 sym->remainSpil = 1;
1760 /* find live ranges with spillocation && not used as pointers */
1761 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1764 sym = leastUsedLR (selectS);
1765 /* mark this as allocation required */
1766 sym->usl.spillLoc->allocreq = 1;
1770 /* find live ranges with spillocation */
1771 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1774 sym = leastUsedLR (selectS);
1775 sym->usl.spillLoc->allocreq = 1;
1779 /* couldn't find then we need to create a spil
1780 location on the stack , for which one? the least
1782 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1785 /* return a created spil location */
1786 sym = createStackSpil (leastUsedLR (selectS));
1787 sym->usl.spillLoc->allocreq = 1;
1791 /* this is an extreme situation we will spill
1792 this one : happens very rarely but it does happen */
1798 /*-----------------------------------------------------------------*/
1799 /* spilSomething - spil some variable & mark registers as free */
1800 /*-----------------------------------------------------------------*/
1802 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1807 debugLog ("%s\n", __FUNCTION__);
1808 /* get something we can spil */
1809 ssym = selectSpil (ic, ebp, forSym);
1811 /* mark it as spilt */
1813 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1815 /* mark it as not register assigned &
1816 take it away from the set */
1817 bitVectUnSetBit (_G.regAssigned, ssym->key);
1819 /* mark the registers as free */
1820 for (i = 0; i < ssym->nRegs; i++)
1822 freeReg (ssym->regs[i]);
1824 /* if spilt on stack then free up r0 & r1
1825 if they could have been assigned to as gprs */
1826 if (!pic14_ptrRegReq && isSpiltOnStack (ssym))
1829 spillLRWithPtrReg (ssym);
1832 /* if this was a block level spil then insert push & pop
1833 at the start & end of block respectively */
1834 if (ssym->blockSpil)
1836 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1837 /* add push to the start of the block */
1838 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1839 ebp->sch->next : ebp->sch));
1840 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1841 /* add pop to the end of the block */
1842 addiCodeToeBBlock (ebp, nic, NULL);
1845 /* if spilt because not used in the remainder of the
1846 block then add a push before this instruction and
1847 a pop at the end of the block */
1848 if (ssym->remainSpil)
1851 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1852 /* add push just before this instruction */
1853 addiCodeToeBBlock (ebp, nic, ic);
1855 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1856 /* add pop to the end of the block */
1857 addiCodeToeBBlock (ebp, nic, NULL);
1866 /*-----------------------------------------------------------------*/
1867 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1868 /*-----------------------------------------------------------------*/
1870 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1875 debugLog ("%s\n", __FUNCTION__);
1877 /* try for a ptr type */
1878 if ((reg = allocReg (REG_PTR)))
1881 /* try for gpr type */
1882 if ((reg = allocReg (REG_GPR)))
1885 /* we have to spil */
1886 if (!spilSomething (ic, ebp, sym))
1889 /* make sure partially assigned registers aren't reused */
1890 for (j=0; j<=sym->nRegs; j++)
1892 sym->regs[j]->isFree = 0;
1894 /* this looks like an infinite loop but
1895 in really selectSpil will abort */
1899 /*-----------------------------------------------------------------*/
1900 /* getRegGpr - will try for GPR if not spil */
1901 /*-----------------------------------------------------------------*/
1903 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1908 debugLog ("%s\n", __FUNCTION__);
1910 /* try for gpr type */
1911 if ((reg = allocReg (REG_GPR)))
1914 if (!pic14_ptrRegReq)
1915 if ((reg = allocReg (REG_PTR)))
1918 /* we have to spil */
1919 if (!spilSomething (ic, ebp, sym))
1922 /* make sure partially assigned registers aren't reused */
1923 for (j=0; j<=sym->nRegs; j++)
1925 sym->regs[j]->isFree = 0;
1927 /* this looks like an infinite loop but
1928 in really selectSpil will abort */
1932 /*-----------------------------------------------------------------*/
1933 /* symHasReg - symbol has a given register */
1934 /*-----------------------------------------------------------------*/
1936 symHasReg (symbol * sym, regs * reg)
1940 debugLog ("%s\n", __FUNCTION__);
1941 for (i = 0; i < sym->nRegs; i++)
1942 if (sym->regs[i] == reg)
1948 /*-----------------------------------------------------------------*/
1949 /* deassignLRs - check the live to and if they have registers & are */
1950 /* not spilt then free up the registers */
1951 /*-----------------------------------------------------------------*/
1953 deassignLRs (iCode * ic, eBBlock * ebp)
1959 debugLog ("%s\n", __FUNCTION__);
1960 for (sym = hTabFirstItem (liveRanges, &k); sym;
1961 sym = hTabNextItem (liveRanges, &k))
1964 symbol *psym = NULL;
1965 /* if it does not end here */
1966 if (sym->liveTo > ic->seq)
1969 /* Prevent the result from being assigned the same registers as (one)
1970 * operand as many genXXX-functions fail otherwise.
1971 * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT
1972 * are known to fail. */
1973 if (sym->liveTo == ic->seq && IC_RESULT(ic))
1977 case '=': /* assignment */
1978 case BITWISEAND: /* bitwise AND */
1979 case '|': /* bitwise OR */
1980 case '^': /* bitwise XOR */
1981 case '~': /* bitwise negate */
1982 case RLC: /* rotate through carry */
1985 case '+': /* addition */
1986 case '-': /* subtraction */
1987 /* go ahead, these are safe to use with
1988 * non-disjoint register sets */
1992 /* do not release operand registers */
1993 //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n");
1998 /* if it was spilt on stack then we can
1999 mark the stack spil location as free */
2004 sym->usl.spillLoc->isFree = 1;
2010 if (!bitVectBitValue (_G.regAssigned, sym->key))
2012 /* special case check if this is an IFX &
2013 the privious one was a pop and the
2014 previous one was not spilt then keep track
2016 if (ic->op == IFX && ic->prev &&
2017 ic->prev->op == IPOP &&
2018 !ic->prev->parmPush &&
2019 IS_SYMOP(IC_LEFT (ic->prev)) &&
2020 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
2021 psym = OP_SYMBOL (IC_LEFT (ic->prev));
2027 bitVectUnSetBit (_G.regAssigned, sym->key);
2029 /* if the result of this one needs registers
2030 and does not have it then assign it right
2032 if (IC_RESULT (ic) &&
2033 !(SKIP_IC2 (ic) || /* not a special icode */
2034 ic->op == JUMPTABLE ||
2039 POINTER_SET (ic)) &&
2040 IS_SYMOP (IC_RESULT (ic)) &&
2041 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
2042 result->liveTo > ic->seq && /* and will live beyond this */
2043 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
2044 result->liveFrom == ic->seq && /* does not start before here */
2045 result->regType == sym->regType && /* same register types */
2046 result->regType == sym->regType && /* same register types */
2047 result->nRegs && /* which needs registers */
2048 !result->isspilt && /* and does not already have them */
2050 !bitVectBitValue (_G.regAssigned, result->key) &&
2051 /* the number of free regs + number of regs in this LR
2052 can accomodate the what result Needs */
2053 ((nfreeRegsType (result->regType) +
2054 sym->nRegs) >= result->nRegs)
2058 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
2060 result->regs[i] = sym->regs[i];
2062 result->regs[i] = getRegGpr (ic, ebp, result);
2064 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
2068 /* free the remaining */
2069 for (; i < sym->nRegs; i++)
2073 if (!symHasReg (psym, sym->regs[i]))
2074 freeReg (sym->regs[i]);
2077 freeReg (sym->regs[i]);
2084 /*-----------------------------------------------------------------*/
2085 /* reassignLR - reassign this to registers */
2086 /*-----------------------------------------------------------------*/
2088 reassignLR (operand * op)
2090 symbol *sym = OP_SYMBOL (op);
2093 debugLog ("%s\n", __FUNCTION__);
2094 /* not spilt any more */
2095 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
2096 bitVectUnSetBit (_G.spiltSet, sym->key);
2098 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2102 for (i = 0; i < sym->nRegs; i++)
2103 sym->regs[i]->isFree = 0;
2106 /*-----------------------------------------------------------------*/
2107 /* willCauseSpill - determines if allocating will cause a spill */
2108 /*-----------------------------------------------------------------*/
2110 willCauseSpill (int nr, int rt)
2112 debugLog ("%s\n", __FUNCTION__);
2113 /* first check if there are any avlb registers
2114 of te type required */
2117 /* special case for pointer type
2118 if pointer type not avlb then
2119 check for type gpr */
2120 if (nFreeRegs (rt) >= nr)
2122 if (nFreeRegs (REG_GPR) >= nr)
2127 if (pic14_ptrRegReq)
2129 if (nFreeRegs (rt) >= nr)
2134 if (nFreeRegs (REG_PTR) +
2135 nFreeRegs (REG_GPR) >= nr)
2140 debugLog (" ... yep it will (cause a spill)\n");
2141 /* it will cause a spil */
2145 /*-----------------------------------------------------------------*/
2146 /* positionRegs - the allocator can allocate same registers to res- */
2147 /* ult and operand, if this happens make sure they are in the same */
2148 /* position as the operand otherwise chaos results */
2149 /*-----------------------------------------------------------------*/
2151 positionRegs (symbol * result, symbol * opsym, int lineno)
2153 int count = min (result->nRegs, opsym->nRegs);
2154 int i, j = 0, shared = 0;
2156 debugLog ("%s\n", __FUNCTION__);
2157 /* if the result has been spilt then cannot share */
2162 /* first make sure that they actually share */
2163 for (i = 0; i < count; i++)
2165 for (j = 0; j < count; j++)
2167 if (result->regs[i] == opsym->regs[j] && i != j)
2177 regs *tmp = result->regs[i];
2178 result->regs[i] = result->regs[j];
2179 result->regs[j] = tmp;
2184 /*------------------------------------------------------------------*/
2185 /* verifyRegsAssigned - make sure an iTemp is properly initialized; */
2186 /* it should either have registers or have beed spilled. Otherwise, */
2187 /* there was an uninitialized variable, so just spill this to get */
2188 /* the operand in a valid state. */
2189 /*------------------------------------------------------------------*/
2191 verifyRegsAssigned (operand *op, iCode * ic)
2196 if (!IS_ITEMP (op)) return;
2198 sym = OP_SYMBOL (op);
2199 if (sym->isspilt) return;
2200 if (!sym->nRegs) return;
2201 if (sym->regs[0]) return;
2203 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT,
2204 sym->prereqv ? sym->prereqv->name : sym->name);
2209 /*-----------------------------------------------------------------*/
2210 /* serialRegAssign - serially allocate registers to the variables */
2211 /*-----------------------------------------------------------------*/
2213 serialRegAssign (eBBlock ** ebbs, int count)
2217 debugLog ("%s\n", __FUNCTION__);
2218 /* for all blocks */
2219 for (i = 0; i < count; i++)
2224 if (ebbs[i]->noPath &&
2225 (ebbs[i]->entryLabel != entryLabel &&
2226 ebbs[i]->entryLabel != returnLabel))
2229 /* of all instructions do */
2230 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2232 debugLog (" op: %s\n", decodeOp (ic->op));
2234 /* if this is an ipop that means some live
2235 range will have to be assigned again */
2237 reassignLR (IC_LEFT (ic));
2239 /* if result is present && is a true symbol */
2240 if (IC_RESULT (ic) && ic->op != IFX &&
2241 IS_TRUE_SYMOP (IC_RESULT (ic)))
2242 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2244 /* take away registers from live
2245 ranges that end at this instruction */
2246 deassignLRs (ic, ebbs[i]);
2248 /* some don't need registers */
2249 if (SKIP_IC2 (ic) ||
2250 ic->op == JUMPTABLE ||
2254 (IC_RESULT (ic) && POINTER_SET (ic)))
2257 /* now we need to allocate registers
2258 only for the result */
2259 if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
2261 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2267 /* Make sure any spill location is definately allocated */
2268 if (sym->isspilt && !sym->remat && sym->usl.spillLoc &&
2269 !sym->usl.spillLoc->allocreq)
2271 sym->usl.spillLoc->allocreq++;
2274 /* if it does not need or is spilt
2275 or is already assigned to registers
2276 or will not live beyond this instructions */
2279 bitVectBitValue (_G.regAssigned, sym->key) ||
2280 sym->liveTo <= ic->seq)
2283 /* if some liverange has been spilt at the block level
2284 and this one live beyond this block then spil this
2286 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2291 /* if trying to allocate this will cause
2292 a spill and there is nothing to spill
2293 or this one is rematerializable then
2295 willCS = willCauseSpill (sym->nRegs, sym->regType);
2296 spillable = computeSpillable (ic);
2298 (willCS && bitVectIsZero (spillable)))
2306 /* If the live range preceeds the point of definition
2307 then ideally we must take into account registers that
2308 have been allocated after sym->liveFrom but freed
2309 before ic->seq. This is complicated, so spill this
2310 symbol instead and let fillGaps handle the allocation. */
2311 if (sym->liveFrom < ic->seq)
2317 /* if it has a spillocation & is used less than
2318 all other live ranges then spill this */
2320 if (sym->usl.spillLoc) {
2321 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2322 allLRs, ebbs[i], ic));
2323 if (leastUsed && leastUsed->used > sym->used) {
2328 /* if none of the liveRanges have a spillLocation then better
2329 to spill this one than anything else already assigned to registers */
2330 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2331 /* if this is local to this block then we might find a block spil */
2332 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2340 if (ic->op == RECEIVE)
2341 debugLog ("When I get clever, I'll optimize the receive logic\n");
2343 /* if we need ptr regs for the right side
2345 if (POINTER_GET (ic)
2346 && IS_SYMOP(IC_LEFT(ic))
2347 && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2348 <= (unsigned) PTRSIZE)
2353 /* else we assign registers to it */
2354 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2356 debugLog (" %d - \n", __LINE__);
2358 bitVectDebugOn(_G.regAssigned, debugF);
2359 for (j = 0; j < sym->nRegs; j++)
2361 if (sym->regType == REG_PTR)
2362 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2364 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2366 /* if the allocation failed which means
2367 this was spilt then break */
2371 debugLog (" %d - \n", __LINE__);
2373 /* if it shares registers with operands make sure
2374 that they are in the same position */
2375 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2376 IS_SYMOP(IC_RESULT(ic)) &&
2377 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2378 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2379 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2380 /* do the same for the right operand */
2381 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2382 IS_SYMOP(IC_RESULT(ic)) &&
2383 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2384 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2385 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2387 debugLog (" %d - \n", __LINE__);
2390 debugLog (" %d - \n", __LINE__);
2399 /* Check for and fix any problems with uninitialized operands */
2400 for (i = 0; i < count; i++)
2404 if (ebbs[i]->noPath &&
2405 (ebbs[i]->entryLabel != entryLabel &&
2406 ebbs[i]->entryLabel != returnLabel))
2409 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2416 verifyRegsAssigned (IC_COND (ic), ic);
2420 if (ic->op == JUMPTABLE)
2422 verifyRegsAssigned (IC_JTCOND (ic), ic);
2426 verifyRegsAssigned (IC_RESULT (ic), ic);
2427 verifyRegsAssigned (IC_LEFT (ic), ic);
2428 verifyRegsAssigned (IC_RIGHT (ic), ic);
2434 /*-----------------------------------------------------------------*/
2435 /* rUmaskForOp :- returns register mask for an operand */
2436 /*-----------------------------------------------------------------*/
2438 rUmaskForOp (operand * op)
2444 debugLog ("%s\n", __FUNCTION__);
2445 /* only temporaries are assigned registers */
2449 sym = OP_SYMBOL (op);
2451 /* if spilt or no registers assigned to it
2453 if (sym->isspilt || !sym->nRegs)
2456 rumask = newBitVect (pic14_nRegs);
2458 for (j = 0; j < sym->nRegs; j++)
2460 rumask = bitVectSetBit (rumask,
2461 sym->regs[j]->rIdx);
2467 /*-----------------------------------------------------------------*/
2468 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2469 /*-----------------------------------------------------------------*/
2471 regsUsedIniCode (iCode * ic)
2473 bitVect *rmask = newBitVect (pic14_nRegs);
2475 debugLog ("%s\n", __FUNCTION__);
2476 /* do the special cases first */
2479 rmask = bitVectUnion (rmask,
2480 rUmaskForOp (IC_COND (ic)));
2484 /* for the jumptable */
2485 if (ic->op == JUMPTABLE)
2487 rmask = bitVectUnion (rmask,
2488 rUmaskForOp (IC_JTCOND (ic)));
2493 /* of all other cases */
2495 rmask = bitVectUnion (rmask,
2496 rUmaskForOp (IC_LEFT (ic)));
2500 rmask = bitVectUnion (rmask,
2501 rUmaskForOp (IC_RIGHT (ic)));
2504 rmask = bitVectUnion (rmask,
2505 rUmaskForOp (IC_RESULT (ic)));
2511 /*-----------------------------------------------------------------*/
2512 /* createRegMask - for each instruction will determine the regsUsed */
2513 /*-----------------------------------------------------------------*/
2515 createRegMask (eBBlock ** ebbs, int count)
2519 debugLog ("%s\n", __FUNCTION__);
2520 /* for all blocks */
2521 for (i = 0; i < count; i++)
2525 if (ebbs[i]->noPath &&
2526 (ebbs[i]->entryLabel != entryLabel &&
2527 ebbs[i]->entryLabel != returnLabel))
2530 /* for all instructions */
2531 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2536 if (SKIP_IC2 (ic) || !ic->rlive)
2539 /* first mark the registers used in this
2541 ic->rUsed = regsUsedIniCode (ic);
2542 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2544 /* now create the register mask for those
2545 registers that are in use : this is a
2546 super set of ic->rUsed */
2547 ic->rMask = newBitVect (pic14_nRegs + 1);
2549 /* for all live Ranges alive at this point */
2550 for (j = 1; j < ic->rlive->size; j++)
2555 /* if not alive then continue */
2556 if (!bitVectBitValue (ic->rlive, j))
2559 /* find the live range we are interested in */
2560 if (!(sym = hTabItemWithKey (liveRanges, j)))
2562 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2563 "createRegMask cannot find live range");
2567 /* if no register assigned to it */
2568 if (!sym->nRegs || sym->isspilt)
2571 /* for all the registers allocated to it */
2572 for (k = 0; k < sym->nRegs; k++)
2575 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2581 /* This was the active version */
2582 /*-----------------------------------------------------------------*/
2583 /* rematStr - returns the rematerialized string for a remat var */
2584 /*-----------------------------------------------------------------*/
2586 rematStr (symbol * sym)
2589 iCode *ic = sym->rematiCode;
2590 symbol *psym = NULL;
2592 debugLog ("%s\n", __FUNCTION__);
2594 //printf ("%s\n", s);
2596 /* if plus or minus print the right hand side */
2598 if (ic->op == '+' || ic->op == '-') {
2600 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2602 sprintf (s, "(%s %c 0x%04x)",
2603 OP_SYMBOL (IC_LEFT (ric))->rname,
2605 (int) operandLitValue (IC_RIGHT (ic)));
2608 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2610 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2611 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2616 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2617 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2619 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2625 /* deprecated version */
2626 /*-----------------------------------------------------------------*/
2627 /* rematStr - returns the rematerialized string for a remat var */
2628 /*-----------------------------------------------------------------*/
2630 rematStr (symbol * sym)
2633 iCode *ic = sym->rematiCode;
2635 debugLog ("%s\n", __FUNCTION__);
2640 /* if plus or minus print the right hand side */
2642 if (ic->op == '+' || ic->op == '-') {
2643 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2646 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2650 if (ic->op == '+' || ic->op == '-')
2652 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2653 sprintf (s, "(%s %c 0x%04x)",
2654 OP_SYMBOL (IC_LEFT (ric))->rname,
2656 (int) operandLitValue (IC_RIGHT (ic)));
2659 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2661 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2665 /* we reached the end */
2666 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2670 printf ("%s\n", buffer);
2675 /*-----------------------------------------------------------------*/
2676 /* regTypeNum - computes the type & number of registers required */
2677 /*-----------------------------------------------------------------*/
2685 debugLog ("%s\n", __FUNCTION__);
2686 /* for each live range do */
2687 for (sym = hTabFirstItem (liveRanges, &k); sym;
2688 sym = hTabNextItem (liveRanges, &k)) {
2690 debugLog (" %d - %s\n", __LINE__, sym->rname);
2692 /* if used zero times then no registers needed */
2693 if ((sym->liveTo - sym->liveFrom) == 0)
2697 /* if the live range is a temporary */
2700 debugLog (" %d - itemp register\n", __LINE__);
2702 /* if the type is marked as a conditional */
2703 if (sym->regType == REG_CND)
2706 /* if used in return only then we don't
2709 if (IS_AGGREGATE (sym->type) || sym->isptr)
2710 sym->type = aggrToPtr (sym->type, FALSE);
2711 debugLog (" %d - no reg needed - accumulator used\n", __LINE__);
2717 //if (IS_AGGREGATE (sym->type) || sym->isptr)
2718 // sym->type = aggrToPtr (sym->type, FALSE);
2719 debugLog (" %d - used as a return\n", __LINE__);
2724 /* if the symbol has only one definition &
2725 that definition is a get_pointer and the
2726 pointer we are getting is rematerializable and
2730 if (bitVectnBitsOn (sym->defs) == 1 &&
2731 (ic = hTabItemWithKey (iCodehTab,
2732 bitVectFirstBit (sym->defs))) &&
2734 !IS_BITVAR (sym->etype) &&
2735 (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
2737 if (ptrPseudoSymSafe (sym, ic)) {
2741 debugLog (" %d - \n", __LINE__);
2743 /* create a psuedo symbol & force a spil */
2744 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2745 psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2746 psym->type = sym->type;
2747 psym->etype = sym->etype;
2748 psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
2749 strcpy (psym->rname, psym->name);
2751 sym->usl.spillLoc = psym;
2755 /* if in data space or idata space then try to
2756 allocate pointer register */
2761 /* if not then we require registers */
2762 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2763 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2764 getSize (sym->type));
2767 if(IS_PTR_CONST (sym->type)) {
2768 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2772 if (sym->nRegs > 4) {
2773 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2774 printTypeChain (sym->type, stderr);
2775 fprintf (stderr, "\n");
2778 /* determine the type of register required */
2779 if (sym->nRegs == 1 &&
2780 IS_PTR (sym->type) &&
2782 sym->regType = REG_PTR;
2784 sym->regType = REG_GPR;
2787 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2791 /* for the first run we don't provide */
2792 /* registers for true symbols we will */
2793 /* see how things go */
2798 DEFSETFUNC (markRegFree)
2800 ((regs *)item)->isFree = 1;
2805 DEFSETFUNC (deallocReg)
2807 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2808 ((regs *)item)->isFree = 1;
2809 ((regs *)item)->wasUsed = 0;
2813 /*-----------------------------------------------------------------*/
2814 /* freeAllRegs - mark all registers as free */
2815 /*-----------------------------------------------------------------*/
2817 pic14_freeAllRegs ()
2821 debugLog ("%s\n", __FUNCTION__);
2823 applyToSet(dynAllocRegs,markRegFree);
2824 applyToSet(dynStackRegs,markRegFree);
2827 for (i = 0; i < pic14_nRegs; i++)
2828 regspic14[i].isFree = 1;
2832 /*-----------------------------------------------------------------*/
2833 /*-----------------------------------------------------------------*/
2835 pic14_deallocateAllRegs ()
2839 debugLog ("%s\n", __FUNCTION__);
2841 applyToSet(dynAllocRegs,deallocReg);
2844 for (i = 0; i < pic14_nRegs; i++) {
2845 if(regspic14[i].pc_type == PO_GPR_TEMP) {
2846 regspic14[i].isFree = 1;
2847 regspic14[i].wasUsed = 0;
2854 /*-----------------------------------------------------------------*/
2855 /* deallocStackSpil - this will set the stack pointer back */
2856 /*-----------------------------------------------------------------*/
2858 DEFSETFUNC (deallocStackSpil)
2862 debugLog ("%s\n", __FUNCTION__);
2867 /*-----------------------------------------------------------------*/
2868 /* farSpacePackable - returns the packable icode for far variables */
2869 /*-----------------------------------------------------------------*/
2871 farSpacePackable (iCode * ic)
2875 debugLog ("%s\n", __FUNCTION__);
2876 /* go thru till we find a definition for the
2877 symbol on the right */
2878 for (dic = ic->prev; dic; dic = dic->prev)
2881 /* if the definition is a call then no */
2882 if ((dic->op == CALL || dic->op == PCALL) &&
2883 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2888 /* if shift by unknown amount then not */
2889 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2890 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2893 /* if pointer get and size > 1 */
2894 if (POINTER_GET (dic) &&
2895 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2898 if (POINTER_SET (dic) &&
2899 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2902 /* if any three is a true symbol in far space */
2903 if (IC_RESULT (dic) &&
2904 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2905 isOperandInFarSpace (IC_RESULT (dic)))
2908 if (IC_RIGHT (dic) &&
2909 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2910 isOperandInFarSpace (IC_RIGHT (dic)) &&
2911 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2914 if (IC_LEFT (dic) &&
2915 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2916 isOperandInFarSpace (IC_LEFT (dic)) &&
2917 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2920 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2922 if ((dic->op == LEFT_OP ||
2923 dic->op == RIGHT_OP ||
2925 IS_OP_LITERAL (IC_RIGHT (dic)))
2935 /*-----------------------------------------------------------------*/
2936 /* packRegsForAssign - register reduction for assignment */
2937 /*-----------------------------------------------------------------*/
2939 packRegsForAssign (iCode * ic, eBBlock * ebp)
2944 debugLog ("%s\n", __FUNCTION__);
2946 debugAopGet (" result:", IC_RESULT (ic));
2947 debugAopGet (" left:", IC_LEFT (ic));
2948 debugAopGet (" right:", IC_RIGHT (ic));
2950 /* if this is at an absolute address, then get the address. */
2951 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2952 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2953 debugLog (" %d - found config word declaration\n", __LINE__);
2954 if(IS_VALOP(IC_RIGHT(ic))) {
2955 debugLog (" setting config word to %x\n",
2956 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2957 assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2958 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2961 /* remove the assignment from the iCode chain. */
2963 remiCodeFromeBBlock (ebp, ic);
2964 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2965 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2972 if (!IS_ITEMP (IC_RESULT (ic))) {
2973 allocDirReg(IC_RESULT (ic));
2974 debugLog (" %d - result is not temp\n", __LINE__);
2977 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2978 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2979 allocDirReg(IC_LEFT (ic));
2983 if (!IS_ITEMP (IC_RIGHT (ic))) {
2984 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2986 /* only pack if this is not a function pointer */
2987 if (!IS_REF (IC_RIGHT (ic)))
2988 allocDirReg(IC_RIGHT (ic));
2992 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2993 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2995 debugLog (" %d - not packing - right side fails \n", __LINE__);
2999 /* if the true symbol is defined in far space or on stack
3000 then we should not since this will increase register pressure */
3001 if (isOperandInFarSpace (IC_RESULT (ic)))
3003 if ((dic = farSpacePackable (ic)))
3009 /* find the definition of iTempNN scanning backwards if we find a
3010 a use of the true symbol before we find the definition then
3012 for (dic = ic->prev; dic; dic = dic->prev)
3015 /* if there is a function call and this is
3016 a parameter & not my parameter then don't pack it */
3017 if ((dic->op == CALL || dic->op == PCALL) &&
3018 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
3019 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
3021 debugLog (" %d - \n", __LINE__);
3029 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
3030 IS_OP_VOLATILE (IC_RESULT (dic)))
3032 debugLog (" %d - dic is VOLATILE \n", __LINE__);
3037 if (IS_SYMOP (IC_RESULT (dic)) &&
3038 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
3040 /* A previous result was assigned to the same register - we'll our definition */
3041 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
3042 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
3043 if (POINTER_SET (dic))
3049 if (IS_SYMOP (IC_RIGHT (dic)) &&
3050 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
3051 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
3053 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
3058 if (IS_SYMOP (IC_LEFT (dic)) &&
3059 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
3060 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
3062 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
3067 if (POINTER_SET (dic) &&
3068 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
3070 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
3078 return 0; /* did not find */
3080 /* if the result is on stack or iaccess then it must be
3081 the same at least one of the operands */
3082 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
3083 OP_SYMBOL (IC_RESULT (ic))->iaccess)
3086 /* the operation has only one symbol
3087 operator then we can pack */
3088 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
3089 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
3092 if (!((IC_LEFT (dic) &&
3093 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
3095 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
3099 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
3100 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
3101 /* found the definition */
3102 /* replace the result with the result of */
3103 /* this assignment and remove this assignment */
3104 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3105 IC_RESULT (dic) = IC_RESULT (ic);
3107 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
3109 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
3111 /* delete from liverange table also
3112 delete from all the points inbetween and the new
3114 for (sic = dic; sic != ic; sic = sic->next)
3116 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
3117 if (IS_ITEMP (IC_RESULT (dic)))
3118 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
3121 remiCodeFromeBBlock (ebp, ic);
3122 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3123 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3124 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3130 /*-----------------------------------------------------------------*/
3131 /* findAssignToSym : scanning backwards looks for first assig found */
3132 /*-----------------------------------------------------------------*/
3134 findAssignToSym (operand * op, iCode * ic)
3138 debugLog ("%s\n", __FUNCTION__);
3139 for (dic = ic->prev; dic; dic = dic->prev)
3142 /* if definition by assignment */
3143 if (dic->op == '=' &&
3144 !POINTER_SET (dic) &&
3145 IC_RESULT (dic)->key == op->key
3146 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
3150 /* we are interested only if defined in far space */
3151 /* or in stack space in case of + & - */
3153 /* if assigned to a non-symbol then return
3155 if (!IS_SYMOP (IC_RIGHT (dic)))
3158 /* if the symbol is in far space then
3160 if (isOperandInFarSpace (IC_RIGHT (dic)))
3163 /* for + & - operations make sure that
3164 if it is on the stack it is the same
3165 as one of the three operands */
3166 if ((ic->op == '+' || ic->op == '-') &&
3167 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3170 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3171 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3172 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3180 /* if we find an usage then we cannot delete it */
3181 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3184 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3187 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3191 /* now make sure that the right side of dic
3192 is not defined between ic & dic */
3195 iCode *sic = dic->next;
3197 for (; sic != ic; sic = sic->next)
3198 if (IC_RESULT (sic) &&
3199 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3208 /*-----------------------------------------------------------------*/
3209 /* packRegsForSupport :- reduce some registers for support calls */
3210 /*-----------------------------------------------------------------*/
3212 packRegsForSupport (iCode * ic, eBBlock * ebp)
3216 debugLog ("%s\n", __FUNCTION__);
3217 /* for the left & right operand :- look to see if the
3218 left was assigned a true symbol in far space in that
3219 case replace them */
3220 if (IS_ITEMP (IC_LEFT (ic)) &&
3221 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3223 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3229 debugAopGet ("removing left:", IC_LEFT (ic));
3231 /* found it we need to remove it from the
3233 for (sic = dic; sic != ic; sic = sic->next)
3234 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3236 IC_LEFT (ic)->operand.symOperand =
3237 IC_RIGHT (dic)->operand.symOperand;
3238 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3239 remiCodeFromeBBlock (ebp, dic);
3240 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3241 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3245 /* do the same for the right operand */
3248 IS_ITEMP (IC_RIGHT (ic)) &&
3249 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3251 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3257 /* if this is a subtraction & the result
3258 is a true symbol in far space then don't pack */
3259 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3261 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3262 if (IN_FARSPACE (SPEC_OCLS (etype)))
3266 debugAopGet ("removing right:", IC_RIGHT (ic));
3268 /* found it we need to remove it from the
3270 for (sic = dic; sic != ic; sic = sic->next)
3271 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3273 IC_RIGHT (ic)->operand.symOperand =
3274 IC_RIGHT (dic)->operand.symOperand;
3275 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3277 remiCodeFromeBBlock (ebp, dic);
3278 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3279 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3286 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3289 /*-----------------------------------------------------------------*/
3290 /* packRegsForOneuse : - will reduce some registers for single Use */
3291 /*-----------------------------------------------------------------*/
3293 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3298 debugLog ("%s\n", __FUNCTION__);
3299 /* if returning a literal then do nothing */
3303 /* only upto 2 bytes since we cannot predict
3304 the usage of b, & acc */
3305 if (getSize (operandType (op)) > (fReturnSizePic - 2) &&
3310 /* this routine will mark the a symbol as used in one
3311 instruction use only && if the definition is local
3312 (ie. within the basic block) && has only one definition &&
3313 that definition is either a return value from a
3314 function or does not contain any variables in
3316 uses = bitVectCopy (OP_USES (op));
3317 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3318 if (!bitVectIsZero (uses)) /* has other uses */
3321 /* if it has only one defintion */
3322 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3323 return NULL; /* has more than one definition */
3325 /* get that definition */
3327 hTabItemWithKey (iCodehTab,
3328 bitVectFirstBit (OP_DEFS (op)))))
3331 /* found the definition now check if it is local */
3332 if (dic->seq < ebp->fSeq ||
3333 dic->seq > ebp->lSeq)
3334 return NULL; /* non-local */
3336 /* now check if it is the return from
3338 if (dic->op == CALL || dic->op == PCALL)
3340 if (ic->op != SEND && ic->op != RETURN &&
3341 !POINTER_SET(ic) && !POINTER_GET(ic))
3343 OP_SYMBOL (op)->ruonly = 1;
3350 /* otherwise check that the definition does
3351 not contain any symbols in far space */
3352 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3353 isOperandInFarSpace (IC_RIGHT (dic)) ||
3354 IS_OP_RUONLY (IC_LEFT (ic)) ||
3355 IS_OP_RUONLY (IC_RIGHT (ic)))
3360 /* if pointer set then make sure the pointer
3362 if (POINTER_SET (dic) &&
3363 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3366 if (POINTER_GET (dic) &&
3367 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3372 /* also make sure the intervenening instructions
3373 don't have any thing in far space */
3374 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3377 /* if there is an intervening function call then no */
3378 if (dic->op == CALL || dic->op == PCALL)
3380 /* if pointer set then make sure the pointer
3382 if (POINTER_SET (dic) &&
3383 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3386 if (POINTER_GET (dic) &&
3387 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3390 /* if address of & the result is remat then okay */
3391 if (dic->op == ADDRESS_OF &&
3392 OP_SYMBOL (IC_RESULT (dic))->remat)
3395 /* if operand has size of three or more & this
3396 operation is a '*','/' or '%' then 'b' may
3398 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3399 getSize (operandType (op)) >= 3)
3402 /* if left or right or result is in far space */
3403 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3404 isOperandInFarSpace (IC_RIGHT (dic)) ||
3405 isOperandInFarSpace (IC_RESULT (dic)) ||
3406 IS_OP_RUONLY (IC_LEFT (dic)) ||
3407 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3408 IS_OP_RUONLY (IC_RESULT (dic)))
3414 OP_SYMBOL (op)->ruonly = 1;
3419 /*-----------------------------------------------------------------*/
3420 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3421 /*-----------------------------------------------------------------*/
3423 isBitwiseOptimizable (iCode * ic)
3425 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3426 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3428 debugLog ("%s\n", __FUNCTION__);
3429 /* bitwise operations are considered optimizable
3430 under the following conditions (Jean-Louis VERN)
3442 if (IS_LITERAL (rtype) ||
3443 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3449 /*-----------------------------------------------------------------*/
3450 /* packRegsForAccUse - pack registers for acc use */
3451 /*-----------------------------------------------------------------*/
3453 packRegsForAccUse (iCode * ic)
3457 debugLog ("%s\n", __FUNCTION__);
3459 /* result too large for WREG? */
3460 if (getSize (operandType (IC_RESULT (ic))) > 1)
3463 /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
3464 * is never used as an operand to an instruction that
3465 * cannot have WREG as an operand (e.g. BTFSx cannot
3466 * operate on WREG...
3467 * For now, store all results into proper registers. */
3471 /* if this is an aggregate, e.g. a one byte char array */
3472 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3475 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3477 /* if + or - then it has to be one byte result */
3478 if ((ic->op == '+' || ic->op == '-')
3479 && getSize (operandType (IC_RESULT (ic))) > 1)
3482 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3483 /* if shift operation make sure right side is not a literal */
3484 if (ic->op == RIGHT_OP &&
3485 (isOperandLiteral (IC_RIGHT (ic)) ||
3486 getSize (operandType (IC_RESULT (ic))) > 1))
3489 if (ic->op == LEFT_OP &&
3490 (isOperandLiteral (IC_RIGHT (ic)) ||
3491 getSize (operandType (IC_RESULT (ic))) > 1))
3494 if (IS_BITWISE_OP (ic) &&
3495 getSize (operandType (IC_RESULT (ic))) > 1)
3499 /* has only one definition */
3500 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3503 /* has only one use */
3504 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3507 /* and the usage immediately follows this iCode */
3508 if (!(uic = hTabItemWithKey (iCodehTab,
3509 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3512 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3513 if (ic->next != uic)
3516 /* if it is a conditional branch then we definitely can */
3520 if (uic->op == JUMPTABLE)
3523 /* if the usage is not is an assignment
3524 or an arithmetic / bitwise / shift operation then not */
3525 if (POINTER_SET (uic) &&
3526 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3529 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3530 if (uic->op != '=' &&
3531 !IS_ARITHMETIC_OP (uic) &&
3532 !IS_BITWISE_OP (uic) &&
3533 uic->op != LEFT_OP &&
3534 uic->op != RIGHT_OP)
3537 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3538 /* if used in ^ operation then make sure right is not a
3540 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3543 /* if shift operation make sure right side is not a literal */
3544 if (uic->op == RIGHT_OP &&
3545 (isOperandLiteral (IC_RIGHT (uic)) ||
3546 getSize (operandType (IC_RESULT (uic))) > 1))
3549 if (uic->op == LEFT_OP &&
3550 (isOperandLiteral (IC_RIGHT (uic)) ||
3551 getSize (operandType (IC_RESULT (uic))) > 1))
3554 /* make sure that the result of this icode is not on the
3555 stack, since acc is used to compute stack offset */
3556 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3557 OP_SYMBOL (IC_RESULT (uic))->onStack)
3560 /* if either one of them in far space then we cannot */
3561 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3562 isOperandInFarSpace (IC_LEFT (uic))) ||
3563 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3564 isOperandInFarSpace (IC_RIGHT (uic))))
3567 /* if the usage has only one operand then we can */
3568 if (IC_LEFT (uic) == NULL ||
3569 IC_RIGHT (uic) == NULL)
3572 /* make sure this is on the left side if not
3573 a '+' since '+' is commutative */
3574 if (ic->op != '+' &&
3575 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3578 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3579 /* if one of them is a literal then we can */
3580 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3581 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3582 (getSize (operandType (IC_RESULT (uic))) <= 1))
3584 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3588 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3589 /* if the other one is not on stack then we can */
3590 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3591 (IS_ITEMP (IC_RIGHT (uic)) ||
3592 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3593 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3596 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3597 (IS_ITEMP (IC_LEFT (uic)) ||
3598 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3599 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3605 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3606 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3610 /*-----------------------------------------------------------------*/
3611 /* packForPush - hueristics to reduce iCode for pushing */
3612 /*-----------------------------------------------------------------*/
3614 packForReceive (iCode * ic, eBBlock * ebp)
3618 debugLog ("%s\n", __FUNCTION__);
3619 debugAopGet (" result:", IC_RESULT (ic));
3620 debugAopGet (" left:", IC_LEFT (ic));
3621 debugAopGet (" right:", IC_RIGHT (ic));
3626 for (dic = ic->next; dic; dic = dic->next)
3631 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3632 debugLog (" used on left\n");
3633 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3634 debugLog (" used on right\n");
3635 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3636 debugLog (" used on result\n");
3638 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3639 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3644 debugLog (" hey we can remove this unnecessary assign\n");
3646 /*-----------------------------------------------------------------*/
3647 /* packForPush - hueristics to reduce iCode for pushing */
3648 /*-----------------------------------------------------------------*/
3650 packForPush (iCode * ic, eBBlock * ebp)
3654 debugLog ("%s\n", __FUNCTION__);
3655 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3658 /* must have only definition & one usage */
3659 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3660 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3663 /* find the definition */
3664 if (!(dic = hTabItemWithKey (iCodehTab,
3665 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3668 if (dic->op != '=' || POINTER_SET (dic))
3671 /* we now we know that it has one & only one def & use
3672 and the that the definition is an assignment */
3673 IC_LEFT (ic) = IC_RIGHT (dic);
3675 remiCodeFromeBBlock (ebp, dic);
3676 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3677 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3680 void printSymType(char * str, sym_link *sl)
3682 debugLog (" %s Symbol type: ",str);
3683 printTypeChain( sl, debugF);
3688 /*-----------------------------------------------------------------*/
3689 /* some debug code to print the symbol S_TYPE. Note that
3690 * the function checkSClass in src/SDCCsymt.c dinks with
3691 * the S_TYPE in ways the PIC port doesn't fully like...*/
3692 /*-----------------------------------------------------------------*/
3693 void isData(sym_link *sl)
3703 for ( ; sl; sl=sl->next) {
3705 switch (SPEC_SCLS(sl)) {
3707 case S_DATA: fprintf (of, "data "); break;
3708 case S_XDATA: fprintf (of, "xdata "); break;
3709 case S_SFR: fprintf (of, "sfr "); break;
3710 case S_SBIT: fprintf (of, "sbit "); break;
3711 case S_CODE: fprintf (of, "code "); break;
3712 case S_IDATA: fprintf (of, "idata "); break;
3713 case S_PDATA: fprintf (of, "pdata "); break;
3714 case S_LITERAL: fprintf (of, "literal "); break;
3715 case S_STACK: fprintf (of, "stack "); break;
3716 case S_XSTACK: fprintf (of, "xstack "); break;
3717 case S_BIT: fprintf (of, "bit "); break;
3718 case S_EEPROM: fprintf (of, "eeprom "); break;
3728 /*-----------------------------------------------------------------*/
3729 /* packRegisters - does some transformations to reduce register */
3731 /*-----------------------------------------------------------------*/
3733 packRegisters (eBBlock * ebp)
3738 debugLog ("%s\n", __FUNCTION__);
3744 /* look for assignments of the form */
3745 /* iTempNN = TRueSym (someoperation) SomeOperand */
3747 /* TrueSym := iTempNN:1 */
3748 for (ic = ebp->sch; ic; ic = ic->next)
3751 /* find assignment of the form TrueSym := iTempNN:1 */
3752 if (ic->op == '=' && !POINTER_SET (ic))
3753 change += packRegsForAssign (ic, ebp);
3757 if (POINTER_SET (ic))
3758 debugLog ("pointer is set\n");
3759 debugAopGet (" result:", IC_RESULT (ic));
3760 debugAopGet (" left:", IC_LEFT (ic));
3761 debugAopGet (" right:", IC_RIGHT (ic));
3770 for (ic = ebp->sch; ic; ic = ic->next) {
3772 if(IS_SYMOP ( IC_LEFT(ic))) {
3773 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3775 debugAopGet (" left:", IC_LEFT (ic));
3776 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3777 debugLog (" is a pointer\n");
3779 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3780 debugLog (" is volatile\n");
3784 printSymType(" ", OP_SYMBOL(IC_LEFT(ic))->type);
3787 if(IS_SYMOP ( IC_RIGHT(ic))) {
3788 debugAopGet (" right:", IC_RIGHT (ic));
3789 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3792 if(IS_SYMOP ( IC_RESULT(ic))) {
3793 debugAopGet (" result:", IC_RESULT (ic));
3794 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3797 if (POINTER_SET (ic))
3798 debugLog (" %d - Pointer set\n", __LINE__);
3801 /* Look for two subsequent iCodes with */
3803 /* _c = iTemp & op; */
3804 /* and replace them by */
3807 if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
3809 ic->prev->op == '=' &&
3810 IS_ITEMP (IC_LEFT (ic)) &&
3811 IC_LEFT (ic) == IC_RESULT (ic->prev) &&
3812 isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev)))
3814 iCode* ic_prev = ic->prev;
3815 symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev));
3817 ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic));
3818 if (IC_RESULT (ic_prev) != IC_RIGHT (ic))
3820 bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key);
3821 if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */
3822 prev_result_sym->liveTo == ic->seq)
3824 prev_result_sym->liveTo = ic_prev->seq;
3827 bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
3829 bitVectSetBit (ic->rlive, IC_RESULT (ic)->key);
3831 if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev))))
3833 bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key);
3834 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key);
3835 remiCodeFromeBBlock (ebp, ic_prev);
3836 hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL);
3840 /* if this is an itemp & result of a address of a true sym
3841 then mark this as rematerialisable */
3842 if (ic->op == ADDRESS_OF &&
3843 IS_ITEMP (IC_RESULT (ic)) &&
3844 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3845 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3846 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3849 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3851 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3852 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3853 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3857 /* if straight assignment then carry remat flag if
3858 this is the only definition */
3859 if (ic->op == '=' &&
3860 !POINTER_SET (ic) &&
3861 IS_SYMOP (IC_RIGHT (ic)) &&
3862 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3863 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3865 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3867 OP_SYMBOL (IC_RESULT (ic))->remat =
3868 OP_SYMBOL (IC_RIGHT (ic))->remat;
3869 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3870 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3873 /* if this is a +/- operation with a rematerizable
3874 then mark this as rematerializable as well */
3875 if ((ic->op == '+' || ic->op == '-') &&
3876 (IS_SYMOP (IC_LEFT (ic)) &&
3877 IS_ITEMP (IC_RESULT (ic)) &&
3878 OP_SYMBOL (IC_LEFT (ic))->remat &&
3879 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3880 IS_OP_LITERAL (IC_RIGHT (ic))))
3882 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3884 operandLitValue (IC_RIGHT (ic));
3885 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3886 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3887 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3890 /* mark the pointer usages */
3891 if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
3893 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3894 debugLog (" marking as a pointer (set) =>");
3895 debugAopGet (" result:", IC_RESULT (ic));
3897 if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
3899 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3900 debugLog (" marking as a pointer (get) =>");
3901 debugAopGet (" left:", IC_LEFT (ic));
3906 /* if we are using a symbol on the stack
3907 then we should say pic14_ptrRegReq */
3908 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3909 pic14_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3910 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3911 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3912 pic14_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3913 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3916 if (IS_SYMOP (IC_LEFT (ic)))
3917 pic14_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3918 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3919 if (IS_SYMOP (IC_RIGHT (ic)))
3920 pic14_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3921 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3922 if (IS_SYMOP (IC_RESULT (ic)))
3923 pic14_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3924 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3927 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic14_ptrRegReq);
3931 /* if the condition of an if instruction
3932 is defined in the previous instruction then
3933 mark the itemp as a conditional */
3934 if ((IS_CONDITIONAL (ic) ||
3935 ((ic->op == BITWISEAND ||
3938 isBitwiseOptimizable (ic))) &&
3939 ic->next && ic->next->op == IFX &&
3940 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3941 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3944 debugLog (" %d\n", __LINE__);
3945 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3949 /* reduce for support function calls */
3950 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3951 packRegsForSupport (ic, ebp);
3953 /* if a parameter is passed, it's in W, so we may not
3954 need to place a copy in a register */
3955 if (ic->op == RECEIVE)
3956 packForReceive (ic, ebp);
3958 /* some cases the redundant moves can
3959 can be eliminated for return statements */
3960 if ((ic->op == RETURN || ic->op == SEND) &&
3961 !isOperandInFarSpace (IC_LEFT (ic)) &&
3963 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3965 /* if pointer set & left has a size more than
3966 one and right is not in far space */
3967 if (POINTER_SET (ic) &&
3968 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3969 IS_SYMOP(IC_RESULT(ic)) &&
3970 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3971 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3972 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3974 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3976 /* if pointer get */
3977 if (POINTER_GET (ic) &&
3978 !isOperandInFarSpace (IC_RESULT (ic)) &&
3979 IS_SYMOP(IC_LEFT(ic)) &&
3980 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3981 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3982 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3984 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3987 /* if this is cast for intergral promotion then
3988 check if only use of the definition of the
3989 operand being casted/ if yes then replace
3990 the result of that arithmetic operation with
3991 this result and get rid of the cast */
3992 if (ic->op == CAST) {
3994 sym_link *fromType = operandType (IC_RIGHT (ic));
3995 sym_link *toType = operandType (IC_LEFT (ic));
3997 debugLog (" %d - casting\n", __LINE__);
3999 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
4000 getSize (fromType) != getSize (toType)) {
4003 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4006 if (IS_ARITHMETIC_OP (dic)) {
4008 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4009 IC_RESULT (dic) = IC_RESULT (ic);
4010 remiCodeFromeBBlock (ebp, ic);
4011 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4012 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4013 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4017 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
4021 /* if the type from and type to are the same
4022 then if this is the only use then packit */
4023 if (compareType (operandType (IC_RIGHT (ic)),
4024 operandType (IC_LEFT (ic))) == 1) {
4026 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
4029 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
4030 IC_RESULT (dic) = IC_RESULT (ic);
4031 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
4032 remiCodeFromeBBlock (ebp, ic);
4033 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
4034 OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
4042 iTempNN := (some variable in farspace) V1
4047 if (ic->op == IPUSH)
4049 packForPush (ic, ebp);
4053 /* pack registers for accumulator use, when the
4054 result of an arithmetic or bit wise operation
4055 has only one use, that use is immediately following
4056 the defintion and the using iCode has only one
4057 operand or has two operands but one is literal &
4058 the result of that operation is not on stack then
4059 we can leave the result of this operation in acc:b
4061 if ((IS_ARITHMETIC_OP (ic)
4063 || IS_BITWISE_OP (ic)
4065 || ic->op == LEFT_OP || ic->op == RIGHT_OP
4068 IS_ITEMP (IC_RESULT (ic)) &&
4069 getSize (operandType (IC_RESULT (ic))) <= 2)
4071 packRegsForAccUse (ic);
4077 dumpEbbsToDebug (eBBlock ** ebbs, int count)
4081 if (!debug || !debugF)
4084 for (i = 0; i < count; i++)
4086 fprintf (debugF, "\n----------------------------------------------------------------\n");
4087 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
4088 ebbs[i]->entryLabel->name,
4091 ebbs[i]->isLastInLoop);
4092 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
4097 fprintf (debugF, "visited %d : hasFcall = %d\n",
4101 fprintf (debugF, "\ndefines bitVector :");
4102 bitVectDebugOn (ebbs[i]->defSet, debugF);
4103 fprintf (debugF, "\nlocal defines bitVector :");
4104 bitVectDebugOn (ebbs[i]->ldefs, debugF);
4105 fprintf (debugF, "\npointers Set bitvector :");
4106 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
4107 fprintf (debugF, "\nin pointers Set bitvector :");
4108 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
4109 fprintf (debugF, "\ninDefs Set bitvector :");
4110 bitVectDebugOn (ebbs[i]->inDefs, debugF);
4111 fprintf (debugF, "\noutDefs Set bitvector :");
4112 bitVectDebugOn (ebbs[i]->outDefs, debugF);
4113 fprintf (debugF, "\nusesDefs Set bitvector :");
4114 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
4115 fprintf (debugF, "\n----------------------------------------------------------------\n");
4116 printiCChain (ebbs[i]->sch, debugF);
4119 /*-----------------------------------------------------------------*/
4120 /* assignRegisters - assigns registers to each live range as need */
4121 /*-----------------------------------------------------------------*/
4123 pic14_assignRegisters (ebbIndex * ebbi)
4125 eBBlock ** ebbs = ebbi->bbOrder;
4126 int count = ebbi->count;
4130 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
4131 debugLog ("\nebbs before optimizing:\n");
4132 dumpEbbsToDebug (ebbs, count);
4134 setToNull ((void *) &_G.funcrUsed);
4135 pic14_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
4138 /* change assignments this will remove some
4139 live ranges reducing some register pressure */
4140 for (i = 0; i < count; i++)
4141 packRegisters (ebbs[i]);
4148 debugLog("dir registers allocated so far:\n");
4149 reg = hTabFirstItem(dynDirectRegNames, &hkey);
4152 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
4153 reg = hTabNextItem(dynDirectRegNames, &hkey);
4158 if (options.dump_pack)
4159 dumpEbbsToFileExt (DUMP_PACK, ebbi);
4161 /* first determine for each live range the number of
4162 registers & the type of registers required for each */
4165 /* and serially allocate registers */
4166 serialRegAssign (ebbs, count);
4168 /* if stack was extended then tell the user */
4171 /* werror(W_TOOMANY_SPILS,"stack", */
4172 /* _G.stackExtend,currFunc->name,""); */
4178 /* werror(W_TOOMANY_SPILS,"data space", */
4179 /* _G.dataExtend,currFunc->name,""); */
4183 /* after that create the register mask
4184 for each of the instruction */
4185 createRegMask (ebbs, count);
4187 /* redo that offsets for stacked automatic variables */
4188 redoStackOffsets ();
4190 if (options.dump_rassgn)
4191 dumpEbbsToFileExt (DUMP_RASSGN, ebbi);
4193 /* now get back the chain */
4194 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4196 debugLog ("ebbs after optimizing:\n");
4197 dumpEbbsToDebug (ebbs, count);
4202 /* free up any _G.stackSpil locations allocated */
4203 applyToSet (_G.stackSpil, deallocStackSpil);
4205 setToNull ((void *) &_G.stackSpil);
4206 setToNull ((void *) &_G.spiltSet);
4207 /* mark all registers as free */
4208 //pic14_freeAllRegs ();
4210 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");