1 /*------------------------------------------------------------------------
3 ralloc.c - source file for register allocation. PIC16 specific
5 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
7 Added Pic16 Port Martin Dubuc m.dubuc@rogers.com (2002)
9 This program is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 In other words, you are welcome to use, share and improve this program.
24 You are forbidden to forbid anyone else to use, share and improve
25 what you give them. Help stamp out software-hoarding!
26 -------------------------------------------------------------------------*/
33 #if defined(__BORLANDC__) || defined(_MSC_VER)
34 #define STRCASECMP stricmp
36 #define STRCASECMP strcasecmp
39 /*-----------------------------------------------------------------*/
40 /* At this point we start getting processor specific although */
41 /* some routines are non-processor specific & can be reused when */
42 /* targetting other processors. The decision for this will have */
43 /* to be made on a routine by routine basis */
44 /* routines used to pack registers are most definitely not reusable */
45 /* since the pack the registers depending strictly on the MCU */
46 /*-----------------------------------------------------------------*/
48 static regs *typeRegWithIdx (int idx, int type, int fixed);
49 extern void genpic16Code (iCode *);
50 extern void pic16_assignConfigWordValue(int address, int value);
60 bitVect *funcrUsed; /* registers used in a function */
66 /* Shared with gen.c */
67 int pic16_ptrRegReq; /* one byte pointer register required */
70 set *pic16_dynAllocRegs=NULL;
71 set *pic16_dynStackRegs=NULL;
72 set *pic16_dynProcessorRegs=NULL;
73 set *pic16_dynDirectRegs=NULL;
74 set *pic16_dynDirectBitRegs=NULL;
75 set *pic16_dynInternalRegs=NULL;
77 static hTab *dynDirectRegNames= NULL;
78 //static hTab *regHash = NULL; /* a hash table containing ALL registers */
80 set *pic16_rel_udata=NULL;
81 set *pic16_fix_udata=NULL;
84 static int dynrIdx=0x20;
85 static int rDirectIdx=0;
87 int pic16_nRegs = 128; // = sizeof (regspic16) / sizeof (regs);
89 int pic16_Gstack_base_addr=0; /* The starting address of registers that
90 * are used to pass and return parameters */
95 static void spillThis (symbol *);
97 static FILE *debugF = NULL;
98 /*-----------------------------------------------------------------*/
99 /* debugLog - open a file for debugging information */
100 /*-----------------------------------------------------------------*/
101 //static void debugLog(char *inst,char *fmt, ...)
103 debugLog (char *fmt,...)
105 static int append = 0; // First time through, open the file without append.
108 //char *bufferP=buffer;
111 if (!debug || !dstFileName)
117 /* create the file name */
118 strcpy (buffer, dstFileName);
119 strcat (buffer, ".d");
121 if (!(debugF = fopen (buffer, (append ? "a+" : "w"))))
123 werror (E_FILE_OPEN_ERR, buffer);
126 append = 1; // Next time debubLog is called, we'll append the debug info
132 vsprintf (buffer, fmt, ap);
134 fprintf (debugF, "%s", buffer);
136 while (isspace(*bufferP)) bufferP++;
138 if (bufferP && *bufferP)
139 lineCurr = (lineCurr ?
140 connectLine(lineCurr,newLineNode(lb)) :
141 (lineHead = newLineNode(lb)));
142 lineCurr->isInline = _G.inLine;
143 lineCurr->isDebug = _G.debugLine;
153 fputc ('\n', debugF);
155 /*-----------------------------------------------------------------*/
156 /* debugLogClose - closes the debug log file (if opened) */
157 /*-----------------------------------------------------------------*/
167 #define AOP(op) op->aop
170 debugAopGet (char *str, operand * op)
175 printOperand (op, debugF);
183 decodeOp (unsigned int op)
186 if (op < 128 && op > ' ')
188 buffer[0] = (op & 0xff);
202 return "STRING_LITERAL";
238 return "LEFT_ASSIGN";
240 return "RIGHT_ASSIGN";
355 case GET_VALUE_AT_ADDRESS:
356 return "GET_VALUE_AT_ADDRESS";
374 return "ENDFUNCTION";
398 sprintf (buffer, "unkown op %d %c", op, op & 0xff);
401 /*-----------------------------------------------------------------*/
402 /*-----------------------------------------------------------------*/
404 debugLogRegType (short type)
417 sprintf (buffer, "unknown reg type %d", type);
421 /*-----------------------------------------------------------------*/
422 /*-----------------------------------------------------------------*/
423 static int regname2key(char const *name)
432 key += (*name++) + 1;
436 return ( (key + (key >> 4) + (key>>8)) & 0x3f);
440 /*-----------------------------------------------------------------*/
441 /* newReg - allocate and init memory for a new register */
442 /*-----------------------------------------------------------------*/
443 static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alias, operand *refop)
448 dReg = Safe_calloc(1,sizeof(regs));
450 dReg->pc_type = pc_type;
453 dReg->name = Safe_strdup(name);
455 sprintf(buffer,"r0x%02X", dReg->rIdx);
458 dReg->name = Safe_strdup(buffer);
461 // fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
465 // dReg->isMapped = 0;
467 dReg->accessBank = 0;
469 if(type == REG_SFR) {
471 dReg->address = rIdx;
479 dReg->reg_alias = NULL;
480 dReg->reglives.usedpFlows = newSet();
481 dReg->reglives.assignedpFlows = newSet();
484 hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
489 /*-----------------------------------------------------------------*/
490 /* regWithIdx - Search through a set of registers that matches idx */
491 /*-----------------------------------------------------------------*/
493 regWithIdx (set *dRegs, int idx, int fixed)
497 for (dReg = setFirstItem(dRegs) ; dReg ;
498 dReg = setNextItem(dRegs)) {
500 if(idx == dReg->rIdx && (fixed == dReg->isFixed)) {
508 /*-----------------------------------------------------------------*/
509 /* regFindFree - Search for a free register in a set of registers */
510 /*-----------------------------------------------------------------*/
512 regFindFree (set *dRegs)
516 for (dReg = setFirstItem(dRegs) ; dReg ;
517 dReg = setNextItem(dRegs)) {
525 /*-----------------------------------------------------------------*/
526 /* pic16_initStack - allocate registers for a pseudo stack */
527 /*-----------------------------------------------------------------*/
528 void pic16_initStack(int base_address, int size)
533 pic16_Gstack_base_addr = base_address;
534 //fprintf(stderr,"initStack");
536 for(i = 0; i<size; i++)
537 addSet(&pic16_dynStackRegs,newReg(REG_STK, PO_GPR_TEMP,base_address++,NULL,1,0, NULL));
540 /*-----------------------------------------------------------------*
541 *-----------------------------------------------------------------*/
543 pic16_allocProcessorRegister(int rIdx, char * name, short po_type, int alias)
545 regs *reg = newReg(REG_SFR, po_type, rIdx, name, 1, alias, NULL);
547 // fprintf(stderr,"%s: %s addr =0x%x\n",__FUNCTION__, name,rIdx);
549 reg->wasUsed = 0; // we do not know if they are going to be used at all
550 reg->accessBank = 1; // implicit add access Bank
552 return addSet(&pic16_dynProcessorRegs, reg);
555 /*-----------------------------------------------------------------*
556 *-----------------------------------------------------------------*/
559 pic16_allocInternalRegister(int rIdx, char * name, short po_type, int alias)
561 regs * reg = newReg(REG_GPR, po_type, rIdx, name,1,alias, NULL);
563 // fprintf(stderr,"pic16_allocInternalRegister %s addr =0x%x\n",name,rIdx);
567 return addSet(&pic16_dynInternalRegs,reg);
572 /*-----------------------------------------------------------------*/
573 /* allocReg - allocates register of given type */
574 /*-----------------------------------------------------------------*/
576 allocReg (short type)
579 debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
580 //fprintf(stderr,"allocReg\n");
583 return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
588 /*-----------------------------------------------------------------*/
589 /* pic16_dirregWithName - search for register by name */
590 /*-----------------------------------------------------------------*/
592 pic16_dirregWithName (char *name)
600 /* hash the name to get a key */
602 hkey = regname2key(name);
604 // fprintf(stderr, "%s:%d: name = %s\thash = %d\n", __FUNCTION__, __LINE__, name, hkey);
606 reg = hTabFirstItemWK(dynDirectRegNames, hkey);
610 if(STRCASECMP(reg->name, name) == 0) {
614 reg = hTabNextItemWK (dynDirectRegNames);
618 return NULL; // name wasn't found in the hash table
621 static int IS_CONFIG_ADDRESS(int address)
624 return address >= 0x300000 && address <= 0x300000d;
627 /*-----------------------------------------------------------------*/
628 /* pic16_allocDirReg - allocates register of given type */
629 /*-----------------------------------------------------------------*/
631 pic16_allocDirReg (operand *op )
638 debugLog ("%s BAD, op is NULL\n", __FUNCTION__);
642 name = OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name;
644 /* If the symbol is at a fixed address, then remove the leading underscore
645 * from the name. This is hack to allow the .asm include file named registers
646 * to match the .c declared register names */
648 //if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && (*name == '_'))
651 /* The above hack is not necessery anymore, since .asm include files are not
652 * used by current implementation of the port -- VR 03-Jan-04 */
654 debugLog ("%s symbol name %s\n", __FUNCTION__,name);
655 // fprintf(stderr, "%s symbol name %s\n", __FUNCTION__,name);
657 if(SPEC_CONST ( OP_SYM_ETYPE(op)) && (IS_CHAR ( OP_SYM_ETYPE(op)) )) {
658 debugLog(" %d const char\n",__LINE__);
659 debugLog(" value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
660 // fprintf(stderr, " %d const char\n",__LINE__);
661 // fprintf(stderr, " value = %s \n",SPEC_CVAL( OP_SYM_ETYPE(op)));
664 debugLog(" %d storage class %d \n",__LINE__,SPEC_SCLS( OP_SYM_ETYPE(op)));
665 if (IS_CODE ( OP_SYM_ETYPE(op)) )
666 debugLog(" %d code space\n",__LINE__);
668 if (IS_INTEGRAL ( OP_SYM_ETYPE(op)) )
669 debugLog(" %d integral\n",__LINE__);
670 if (IS_LITERAL ( OP_SYM_ETYPE(op)) )
671 debugLog(" %d literal\n",__LINE__);
672 if (IS_SPEC ( OP_SYM_ETYPE(op)) )
673 debugLog(" %d specifier\n",__LINE__);
674 debugAopGet(NULL, op);
677 if (IS_CODE ( OP_SYM_ETYPE(op)) )
680 /* First, search the hash table to see if there is a register with this name */
681 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) && !(IS_BITVAR (OP_SYM_ETYPE(op))) ) {
682 reg = regWithIdx (pic16_dynProcessorRegs, SPEC_ADDR ( OP_SYM_ETYPE(op)), 1);
686 fprintf(stderr,"%s:%d: ralloc %s is at fixed address but not a processor reg, addr=0x%x\n",
687 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
689 fprintf(stderr,"%s:%d: ralloc %s at fixed address has already been declared, addr=0x%x\n",
690 __FUNCTION__, __LINE__, name, SPEC_ADDR ( OP_SYM_ETYPE(op)));
693 // fprintf(stderr,"ralloc:%d %s \n", __LINE__,name);
695 reg = pic16_dirregWithName(name);
701 /* if this is at an absolute address, then get the address. */
702 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
703 address = SPEC_ADDR ( OP_SYM_ETYPE(op));
704 //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
707 /* Register wasn't found in hash, so let's create
708 * a new one and put it in the hash table AND in the
709 * dynDirectRegNames set */
710 if(!IS_CONFIG_ADDRESS(address)) {
711 //fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
713 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,getSize (OP_SYMBOL (op)->type),0, op);
714 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
716 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* commented out */
718 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
720 //fprintf(stderr, " ralloc.c at fixed address: %s - changing to REG_SFR\n",name);
724 if (IS_BITVAR (OP_SYM_ETYPE(op))) {
725 addSet(&pic16_dynDirectBitRegs, reg);
728 addSet(&pic16_dynDirectRegs, reg);
731 debugLog (" -- %s is declared at address 0x30000x\n",name);
732 fprintf(stderr, " -- %s is declared at address 0x30000x\n",name);
735 fprintf(stderr, " setting config word to %x\n",
736 (int) floatFromVal (op->operand.valOperand)); //IC_RIGHT(ic)->operand.valOperand));
738 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
739 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
747 if (SPEC_ABSA ( OP_SYM_ETYPE(op)) ) {
749 reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
750 debugLog (" -- and it is at a fixed address 0x%02x\n",reg->address);
756 /*-----------------------------------------------------------------*/
757 /* pic16_allocRegByName - allocates register of given type */
758 /*-----------------------------------------------------------------*/
760 pic16_allocRegByName (char *name, int size)
766 fprintf(stderr, "%s - allocating a NULL register\n",__FUNCTION__);
770 /* First, search the hash table to see if there is a register with this name */
771 reg = pic16_dirregWithName(name);
775 /* Register wasn't found in hash, so let's create
776 * a new one and put it in the hash table AND in the
777 * dynDirectRegNames set */
778 //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
779 reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0, NULL);
781 debugLog ("%d -- added %s to hash, size = %d\n", __LINE__, name,reg->size);
782 //fprintf(stderr, " -- added %s to hash, size = %d\n", name,reg->size);
784 //hTabAddItem(&dynDirectRegNames, regname2key(name), reg); /* initially commented out */
785 addSet(&pic16_dynDirectRegs, reg);
791 /*-----------------------------------------------------------------*/
792 /* RegWithIdx - returns pointer to register with index number */
793 /*-----------------------------------------------------------------*/
795 typeRegWithIdx (int idx, int type, int fixed)
800 debugLog ("%s - requesting index = 0x%x\n", __FUNCTION__,idx);
805 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx, fixed)) != NULL) {
807 debugLog ("Found a Dynamic Register!\n");
810 if( (dReg = regWithIdx ( pic16_dynDirectRegs, idx, fixed)) != NULL ) {
811 debugLog ("Found a Direct Register!\n");
817 if( (dReg = regWithIdx ( pic16_dynStackRegs, idx, fixed)) != NULL ) {
818 debugLog ("Found a Stack Register!\n");
823 if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx, fixed)) != NULL ) {
824 debugLog ("Found a Processor Register!\n");
838 /*-----------------------------------------------------------------*/
839 /* pic16_regWithIdx - returns pointer to register with index number*/
840 /*-----------------------------------------------------------------*/
842 pic16_regWithIdx (int idx)
846 if( (dReg = typeRegWithIdx(idx,REG_GPR,0)) != NULL)
849 if( (dReg = typeRegWithIdx(idx,REG_SFR,0)) != NULL)
852 if( (dReg = typeRegWithIdx(idx,REG_STK,0)) != NULL)
858 /*-----------------------------------------------------------------*/
859 /* pic16_regWithIdx - returns pointer to register with index number */
860 /*-----------------------------------------------------------------*/
862 pic16_allocWithIdx (int idx)
867 debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx);
869 if( (dReg = regWithIdx ( pic16_dynAllocRegs, idx,0)) != NULL) {
871 debugLog ("Found a Dynamic Register!\n");
872 } else if( (dReg = regWithIdx ( pic16_dynStackRegs, idx,0)) != NULL ) {
873 debugLog ("Found a Stack Register!\n");
874 } else if( (dReg = regWithIdx ( pic16_dynProcessorRegs, idx,0)) != NULL ) {
875 debugLog ("Found a Processor Register!\n");
876 fprintf(stderr, "Found a processor register! %s\n", dReg->name);
877 } else if( (dReg = regWithIdx ( pic16_dynInternalRegs, idx,0)) != NULL ) {
878 debugLog ("Found an Internal Register!\n");
881 debugLog ("Dynamic Register not found\n");
884 //fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx);
885 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
886 "regWithIdx not found");
896 /*-----------------------------------------------------------------*/
897 /*-----------------------------------------------------------------*/
899 pic16_findFreeReg(short type)
906 if((dReg = regFindFree(pic16_dynAllocRegs)) != NULL)
908 return addSet(&pic16_dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0, NULL));
912 if((dReg = regFindFree(pic16_dynStackRegs)) != NULL)
924 /*-----------------------------------------------------------------*/
925 /* freeReg - frees a register */
926 /*-----------------------------------------------------------------*/
930 debugLog ("%s\n", __FUNCTION__);
935 /*-----------------------------------------------------------------*/
936 /* nFreeRegs - returns number of free registers */
937 /*-----------------------------------------------------------------*/
941 /* dynamically allocate as many as we need and worry about
942 * fitting them into a PIC later */
949 debugLog ("%s\n", __FUNCTION__);
950 for (i = 0; i < pic16_nRegs; i++)
951 if (regspic16[i].isFree && regspic16[i].type == type)
957 /*-----------------------------------------------------------------*/
958 /* nfreeRegsType - free registers with type */
959 /*-----------------------------------------------------------------*/
961 nfreeRegsType (int type)
964 debugLog ("%s\n", __FUNCTION__);
967 if ((nfr = nFreeRegs (type)) == 0)
968 return nFreeRegs (REG_GPR);
971 return nFreeRegs (type);
974 static void writeSetUsedRegs(FILE *of, set *dRegs)
979 for (dReg = setFirstItem(dRegs) ; dReg ;
980 dReg = setNextItem(dRegs)) {
983 fprintf (of, "\t%s\n",dReg->name);
989 extern void pic16_groupRegistersInSection(set *regset);
991 extern void pic16_dump_map(void);
992 extern void pic16_dump_section(FILE *of, char *sname, set *section, int fix);
995 static void packBits(set *bregs)
1000 regs *relocbitfield=NULL;
1006 for (regset = bregs ; regset ;
1007 regset = regset->next) {
1009 breg = regset->item;
1010 breg->isBitField = 1;
1011 //fprintf(stderr,"bit reg: %s\n",breg->name);
1014 //fprintf(stderr,"packing bit at fixed address = 0x%03x\n",breg->address);
1016 bitfield = typeRegWithIdx (breg->address >> 3, -1 , 1);
1017 breg->rIdx = breg->address & 7;
1018 breg->address >>= 3;
1021 sprintf (buffer, "fbitfield%02x", breg->address);
1022 //fprintf(stderr,"new bit field\n");
1023 bitfield = newReg(REG_SFR, PO_GPR_BIT,breg->address,buffer,1,0, NULL);
1024 bitfield->isBitField = 1;
1025 bitfield->isFixed = 1;
1026 bitfield->address = breg->address;
1027 addSet(&pic16_dynDirectRegs,bitfield);
1028 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), bitfield);
1030 //fprintf(stderr," which is occupied by %s (addr = %d)\n",bitfield->name,bitfield->address);
1033 breg->reg_alias = bitfield;
1037 if(!relocbitfield || bit_no >7) {
1040 sprintf (buffer, "bitfield%d", byte_no);
1041 //fprintf(stderr,"new relocatable bit field\n");
1042 relocbitfield = newReg(REG_GPR, PO_GPR_BIT,rDirectIdx++,buffer,1,0, NULL);
1043 relocbitfield->isBitField = 1;
1044 addSet(&pic16_dynDirectRegs,relocbitfield);
1045 //hTabAddItem(&dynDirectRegNames, regname2key(buffer), relocbitfield);
1049 breg->reg_alias = relocbitfield;
1050 breg->address = rDirectIdx; /* byte_no; */
1051 breg->rIdx = bit_no++;
1060 static void bitEQUs(FILE *of, set *bregs)
1062 regs *breg,*bytereg;
1065 //fprintf(stderr," %s\n",__FUNCTION__);
1066 for (breg = setFirstItem(bregs) ; breg ;
1067 breg = setNextItem(bregs)) {
1069 //fprintf(stderr,"bit reg: %s\n",breg->name);
1071 bytereg = breg->reg_alias;
1073 fprintf (of, "%s\tEQU\t( (%s<<3)+%d)\n",
1076 breg->rIdx & 0x0007);
1079 fprintf(stderr, "bit field is not assigned to a register\n");
1080 fprintf (of, "%s\tEQU\t( (bitfield%d<<3)+%d)\n",
1091 static void aliasEQUs(FILE *of, set *fregs, int use_rIdx)
1096 for (reg = setFirstItem(fregs) ; reg ;
1097 reg = setNextItem(fregs)) {
1099 if(!reg->isEmitted && reg->wasUsed) {
1101 if (reg->type != REG_SFR) {
1102 fprintf (of, "%s\tEQU\t0x%03x\n",
1108 fprintf (of, "%s\tEQU\t0x%03x\n",
1117 void pic16_writeUsedRegs(FILE *of)
1119 packBits(pic16_dynDirectBitRegs);
1121 pic16_groupRegistersInSection(pic16_dynAllocRegs);
1122 pic16_groupRegistersInSection(pic16_dynInternalRegs);
1123 pic16_groupRegistersInSection(pic16_dynStackRegs);
1124 pic16_groupRegistersInSection(pic16_dynDirectRegs);
1125 pic16_groupRegistersInSection(pic16_dynDirectBitRegs);
1126 pic16_groupRegistersInSection(pic16_dynProcessorRegs);
1130 pic16_assignFixedRegisters(pic16_dynAllocRegs);
1131 pic16_assignFixedRegisters(pic16_dynStackRegs);
1132 pic16_assignFixedRegisters(pic16_dynDirectRegs);
1133 pic16_assignFixedRegisters(pic16_dynProcessorRegs);
1135 pic16_assignRelocatableRegisters(pic16_dynDirectBitRegs, 0);
1136 pic16_assignRelocatableRegisters(pic16_dynInternalRegs,0);
1137 pic16_assignRelocatableRegisters(pic16_dynAllocRegs,0);
1138 pic16_assignRelocatableRegisters(pic16_dynStackRegs,0);
1139 pic16_assignRelocatableRegisters(pic16_dynDirectRegs,0);
1142 // pic16_dump_map();
1143 // pic16_dump_cblock(of);
1145 pic16_dump_section(of, "ud1", pic16_rel_udata, 0);
1146 pic16_dump_section(of, "ud2", pic16_fix_udata, 1);
1149 bitEQUs(of,pic16_dynDirectBitRegs);
1150 aliasEQUs(of,pic16_dynAllocRegs,0);
1151 aliasEQUs(of,pic16_dynDirectRegs,0);
1152 aliasEQUs(of,pic16_dynStackRegs,0);
1153 aliasEQUs(of,pic16_dynProcessorRegs,1);
1159 /*-----------------------------------------------------------------*/
1160 /* allDefsOutOfRange - all definitions are out of a range */
1161 /*-----------------------------------------------------------------*/
1163 allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
1167 debugLog ("%s\n", __FUNCTION__);
1171 for (i = 0; i < defs->size; i++)
1175 if (bitVectBitValue (defs, i) &&
1176 (ic = hTabItemWithKey (iCodehTab, i)) &&
1177 (ic->seq >= fseq && ic->seq <= toseq))
1187 /*-----------------------------------------------------------------*/
1188 /* computeSpillable - given a point find the spillable live ranges */
1189 /*-----------------------------------------------------------------*/
1191 computeSpillable (iCode * ic)
1195 debugLog ("%s\n", __FUNCTION__);
1196 /* spillable live ranges are those that are live at this
1197 point . the following categories need to be subtracted
1199 a) - those that are already spilt
1200 b) - if being used by this one
1201 c) - defined by this one */
1203 spillable = bitVectCopy (ic->rlive);
1205 bitVectCplAnd (spillable, _G.spiltSet); /* those already spilt */
1207 bitVectCplAnd (spillable, ic->uses); /* used in this one */
1208 bitVectUnSetBit (spillable, ic->defKey);
1209 spillable = bitVectIntersect (spillable, _G.regAssigned);
1214 /*-----------------------------------------------------------------*/
1215 /* noSpilLoc - return true if a variable has no spil location */
1216 /*-----------------------------------------------------------------*/
1218 noSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1220 debugLog ("%s\n", __FUNCTION__);
1221 return (sym->usl.spillLoc ? 0 : 1);
1224 /*-----------------------------------------------------------------*/
1225 /* hasSpilLoc - will return 1 if the symbol has spil location */
1226 /*-----------------------------------------------------------------*/
1228 hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1230 debugLog ("%s\n", __FUNCTION__);
1231 return (sym->usl.spillLoc ? 1 : 0);
1234 /*-----------------------------------------------------------------*/
1235 /* directSpilLoc - will return 1 if the splilocation is in direct */
1236 /*-----------------------------------------------------------------*/
1238 directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic)
1240 debugLog ("%s\n", __FUNCTION__);
1241 if (sym->usl.spillLoc &&
1242 (IN_DIRSPACE (SPEC_OCLS (sym->usl.spillLoc->etype))))
1248 /*-----------------------------------------------------------------*/
1249 /* hasSpilLocnoUptr - will return 1 if the symbol has spil location */
1250 /* but is not used as a pointer */
1251 /*-----------------------------------------------------------------*/
1253 hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic)
1255 debugLog ("%s\n", __FUNCTION__);
1256 return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0);
1259 /*-----------------------------------------------------------------*/
1260 /* rematable - will return 1 if the remat flag is set */
1261 /*-----------------------------------------------------------------*/
1263 rematable (symbol * sym, eBBlock * ebp, iCode * ic)
1265 debugLog ("%s\n", __FUNCTION__);
1269 /*-----------------------------------------------------------------*/
1270 /* notUsedInRemaining - not used or defined in remain of the block */
1271 /*-----------------------------------------------------------------*/
1273 notUsedInRemaining (symbol * sym, eBBlock * ebp, iCode * ic)
1275 debugLog ("%s\n", __FUNCTION__);
1276 return ((usedInRemaining (operandFromSymbol (sym), ic) ? 0 : 1) &&
1277 allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq));
1280 /*-----------------------------------------------------------------*/
1281 /* allLRs - return true for all */
1282 /*-----------------------------------------------------------------*/
1284 allLRs (symbol * sym, eBBlock * ebp, iCode * ic)
1286 debugLog ("%s\n", __FUNCTION__);
1290 /*-----------------------------------------------------------------*/
1291 /* liveRangesWith - applies function to a given set of live range */
1292 /*-----------------------------------------------------------------*/
1294 liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *),
1295 eBBlock * ebp, iCode * ic)
1300 debugLog ("%s\n", __FUNCTION__);
1301 if (!lrs || !lrs->size)
1304 for (i = 1; i < lrs->size; i++)
1307 if (!bitVectBitValue (lrs, i))
1310 /* if we don't find it in the live range
1311 hash table we are in serious trouble */
1312 if (!(sym = hTabItemWithKey (liveRanges, i)))
1314 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1315 "liveRangesWith could not find liveRange");
1319 if (func (sym, ebp, ic) && bitVectBitValue (_G.regAssigned, sym->key))
1320 addSetHead (&rset, sym);
1327 /*-----------------------------------------------------------------*/
1328 /* leastUsedLR - given a set determines which is the least used */
1329 /*-----------------------------------------------------------------*/
1331 leastUsedLR (set * sset)
1333 symbol *sym = NULL, *lsym = NULL;
1335 debugLog ("%s\n", __FUNCTION__);
1336 sym = lsym = setFirstItem (sset);
1341 for (; lsym; lsym = setNextItem (sset))
1344 /* if usage is the same then prefer
1345 the spill the smaller of the two */
1346 if (lsym->used == sym->used)
1347 if (getSize (lsym->type) < getSize (sym->type))
1351 if (lsym->used < sym->used)
1356 setToNull ((void *) &sset);
1361 /*-----------------------------------------------------------------*/
1362 /* noOverLap - will iterate through the list looking for over lap */
1363 /*-----------------------------------------------------------------*/
1365 noOverLap (set * itmpStack, symbol * fsym)
1368 debugLog ("%s\n", __FUNCTION__);
1371 for (sym = setFirstItem (itmpStack); sym;
1372 sym = setNextItem (itmpStack))
1374 if (sym->liveTo > fsym->liveFrom)
1382 /*-----------------------------------------------------------------*/
1383 /* isFree - will return 1 if the a free spil location is found */
1384 /*-----------------------------------------------------------------*/
1389 V_ARG (symbol **, sloc);
1390 V_ARG (symbol *, fsym);
1392 debugLog ("%s\n", __FUNCTION__);
1393 /* if already found */
1397 /* if it is free && and the itmp assigned to
1398 this does not have any overlapping live ranges
1399 with the one currently being assigned and
1400 the size can be accomodated */
1402 noOverLap (sym->usl.itmpStack, fsym) &&
1403 getSize (sym->type) >= getSize (fsym->type))
1412 /*-----------------------------------------------------------------*/
1413 /* spillLRWithPtrReg :- will spil those live ranges which use PTR */
1414 /*-----------------------------------------------------------------*/
1416 spillLRWithPtrReg (symbol * forSym)
1422 debugLog ("%s\n", __FUNCTION__);
1423 if (!_G.regAssigned ||
1424 bitVectIsZero (_G.regAssigned))
1427 r0 = pic16_regWithIdx (R0_IDX);
1428 r1 = pic16_regWithIdx (R1_IDX);
1430 /* for all live ranges */
1431 for (lrsym = hTabFirstItem (liveRanges, &k); lrsym;
1432 lrsym = hTabNextItem (liveRanges, &k))
1436 /* if no registers assigned to it or
1438 /* if it does not overlap with this then
1439 not need to spill it */
1441 if (lrsym->isspilt || !lrsym->nRegs ||
1442 (lrsym->liveTo < forSym->liveFrom))
1445 /* go thru the registers : if it is either
1446 r0 or r1 then spil it */
1447 for (j = 0; j < lrsym->nRegs; j++)
1448 if (lrsym->regs[j] == r0 ||
1449 lrsym->regs[j] == r1)
1458 /*-----------------------------------------------------------------*/
1459 /* createStackSpil - create a location on the stack to spil */
1460 /*-----------------------------------------------------------------*/
1462 createStackSpil (symbol * sym)
1464 symbol *sloc = NULL;
1465 int useXstack, model, noOverlay;
1467 char slocBuffer[30];
1468 debugLog ("%s\n", __FUNCTION__);
1470 /* first go try and find a free one that is already
1471 existing on the stack */
1472 if (applyToSet (_G.stackSpil, isFree, &sloc, sym))
1474 /* found a free one : just update & return */
1475 sym->usl.spillLoc = sloc;
1478 addSetHead (&sloc->usl.itmpStack, sym);
1482 /* could not then have to create one , this is the hard part
1483 we need to allocate this on the stack : this is really a
1484 hack!! but cannot think of anything better at this time */
1486 if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer))
1488 fprintf (stderr, "kkkInternal error: slocBuffer overflowed: %s:%d\n",
1489 __FILE__, __LINE__);
1493 sloc = newiTemp (slocBuffer);
1495 /* set the type to the spilling symbol */
1496 sloc->type = copyLinkChain (sym->type);
1497 sloc->etype = getSpec (sloc->type);
1498 SPEC_SCLS (sloc->etype) = S_DATA;
1499 SPEC_EXTR (sloc->etype) = 0;
1500 SPEC_STAT (sloc->etype) = 0;
1502 /* we don't allow it to be allocated`
1503 onto the external stack since : so we
1504 temporarily turn it off ; we also
1505 turn off memory model to prevent
1506 the spil from going to the external storage
1507 and turn off overlaying
1510 useXstack = options.useXstack;
1511 model = options.model;
1512 noOverlay = options.noOverlay;
1513 options.noOverlay = 1;
1514 options.model = options.useXstack = 0;
1518 options.useXstack = useXstack;
1519 options.model = model;
1520 options.noOverlay = noOverlay;
1521 sloc->isref = 1; /* to prevent compiler warning */
1523 /* if it is on the stack then update the stack */
1524 if (IN_STACK (sloc->etype))
1526 currFunc->stack += getSize (sloc->type);
1527 _G.stackExtend += getSize (sloc->type);
1530 _G.dataExtend += getSize (sloc->type);
1532 /* add it to the _G.stackSpil set */
1533 addSetHead (&_G.stackSpil, sloc);
1534 sym->usl.spillLoc = sloc;
1537 /* add it to the set of itempStack set
1538 of the spill location */
1539 addSetHead (&sloc->usl.itmpStack, sym);
1543 /*-----------------------------------------------------------------*/
1544 /* isSpiltOnStack - returns true if the spil location is on stack */
1545 /*-----------------------------------------------------------------*/
1547 isSpiltOnStack (symbol * sym)
1551 debugLog ("%s\n", __FUNCTION__);
1558 /* if (sym->_G.stackSpil) */
1561 if (!sym->usl.spillLoc)
1564 etype = getSpec (sym->usl.spillLoc->type);
1565 if (IN_STACK (etype))
1571 /*-----------------------------------------------------------------*/
1572 /* spillThis - spils a specific operand */
1573 /*-----------------------------------------------------------------*/
1575 spillThis (symbol * sym)
1578 debugLog ("%s : %s\n", __FUNCTION__, sym->rname);
1580 /* if this is rematerializable or has a spillLocation
1581 we are okay, else we need to create a spillLocation
1583 if (!(sym->remat || sym->usl.spillLoc))
1584 createStackSpil (sym);
1587 /* mark it has spilt & put it in the spilt set */
1589 _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key);
1591 bitVectUnSetBit (_G.regAssigned, sym->key);
1593 for (i = 0; i < sym->nRegs; i++)
1597 freeReg (sym->regs[i]);
1598 sym->regs[i] = NULL;
1601 /* if spilt on stack then free up r0 & r1
1602 if they could have been assigned to some
1604 if (!pic16_ptrRegReq && isSpiltOnStack (sym))
1607 spillLRWithPtrReg (sym);
1610 if (sym->usl.spillLoc && !sym->remat)
1611 sym->usl.spillLoc->allocreq = 1;
1615 /*-----------------------------------------------------------------*/
1616 /* selectSpil - select a iTemp to spil : rather a simple procedure */
1617 /*-----------------------------------------------------------------*/
1619 selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym)
1621 bitVect *lrcs = NULL;
1625 debugLog ("%s\n", __FUNCTION__);
1626 /* get the spillable live ranges */
1627 lrcs = computeSpillable (ic);
1629 /* get all live ranges that are rematerizable */
1630 if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic)))
1633 /* return the least used of these */
1634 return leastUsedLR (selectS);
1637 /* get live ranges with spillLocations in direct space */
1638 if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic)))
1640 sym = leastUsedLR (selectS);
1641 strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ?
1642 sym->usl.spillLoc->rname :
1643 sym->usl.spillLoc->name));
1645 /* mark it as allocation required */
1646 sym->usl.spillLoc->allocreq = 1;
1650 /* if the symbol is local to the block then */
1651 if (forSym->liveTo < ebp->lSeq)
1654 /* check if there are any live ranges allocated
1655 to registers that are not used in this block */
1656 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic)))
1658 sym = leastUsedLR (selectS);
1659 /* if this is not rematerializable */
1668 /* check if there are any live ranges that not
1669 used in the remainder of the block */
1670 if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInRemaining, ebp, ic)))
1672 sym = leastUsedLR (selectS);
1675 sym->remainSpil = 1;
1682 /* find live ranges with spillocation && not used as pointers */
1683 if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic)))
1686 sym = leastUsedLR (selectS);
1687 /* mark this as allocation required */
1688 sym->usl.spillLoc->allocreq = 1;
1692 /* find live ranges with spillocation */
1693 if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic)))
1696 sym = leastUsedLR (selectS);
1697 sym->usl.spillLoc->allocreq = 1;
1701 /* couldn't find then we need to create a spil
1702 location on the stack , for which one? the least
1704 if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic)))
1707 /* return a created spil location */
1708 sym = createStackSpil (leastUsedLR (selectS));
1709 sym->usl.spillLoc->allocreq = 1;
1713 /* this is an extreme situation we will spill
1714 this one : happens very rarely but it does happen */
1720 /*-----------------------------------------------------------------*/
1721 /* spilSomething - spil some variable & mark registers as free */
1722 /*-----------------------------------------------------------------*/
1724 spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym)
1729 debugLog ("%s\n", __FUNCTION__);
1730 /* get something we can spil */
1731 ssym = selectSpil (ic, ebp, forSym);
1733 /* mark it as spilt */
1735 _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key);
1737 /* mark it as not register assigned &
1738 take it away from the set */
1739 bitVectUnSetBit (_G.regAssigned, ssym->key);
1741 /* mark the registers as free */
1742 for (i = 0; i < ssym->nRegs; i++)
1744 freeReg (ssym->regs[i]);
1746 /* if spilt on stack then free up r0 & r1
1747 if they could have been assigned to as gprs */
1748 if (!pic16_ptrRegReq && isSpiltOnStack (ssym))
1751 spillLRWithPtrReg (ssym);
1754 /* if this was a block level spil then insert push & pop
1755 at the start & end of block respectively */
1756 if (ssym->blockSpil)
1758 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1759 /* add push to the start of the block */
1760 addiCodeToeBBlock (ebp, nic, (ebp->sch->op == LABEL ?
1761 ebp->sch->next : ebp->sch));
1762 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1763 /* add pop to the end of the block */
1764 addiCodeToeBBlock (ebp, nic, NULL);
1767 /* if spilt because not used in the remainder of the
1768 block then add a push before this instruction and
1769 a pop at the end of the block */
1770 if (ssym->remainSpil)
1773 iCode *nic = newiCode (IPUSH, operandFromSymbol (ssym), NULL);
1774 /* add push just before this instruction */
1775 addiCodeToeBBlock (ebp, nic, ic);
1777 nic = newiCode (IPOP, operandFromSymbol (ssym), NULL);
1778 /* add pop to the end of the block */
1779 addiCodeToeBBlock (ebp, nic, NULL);
1788 /*-----------------------------------------------------------------*/
1789 /* getRegPtr - will try for PTR if not a GPR type if not spil */
1790 /*-----------------------------------------------------------------*/
1792 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
1796 debugLog ("%s\n", __FUNCTION__);
1798 /* try for a ptr type */
1799 if ((reg = allocReg (REG_PTR)))
1802 /* try for gpr type */
1803 if ((reg = allocReg (REG_GPR)))
1806 /* we have to spil */
1807 if (!spilSomething (ic, ebp, sym))
1810 /* this looks like an infinite loop but
1811 in really selectSpil will abort */
1815 /*-----------------------------------------------------------------*/
1816 /* getRegGpr - will try for GPR if not spil */
1817 /*-----------------------------------------------------------------*/
1819 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
1823 debugLog ("%s\n", __FUNCTION__);
1825 /* try for gpr type */
1826 if ((reg = allocReg (REG_GPR)))
1829 if (!pic16_ptrRegReq)
1830 if ((reg = allocReg (REG_PTR)))
1833 /* we have to spil */
1834 if (!spilSomething (ic, ebp, sym))
1837 /* this looks like an infinite loop but
1838 in really selectSpil will abort */
1842 /*-----------------------------------------------------------------*/
1843 /* symHasReg - symbol has a given register */
1844 /*-----------------------------------------------------------------*/
1846 symHasReg (symbol * sym, regs * reg)
1850 debugLog ("%s\n", __FUNCTION__);
1851 for (i = 0; i < sym->nRegs; i++)
1852 if (sym->regs[i] == reg)
1858 /*-----------------------------------------------------------------*/
1859 /* deassignLRs - check the live to and if they have registers & are */
1860 /* not spilt then free up the registers */
1861 /*-----------------------------------------------------------------*/
1863 deassignLRs (iCode * ic, eBBlock * ebp)
1869 debugLog ("%s\n", __FUNCTION__);
1870 for (sym = hTabFirstItem (liveRanges, &k); sym;
1871 sym = hTabNextItem (liveRanges, &k))
1874 symbol *psym = NULL;
1875 /* if it does not end here */
1876 if (sym->liveTo > ic->seq)
1879 /* if it was spilt on stack then we can
1880 mark the stack spil location as free */
1885 sym->usl.spillLoc->isFree = 1;
1891 if (!bitVectBitValue (_G.regAssigned, sym->key))
1894 /* special case check if this is an IFX &
1895 the privious one was a pop and the
1896 previous one was not spilt then keep track
1898 if (ic->op == IFX && ic->prev &&
1899 ic->prev->op == IPOP &&
1900 !ic->prev->parmPush &&
1901 !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
1902 psym = OP_SYMBOL (IC_LEFT (ic->prev));
1908 bitVectUnSetBit (_G.regAssigned, sym->key);
1910 /* if the result of this one needs registers
1911 and does not have it then assign it right
1913 if (IC_RESULT (ic) &&
1914 !(SKIP_IC2 (ic) || /* not a special icode */
1915 ic->op == JUMPTABLE ||
1920 POINTER_SET (ic)) &&
1921 (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */
1922 result->liveTo > ic->seq && /* and will live beyond this */
1923 result->liveTo <= ebp->lSeq && /* does not go beyond this block */
1924 result->regType == sym->regType && /* same register types */
1925 result->nRegs && /* which needs registers */
1926 !result->isspilt && /* and does not already have them */
1928 !bitVectBitValue (_G.regAssigned, result->key) &&
1929 /* the number of free regs + number of regs in this LR
1930 can accomodate the what result Needs */
1931 ((nfreeRegsType (result->regType) +
1932 sym->nRegs) >= result->nRegs)
1936 for (i = 0; i < max (sym->nRegs, result->nRegs); i++)
1938 result->regs[i] = sym->regs[i];
1940 result->regs[i] = getRegGpr (ic, ebp, result);
1942 _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
1946 /* free the remaining */
1947 for (; i < sym->nRegs; i++)
1951 if (!symHasReg (psym, sym->regs[i]))
1952 freeReg (sym->regs[i]);
1955 freeReg (sym->regs[i]);
1962 /*-----------------------------------------------------------------*/
1963 /* reassignLR - reassign this to registers */
1964 /*-----------------------------------------------------------------*/
1966 reassignLR (operand * op)
1968 symbol *sym = OP_SYMBOL (op);
1971 debugLog ("%s\n", __FUNCTION__);
1972 /* not spilt any more */
1973 sym->isspilt = sym->blockSpil = sym->remainSpil = 0;
1974 bitVectUnSetBit (_G.spiltSet, sym->key);
1976 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
1980 for (i = 0; i < sym->nRegs; i++)
1981 sym->regs[i]->isFree = 0;
1984 /*-----------------------------------------------------------------*/
1985 /* willCauseSpill - determines if allocating will cause a spill */
1986 /*-----------------------------------------------------------------*/
1988 willCauseSpill (int nr, int rt)
1990 debugLog ("%s\n", __FUNCTION__);
1991 /* first check if there are any avlb registers
1992 of te type required */
1995 /* special case for pointer type
1996 if pointer type not avlb then
1997 check for type gpr */
1998 if (nFreeRegs (rt) >= nr)
2000 if (nFreeRegs (REG_GPR) >= nr)
2005 if (pic16_ptrRegReq)
2007 if (nFreeRegs (rt) >= nr)
2012 if (nFreeRegs (REG_PTR) +
2013 nFreeRegs (REG_GPR) >= nr)
2018 debugLog (" ... yep it will (cause a spill)\n");
2019 /* it will cause a spil */
2023 /*-----------------------------------------------------------------*/
2024 /* positionRegs - the allocator can allocate same registers to res- */
2025 /* ult and operand, if this happens make sure they are in the same */
2026 /* position as the operand otherwise chaos results */
2027 /*-----------------------------------------------------------------*/
2029 positionRegs (symbol * result, symbol * opsym, int lineno)
2031 int count = min (result->nRegs, opsym->nRegs);
2032 int i, j = 0, shared = 0;
2034 debugLog ("%s\n", __FUNCTION__);
2035 /* if the result has been spilt then cannot share */
2040 /* first make sure that they actually share */
2041 for (i = 0; i < count; i++)
2043 for (j = 0; j < count; j++)
2045 if (result->regs[i] == opsym->regs[j] && i != j)
2055 regs *tmp = result->regs[i];
2056 result->regs[i] = result->regs[j];
2057 result->regs[j] = tmp;
2062 /*-----------------------------------------------------------------*/
2063 /* serialRegAssign - serially allocate registers to the variables */
2064 /*-----------------------------------------------------------------*/
2066 serialRegAssign (eBBlock ** ebbs, int count)
2070 debugLog ("%s\n", __FUNCTION__);
2071 /* for all blocks */
2072 for (i = 0; i < count; i++)
2077 if (ebbs[i]->noPath &&
2078 (ebbs[i]->entryLabel != entryLabel &&
2079 ebbs[i]->entryLabel != returnLabel))
2082 /* of all instructions do */
2083 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2086 debugLog (" op: %s\n", decodeOp (ic->op));
2088 /* if this is an ipop that means some live
2089 range will have to be assigned again */
2091 reassignLR (IC_LEFT (ic));
2093 /* if result is present && is a true symbol */
2094 if (IC_RESULT (ic) && ic->op != IFX &&
2095 IS_TRUE_SYMOP (IC_RESULT (ic)))
2096 OP_SYMBOL (IC_RESULT (ic))->allocreq = 1;
2098 /* take away registers from live
2099 ranges that end at this instruction */
2100 deassignLRs (ic, ebbs[i]);
2102 /* some don't need registers */
2103 if (SKIP_IC2 (ic) ||
2104 ic->op == JUMPTABLE ||
2108 (IC_RESULT (ic) && POINTER_SET (ic)))
2111 /* now we need to allocate registers
2112 only for the result */
2115 symbol *sym = OP_SYMBOL (IC_RESULT (ic));
2121 /* if it does not need or is spilt
2122 or is already assigned to registers
2123 or will not live beyond this instructions */
2126 bitVectBitValue (_G.regAssigned, sym->key) ||
2127 sym->liveTo <= ic->seq)
2130 /* if some liverange has been spilt at the block level
2131 and this one live beyond this block then spil this
2133 if (_G.blockSpil && sym->liveTo > ebbs[i]->lSeq)
2138 /* if trying to allocate this will cause
2139 a spill and there is nothing to spill
2140 or this one is rematerializable then
2142 willCS = willCauseSpill (sym->nRegs, sym->regType);
2143 spillable = computeSpillable (ic);
2145 (willCS && bitVectIsZero (spillable)))
2153 /* if it has a spillocation & is used less than
2154 all other live ranges then spill this */
2156 if (sym->usl.spillLoc) {
2157 symbol *leastUsed = leastUsedLR (liveRangesWith (spillable,
2158 allLRs, ebbs[i], ic));
2159 if (leastUsed && leastUsed->used > sym->used) {
2164 /* if none of the liveRanges have a spillLocation then better
2165 to spill this one than anything else already assigned to registers */
2166 if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) {
2167 /* if this is local to this block then we might find a block spil */
2168 if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) {
2176 if (ic->op == RECEIVE)
2177 debugLog ("When I get clever, I'll optimize the receive logic\n");
2179 /* if we need ptr regs for the right side
2181 if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
2182 <= (unsigned) PTRSIZE)
2187 /* else we assign registers to it */
2188 _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key);
2190 debugLog (" %d - \n", __LINE__);
2192 bitVectDebugOn(_G.regAssigned, debugF);
2194 for (j = 0; j < sym->nRegs; j++)
2196 if (sym->regType == REG_PTR)
2197 sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
2199 sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
2201 /* if the allocation falied which means
2202 this was spilt then break */
2206 debugLog (" %d - \n", __LINE__);
2208 /* if it shares registers with operands make sure
2209 that they are in the same position */
2210 if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
2211 OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
2212 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2213 OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
2214 /* do the same for the right operand */
2215 if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
2216 OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
2217 positionRegs (OP_SYMBOL (IC_RESULT (ic)),
2218 OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
2220 debugLog (" %d - \n", __LINE__);
2223 debugLog (" %d - \n", __LINE__);
2233 /*-----------------------------------------------------------------*/
2234 /* rUmaskForOp :- returns register mask for an operand */
2235 /*-----------------------------------------------------------------*/
2237 rUmaskForOp (operand * op)
2243 debugLog ("%s\n", __FUNCTION__);
2244 /* only temporaries are assigned registers */
2248 sym = OP_SYMBOL (op);
2250 /* if spilt or no registers assigned to it
2252 if (sym->isspilt || !sym->nRegs)
2255 rumask = newBitVect (pic16_nRegs);
2257 for (j = 0; j < sym->nRegs; j++)
2259 rumask = bitVectSetBit (rumask,
2260 sym->regs[j]->rIdx);
2266 /*-----------------------------------------------------------------*/
2267 /* regsUsedIniCode :- returns bit vector of registers used in iCode */
2268 /*-----------------------------------------------------------------*/
2270 regsUsedIniCode (iCode * ic)
2272 bitVect *rmask = newBitVect (pic16_nRegs);
2274 debugLog ("%s\n", __FUNCTION__);
2275 /* do the special cases first */
2278 rmask = bitVectUnion (rmask,
2279 rUmaskForOp (IC_COND (ic)));
2283 /* for the jumptable */
2284 if (ic->op == JUMPTABLE)
2286 rmask = bitVectUnion (rmask,
2287 rUmaskForOp (IC_JTCOND (ic)));
2292 /* of all other cases */
2294 rmask = bitVectUnion (rmask,
2295 rUmaskForOp (IC_LEFT (ic)));
2299 rmask = bitVectUnion (rmask,
2300 rUmaskForOp (IC_RIGHT (ic)));
2303 rmask = bitVectUnion (rmask,
2304 rUmaskForOp (IC_RESULT (ic)));
2310 /*-----------------------------------------------------------------*/
2311 /* createRegMask - for each instruction will determine the regsUsed */
2312 /*-----------------------------------------------------------------*/
2314 createRegMask (eBBlock ** ebbs, int count)
2318 debugLog ("%s\n", __FUNCTION__);
2319 /* for all blocks */
2320 for (i = 0; i < count; i++)
2324 if (ebbs[i]->noPath &&
2325 (ebbs[i]->entryLabel != entryLabel &&
2326 ebbs[i]->entryLabel != returnLabel))
2329 /* for all instructions */
2330 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2335 if (SKIP_IC2 (ic) || !ic->rlive)
2338 /* first mark the registers used in this
2340 ic->rUsed = regsUsedIniCode (ic);
2341 _G.funcrUsed = bitVectUnion (_G.funcrUsed, ic->rUsed);
2343 /* now create the register mask for those
2344 registers that are in use : this is a
2345 super set of ic->rUsed */
2346 ic->rMask = newBitVect (pic16_nRegs + 1);
2348 /* for all live Ranges alive at this point */
2349 for (j = 1; j < ic->rlive->size; j++)
2354 /* if not alive then continue */
2355 if (!bitVectBitValue (ic->rlive, j))
2358 /* find the live range we are interested in */
2359 if (!(sym = hTabItemWithKey (liveRanges, j)))
2361 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
2362 "createRegMask cannot find live range");
2366 /* if no register assigned to it */
2367 if (!sym->nRegs || sym->isspilt)
2370 /* for all the registers allocated to it */
2371 for (k = 0; k < sym->nRegs; k++)
2374 bitVectSetBit (ic->rMask, sym->regs[k]->rIdx);
2380 /*-----------------------------------------------------------------*/
2381 /* rematStr - returns the rematerialized string for a remat var */
2382 /*-----------------------------------------------------------------*/
2384 rematStr (symbol * sym)
2387 iCode *ic = sym->rematiCode;
2388 symbol *psym = NULL;
2390 debugLog ("%s\n", __FUNCTION__);
2392 //printf ("%s\n", s);
2394 /* if plus or minus print the right hand side */
2396 if (ic->op == '+' || ic->op == '-') {
2398 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2400 sprintf (s, "(%s %c 0x%04x)",
2401 OP_SYMBOL (IC_LEFT (ric))->rname,
2403 (int) operandLitValue (IC_RIGHT (ic)));
2406 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2408 psym = newSymbol (OP_SYMBOL (IC_LEFT (ric))->rname, 1);
2409 psym->offset = (int) operandLitValue (IC_RIGHT (ic));
2414 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2415 psym = newSymbol (OP_SYMBOL (IC_LEFT (ic))->rname, 1);
2417 //printf ("ralloc.c:%d %s\n", __LINE__,buffer);
2422 /*-----------------------------------------------------------------*/
2423 /* rematStr - returns the rematerialized string for a remat var */
2424 /*-----------------------------------------------------------------*/
2426 rematStr (symbol * sym)
2429 iCode *ic = sym->rematiCode;
2431 debugLog ("%s\n", __FUNCTION__);
2436 /* if plus or minus print the right hand side */
2438 if (ic->op == '+' || ic->op == '-') {
2439 sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
2442 ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2446 if (ic->op == '+' || ic->op == '-')
2448 iCode *ric = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
2449 sprintf (s, "(%s %c 0x%04x)",
2450 OP_SYMBOL (IC_LEFT (ric))->rname,
2452 (int) operandLitValue (IC_RIGHT (ic)));
2455 //ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
2457 //fprintf(stderr, "ralloc.c:%d OOPS %s\n",__LINE__,s);
2461 /* we reached the end */
2462 sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname);
2466 printf ("%s\n", buffer);
2471 /*-----------------------------------------------------------------*/
2472 /* regTypeNum - computes the type & number of registers required */
2473 /*-----------------------------------------------------------------*/
2481 debugLog ("%s\n", __FUNCTION__);
2482 /* for each live range do */
2483 for (sym = hTabFirstItem (liveRanges, &k); sym;
2484 sym = hTabNextItem (liveRanges, &k)) {
2486 debugLog (" %d - %s\n", __LINE__, sym->rname);
2487 //fprintf(stderr," %d - %s\n", __LINE__, sym->rname);
2489 /* if used zero times then no registers needed */
2490 if ((sym->liveTo - sym->liveFrom) == 0)
2494 /* if the live range is a temporary */
2497 debugLog (" %d - itemp register\n", __LINE__);
2499 /* if the type is marked as a conditional */
2500 if (sym->regType == REG_CND)
2503 /* if used in return only then we don't
2505 if (sym->ruonly || sym->accuse) {
2506 if (IS_AGGREGATE (sym->type) || sym->isptr)
2507 sym->type = aggrToPtr (sym->type, FALSE);
2508 debugLog (" %d - no reg needed - used as a return\n", __LINE__);
2513 /* if the symbol has only one definition &
2514 that definition is a get_pointer and the
2515 pointer we are getting is rematerializable and
2518 if (bitVectnBitsOn (sym->defs) == 1 &&
2519 (ic = hTabItemWithKey (iCodehTab,
2520 bitVectFirstBit (sym->defs))) &&
2523 !IS_BITVAR (sym->etype)) {
2526 debugLog (" %d - \n", __LINE__);
2528 /* if remat in data space */
2529 if (OP_SYMBOL (IC_LEFT (ic))->remat &&
2530 DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
2532 /* create a psuedo symbol & force a spil */
2533 //X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
2534 symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
2535 psym->type = sym->type;
2536 psym->etype = sym->etype;
2537 strcpy (psym->rname, psym->name);
2539 sym->usl.spillLoc = psym;
2543 /* if in data space or idata space then try to
2544 allocate pointer register */
2548 /* if not then we require registers */
2549 sym->nRegs = ((IS_AGGREGATE (sym->type) || sym->isptr) ?
2550 getSize (sym->type = aggrToPtr (sym->type, FALSE)) :
2551 getSize (sym->type));
2555 if(IS_PTR_CONST (sym->type)) {
2557 if(IS_CODEPTR (sym->type)) {
2559 debugLog (" %d const pointer type requires %d registers, changing to 2\n",__LINE__,sym->nRegs);
2563 if (sym->nRegs > 4) {
2564 fprintf (stderr, "allocated more than 4 or 0 registers for type ");
2565 printTypeChain (sym->type, stderr);
2566 fprintf (stderr, "\n");
2569 /* determine the type of register required */
2570 if (sym->nRegs == 1 &&
2571 IS_PTR (sym->type) &&
2573 sym->regType = REG_PTR;
2575 sym->regType = REG_GPR;
2578 debugLog (" reg name %s, reg type %s\n", sym->rname, debugLogRegType (sym->regType));
2582 /* for the first run we don't provide */
2583 /* registers for true symbols we will */
2584 /* see how things go */
2589 static DEFSETFUNC (markRegFree)
2591 ((regs *)item)->isFree = 1;
2596 DEFSETFUNC (pic16_deallocReg)
2598 fprintf(stderr,"deallocting register %s\n",((regs *)item)->name);
2599 ((regs *)item)->isFree = 1;
2600 ((regs *)item)->wasUsed = 0;
2604 /*-----------------------------------------------------------------*/
2605 /* freeAllRegs - mark all registers as free */
2606 /*-----------------------------------------------------------------*/
2608 pic16_freeAllRegs ()
2612 debugLog ("%s\n", __FUNCTION__);
2614 applyToSet(pic16_dynAllocRegs,markRegFree);
2615 applyToSet(pic16_dynStackRegs,markRegFree);
2618 for (i = 0; i < pic16_nRegs; i++)
2619 regspic16[i].isFree = 1;
2623 /*-----------------------------------------------------------------*/
2624 /*-----------------------------------------------------------------*/
2626 pic16_deallocateAllRegs ()
2630 debugLog ("%s\n", __FUNCTION__);
2632 applyToSet(pic16_dynAllocRegs,pic16_deallocReg);
2635 for (i = 0; i < pic16_nRegs; i++) {
2636 if(regspic16[i].pc_type == PO_GPR_TEMP) {
2637 regspic16[i].isFree = 1;
2638 regspic16[i].wasUsed = 0;
2645 /*-----------------------------------------------------------------*/
2646 /* deallocStackSpil - this will set the stack pointer back */
2647 /*-----------------------------------------------------------------*/
2649 DEFSETFUNC (deallocStackSpil)
2653 debugLog ("%s\n", __FUNCTION__);
2658 /*-----------------------------------------------------------------*/
2659 /* farSpacePackable - returns the packable icode for far variables */
2660 /*-----------------------------------------------------------------*/
2662 farSpacePackable (iCode * ic)
2666 debugLog ("%s\n", __FUNCTION__);
2667 /* go thru till we find a definition for the
2668 symbol on the right */
2669 for (dic = ic->prev; dic; dic = dic->prev)
2672 /* if the definition is a call then no */
2673 if ((dic->op == CALL || dic->op == PCALL) &&
2674 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2679 /* if shift by unknown amount then not */
2680 if ((dic->op == LEFT_OP || dic->op == RIGHT_OP) &&
2681 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2684 /* if pointer get and size > 1 */
2685 if (POINTER_GET (dic) &&
2686 getSize (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)) > 1)
2689 if (POINTER_SET (dic) &&
2690 getSize (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)) > 1)
2693 /* if any three is a true symbol in far space */
2694 if (IC_RESULT (dic) &&
2695 IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2696 isOperandInFarSpace (IC_RESULT (dic)))
2699 if (IC_RIGHT (dic) &&
2700 IS_TRUE_SYMOP (IC_RIGHT (dic)) &&
2701 isOperandInFarSpace (IC_RIGHT (dic)) &&
2702 !isOperandEqual (IC_RIGHT (dic), IC_RESULT (ic)))
2705 if (IC_LEFT (dic) &&
2706 IS_TRUE_SYMOP (IC_LEFT (dic)) &&
2707 isOperandInFarSpace (IC_LEFT (dic)) &&
2708 !isOperandEqual (IC_LEFT (dic), IC_RESULT (ic)))
2711 if (isOperandEqual (IC_RIGHT (ic), IC_RESULT (dic)))
2713 if ((dic->op == LEFT_OP ||
2714 dic->op == RIGHT_OP ||
2716 IS_OP_LITERAL (IC_RIGHT (dic)))
2726 /*-----------------------------------------------------------------*/
2727 /* packRegsForAssign - register reduction for assignment */
2728 /*-----------------------------------------------------------------*/
2730 packRegsForAssign (iCode * ic, eBBlock * ebp)
2735 debugLog ("%d\t%s\n", __LINE__, __FUNCTION__);
2736 debugLog ("ic->op = %s\n", decodeOp( ic->op ) );
2737 debugAopGet (" result:", IC_RESULT (ic));
2738 debugAopGet (" left:", IC_LEFT (ic));
2739 debugAopGet (" right:", IC_RIGHT (ic));
2741 /* if this is at an absolute address, then get the address. */
2742 if (SPEC_ABSA ( OP_SYM_ETYPE(IC_RESULT(ic))) ) {
2743 if(IS_CONFIG_ADDRESS( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))))) {
2744 debugLog (" %d - found config word declaration\n", __LINE__);
2745 if(IS_VALOP(IC_RIGHT(ic))) {
2746 debugLog (" setting config word to %x\n",
2747 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2748 fprintf(stderr, " setting config word to %x\n",
2749 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2750 pic16_assignConfigWordValue( SPEC_ADDR ( OP_SYM_ETYPE(IC_RESULT(ic))),
2751 (int) floatFromVal (IC_RIGHT(ic)->operand.valOperand));
2755 debugLog(" %d\n", __LINE__);
2757 /* remove the assignment from the iCode chain. */
2759 remiCodeFromeBBlock (ebp, ic);
2760 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2761 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2767 debugLog(" %d - actuall processing\n", __LINE__ );
2769 if (!IS_ITEMP (IC_RESULT (ic))) {
2770 pic16_allocDirReg(IC_RESULT (ic));
2771 debugLog (" %d - result is not temp\n", __LINE__);
2775 if (IC_LEFT (ic) && !IS_ITEMP (IC_LEFT (ic))) {
2776 debugLog (" %d - left is not temp, allocating\n", __LINE__);
2777 pic16_allocDirReg(IC_LEFT (ic));
2781 /* See BUGLOG0001 - VR */
2783 if (!IS_ITEMP (IC_RIGHT (ic))) {
2784 debugLog (" %d - not packing - right is not temp\n", __LINE__);
2785 pic16_allocDirReg(IC_RIGHT (ic));
2790 if (OP_SYMBOL (IC_RIGHT (ic))->isind ||
2791 OP_LIVETO (IC_RIGHT (ic)) > ic->seq)
2793 debugLog (" %d - not packing - right side fails \n", __LINE__);
2797 /* if the true symbol is defined in far space or on stack
2798 then we should not since this will increase register pressure */
2799 if (isOperandInFarSpace (IC_RESULT (ic)))
2801 if ((dic = farSpacePackable (ic)))
2807 /* find the definition of iTempNN scanning backwards if we find a
2808 a use of the true symbol before we find the definition then
2810 for (dic = ic->prev; dic; dic = dic->prev)
2813 /* if there is a function call and this is
2814 a parameter & not my parameter then don't pack it */
2815 if ((dic->op == CALL || dic->op == PCALL) &&
2816 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
2817 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
2819 debugLog (" %d - \n", __LINE__);
2827 debugLog("%d\tSearching for iTempNN\n", __LINE__);
2830 if(IS_TRUE_SYMOP( IC_RESULT(dic))) {
2831 debugLog("%d - dic result is a TRUE_SYMOP\n", __LINE__);
2832 debugAopGet(" result is ", IC_RESULT(dic));
2834 if(IS_TRUE_SYMOP( IC_LEFT(dic))) {
2835 debugLog("%d - dic left is a SYMOP\n", __LINE__);
2836 debugAopGet(" left is ", IC_LEFT(dic));
2838 if(IS_TRUE_SYMOP( IC_RIGHT(dic))) {
2839 debugLog("%d - dic right is a SYMOP\n", __LINE__);
2840 debugAopGet(" right is ", IC_RIGHT(dic));
2844 if (IS_TRUE_SYMOP (IC_RESULT (dic)) &&
2845 IS_OP_VOLATILE (IC_RESULT (dic)))
2847 debugLog (" %d - dic is VOLATILE \n", __LINE__);
2853 if (IS_TRUE_SYMOP( IC_RIGHT (dic)) &&
2854 IS_OP_VOLATILE (IC_RIGHT(dic)))
2856 debugLog (" %d - dic right is VOLATILE\n", __LINE__);
2863 if (IS_TRUE_SYMOP( IC_LEFT (dic)) &&
2864 IS_OP_VOLATILE (IC_LEFT(dic)))
2866 debugLog (" %d - dic left is VOLATILE\n", __LINE__);
2872 if (IS_SYMOP (IC_RESULT (dic)) &&
2873 IC_RESULT (dic)->key == IC_RIGHT (ic)->key)
2875 /* A previous result was assigned to the same register - we'll our definition */
2876 debugLog (" %d - dic result key == ic right key -- pointer set=%c\n",
2877 __LINE__, ((POINTER_SET (dic)) ? 'Y' : 'N'));
2878 if (POINTER_SET (dic))
2884 if (IS_SYMOP (IC_RIGHT (dic)) &&
2885 (IC_RIGHT (dic)->key == IC_RESULT (ic)->key ||
2886 IC_RIGHT (dic)->key == IC_RIGHT (ic)->key))
2888 debugLog (" %d - dic right key == ic rightor result key\n", __LINE__);
2893 if (IS_SYMOP (IC_LEFT (dic)) &&
2894 (IC_LEFT (dic)->key == IC_RESULT (ic)->key ||
2895 IC_LEFT (dic)->key == IC_RIGHT (ic)->key))
2897 debugLog (" %d - dic left key == ic rightor result key\n", __LINE__);
2902 if (POINTER_SET (dic) &&
2903 IC_RESULT (dic)->key == IC_RESULT (ic)->key)
2905 debugLog (" %d - dic result key == ic result key -- pointer set=Y\n",
2913 return 0; /* did not find */
2915 /* if the result is on stack or iaccess then it must be
2916 the same atleast one of the operands */
2917 if (OP_SYMBOL (IC_RESULT (ic))->onStack ||
2918 OP_SYMBOL (IC_RESULT (ic))->iaccess)
2921 /* the operation has only one symbol
2922 operator then we can pack */
2923 if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
2924 (IC_RIGHT (dic) && !IS_SYMOP (IC_RIGHT (dic))))
2927 if (!((IC_LEFT (dic) &&
2928 IC_RESULT (ic)->key == IC_LEFT (dic)->key) ||
2930 IC_RESULT (ic)->key == IC_RIGHT (dic)->key)))
2934 debugLog (" packing. removing %s\n", OP_SYMBOL (IC_RIGHT (ic))->rname);
2935 debugLog (" replacing with %s\n", OP_SYMBOL (IC_RESULT (dic))->rname);
2936 /* found the definition */
2937 /* replace the result with the result of */
2938 /* this assignment and remove this assignment */
2939 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
2940 IC_RESULT (dic) = IC_RESULT (ic);
2942 if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq)
2944 OP_SYMBOL (IC_RESULT (dic))->liveFrom = dic->seq;
2946 /* delete from liverange table also
2947 delete from all the points inbetween and the new
2949 for (sic = dic; sic != ic; sic = sic->next)
2951 bitVectUnSetBit (sic->rlive, IC_RESULT (ic)->key);
2952 if (IS_ITEMP (IC_RESULT (dic)))
2953 bitVectSetBit (sic->rlive, IC_RESULT (dic)->key);
2956 remiCodeFromeBBlock (ebp, ic);
2957 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
2959 debugLog(" %d\n", __LINE__ );
2960 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
2961 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
2967 /*-----------------------------------------------------------------*/
2968 /* findAssignToSym : scanning backwards looks for first assig found */
2969 /*-----------------------------------------------------------------*/
2971 findAssignToSym (operand * op, iCode * ic)
2975 debugLog ("%s\n", __FUNCTION__);
2976 for (dic = ic->prev; dic; dic = dic->prev)
2979 /* if definition by assignment */
2980 if (dic->op == '=' &&
2981 !POINTER_SET (dic) &&
2982 IC_RESULT (dic)->key == op->key
2983 /* && IS_TRUE_SYMOP(IC_RIGHT(dic)) */
2987 /* we are interested only if defined in far space */
2988 /* or in stack space in case of + & - */
2990 /* if assigned to a non-symbol then return
2992 if (!IS_SYMOP (IC_RIGHT (dic)))
2995 /* if the symbol is in far space then
2997 if (isOperandInFarSpace (IC_RIGHT (dic)))
3000 /* for + & - operations make sure that
3001 if it is on the stack it is the same
3002 as one of the three operands */
3003 if ((ic->op == '+' || ic->op == '-') &&
3004 OP_SYMBOL (IC_RIGHT (dic))->onStack)
3007 if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
3008 IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
3009 IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)
3017 /* if we find an usage then we cannot delete it */
3018 if (IC_LEFT (dic) && IC_LEFT (dic)->key == op->key)
3021 if (IC_RIGHT (dic) && IC_RIGHT (dic)->key == op->key)
3024 if (POINTER_SET (dic) && IC_RESULT (dic)->key == op->key)
3028 /* now make sure that the right side of dic
3029 is not defined between ic & dic */
3032 iCode *sic = dic->next;
3034 for (; sic != ic; sic = sic->next)
3035 if (IC_RESULT (sic) &&
3036 IC_RESULT (sic)->key == IC_RIGHT (dic)->key)
3045 /*-----------------------------------------------------------------*/
3046 /* packRegsForSupport :- reduce some registers for support calls */
3047 /*-----------------------------------------------------------------*/
3049 packRegsForSupport (iCode * ic, eBBlock * ebp)
3053 debugLog ("%s\n", __FUNCTION__);
3054 /* for the left & right operand :- look to see if the
3055 left was assigned a true symbol in far space in that
3056 case replace them */
3057 if (IS_ITEMP (IC_LEFT (ic)) &&
3058 OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq)
3060 iCode *dic = findAssignToSym (IC_LEFT (ic), ic);
3066 debugAopGet ("removing left:", IC_LEFT (ic));
3068 /* found it we need to remove it from the
3070 for (sic = dic; sic != ic; sic = sic->next)
3071 bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key);
3073 IC_LEFT (ic)->operand.symOperand =
3074 IC_RIGHT (dic)->operand.symOperand;
3075 IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3076 remiCodeFromeBBlock (ebp, dic);
3077 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3078 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3082 /* do the same for the right operand */
3085 IS_ITEMP (IC_RIGHT (ic)) &&
3086 OP_SYMBOL (IC_RIGHT (ic))->liveTo <= ic->seq)
3088 iCode *dic = findAssignToSym (IC_RIGHT (ic), ic);
3094 /* if this is a subtraction & the result
3095 is a true symbol in far space then don't pack */
3096 if (ic->op == '-' && IS_TRUE_SYMOP (IC_RESULT (dic)))
3098 sym_link *etype = getSpec (operandType (IC_RESULT (dic)));
3099 if (IN_FARSPACE (SPEC_OCLS (etype)))
3103 debugAopGet ("removing right:", IC_RIGHT (ic));
3105 /* found it we need to remove it from the
3107 for (sic = dic; sic != ic; sic = sic->next)
3108 bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key);
3110 IC_RIGHT (ic)->operand.symOperand =
3111 IC_RIGHT (dic)->operand.symOperand;
3112 IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key;
3114 remiCodeFromeBBlock (ebp, dic);
3115 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3116 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3123 #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly)
3126 /*-----------------------------------------------------------------*/
3127 /* packRegsForOneuse : - will reduce some registers for single Use */
3128 /*-----------------------------------------------------------------*/
3130 packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp)
3135 debugLog ("%s\n", __FUNCTION__);
3136 /* if returning a literal then do nothing */
3140 /* only upto 2 bytes since we cannot predict
3141 the usage of b, & acc */
3142 if (getSize (operandType (op)) > (pic16_fReturnSizePic - 2) &&
3147 /* this routine will mark the a symbol as used in one
3148 instruction use only && if the definition is local
3149 (ie. within the basic block) && has only one definition &&
3150 that definition is either a return value from a
3151 function or does not contain any variables in
3153 uses = bitVectCopy (OP_USES (op));
3154 bitVectUnSetBit (uses, ic->key); /* take away this iCode */
3155 if (!bitVectIsZero (uses)) /* has other uses */
3158 /* if it has only one defintion */
3159 if (bitVectnBitsOn (OP_DEFS (op)) > 1)
3160 return NULL; /* has more than one definition */
3162 /* get that definition */
3164 hTabItemWithKey (iCodehTab,
3165 bitVectFirstBit (OP_DEFS (op)))))
3168 /* found the definition now check if it is local */
3169 if (dic->seq < ebp->fSeq ||
3170 dic->seq > ebp->lSeq)
3171 return NULL; /* non-local */
3173 /* now check if it is the return from
3175 if (dic->op == CALL || dic->op == PCALL)
3177 if (ic->op != SEND && ic->op != RETURN &&
3178 !POINTER_SET(ic) && !POINTER_GET(ic))
3180 OP_SYMBOL (op)->ruonly = 1;
3187 /* otherwise check that the definition does
3188 not contain any symbols in far space */
3189 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3190 isOperandInFarSpace (IC_RIGHT (dic)) ||
3191 IS_OP_RUONLY (IC_LEFT (ic)) ||
3192 IS_OP_RUONLY (IC_RIGHT (ic)))
3197 /* if pointer set then make sure the pointer
3199 if (POINTER_SET (dic) &&
3200 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3203 if (POINTER_GET (dic) &&
3204 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3209 /* also make sure the intervenening instructions
3210 don't have any thing in far space */
3211 for (dic = dic->next; dic && dic != ic; dic = dic->next)
3214 /* if there is an intervening function call then no */
3215 if (dic->op == CALL || dic->op == PCALL)
3217 /* if pointer set then make sure the pointer
3219 if (POINTER_SET (dic) &&
3220 !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE)))
3223 if (POINTER_GET (dic) &&
3224 !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE)))
3227 /* if address of & the result is remat then okay */
3228 if (dic->op == ADDRESS_OF &&
3229 OP_SYMBOL (IC_RESULT (dic))->remat)
3232 /* if operand has size of three or more & this
3233 operation is a '*','/' or '%' then 'b' may
3235 if ((dic->op == '%' || dic->op == '/' || dic->op == '*') &&
3236 getSize (operandType (op)) >= 3)
3239 /* if left or right or result is in far space */
3240 if (isOperandInFarSpace (IC_LEFT (dic)) ||
3241 isOperandInFarSpace (IC_RIGHT (dic)) ||
3242 isOperandInFarSpace (IC_RESULT (dic)) ||
3243 IS_OP_RUONLY (IC_LEFT (dic)) ||
3244 IS_OP_RUONLY (IC_RIGHT (dic)) ||
3245 IS_OP_RUONLY (IC_RESULT (dic)))
3251 OP_SYMBOL (op)->ruonly = 1;
3256 /*-----------------------------------------------------------------*/
3257 /* isBitwiseOptimizable - requirements of JEAN LOUIS VERN */
3258 /*-----------------------------------------------------------------*/
3260 isBitwiseOptimizable (iCode * ic)
3262 sym_link *ltype = getSpec (operandType (IC_LEFT (ic)));
3263 sym_link *rtype = getSpec (operandType (IC_RIGHT (ic)));
3265 debugLog ("%s\n", __FUNCTION__);
3266 /* bitwise operations are considered optimizable
3267 under the following conditions (Jean-Louis VERN)
3279 if (IS_LITERAL (rtype) ||
3280 (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype))))
3286 /*-----------------------------------------------------------------*/
3287 /* packRegsForAccUse - pack registers for acc use */
3288 /*-----------------------------------------------------------------*/
3290 packRegsForAccUse (iCode * ic)
3294 debugLog ("%s\n", __FUNCTION__);
3296 /* if this is an aggregate, e.g. a one byte char array */
3297 if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
3300 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3302 /* if + or - then it has to be one byte result */
3303 if ((ic->op == '+' || ic->op == '-')
3304 && getSize (operandType (IC_RESULT (ic))) > 1)
3307 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3308 /* if shift operation make sure right side is not a literal */
3309 if (ic->op == RIGHT_OP &&
3310 (isOperandLiteral (IC_RIGHT (ic)) ||
3311 getSize (operandType (IC_RESULT (ic))) > 1))
3314 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3315 if (ic->op == LEFT_OP &&
3316 (isOperandLiteral (IC_RIGHT (ic)) ||
3317 getSize (operandType (IC_RESULT (ic))) > 1))
3320 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3321 if (IS_BITWISE_OP (ic) &&
3322 getSize (operandType (IC_RESULT (ic))) > 1)
3326 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3327 /* has only one definition */
3328 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
3331 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3332 /* has only one use */
3333 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
3336 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3337 /* and the usage immediately follows this iCode */
3338 if (!(uic = hTabItemWithKey (iCodehTab,
3339 bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
3342 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3343 if (ic->next != uic)
3346 /* if it is a conditional branch then we definitely can */
3350 if (uic->op == JUMPTABLE)
3353 /* if the usage is not is an assignment
3354 or an arithmetic / bitwise / shift operation then not */
3355 if (POINTER_SET (uic) &&
3356 getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
3359 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3360 if (uic->op != '=' &&
3361 !IS_ARITHMETIC_OP (uic) &&
3362 !IS_BITWISE_OP (uic) &&
3363 uic->op != LEFT_OP &&
3364 uic->op != RIGHT_OP)
3367 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3368 /* if used in ^ operation then make sure right is not a
3370 if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
3373 /* if shift operation make sure right side is not a literal */
3374 if (uic->op == RIGHT_OP &&
3375 (isOperandLiteral (IC_RIGHT (uic)) ||
3376 getSize (operandType (IC_RESULT (uic))) > 1))
3379 if (uic->op == LEFT_OP &&
3380 (isOperandLiteral (IC_RIGHT (uic)) ||
3381 getSize (operandType (IC_RESULT (uic))) > 1))
3384 /* make sure that the result of this icode is not on the
3385 stack, since acc is used to compute stack offset */
3386 if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
3387 OP_SYMBOL (IC_RESULT (uic))->onStack)
3390 /* if either one of them in far space then we cannot */
3391 if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3392 isOperandInFarSpace (IC_LEFT (uic))) ||
3393 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3394 isOperandInFarSpace (IC_RIGHT (uic))))
3397 /* if the usage has only one operand then we can */
3398 if (IC_LEFT (uic) == NULL ||
3399 IC_RIGHT (uic) == NULL)
3402 /* make sure this is on the left side if not
3403 a '+' since '+' is commutative */
3404 if (ic->op != '+' &&
3405 IC_LEFT (uic)->key != IC_RESULT (ic)->key)
3408 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3409 /* if one of them is a literal then we can */
3410 if ( ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
3411 (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) &&
3412 (getSize (operandType (IC_RESULT (uic))) <= 1))
3414 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3418 debugLog (" %s:%d\n", __FUNCTION__,__LINE__);
3419 /* if the other one is not on stack then we can */
3420 if (IC_LEFT (uic)->key == IC_RESULT (ic)->key &&
3421 (IS_ITEMP (IC_RIGHT (uic)) ||
3422 (IS_TRUE_SYMOP (IC_RIGHT (uic)) &&
3423 !OP_SYMBOL (IC_RIGHT (uic))->onStack)))
3426 if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key &&
3427 (IS_ITEMP (IC_LEFT (uic)) ||
3428 (IS_TRUE_SYMOP (IC_LEFT (uic)) &&
3429 !OP_SYMBOL (IC_LEFT (uic))->onStack)))
3435 debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
3436 OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
3441 /*-----------------------------------------------------------------*/
3442 /* packForPush - hueristics to reduce iCode for pushing */
3443 /*-----------------------------------------------------------------*/
3445 packForReceive (iCode * ic, eBBlock * ebp)
3449 debugLog ("%s\n", __FUNCTION__);
3450 debugAopGet (" result:", IC_RESULT (ic));
3451 debugAopGet (" left:", IC_LEFT (ic));
3452 debugAopGet (" right:", IC_RIGHT (ic));
3457 for (dic = ic->next; dic; dic = dic->next)
3462 if (IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key))
3463 debugLog (" used on left\n");
3464 if (IC_RIGHT (dic) && IC_RESULT (ic)->key == IC_RIGHT (dic)->key)
3465 debugLog (" used on right\n");
3466 if (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key)
3467 debugLog (" used on result\n");
3469 if ((IC_LEFT (dic) && (IC_RESULT (ic)->key == IC_LEFT (dic)->key)) ||
3470 (IC_RESULT (dic) && IC_RESULT (ic)->key == IC_RESULT (dic)->key))
3475 debugLog (" hey we can remove this unnecessary assign\n");
3477 /*-----------------------------------------------------------------*/
3478 /* packForPush - hueristics to reduce iCode for pushing */
3479 /*-----------------------------------------------------------------*/
3481 packForPush (iCode * ic, eBBlock * ebp)
3485 debugLog ("%s\n", __FUNCTION__);
3486 if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic)))
3489 /* must have only definition & one usage */
3490 if (bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 1 ||
3491 bitVectnBitsOn (OP_USES (IC_LEFT (ic))) != 1)
3494 /* find the definition */
3495 if (!(dic = hTabItemWithKey (iCodehTab,
3496 bitVectFirstBit (OP_DEFS (IC_LEFT (ic))))))
3499 if (dic->op != '=' || POINTER_SET (dic))
3502 /* we now we know that it has one & only one def & use
3503 and the that the definition is an assignment */
3504 IC_LEFT (ic) = IC_RIGHT (dic);
3506 remiCodeFromeBBlock (ebp, dic);
3507 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3508 hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL);
3511 static void printSymType(char * str, sym_link *sl)
3513 debugLog (" %s Symbol type: ",str);
3514 printTypeChain( sl, debugF);
3519 /*-----------------------------------------------------------------*/
3520 /* some debug code to print the symbol S_TYPE. Note that
3521 * the function checkSClass in src/SDCCsymt.c dinks with
3522 * the S_TYPE in ways the PIC port doesn't fully like...*/
3523 /*-----------------------------------------------------------------*/
3524 static void isData(sym_link *sl)
3534 for ( ; sl; sl=sl->next) {
3536 switch (SPEC_SCLS(sl)) {
3538 case S_DATA: fprintf (of, "data "); break;
3539 case S_XDATA: fprintf (of, "xdata "); break;
3540 case S_SFR: fprintf (of, "sfr "); break;
3541 case S_SBIT: fprintf (of, "sbit "); break;
3542 case S_CODE: fprintf (of, "code "); break;
3543 case S_IDATA: fprintf (of, "idata "); break;
3544 case S_PDATA: fprintf (of, "pdata "); break;
3545 case S_LITERAL: fprintf (of, "literal "); break;
3546 case S_STACK: fprintf (of, "stack "); break;
3547 case S_XSTACK: fprintf (of, "xstack "); break;
3548 case S_BIT: fprintf (of, "bit "); break;
3549 case S_EEPROM: fprintf (of, "eeprom "); break;
3559 /*--------------------------------------------------------------------*/
3560 /* pic16_packRegisters - does some transformations to reduce */
3561 /* register pressure */
3563 /*--------------------------------------------------------------------*/
3565 pic16_packRegisters (eBBlock * ebp)
3570 debugLog ("%s\n", __FUNCTION__);
3576 /* look for assignments of the form */
3577 /* iTempNN = TRueSym (someoperation) SomeOperand */
3579 /* TrueSym := iTempNN:1 */
3580 for (ic = ebp->sch; ic; ic = ic->next)
3582 // debugLog("%d\n", __LINE__);
3583 /* find assignment of the form TrueSym := iTempNN:1 */
3584 /* see BUGLOG0001 for workaround with the CAST - VR */
3585 if ((ic->op == '=' || ic->op == CAST) && !POINTER_SET (ic))
3586 change += packRegsForAssign (ic, ebp);
3590 if (POINTER_SET (ic))
3591 debugLog ("pointer is set\n");
3592 debugAopGet (" result:", IC_RESULT (ic));
3593 debugAopGet (" left:", IC_LEFT (ic));
3594 debugAopGet (" right:", IC_RIGHT (ic));
3603 for (ic = ebp->sch; ic; ic = ic->next) {
3605 if(IS_SYMOP ( IC_LEFT(ic))) {
3606 sym_link *etype = getSpec (operandType (IC_LEFT (ic)));
3608 debugAopGet ("x left:", IC_LEFT (ic));
3610 if(IS_PTR_CONST(OP_SYMBOL(IC_LEFT(ic))->type))
3612 if(IS_CODEPTR(OP_SYMBOL(IC_LEFT(ic))->type))
3614 debugLog (" is a pointer\n");
3616 if(IS_PTR(OP_SYMBOL(IC_LEFT(ic))->type))
3617 debugLog (" is a ptr\n");
3619 if(IS_OP_VOLATILE(IC_LEFT(ic)))
3620 debugLog (" is volatile\n");
3624 if(IS_OP_VOLATILE(IC_LEFT(ic))) {
3625 debugLog (" %d - left is not temp, allocating\n", __LINE__);
3626 pic16_allocDirReg(IC_LEFT (ic));
3629 printSymType("c ", OP_SYMBOL(IC_LEFT(ic))->type);
3632 if(IS_SYMOP ( IC_RIGHT(ic))) {
3633 debugAopGet (" right:", IC_RIGHT (ic));
3634 printSymType(" ", OP_SYMBOL(IC_RIGHT(ic))->type);
3637 if(IS_SYMOP ( IC_RESULT(ic))) {
3638 debugAopGet (" result:", IC_RESULT (ic));
3639 printSymType(" ", OP_SYMBOL(IC_RESULT(ic))->type);
3642 if (POINTER_SET (ic))
3643 debugLog (" %d - Pointer set\n", __LINE__);
3646 /* if this is an itemp & result of a address of a true sym
3647 then mark this as rematerialisable */
3648 if (ic->op == ADDRESS_OF &&
3649 IS_ITEMP (IC_RESULT (ic)) &&
3650 IS_TRUE_SYMOP (IC_LEFT (ic)) &&
3651 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3652 !OP_SYMBOL (IC_LEFT (ic))->onStack)
3655 debugLog (" %d - %s. result is rematerializable\n", __LINE__,__FUNCTION__);
3657 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3658 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3659 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3663 /* if straight assignment then carry remat flag if
3664 this is the only definition */
3665 if (ic->op == '=' &&
3666 !POINTER_SET (ic) &&
3667 IS_SYMOP (IC_RIGHT (ic)) &&
3668 OP_SYMBOL (IC_RIGHT (ic))->remat &&
3669 bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1)
3671 debugLog (" %d - %s. straight rematerializable\n", __LINE__,__FUNCTION__);
3673 OP_SYMBOL (IC_RESULT (ic))->remat =
3674 OP_SYMBOL (IC_RIGHT (ic))->remat;
3675 OP_SYMBOL (IC_RESULT (ic))->rematiCode =
3676 OP_SYMBOL (IC_RIGHT (ic))->rematiCode;
3679 /* if this is a +/- operation with a rematerizable
3680 then mark this as rematerializable as well */
3681 if ((ic->op == '+' || ic->op == '-') &&
3682 (IS_SYMOP (IC_LEFT (ic)) &&
3683 IS_ITEMP (IC_RESULT (ic)) &&
3684 OP_SYMBOL (IC_LEFT (ic))->remat &&
3685 bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 &&
3686 IS_OP_LITERAL (IC_RIGHT (ic))))
3688 debugLog (" %d - %s. rematerializable because op is +/-\n", __LINE__,__FUNCTION__);
3690 operandLitValue (IC_RIGHT (ic));
3691 OP_SYMBOL (IC_RESULT (ic))->remat = 1;
3692 OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic;
3693 OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL;
3696 /* mark the pointer usages */
3697 if (POINTER_SET (ic))
3699 OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
3700 debugLog (" marking as a pointer (set) =>");
3701 debugAopGet (" result:", IC_RESULT (ic));
3703 if (POINTER_GET (ic))
3705 OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
3706 debugLog (" marking as a pointer (get) =>");
3707 debugAopGet (" left:", IC_LEFT (ic));
3710 //debugLog(" %d %s\n", __LINE__, __FUNCTION__);
3714 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3715 /* if we are using a symbol on the stack
3716 then we should say pic16_ptrRegReq */
3717 if (ic->op == IFX && IS_SYMOP (IC_COND (ic)))
3718 pic16_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ||
3719 OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0);
3720 else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic)))
3721 pic16_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ||
3722 OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0);
3726 //debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3727 if (IS_SYMOP (IC_LEFT (ic)))
3728 pic16_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ||
3729 OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0);
3730 if (IS_SYMOP (IC_RIGHT (ic)))
3731 pic16_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ||
3732 OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0);
3733 if (IS_SYMOP (IC_RESULT (ic)))
3734 pic16_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ||
3735 OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0);
3738 debugLog (" %d - pointer reg req = %d\n", __LINE__,pic16_ptrRegReq);
3742 /* if the condition of an if instruction
3743 is defined in the previous instruction then
3744 mark the itemp as a conditional */
3745 if ((IS_CONDITIONAL (ic) ||
3746 ((ic->op == BITWISEAND ||
3749 isBitwiseOptimizable (ic))) &&
3750 ic->next && ic->next->op == IFX &&
3751 isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) &&
3752 OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
3755 debugLog (" %d\n", __LINE__);
3756 OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND;
3760 debugLog(" %d\n", __LINE__);
3762 /* reduce for support function calls */
3763 if (ic->supportRtn || ic->op == '+' || ic->op == '-')
3764 packRegsForSupport (ic, ebp);
3766 /* if a parameter is passed, it's in W, so we may not
3767 need to place a copy in a register */
3768 if (ic->op == RECEIVE)
3769 packForReceive (ic, ebp);
3771 /* some cases the redundant moves can
3772 can be eliminated for return statements */
3773 if ((ic->op == RETURN || ic->op == SEND) &&
3774 !isOperandInFarSpace (IC_LEFT (ic)) &&
3776 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3778 /* if pointer set & left has a size more than
3779 one and right is not in far space */
3780 if (POINTER_SET (ic) &&
3781 !isOperandInFarSpace (IC_RIGHT (ic)) &&
3782 !OP_SYMBOL (IC_RESULT (ic))->remat &&
3783 !IS_OP_RUONLY (IC_RIGHT (ic)) &&
3784 getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
3786 packRegsForOneuse (ic, IC_RESULT (ic), ebp);
3788 /* if pointer get */
3789 if (POINTER_GET (ic) &&
3790 !isOperandInFarSpace (IC_RESULT (ic)) &&
3791 !OP_SYMBOL (IC_LEFT (ic))->remat &&
3792 !IS_OP_RUONLY (IC_RESULT (ic)) &&
3793 getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)
3795 packRegsForOneuse (ic, IC_LEFT (ic), ebp);
3796 debugLog("%d - return from packRegsForOneuse\n", __LINE__);
3798 /* if this is cast for intergral promotion then
3799 check if only use of the definition of the
3800 operand being casted/ if yes then replace
3801 the result of that arithmetic operation with
3802 this result and get rid of the cast */
3803 if (ic->op == CAST) {
3805 sym_link *fromType = operandType (IC_RIGHT (ic));
3806 sym_link *toType = operandType (IC_LEFT (ic));
3808 debugLog (" %d - casting\n", __LINE__);
3810 if (IS_INTEGRAL (fromType) && IS_INTEGRAL (toType) &&
3811 getSize (fromType) != getSize (toType)) {
3814 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3817 if (IS_ARITHMETIC_OP (dic)) {
3818 debugLog(" %d %s\n", __LINE__, __FUNCTION__ );
3820 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3821 IC_RESULT (dic) = IC_RESULT (ic);
3822 remiCodeFromeBBlock (ebp, ic);
3823 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3824 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3825 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3829 OP_SYMBOL (IC_RIGHT (ic))->ruonly = 0;
3833 /* if the type from and type to are the same
3834 then if this is the only use then packit */
3835 if (compareType (operandType (IC_RIGHT (ic)),
3836 operandType (IC_LEFT (ic))) == 1) {
3838 iCode *dic = packRegsForOneuse (ic, IC_RIGHT (ic), ebp);
3841 debugLog(" %d\n", __LINE__);
3843 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key);
3844 IC_RESULT (dic) = IC_RESULT (ic);
3845 bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);
3846 remiCodeFromeBBlock (ebp, ic);
3847 hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL);
3848 OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key);
3856 iTempNN := (some variable in farspace) V1
3861 if (ic->op == IPUSH)
3863 packForPush (ic, ebp);
3867 /* pack registers for accumulator use, when the
3868 result of an arithmetic or bit wise operation
3869 has only one use, that use is immediately following
3870 the defintion and the using iCode has only one
3871 operand or has two operands but one is literal &
3872 the result of that operation is not on stack then
3873 we can leave the result of this operation in acc:b
3875 if ((IS_ARITHMETIC_OP (ic)
3877 || IS_BITWISE_OP (ic)
3879 || ic->op == LEFT_OP || ic->op == RIGHT_OP
3882 IS_ITEMP (IC_RESULT (ic)) &&
3883 getSize (operandType (IC_RESULT (ic))) <= 2)
3885 packRegsForAccUse (ic);
3891 dumpEbbsToDebug (eBBlock ** ebbs, int count)
3895 if (!debug || !debugF)
3898 for (i = 0; i < count; i++)
3900 fprintf (debugF, "\n----------------------------------------------------------------\n");
3901 fprintf (debugF, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
3902 ebbs[i]->entryLabel->name,
3905 ebbs[i]->isLastInLoop);
3906 fprintf (debugF, "depth 1st num %d : bbnum = %d 1st iCode = %d , last iCode = %d\n",
3911 fprintf (debugF, "visited %d : hasFcall = %d\n",
3915 fprintf (debugF, "\ndefines bitVector :");
3916 bitVectDebugOn (ebbs[i]->defSet, debugF);
3917 fprintf (debugF, "\nlocal defines bitVector :");
3918 bitVectDebugOn (ebbs[i]->ldefs, debugF);
3919 fprintf (debugF, "\npointers Set bitvector :");
3920 bitVectDebugOn (ebbs[i]->ptrsSet, debugF);
3921 fprintf (debugF, "\nin pointers Set bitvector :");
3922 bitVectDebugOn (ebbs[i]->inPtrsSet, debugF);
3923 fprintf (debugF, "\ninDefs Set bitvector :");
3924 bitVectDebugOn (ebbs[i]->inDefs, debugF);
3925 fprintf (debugF, "\noutDefs Set bitvector :");
3926 bitVectDebugOn (ebbs[i]->outDefs, debugF);
3927 fprintf (debugF, "\nusesDefs Set bitvector :");
3928 bitVectDebugOn (ebbs[i]->usesDefs, debugF);
3929 fprintf (debugF, "\n----------------------------------------------------------------\n");
3930 printiCChain (ebbs[i]->sch, debugF);
3933 /*-----------------------------------------------------------------*/
3934 /* pic16_assignRegisters - assigns registers to each live range as need */
3935 /*-----------------------------------------------------------------*/
3937 pic16_assignRegisters (eBBlock ** ebbs, int count)
3942 debugLog ("<><><><><><><><><><><><><><><><><>\nstarting\t%s:%s", __FILE__, __FUNCTION__);
3943 debugLog ("\nebbs before optimizing:\n");
3944 dumpEbbsToDebug (ebbs, count);
3946 setToNull ((void *) &_G.funcrUsed);
3947 pic16_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
3950 /* change assignments this will remove some
3951 live ranges reducing some register pressure */
3952 for (i = 0; i < count; i++)
3953 pic16_packRegisters (ebbs[i]);
3960 debugLog("dir registers allocated so far:\n");
3961 reg = hTabFirstItem(dynDirectRegNames, &hkey);
3964 debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3965 // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size);
3966 reg = hTabNextItem(dynDirectRegNames, &hkey);
3971 /* liveranges probably changed by register packing
3972 so we compute them again */
3973 recomputeLiveRanges (ebbs, count);
3975 if (options.dump_pack)
3976 dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
3978 /* first determine for each live range the number of
3979 registers & the type of registers required for each */
3982 /* and serially allocate registers */
3983 serialRegAssign (ebbs, count);
3985 /* if stack was extended then tell the user */
3988 /* werror(W_TOOMANY_SPILS,"stack", */
3989 /* _G.stackExtend,currFunc->name,""); */
3995 /* werror(W_TOOMANY_SPILS,"data space", */
3996 /* _G.dataExtend,currFunc->name,""); */
4000 /* after that create the register mask
4001 for each of the instruction */
4002 createRegMask (ebbs, count);
4004 /* redo that offsets for stacked automatic variables */
4005 redoStackOffsets ();
4007 if (options.dump_rassgn)
4008 dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);
4010 /* now get back the chain */
4011 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count));
4013 debugLog ("ebbs after optimizing:\n");
4014 dumpEbbsToDebug (ebbs, count);
4019 /* free up any _G.stackSpil locations allocated */
4020 applyToSet (_G.stackSpil, deallocStackSpil);
4022 setToNull ((void *) &_G.stackSpil);
4023 setToNull ((void *) &_G.spiltSet);
4024 /* mark all registers as free */
4025 //pic16_freeAllRegs ();
4027 debugLog ("leaving\n<><><><><><><><><><><><><><><><><>\n");