From 2a5f5d119dd294a5d32b607c4c179d386a70f4de Mon Sep 17 00:00:00 2001 From: sdattalo Date: Sun, 7 Jul 2002 00:44:53 +0000 Subject: [PATCH] inline assembly was generated as plain text, now it is assembled into pCodes. addpCode2pBlock would dump core if the pCode being added was NULL. pBlockMergeLabels couldn't merge labels into instructions if the two labels occurred as consecutive pCodes. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2032 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- src/pic/gen.c | 17 ++++++---- src/pic/pcode.c | 24 +++++++------- src/pic/pcodepeep.c | 47 ++++++++++++++++++++++++--- src/pic/pcoderegs.c | 79 ++++++++++++++++++++++++++++++++++++--------- 4 files changed, 128 insertions(+), 39 deletions(-) diff --git a/src/pic/gen.c b/src/pic/gen.c index e7441b1b..78a8fcc0 100644 --- a/src/pic/gen.c +++ b/src/pic/gen.c @@ -63,6 +63,8 @@ extern void genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *); extern void genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *); void genMult8X8_8 (operand *, operand *,operand *); +pCode *AssembleLine(char *line); +extern void printpBlock(FILE *of, pBlock *pb); static int labelOffset=0; extern int debug_verbose; @@ -6023,8 +6025,9 @@ static void genInline (iCode *ic) while (*bp) { if (*bp == '\n') { *bp++ = '\0'; - pic14_emitcode(bp1,""); - addpCode2pBlock(pb,newpCodeInlineP(bp1)); + + if(*bp1) + addpCode2pBlock(pb,AssembleLine(bp1)); bp1 = bp; } else { if (*bp == ':') { @@ -6037,11 +6040,11 @@ static void genInline (iCode *ic) bp++; } } - if (bp1 != bp) { - pic14_emitcode(bp1,""); - addpCode2pBlock(pb,newpCodeInlineP(bp1)); - } - /* pic14_emitcode("",buffer); */ + if ((bp1 != bp) && *bp1) + addpCode2pBlock(pb,AssembleLine(bp1)); + + Safe_free(buffer); + _G.inLine -= (!options.asmpeep); } diff --git a/src/pic/pcode.c b/src/pic/pcode.c index 2acf43f5..8630f73a 100644 --- a/src/pic/pcode.c +++ b/src/pic/pcode.c @@ -2224,16 +2224,22 @@ void pCodeReadCodeTable(void) /*-----------------------------------------------------------------*/ void addpCode2pBlock(pBlock *pb, pCode *pc) { + + if(!pc) + return; + if(!pb->pcHead) { /* If this is the first pcode to be added to a block that * was initialized with a NULL pcode, then go ahead and * make this pcode the head and tail */ pb->pcHead = pb->pcTail = pc; } else { + // if(pb->pcTail) pb->pcTail->next = pc; + pc->prev = pb->pcTail; - //pc->next = NULL; pc->pb = pb; + pb->pcTail = pc; } } @@ -4315,7 +4321,11 @@ void pBlockMergeLabels(pBlock *pb) /* Now loop through the pBlock and merge the labels with the opcodes */ - for(pc = pb->pcHead; pc; pc = pc->next) { + pc = pb->pcHead; + // for(pc = pb->pcHead; pc; pc = pc->next) { + + while(pc) { + pCode *pcn = pc->next; if(pc->type == PC_LABEL) { @@ -4323,8 +4333,6 @@ void pBlockMergeLabels(pBlock *pb) //fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key); if((pcnext = findNextInstruction(pc) )) { - pCode *pcn = pc->next; - // Unlink the pCode label from it's pCode chain unlinkpCode(pc); @@ -4340,10 +4348,7 @@ void pBlockMergeLabels(pBlock *pb) pbr->pc = pc; pbr->next = NULL; - PCI(pcnext)->label = pBranchAppend(PCI(pcnext)->label,pbr); - - pc = pcn; } else { fprintf(stderr, "WARNING: couldn't associate label %s with an instruction\n",PCL(pc)->label); @@ -4353,18 +4358,15 @@ void pBlockMergeLabels(pBlock *pb) /* merge the source line symbolic info into the next instruction */ if((pcnext = findNextInstruction(pc) )) { - pCode *pcn = pc->next; - // Unlink the pCode label from it's pCode chain unlinkpCode(pc); PCI(pcnext)->cline = PCCS(pc); //fprintf(stderr, "merging CSRC\n"); //genericPrint(stderr,pcnext); - pc = pcn; } } - + pc = pcn; } pBlockRemoveUnusedLabels(pb); diff --git a/src/pic/pcodepeep.c b/src/pic/pcodepeep.c index 9df610d2..ecb5b092 100644 --- a/src/pic/pcodepeep.c +++ b/src/pic/pcodepeep.c @@ -603,6 +603,11 @@ static void * cvt_altpat_mnem2a(void *pp,pCodeWildBlock *pcwb) pCodeInstruction *pci=NULL; pCodeOp *pcosubtype; + if(!pcwb) { + fprintf(stderr,"ERROR %s:%d - can't assemble line\n",__FILE__,__LINE__); + return NULL; + } + dest = cvt_extract_destination(&p[3]); DFPRINTF((stderr,"altpat_mnem2a %s var %d destination %s(%d)\n", @@ -893,13 +898,14 @@ int advTokIdx(int *v, int amt) /* pcode. */ /*-----------------------------------------------------------------*/ -void parseTokens(pCodeWildBlock *pcwb) +int parseTokens(pCodeWildBlock *pcwb, pCode **pcret) { unsigned i; pCode *pc; + int error = 0; if(!tokIdx) - return; + return error; for(i=0; i<=tokIdx; i++) dump1Token(tokArr[i].tt); @@ -1074,7 +1080,14 @@ void parseTokens(pCodeWildBlock *pcwb) //if(curBlock && pc) //addpCode2pBlock(curBlock, pc); - addpCode2pBlock(pcwb->pb, pc); + if(pc) { + if (pcret) { + *pcret = pc; + return 0; // Only accept one line for now. + } else + addpCode2pBlock(pcwb->pb, pc); + } else + error++; } j += c; } @@ -1098,7 +1111,7 @@ void parseTokens(pCodeWildBlock *pcwb) } - + return error; } /*-----------------------------------------------------------------*/ @@ -1115,9 +1128,33 @@ void peepRuleBlock2pCodeBlock( lineNode *ln, pCodeWildBlock *pcwb) //DFPRINTF((stderr,"%s\n",ln->line)); tokenizeLineNode(ln->line); - parseTokens(pcwb); + + if(parseTokens(pcwb,NULL)) { + fprintf(stderr,"ERROR assembling line:\n%s\n",ln->line); + exit (1); + } + } +} +/*-----------------------------------------------------------------*/ +/* */ +/*-----------------------------------------------------------------*/ +pCode *AssembleLine(char *line) +{ + pCode *pc=NULL; + + if(!line || !*line) { + fprintf(stderr,"WARNING returning NULL in AssembleLine\n"); + return NULL; } + + tokenizeLineNode(line); + + if(parseTokens(NULL,&pc)) + fprintf(stderr, "WARNING: unable to assemble line:\n%s\n",line); + + return pc; + } /*-----------------------------------------------------------------*/ diff --git a/src/pic/pcoderegs.c b/src/pic/pcoderegs.c index 82c585cb..7b4cee86 100644 --- a/src/pic/pcoderegs.c +++ b/src/pic/pcoderegs.c @@ -346,7 +346,6 @@ void RemoveUnusedRegisters(void) { /* First, get rid of registers that are used only one time */ - RemoveRegsFromSet(dynInternalRegs); RemoveRegsFromSet(dynAllocRegs); RemoveRegsFromSet(dynStackRegs); @@ -420,11 +419,13 @@ int regUsedinRange(pCode *pc1, pCode *pc2, regs *reg) * * *-----------------------------------------------------------------*/ -void pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int can_free) +int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int can_free) { pCode *pct1, *pct2; regs *reg1, *reg2; + int t = total_registers_saved; + if(pc2->seq < pc1->seq) { pct1 = pc2; pc2 = pc1; @@ -480,13 +481,13 @@ void pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int if(PCI(pct2)->op == POC_MOVWF) { reg2 = getRegFromInstruction(pct2); - if(reg2 && !regUsedinRange(pc1,pc2,reg2)) { + if(reg2 && !regUsedinRange(pc1,pc2,reg2) && (reg2->type != REG_SFR)) { pct2->seq = pc1->seq; unlinkpCode(pct2); pCodeInsertAfter(pc1,pct2); Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free); total_registers_saved++; // debugging stats. - return; + return 1; } /* fprintf(stderr, " couldn't optimize\n"); @@ -528,15 +529,17 @@ void pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int } + return (total_registers_saved != t); } /*-----------------------------------------------------------------* * void pCodeRegOptimeRegUsage(pBlock *pb) *-----------------------------------------------------------------*/ -void OptimizeRegUsage(set *fregs) +void OptimizeRegUsage(set *fregs, int optimize_multi_uses) { regs *reg; int used; + pCode *pc1=NULL, *pc2=NULL; while(fregs) { @@ -566,7 +569,6 @@ void OptimizeRegUsage(set *fregs) * instructions are examined. If possible, they're optimized out. */ - pCode *pc1, *pc2; /* fprintf (stderr, "OptimizeRegUsage: %s addr=0x%03x rIdx=0x%03x type=%d used=%d\n", reg->name, @@ -634,10 +636,46 @@ void OptimizeRegUsage(set *fregs) reg->wasUsed = 0; total_registers_saved++; // debugging stats. - } else if(used > 2) { + } else if( (used > 2) && optimize_multi_uses) { + + set *rset1=NULL; + set *rset2=NULL; + int searching=1; + + pCodeFlow *pcfl1=NULL, *pcfl2=NULL; /* examine the number of times this register is used */ + + rset1 = reg->reglives.usedpCodes; + while(rset1 && searching) { + + pc1 = rset1->item; + rset2 = rset1->next; + + if(pc1 && isPCI(pc1) && ( (pcfl1 = PCI(pc1)->pcflow) != NULL) ) { + + while(rset2 && searching) { + + pc2 = rset2->item; + if(pc2 && isPCI(pc2) && ( (pcfl2 = PCI(pc2)->pcflow) != NULL) ) { + if(pcfl2 == pcfl1) { +/* + fprintf(stderr, " two instruction in same flow\n"); + pc1->print(stderr, pc1); + pc2->print(stderr, pc2); +*/ + //if(pCodeOptime2pCodes(pc1, pc2, pcfl_used, reg, 1)) + // searching = 0; + } + } + + rset2 = rset2->next; + + } + } + rset1 = rset1->next; + } } } @@ -650,23 +688,32 @@ void OptimizeRegUsage(set *fregs) void pCodeRegOptimizeRegUsage(void) { - int passes = 4; + int passes; int saved = 0; int t = total_registers_saved; + int optimize_multi = 0; do { - saved = total_registers_saved; + passes = 4; + + //fprintf(stderr, " multi opti %d\n",optimize_multi); + + do { + saved = total_registers_saved; - /* Identify registers used in one flow sequence */ - OptimizeRegUsage(dynAllocRegs); - OptimizeRegUsage(dynStackRegs); - OptimizeRegUsage(dynDirectRegs); + /* Identify registers used in one flow sequence */ + OptimizeRegUsage(dynAllocRegs,optimize_multi); + OptimizeRegUsage(dynStackRegs,0); + OptimizeRegUsage(dynDirectRegs,0); - if(total_registers_saved != saved) - fprintf(stderr, " *** Saved %d registers, total saved %d ***\n", total_registers_saved-saved,total_registers_saved); + if(total_registers_saved != saved) + fprintf(stderr, " *** Saved %d registers, total saved %d ***\n", total_registers_saved-saved,total_registers_saved); + + } while( passes-- && (total_registers_saved != saved)); - } while( passes-- && (total_registers_saved != saved)); + optimize_multi++; + } while (optimize_multi < 2); if(total_registers_saved == t) fprintf(stderr, "No registers saved on this pass\n"); -- 2.30.2