From 29779804200986ce903b5086441b49265a122dc5 Mon Sep 17 00:00:00 2001 From: johanknol Date: Wed, 14 Feb 2001 19:32:19 +0000 Subject: [PATCH] Beautified (indented) compiler source tree git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@618 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- src/SDCCBBlock.c | 947 +++---- src/SDCCBBlock.h | 128 +- src/SDCCast.c | 6145 ++++++++++++++++++++++++---------------------- src/SDCCast.h | 188 +- src/SDCCbitv.c | 371 +-- src/SDCCbitv.h | 43 +- src/SDCCcflow.c | 556 +++-- src/SDCCcflow.h | 16 +- src/SDCCcse.c | 2524 ++++++++++--------- src/SDCCcse.h | 44 +- src/SDCCdflow.c | 541 ++-- src/SDCCdflow.h | 14 +- src/SDCCglobl.h | 235 +- src/SDCCglue.c | 2021 +++++++-------- src/SDCCglue.h | 6 +- src/SDCChasht.c | 604 ++--- src/SDCChasht.h | 90 +- src/SDCCicode.c | 4577 +++++++++++++++++----------------- src/SDCCicode.h | 286 ++- src/SDCClabel.c | 709 +++--- src/SDCClabel.h | 6 +- src/SDCCloop.c | 1726 ++++++------- src/SDCCloop.h | 46 +- src/SDCClrange.c | 804 +++--- src/SDCClrange.h | 2 +- src/SDCCmain.c | 64 +- src/SDCCmem.c | 1756 ++++++------- src/SDCCmem.h | 104 +- src/SDCCopt.c | 1289 +++++----- src/SDCCopt.h | 6 +- src/SDCCpeeph.c | 1335 +++++----- src/SDCCpeeph.h | 24 +- src/SDCCptropt.c | 142 +- src/SDCCset.c | 590 +++-- src/SDCCset.h | 69 +- src/SDCCsymt.c | 3164 +++++++++++++----------- src/SDCCsymt.h | 553 +++-- src/SDCCval.c | 1937 ++++++++------- src/SDCCval.h | 133 +- src/altlex.c | 1701 +++++++------ src/asm.c | 457 ++-- src/asm.h | 23 +- src/port.h | 148 +- src/spawn.c | 50 +- src/spawn.h | 6 +- 45 files changed, 19083 insertions(+), 17097 deletions(-) diff --git a/src/SDCCBBlock.c b/src/SDCCBBlock.c index 5693670b..affc68fa 100644 --- a/src/SDCCBBlock.c +++ b/src/SDCCBBlock.c @@ -27,305 +27,335 @@ #include "newalloc.h" int eBBNum = 0; -set *graphEdges = NULL ; /* list of edges in this flow graph */ +set *graphEdges = NULL; /* list of edges in this flow graph */ /*-----------------------------------------------------------------*/ /* printEntryLabel - prints entry label of a ebblock */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(printEntryLabel) +DEFSETFUNC (printEntryLabel) { - eBBlock *bp = item; + eBBlock *bp = item; - fprintf (stdout," %-20s ",bp->entryLabel->name); - return 0; + fprintf (stdout, " %-20s ", bp->entryLabel->name); + return 0; } /*-----------------------------------------------------------------*/ /* neweBBlock - allocate & return a new extended basic block */ /*-----------------------------------------------------------------*/ -eBBlock *neweBBlock () +eBBlock * +neweBBlock () { - eBBlock *ebb; + eBBlock *ebb; - ebb = Safe_calloc(1,sizeof(eBBlock)); - return ebb ; + ebb = Safe_calloc (1, sizeof (eBBlock)); + return ebb; } /*-----------------------------------------------------------------*/ /* newEdge - allocates & initialises an edge to given values */ /*-----------------------------------------------------------------*/ -edge *newEdge (eBBlock *from, eBBlock *to) +edge * +newEdge (eBBlock * from, eBBlock * to) { - edge *ep ; + edge *ep; - ep = Safe_calloc(1,sizeof(edge)); + ep = Safe_calloc (1, sizeof (edge)); - ep->from = from; - ep->to = to; - return ep; + ep->from = from; + ep->to = to; + return ep; } /*-----------------------------------------------------------------*/ /* dumpLiveRanges - dump liverange information into a file */ /*-----------------------------------------------------------------*/ -void dumpLiveRanges (char *ext,hTab *liveRanges) +void +dumpLiveRanges (char *ext, hTab * liveRanges) { - FILE *file; - symbol *sym; - int k; - - if (ext) { - /* create the file name */ - strcpy(buffer,srcFileName); - strcat(buffer,ext); - - if (!(file = fopen(buffer,"a+"))) { - werror(E_FILE_OPEN_ERR,buffer); - exit(1); - } - } else - file = stdout; - - for (sym = hTabFirstItem(liveRanges,&k); sym ; - sym = hTabNextItem(liveRanges,&k)) { - - fprintf (file,"%s [k%d lr%d:%d so:%d]{ re%d rm%d}", - (sym->rname[0] ? sym->rname : sym->name), - sym->key, - sym->liveFrom,sym->liveTo, - sym->stack, - sym->isreqv,sym->remat - ); - - fprintf(file,"{"); printTypeChain(sym->type,file); - if (sym->usl.spillLoc) { - fprintf(file,"}{ sir@ %s",sym->usl.spillLoc->rname); - } - fprintf(file,"}"); - - /* if assigned to registers */ - if (sym->nRegs) { - if (sym->isspilt) { - if (!sym->remat) - if (sym->usl.spillLoc) - fprintf(file,"[%s]",(sym->usl.spillLoc->rname[0] ? - sym->usl.spillLoc->rname : - sym->usl.spillLoc->name)); - else - fprintf(file,"[err]"); - else - fprintf(file,"[remat]"); - } - else { - int i; - fprintf(file,"["); - for(i=0;inRegs;i++) - fprintf(file,"%s ", port->getRegName(sym->regs[i])); - fprintf(file,"]"); - } - } - fprintf(file,"\n"); + FILE *file; + symbol *sym; + int k; + + if (ext) + { + /* create the file name */ + strcpy (buffer, srcFileName); + strcat (buffer, ext); + + if (!(file = fopen (buffer, "a+"))) + { + werror (E_FILE_OPEN_ERR, buffer); + exit (1); + } } + else + file = stdout; - fclose(file); + for (sym = hTabFirstItem (liveRanges, &k); sym; + sym = hTabNextItem (liveRanges, &k)) + { + + fprintf (file, "%s [k%d lr%d:%d so:%d]{ re%d rm%d}", + (sym->rname[0] ? sym->rname : sym->name), + sym->key, + sym->liveFrom, sym->liveTo, + sym->stack, + sym->isreqv, sym->remat + ); + + fprintf (file, "{"); + printTypeChain (sym->type, file); + if (sym->usl.spillLoc) + { + fprintf (file, "}{ sir@ %s", sym->usl.spillLoc->rname); + } + fprintf (file, "}"); + + /* if assigned to registers */ + if (sym->nRegs) + { + if (sym->isspilt) + { + if (!sym->remat) + if (sym->usl.spillLoc) + fprintf (file, "[%s]", (sym->usl.spillLoc->rname[0] ? + sym->usl.spillLoc->rname : + sym->usl.spillLoc->name)); + else + fprintf (file, "[err]"); + else + fprintf (file, "[remat]"); + } + else + { + int i; + fprintf (file, "["); + for (i = 0; i < sym->nRegs; i++) + fprintf (file, "%s ", port->getRegName (sym->regs[i])); + fprintf (file, "]"); + } + } + fprintf (file, "\n"); + } + + fclose (file); } /*-----------------------------------------------------------------*/ /* dumpEbbsToFileExt - writeall the basic blocks to a file */ /*-----------------------------------------------------------------*/ -void dumpEbbsToFileExt (char *ext,eBBlock **ebbs, int count) +void +dumpEbbsToFileExt (char *ext, eBBlock ** ebbs, int count) { - FILE *of; - int i; - - if (ext) { - /* create the file name */ - strcpy(buffer,srcFileName); - strcat(buffer,ext); - - if (!(of = fopen(buffer,"a+"))) { - werror(E_FILE_OPEN_ERR,buffer); - exit(1); - } - } else - of = stdout; - - for (i=0; i < count ; i++ ) { - fprintf(of,"\n----------------------------------------------------------------\n"); - fprintf(of,"Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n", - ebbs[i]->entryLabel->name, - ebbs[i]->depth, - ebbs[i]->noPath, - ebbs[i]->isLastInLoop); - fprintf(of,"\ndefines bitVector :"); - bitVectDebugOn(ebbs[i]->defSet,of); - fprintf(of,"\nlocal defines bitVector :"); - bitVectDebugOn(ebbs[i]->ldefs,of); - fprintf(of,"\npointers Set bitvector :"); - bitVectDebugOn(ebbs[i]->ptrsSet,of); - fprintf(of,"\n----------------------------------------------------------------\n"); - printiCChain(ebbs[i]->sch,of); + FILE *of; + int i; + + if (ext) + { + /* create the file name */ + strcpy (buffer, srcFileName); + strcat (buffer, ext); + + if (!(of = fopen (buffer, "a+"))) + { + werror (E_FILE_OPEN_ERR, buffer); + exit (1); + } + } + else + of = stdout; + + for (i = 0; i < count; i++) + { + fprintf (of, "\n----------------------------------------------------------------\n"); + fprintf (of, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n", + ebbs[i]->entryLabel->name, + ebbs[i]->depth, + ebbs[i]->noPath, + ebbs[i]->isLastInLoop); + fprintf (of, "\ndefines bitVector :"); + bitVectDebugOn (ebbs[i]->defSet, of); + fprintf (of, "\nlocal defines bitVector :"); + bitVectDebugOn (ebbs[i]->ldefs, of); + fprintf (of, "\npointers Set bitvector :"); + bitVectDebugOn (ebbs[i]->ptrsSet, of); + fprintf (of, "\n----------------------------------------------------------------\n"); + printiCChain (ebbs[i]->sch, of); } - fclose(of); + fclose (of); } /*-----------------------------------------------------------------*/ /* iCode2eBBlock - converts a sequnce till label to a ebb */ /*-----------------------------------------------------------------*/ -eBBlock *iCode2eBBlock (iCode *ic) +eBBlock * +iCode2eBBlock (iCode * ic) { - iCode *loop ; - eBBlock *ebb = neweBBlock(); /* a llocate an entry */ - - /* put the first one unconditionally */ - ebb->sch = ic ; - - /* if this is a label then */ - if (ic->op == LABEL) - ebb->entryLabel = ic->argLabel.label ; - else { - sprintf(buffer,"_eBBlock%d",eBBNum++); - ebb->entryLabel = newSymbol(buffer,1); - ebb->entryLabel->key = labelKey++; + iCode *loop; + eBBlock *ebb = neweBBlock (); /* a llocate an entry */ + + /* put the first one unconditionally */ + ebb->sch = ic; + + /* if this is a label then */ + if (ic->op == LABEL) + ebb->entryLabel = ic->argLabel.label; + else + { + sprintf (buffer, "_eBBlock%d", eBBNum++); + ebb->entryLabel = newSymbol (buffer, 1); + ebb->entryLabel->key = labelKey++; } - if (ic && - ( ic->op == GOTO || - ic->op == JUMPTABLE || - ic->op == IFX )) { - ebb->ech = ebb->sch; - return ebb; + if (ic && + (ic->op == GOTO || + ic->op == JUMPTABLE || + ic->op == IFX)) + { + ebb->ech = ebb->sch; + return ebb; } - if ((ic->next && ic->next->op == LABEL) || - !ic->next ) { - ebb->ech = ebb->sch ; - return ebb ; + if ((ic->next && ic->next->op == LABEL) || + !ic->next) + { + ebb->ech = ebb->sch; + return ebb; } - /* loop thru till we find one with a label */ - for ( loop = ic->next ; loop ; loop = loop->next ) { - - /* if this is the last one */ - if (!loop->next) - break; - /* if this is a function call */ - if (loop->op == CALL || loop->op == PCALL) { - ebb->hasFcall = 1; - if (currFunc) - currFunc->hasFcall = 1; - } - - /* if the next one is a label */ - /* if this is a goto or ifx */ - if (loop->next->op == LABEL || - loop->op == GOTO || - loop->op == JUMPTABLE || - loop->op == IFX ) - break ; + /* loop thru till we find one with a label */ + for (loop = ic->next; loop; loop = loop->next) + { + + /* if this is the last one */ + if (!loop->next) + break; + /* if this is a function call */ + if (loop->op == CALL || loop->op == PCALL) + { + ebb->hasFcall = 1; + if (currFunc) + currFunc->hasFcall = 1; + } + + /* if the next one is a label */ + /* if this is a goto or ifx */ + if (loop->next->op == LABEL || + loop->op == GOTO || + loop->op == JUMPTABLE || + loop->op == IFX) + break; } - /* mark the end of the chain */ - ebb->ech = loop ; + /* mark the end of the chain */ + ebb->ech = loop; - return ebb; + return ebb; } /*-----------------------------------------------------------------*/ /* eBBWithEntryLabel - finds the basic block with the entry label */ /*-----------------------------------------------------------------*/ -eBBlock *eBBWithEntryLabel ( eBBlock **ebbs , symbol *eLabel, int count) +eBBlock * +eBBWithEntryLabel (eBBlock ** ebbs, symbol * eLabel, int count) { - int i; + int i; - for ( i = 0 ; i < count ; i++ ) { - if (isSymbolEqual(ebbs[i]->entryLabel,eLabel)) - return ebbs[i] ; + for (i = 0; i < count; i++) + { + if (isSymbolEqual (ebbs[i]->entryLabel, eLabel)) + return ebbs[i]; } - return NULL ; + return NULL; } /*-----------------------------------------------------------------*/ /* ifFromIs - will return 1 if the from block matches this */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(ifFromIs) +DEFSETFUNC (ifFromIs) { - edge *ep = item; - V_ARG(eBBlock *,this); + edge *ep = item; + V_ARG (eBBlock *, this); - if (ep->from == this) - return 1; + if (ep->from == this) + return 1; - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* edgesTo - returns a set of edges with to == supplied value */ /*-----------------------------------------------------------------*/ -set *edgesTo ( eBBlock *to ) +set * +edgesTo (eBBlock * to) { - set *result = NULL ; - edge *loop ; + set *result = NULL; + edge *loop; - for (loop = setFirstItem(graphEdges) ; loop ; loop = setNextItem(graphEdges)) - if (loop->to == to && !loop->from->noPath) - addSet(&result,loop->from); + for (loop = setFirstItem (graphEdges); loop; loop = setNextItem (graphEdges)) + if (loop->to == to && !loop->from->noPath) + addSet (&result, loop->from); - return result ; + return result; } /*-----------------------------------------------------------------*/ /* addiCodeToeBBlock - will add an iCode to the end of a block */ /*-----------------------------------------------------------------*/ -void addiCodeToeBBlock ( eBBlock *ebp, iCode *ic , iCode *ip) +void +addiCodeToeBBlock (eBBlock * ebp, iCode * ic, iCode * ip) { - ic->prev = ic->next = NULL; - /* if the insert point is given */ - if (ip) { - ic->lineno = ip->lineno; - ic->prev = ip->prev; - ip->prev = ic; - ic->next = ip; - if (!ic->prev) - ebp->sch = ic; - else - ic->prev->next = ic; - return; + ic->prev = ic->next = NULL; + /* if the insert point is given */ + if (ip) + { + ic->lineno = ip->lineno; + ic->prev = ip->prev; + ip->prev = ic; + ic->next = ip; + if (!ic->prev) + ebp->sch = ic; + else + ic->prev->next = ic; + return; } - /* if the block has no instructions */ - if (ebp->ech == NULL ) { - ebp->sch = ebp->ech = ic; - ic->next = NULL; - return ; + /* if the block has no instructions */ + if (ebp->ech == NULL) + { + ebp->sch = ebp->ech = ic; + ic->next = NULL; + return; } - /* if the last instruction is a goto */ - /* we add it just before the goto */ - if ( ebp->ech->op == GOTO || ebp->ech->op == JUMPTABLE + /* if the last instruction is a goto */ + /* we add it just before the goto */ + if (ebp->ech->op == GOTO || ebp->ech->op == JUMPTABLE || ebp->ech->op == RETURN) { - ic->lineno = ebp->ech->lineno; - ic->prev = ebp->ech->prev; - ebp->ech->prev = ic; - ic->next = ebp->ech; - if (!ic->prev) /* was the last only on in the block */ - ebp->sch = ic; - else - ic->prev->next = ic; - return; + ic->lineno = ebp->ech->lineno; + ic->prev = ebp->ech->prev; + ebp->ech->prev = ic; + ic->next = ebp->ech; + if (!ic->prev) /* was the last only on in the block */ + ebp->sch = ic; + else + ic->prev->next = ic; + return; } - /* if the last one was a ifx statement we check to see */ - /* if the condition was defined in the previous instruction */ - /* if this is true then we put it before the condition else */ - /* we put it before if, this is to reduce register pressure,*/ - /* we don't have to hold condition too long in a register */ - if ( ebp->ech->op == IFX ) { - iCode *ipoint ; + /* if the last one was a ifx statement we check to see */ + /* if the condition was defined in the previous instruction */ + /* if this is true then we put it before the condition else */ + /* we put it before if, this is to reduce register pressure, */ + /* we don't have to hold condition too long in a register */ + if (ebp->ech->op == IFX) + { + iCode *ipoint; /* if ( !ebp->ech->prev ) */ /* ipoint = ebp->ech ; */ @@ -337,231 +367,249 @@ void addiCodeToeBBlock ( eBBlock *ebp, iCode *ic , iCode *ip) /* ipoint = ebp->ech->prev; */ /* else */ /* ipoint = ebp->ech ; */ - ipoint = ebp->ech ; - ic->lineno = ipoint->lineno; - ic->prev = ipoint->prev; - ipoint->prev = ic; - ic->next = ipoint; - if (!ic->prev) - ebp->sch = ic; - else - ic->prev->next = ic; - return; + ipoint = ebp->ech; + ic->lineno = ipoint->lineno; + ic->prev = ipoint->prev; + ipoint->prev = ic; + ic->next = ipoint; + if (!ic->prev) + ebp->sch = ic; + else + ic->prev->next = ic; + return; } - /* will add it to the very end */ - ip = ebp->ech; - ip->next = ic; - ic->prev = ip; - ic->next = NULL; - ebp->ech = ic; + /* will add it to the very end */ + ip = ebp->ech; + ip->next = ic; + ic->prev = ip; + ic->next = NULL; + ebp->ech = ic; - return ; + return; } /*-----------------------------------------------------------------*/ /* remiCodeFromeBBlock - remove an iCode from BBlock */ /*-----------------------------------------------------------------*/ -void remiCodeFromeBBlock (eBBlock *ebb, iCode *ic) +void +remiCodeFromeBBlock (eBBlock * ebb, iCode * ic) { - if (ic->prev) - ic->prev->next = ic->next ; - else - ebb->sch = ic->next ; - - if (ic->next) - ic->next->prev = ic->prev; - else - ebb->ech = ic->prev; + if (ic->prev) + ic->prev->next = ic->next; + else + ebb->sch = ic->next; + + if (ic->next) + ic->next->prev = ic->prev; + else + ebb->ech = ic->prev; } /*-----------------------------------------------------------------*/ /* iCodeBreakDown : breakDown iCode chain to blocks */ /*-----------------------------------------------------------------*/ -eBBlock **iCodeBreakDown (iCode *ic, int *count) +eBBlock ** +iCodeBreakDown (iCode * ic, int *count) { - eBBlock **ebbs = NULL ; - iCode *loop = ic; - - *count = 0 ; - - /* allocate for the first entry */ - - ebbs = Safe_calloc(1,sizeof(eBBlock **)); - - while (loop) { - - /* convert 2 block */ - eBBlock *ebb = iCode2eBBlock(loop); - loop = ebb->ech->next ; - - ebb->ech->next = NULL ; /* mark the end of this chain */ - if (loop) - loop->prev = NULL ; - ebb->bbnum = *count ; /* save this block number */ - /* put it in the array */ - ebbs[(*count)++] = ebb ; - - /* allocate for the next one. Remember to clear the new */ - /* pointer at the end, that was created by realloc. */ - - ebbs = Safe_realloc(ebbs,(*count + 1)*sizeof(eBBlock **)) ; - - ebbs[*count] = 0; - - /* if this one ends in a goto or a conditional */ - /* branch then check if the block it is going */ - /* to already exists, if yes then this could */ - /* be a loop, add a preheader to the block it */ - /* goes to if it does not already have one */ - if (ebbs[(*count) - 1]->ech && - (ebbs[(*count) - 1]->ech->op == GOTO || - ebbs[(*count) - 1]->ech->op == IFX )) { - - symbol *label ; - eBBlock *destBlock; - - if (ebbs[(*count) - 1]->ech->op == GOTO) - label = IC_LABEL(ebbs[(*count)-1]->ech); - else - if (!(label = IC_TRUE(ebbs[(*count)-1]->ech))) - label = IC_FALSE(ebbs[(*count)-1]->ech); - - if ((destBlock = eBBWithEntryLabel(ebbs,label,(*count))) && - destBlock->preHeader == NULL && - otherPathsPresent(ebbs,destBlock) ) { - - symbol *preHeaderLabel = newiTempPreheaderLabel(); - int i,j ; - eBBlock *pBlock ; - - /* go thru all block replacing the entryLabel with new label */ - /* till we reach the block , then we insert a new ebblock */ - for ( i = 0 ; i < (*count) ; i++ ) { - if ( ebbs[i] == destBlock ) - break ; - replaceLabel(ebbs[i],label,preHeaderLabel); - } - - (*count)++ ; - - /* if we have stopped at the block , allocate for an extra one */ + eBBlock **ebbs = NULL; + iCode *loop = ic; - ebbs = Safe_realloc(ebbs,(*count + 1)*sizeof(eBBlock **)) ; + *count = 0; - ebbs[*count] = 0; + /* allocate for the first entry */ - /* then move the block down one count */ - pBlock = ebbs[j = i]; - for ( i += 1; i < (*count) ; i++ ) { - eBBlock *xBlock; + ebbs = Safe_calloc (1, sizeof (eBBlock **)); - xBlock = ebbs[i]; - ebbs[i] = pBlock; - ebbs[i]->bbnum = i; - pBlock = xBlock ; - } + while (loop) + { - destBlock->preHeader = ebbs[j] = neweBBlock(); - ebbs[j]->bbnum = j; - ebbs[j]->entryLabel = preHeaderLabel ; - ebbs[j]->sch = ebbs[j]->ech = newiCodeLabelGoto(LABEL,preHeaderLabel); - ebbs[j]->sch->lineno = destBlock->sch->lineno; - } - } + /* convert 2 block */ + eBBlock *ebb = iCode2eBBlock (loop); + loop = ebb->ech->next; + + ebb->ech->next = NULL; /* mark the end of this chain */ + if (loop) + loop->prev = NULL; + ebb->bbnum = *count; /* save this block number */ + /* put it in the array */ + ebbs[(*count)++] = ebb; + + /* allocate for the next one. Remember to clear the new */ + /* pointer at the end, that was created by realloc. */ + + ebbs = Safe_realloc (ebbs, (*count + 1) * sizeof (eBBlock **)); + + ebbs[*count] = 0; + + /* if this one ends in a goto or a conditional */ + /* branch then check if the block it is going */ + /* to already exists, if yes then this could */ + /* be a loop, add a preheader to the block it */ + /* goes to if it does not already have one */ + if (ebbs[(*count) - 1]->ech && + (ebbs[(*count) - 1]->ech->op == GOTO || + ebbs[(*count) - 1]->ech->op == IFX)) + { + + symbol *label; + eBBlock *destBlock; + + if (ebbs[(*count) - 1]->ech->op == GOTO) + label = IC_LABEL (ebbs[(*count) - 1]->ech); + else if (!(label = IC_TRUE (ebbs[(*count) - 1]->ech))) + label = IC_FALSE (ebbs[(*count) - 1]->ech); + + if ((destBlock = eBBWithEntryLabel (ebbs, label, (*count))) && + destBlock->preHeader == NULL && + otherPathsPresent (ebbs, destBlock)) + { + + symbol *preHeaderLabel = newiTempPreheaderLabel (); + int i, j; + eBBlock *pBlock; + + /* go thru all block replacing the entryLabel with new label */ + /* till we reach the block , then we insert a new ebblock */ + for (i = 0; i < (*count); i++) + { + if (ebbs[i] == destBlock) + break; + replaceLabel (ebbs[i], label, preHeaderLabel); + } + + (*count)++; + + /* if we have stopped at the block , allocate for an extra one */ + + ebbs = Safe_realloc (ebbs, (*count + 1) * sizeof (eBBlock **)); + + ebbs[*count] = 0; + + /* then move the block down one count */ + pBlock = ebbs[j = i]; + for (i += 1; i < (*count); i++) + { + eBBlock *xBlock; + + xBlock = ebbs[i]; + ebbs[i] = pBlock; + ebbs[i]->bbnum = i; + pBlock = xBlock; + } + + destBlock->preHeader = ebbs[j] = neweBBlock (); + ebbs[j]->bbnum = j; + ebbs[j]->entryLabel = preHeaderLabel; + ebbs[j]->sch = ebbs[j]->ech = newiCodeLabelGoto (LABEL, preHeaderLabel); + ebbs[j]->sch->lineno = destBlock->sch->lineno; + } + } } - /* mark the end */ - ebbs[*count] = NULL ; + /* mark the end */ + ebbs[*count] = NULL; - return ebbs ; + return ebbs; } /*-----------------------------------------------------------------*/ /* replaceSymBySym : - replace operand by operand in blocks */ /* replaces only left & right in blocks */ /*-----------------------------------------------------------------*/ - void replaceSymBySym (set *sset, operand *src, operand *dest) +void +replaceSymBySym (set * sset, operand * src, operand * dest) { - set *loop ; - eBBlock *rBlock ; - - /* for all blocks in the set do */ - for ( loop = sset ; loop ; loop = loop->next) { - iCode *ic ; - - rBlock = loop->item ; - /* for all instructions in this block do */ - for ( ic = rBlock->sch ; ic ; ic = ic->next ) { - - /* if we find usage */ - if (ic->op == IFX && isOperandEqual(src,IC_COND(ic))) { - bitVectUnSetBit (OP_USES(IC_COND(ic)),ic->key); - IC_COND(ic) = operandFromOperand(dest); - OP_USES(dest) = bitVectSetBit (OP_USES(dest),ic->key); - continue ; - } - - if (isOperandEqual(IC_RIGHT(ic),src)) { - bitVectUnSetBit (OP_USES(IC_RIGHT(ic)),ic->key); - IC_RIGHT(ic) = operandFromOperand(dest); - IC_RIGHT(ic)->isaddr = 0; - OP_USES(dest) = bitVectSetBit (OP_USES(dest),ic->key); - } - - if (isOperandEqual(IC_LEFT(ic),src)) { - bitVectUnSetBit (OP_USES(IC_LEFT(ic)),ic->key); - if (POINTER_GET(ic) && IS_ITEMP(dest)) { - IC_LEFT(ic) = operandFromOperand(dest); - IC_LEFT(ic)->isaddr = 1; - } else { - IC_LEFT(ic) = operandFromOperand(dest); - IC_LEFT(ic)->isaddr = 0; - } - OP_USES(dest) = bitVectSetBit (OP_USES(dest),ic->key); - } - - /* special case for pointer sets */ - if (POINTER_SET(ic) && - isOperandEqual(IC_RESULT(ic),src)) { - bitVectUnSetBit (OP_USES(IC_RESULT(ic)),ic->key); - IC_RESULT(ic) = operandFromOperand(dest); - IC_RESULT(ic)->isaddr = 1; - OP_USES(dest) = bitVectSetBit(OP_USES(dest),ic->key); - } - } + set *loop; + eBBlock *rBlock; + + /* for all blocks in the set do */ + for (loop = sset; loop; loop = loop->next) + { + iCode *ic; + + rBlock = loop->item; + /* for all instructions in this block do */ + for (ic = rBlock->sch; ic; ic = ic->next) + { + + /* if we find usage */ + if (ic->op == IFX && isOperandEqual (src, IC_COND (ic))) + { + bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key); + IC_COND (ic) = operandFromOperand (dest); + OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key); + continue; + } + + if (isOperandEqual (IC_RIGHT (ic), src)) + { + bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key); + IC_RIGHT (ic) = operandFromOperand (dest); + IC_RIGHT (ic)->isaddr = 0; + OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key); + } + + if (isOperandEqual (IC_LEFT (ic), src)) + { + bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key); + if (POINTER_GET (ic) && IS_ITEMP (dest)) + { + IC_LEFT (ic) = operandFromOperand (dest); + IC_LEFT (ic)->isaddr = 1; + } + else + { + IC_LEFT (ic) = operandFromOperand (dest); + IC_LEFT (ic)->isaddr = 0; + } + OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key); + } + + /* special case for pointer sets */ + if (POINTER_SET (ic) && + isOperandEqual (IC_RESULT (ic), src)) + { + bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key); + IC_RESULT (ic) = operandFromOperand (dest); + IC_RESULT (ic)->isaddr = 1; + OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key); + } + } } } /*-----------------------------------------------------------------*/ /* replaceLabel - replace reference to one label by another */ /*-----------------------------------------------------------------*/ - void replaceLabel(eBBlock *ebp, symbol *fromLbl, symbol *toLbl) +void +replaceLabel (eBBlock * ebp, symbol * fromLbl, symbol * toLbl) { - iCode *ic; + iCode *ic; - if (!ebp) - return ; - - for (ic = ebp->sch ; ic ; ic = ic->next ) { - switch (ic->op) { - - case GOTO : - if (isSymbolEqual(IC_LABEL(ic),fromLbl)) - IC_LABEL(ic) = toLbl; - break; + if (!ebp) + return; - case IFX: - if (IC_TRUE(ic) && isSymbolEqual(IC_TRUE(ic),fromLbl)) - IC_TRUE(ic) = toLbl ; - else - if (isSymbolEqual(IC_FALSE(ic),fromLbl)) - IC_FALSE(ic) = toLbl; - break; - } + for (ic = ebp->sch; ic; ic = ic->next) + { + switch (ic->op) + { + + case GOTO: + if (isSymbolEqual (IC_LABEL (ic), fromLbl)) + IC_LABEL (ic) = toLbl; + break; + + case IFX: + if (IC_TRUE (ic) && isSymbolEqual (IC_TRUE (ic), fromLbl)) + IC_TRUE (ic) = toLbl; + else if (isSymbolEqual (IC_FALSE (ic), fromLbl)) + IC_FALSE (ic) = toLbl; + break; + } } - return; + return; } @@ -569,71 +617,78 @@ eBBlock **iCodeBreakDown (iCode *ic, int *count) /*-----------------------------------------------------------------*/ /* iCodeFromeBBlock - convert basic block to iCode chain */ /*-----------------------------------------------------------------*/ -iCode *iCodeFromeBBlock ( eBBlock **ebbs, int count) +iCode * +iCodeFromeBBlock (eBBlock ** ebbs, int count) { - int i = 1 ; - iCode *ric = ebbs[0]->sch ; - iCode *lic = ebbs[0]->ech ; - - for ( ; i < count; i++ ) { - if ( ebbs[i]->sch == NULL) - continue ; - - if ( ebbs[i]->noPath && - (ebbs[i]->entryLabel != entryLabel && - ebbs[i]->entryLabel != returnLabel )) { - werror(W_CODE_UNREACH,ebbs[i]->sch->filename,ebbs[i]->sch->lineno); - continue ; - } - - lic->next = ebbs[i]->sch ; - lic->next->prev = lic; - lic = ebbs[i]->ech ; + int i = 1; + iCode *ric = ebbs[0]->sch; + iCode *lic = ebbs[0]->ech; + + for (; i < count; i++) + { + if (ebbs[i]->sch == NULL) + continue; + + if (ebbs[i]->noPath && + (ebbs[i]->entryLabel != entryLabel && + ebbs[i]->entryLabel != returnLabel)) + { + werror (W_CODE_UNREACH, ebbs[i]->sch->filename, ebbs[i]->sch->lineno); + continue; + } + + lic->next = ebbs[i]->sch; + lic->next->prev = lic; + lic = ebbs[i]->ech; } - return ric; + return ric; } /*-----------------------------------------------------------------*/ /* otherPathsPresent - determines if there is a path from _entry */ /* to this block in a half constructed set of blocks */ /*-----------------------------------------------------------------*/ -int otherPathsPresent (eBBlock **ebbs, eBBlock *this) +int +otherPathsPresent (eBBlock ** ebbs, eBBlock * this) { - int i ; - - /* for all blocks preceding this block */ - for ( i = 0 ; i < this->bbnum ; i++ ) { - iCode *ic ; - - /* if there is a reference to the entry label of this block */ - for ( ic = ebbs[i]->sch ; ic ; ic = ic->next ) { - switch (ic->op) { - case GOTO : - if (IC_LABEL(ic)->key == this->entryLabel->key) - return 1; - break; - - case IFX : - if (IC_TRUE(ic)) { - if (IC_TRUE(ic)->key == this->entryLabel->key) - return 1; - } else - if (IC_FALSE(ic)->key == this->entryLabel->key) - return 1 ; - break; - } - } + int i; + + /* for all blocks preceding this block */ + for (i = 0; i < this->bbnum; i++) + { + iCode *ic; + + /* if there is a reference to the entry label of this block */ + for (ic = ebbs[i]->sch; ic; ic = ic->next) + { + switch (ic->op) + { + case GOTO: + if (IC_LABEL (ic)->key == this->entryLabel->key) + return 1; + break; + + case IFX: + if (IC_TRUE (ic)) + { + if (IC_TRUE (ic)->key == this->entryLabel->key) + return 1; + } + else if (IC_FALSE (ic)->key == this->entryLabel->key) + return 1; + break; + } + } } - /* comes here means we have not found it yet */ - /* in this case check if the previous block */ - /* ends in a goto if it does then we have no */ - /* path else we have a path */ - if (this->bbnum && ebbs[this->bbnum - 1]->ech && - ebbs[this->bbnum - 1]->ech->op == GOTO ) - return 0; - else - return 1; + /* comes here means we have not found it yet */ + /* in this case check if the previous block */ + /* ends in a goto if it does then we have no */ + /* path else we have a path */ + if (this->bbnum && ebbs[this->bbnum - 1]->ech && + ebbs[this->bbnum - 1]->ech->op == GOTO) + return 0; + else + return 1; } - diff --git a/src/SDCCBBlock.h b/src/SDCCBBlock.h index f4bf9a65..d1dc54c8 100644 --- a/src/SDCCBBlock.h +++ b/src/SDCCBBlock.h @@ -27,70 +27,74 @@ #define SDCCBBLOCK_H 1 /* definition of a basic block */ -typedef struct eBBlock { - int dfnum ; /* depth first number */ - int bbnum ; /* index into array of numbers */ - int depth ; /* loop depth of this block */ - int fSeq ; /* sequence number of first iCode */ - int lSeq ; /* sequence number of the last iCode */ - unsigned int visited:1; /* visitied flag */ - unsigned int hasFcall:1;/* has a function call */ - unsigned int noPath :1; /* there is no path from _entry to this block */ - unsigned int isLastInLoop:1; /* is the last block in a loop */ - symbol *entryLabel ; /* entry label */ - - iCode *sch ; /* pointer to start of code chain */ - iCode *ech ; /* pointer to last of code chain */ - - struct eBBlock *preHeader ; /* preheader if this is a loop entry */ - struct region *partOfLoop; /* pointer to the loop region this block is part of */ +typedef struct eBBlock + { + int dfnum; /* depth first number */ + int bbnum; /* index into array of numbers */ + int depth; /* loop depth of this block */ + int fSeq; /* sequence number of first iCode */ + int lSeq; /* sequence number of the last iCode */ + unsigned int visited:1; /* visitied flag */ + unsigned int hasFcall:1; /* has a function call */ + unsigned int noPath:1; /* there is no path from _entry to this block */ + unsigned int isLastInLoop:1; /* is the last block in a loop */ + symbol *entryLabel; /* entry label */ + + iCode *sch; /* pointer to start of code chain */ + iCode *ech; /* pointer to last of code chain */ + + struct eBBlock *preHeader; /* preheader if this is a loop entry */ + struct region *partOfLoop; /* pointer to the loop region this block is part of */ /* control flow analysis */ - set *succList ; /* list eBBlocks which are successors */ - bitVect *succVect ; /* bitVector of successors */ - set *predList ; /* predecessors of this basic block */ - bitVect *domVect ; /* list of nodes this is dominated by */ + set *succList; /* list eBBlocks which are successors */ + bitVect *succVect; /* bitVector of successors */ + set *predList; /* predecessors of this basic block */ + bitVect *domVect; /* list of nodes this is dominated by */ /* data flow analysis */ - set *inExprs ; /* in coming common expressions */ - set *outExprs ; /* out going common expressions */ - bitVect *inDefs; /* in coming defintions */ - bitVect *outDefs; /* out going defintions */ - bitVect *defSet; /* symbols defined in block */ - bitVect *ldefs ; /* local definitions only */ - bitVect *usesDefs;/* which definitions are used in this block */ - bitVect *ptrsSet; /* pointers assigned values in the block */ - bitVect *inPtrsSet;/* in coming pointers assigned values */ - bitVect *ndompset; /* pointers set by non-dominating basic blocks */ - set *addrOf ; /* symbols for which addres has been taken in the block */ - bitVect *linds ; /* if loop exit this contains defNumbers - for the inductions */ -} eBBlock ; - -typedef struct edge { - - eBBlock *from ; /* from basic block */ - eBBlock *to ; /* to Basic Block */ -} edge ; - -extern int eBBNum ; -extern set *graphEdges ; - - -DEFSETFUNC(printEntryLabel) ; -eBBlock *neweBBlock () ; -edge *newEdge (eBBlock *, eBBlock *) ; -eBBlock *eBBWithEntryLabel ( eBBlock **, symbol *, int); -DEFSETFUNC(ifFromIs) ; -set *edgesTo ( eBBlock *); -void remiCodeFromeBBlock (eBBlock *, iCode *); -void addiCodeToeBBlock ( eBBlock *,iCode *,iCode *); -eBBlock **iCodeBreakDown (iCode *, int *); -void replaceSymBySym (set *, operand *, operand *); -iCode *iCodeFromeBBlock ( eBBlock **,int); -int otherPathsPresent (eBBlock **,eBBlock *); -void replaceLabel(eBBlock *,symbol *,symbol *); -void dumpEbbsToFileExt (char *,eBBlock **,int); + set *inExprs; /* in coming common expressions */ + set *outExprs; /* out going common expressions */ + bitVect *inDefs; /* in coming defintions */ + bitVect *outDefs; /* out going defintions */ + bitVect *defSet; /* symbols defined in block */ + bitVect *ldefs; /* local definitions only */ + bitVect *usesDefs; /* which definitions are used in this block */ + bitVect *ptrsSet; /* pointers assigned values in the block */ + bitVect *inPtrsSet; /* in coming pointers assigned values */ + bitVect *ndompset; /* pointers set by non-dominating basic blocks */ + set *addrOf; /* symbols for which addres has been taken in the block */ + bitVect *linds; /* if loop exit this contains defNumbers + for the inductions */ + } +eBBlock; + +typedef struct edge + { + + eBBlock *from; /* from basic block */ + eBBlock *to; /* to Basic Block */ + } +edge; + +extern int eBBNum; +extern set *graphEdges; + + +DEFSETFUNC (printEntryLabel); +eBBlock *neweBBlock (); +edge *newEdge (eBBlock *, eBBlock *); +eBBlock *eBBWithEntryLabel (eBBlock **, symbol *, int); +DEFSETFUNC (ifFromIs); +set *edgesTo (eBBlock *); +void remiCodeFromeBBlock (eBBlock *, iCode *); +void addiCodeToeBBlock (eBBlock *, iCode *, iCode *); +eBBlock **iCodeBreakDown (iCode *, int *); +void replaceSymBySym (set *, operand *, operand *); +iCode *iCodeFromeBBlock (eBBlock **, int); +int otherPathsPresent (eBBlock **, eBBlock *); +void replaceLabel (eBBlock *, symbol *, symbol *); +void dumpEbbsToFileExt (char *, eBBlock **, int); #if defined(_MSC_VER) @@ -98,8 +102,8 @@ void dumpEbbsToFileExt (char *,eBBlock **,int); /* dumpLiveRanges - dump liverange information into a file */ /*-----------------------------------------------------------------*/ -void dumpLiveRanges (char *ext,hTab *liveRanges) ; +void dumpLiveRanges (char *ext, hTab * liveRanges); -#endif // _MSC_VER +#endif // _MSC_VER #endif diff --git a/src/SDCCast.c b/src/SDCCast.c index d9f4eed7..030946d2 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -25,11 +25,11 @@ #include "common.h" #include "newalloc.h" -int currLineno = 0; -set *astList = NULL ; +int currLineno = 0; +set *astList = NULL; set *operKeyReset = NULL; ast *staticAutos = NULL; -int labelKey = 1 ; +int labelKey = 1; #define LRVAL(x) x->left->rvalue #define RRVAL(x) x->right->rvalue @@ -46,20 +46,22 @@ int labelKey = 1 ; #define ALLOCATE 1 #define DEALLOCATE 2 -char buffer[1024]; +char buffer[1024]; int noLineno = 0; -int noAlloc = 0 ; -symbol *currFunc ; -ast *createIval (ast *, sym_link *, initList *, ast *); +int noAlloc = 0; +symbol *currFunc; +ast *createIval (ast *, sym_link *, initList *, ast *); ast *createIvalCharPtr (ast *, sym_link *, ast *); -ast *optimizeRRCRLC ( ast * ); -ast *optimizeGetHbit(ast *); -ast *backPatchLabels (ast *,symbol *,symbol *); -int inInitMode = 0; -FILE *codeOutFile ; -int ptt(ast *tree) { - printTypeChain(tree->ftype,stdout); - return 0; +ast *optimizeRRCRLC (ast *); +ast *optimizeGetHbit (ast *); +ast *backPatchLabels (ast *, symbol *, symbol *); +int inInitMode = 0; +FILE *codeOutFile; +int +ptt (ast * tree) +{ + printTypeChain (tree->ftype, stdout); + return 0; } @@ -67,157 +69,170 @@ int ptt(ast *tree) { /* newAst - creates a fresh node for an expression tree */ /*-----------------------------------------------------------------*/ #if 0 -ast *newAst (int type, void *op ) +ast * +newAst (int type, void *op) { - ast *ex ; - static int oldLineno = 0 ; - - Safe_calloc(1,ex,sizeof(ast)); - - ex->type = type ; - ex->lineno = (noLineno ? oldLineno : yylineno); - ex->filename = currFname ; - ex->level = NestLevel ; - ex->block = currBlockno ; - ex->initMode = inInitMode; - - /* depending on the type */ - switch (type) { - case EX_VALUE : - ex->opval.val = (value *) op; - break ; - case EX_OP : - ex->opval.op = (long) op ; - break ; - case EX_LINK : - ex->opval.lnk = (sym_link *) op; - break ; - case EX_STMNT : - ex->opval.stmnt= (unsigned) op; - } - - return ex; + ast *ex; + static int oldLineno = 0; + + Safe_calloc (1, ex, sizeof (ast)); + + ex->type = type; + ex->lineno = (noLineno ? oldLineno : yylineno); + ex->filename = currFname; + ex->level = NestLevel; + ex->block = currBlockno; + ex->initMode = inInitMode; + + /* depending on the type */ + switch (type) + { + case EX_VALUE: + ex->opval.val = (value *) op; + break; + case EX_OP: + ex->opval.op = (long) op; + break; + case EX_LINK: + ex->opval.lnk = (sym_link *) op; + break; + case EX_STMNT: + ex->opval.stmnt = (unsigned) op; + } + + return ex; } #endif -static ast* newAst_(unsigned type) +static ast * +newAst_ (unsigned type) { - ast *ex ; - static int oldLineno = 0 ; - - ex = Safe_calloc(1,sizeof(ast)); - - ex->type = type ; - ex->lineno = (noLineno ? oldLineno : yylineno); - ex->filename = currFname ; - ex->level = NestLevel ; - ex->block = currBlockno ; - ex->initMode = inInitMode; - return ex; + ast *ex; + static int oldLineno = 0; + + ex = Safe_calloc (1, sizeof (ast)); + + ex->type = type; + ex->lineno = (noLineno ? oldLineno : yylineno); + ex->filename = currFname; + ex->level = NestLevel; + ex->block = currBlockno; + ex->initMode = inInitMode; + return ex; } -ast* newAst_VALUE(value*val) +ast * +newAst_VALUE (value * val) { - ast* ex = newAst_(EX_VALUE); - ex->opval.val = val; - return ex; + ast *ex = newAst_ (EX_VALUE); + ex->opval.val = val; + return ex; } -ast* newAst_OP(unsigned op) +ast * +newAst_OP (unsigned op) { - ast*ex = newAst_(EX_OP); - ex->opval.op = op; - return ex; + ast *ex = newAst_ (EX_OP); + ex->opval.op = op; + return ex; } -ast* newAst_LINK(sym_link*val) +ast * +newAst_LINK (sym_link * val) { - ast* ex = newAst_(EX_LINK); - ex->opval.lnk = val; - return ex; + ast *ex = newAst_ (EX_LINK); + ex->opval.lnk = val; + return ex; } -ast* newAst_STMNT(unsigned val) +ast * +newAst_STMNT (unsigned val) { - ast* ex = newAst_(EX_STMNT); - ex->opval.stmnt = val; - return ex; + ast *ex = newAst_ (EX_STMNT); + ex->opval.stmnt = val; + return ex; } /*-----------------------------------------------------------------*/ /* newNode - creates a new node */ /*-----------------------------------------------------------------*/ -ast *newNode ( long op, ast *left, ast *right ) +ast * +newNode (long op, ast * left, ast * right) { - ast *ex ; + ast *ex; - ex = newAst_OP(op) ; - ex->left = left ; - ex->right = right; + ex = newAst_OP (op); + ex->left = left; + ex->right = right; - return ex ; + return ex; } /*-----------------------------------------------------------------*/ /* newIfxNode - creates a new Ifx Node */ /*-----------------------------------------------------------------*/ -ast *newIfxNode (ast *condAst, symbol *trueLabel, symbol *falseLabel) +ast * +newIfxNode (ast * condAst, symbol * trueLabel, symbol * falseLabel) { - ast *ifxNode ; + ast *ifxNode; - /* if this is a literal then we already know the result */ - if (condAst->etype && IS_LITERAL(condAst->etype)) { + /* if this is a literal then we already know the result */ + if (condAst->etype && IS_LITERAL (condAst->etype)) + { - /* then depending on the expression value */ - if ( floatFromVal(condAst->opval.val) ) - ifxNode = newNode(GOTO, - newAst_VALUE(symbolVal(trueLabel)), - NULL); - else - ifxNode = newNode(GOTO, - newAst_VALUE(symbolVal(falseLabel)), - NULL); + /* then depending on the expression value */ + if (floatFromVal (condAst->opval.val)) + ifxNode = newNode (GOTO, + newAst_VALUE (symbolVal (trueLabel)), + NULL); + else + ifxNode = newNode (GOTO, + newAst_VALUE (symbolVal (falseLabel)), + NULL); } - else { - ifxNode = newNode(IFX,condAst,NULL); - ifxNode->trueLabel = trueLabel; - ifxNode->falseLabel= falseLabel; + else + { + ifxNode = newNode (IFX, condAst, NULL); + ifxNode->trueLabel = trueLabel; + ifxNode->falseLabel = falseLabel; } - return ifxNode ; + return ifxNode; } /*-----------------------------------------------------------------*/ /* copyAstValues - copies value portion of ast if needed */ /*-----------------------------------------------------------------*/ -void copyAstValues (ast *dest,ast *src) +void +copyAstValues (ast * dest, ast * src) { - switch (src->opval.op) { + switch (src->opval.op) + { case BLOCK: - dest->values.sym = copySymbolChain(src->values.sym); - break; + dest->values.sym = copySymbolChain (src->values.sym); + break; case SWITCH: - dest->values.switchVals.swVals = - copyValue(src->values.switchVals.swVals); - dest->values.switchVals.swDefault = - src->values.switchVals.swDefault ; - dest->values.switchVals.swNum = - src->values.switchVals.swNum ; - break ; + dest->values.switchVals.swVals = + copyValue (src->values.switchVals.swVals); + dest->values.switchVals.swDefault = + src->values.switchVals.swDefault; + dest->values.switchVals.swNum = + src->values.switchVals.swNum; + break; case INLINEASM: - dest->values.inlineasm = Safe_calloc(1,strlen(src->values.inlineasm)+1); - strcpy(dest->values.inlineasm,src->values.inlineasm); + dest->values.inlineasm = Safe_calloc (1, strlen (src->values.inlineasm) + 1); + strcpy (dest->values.inlineasm, src->values.inlineasm); case FOR: - AST_FOR(dest,trueLabel) = copySymbol(AST_FOR(src,trueLabel)); - AST_FOR(dest,continueLabel) = copySymbol(AST_FOR(src,continueLabel)); - AST_FOR(dest,falseLabel) = copySymbol(AST_FOR(src,falseLabel)); - AST_FOR(dest,condLabel) = copySymbol(AST_FOR(src,condLabel)); - AST_FOR(dest,initExpr) = copyAst (AST_FOR(src,initExpr)) ; - AST_FOR(dest,condExpr) = copyAst (AST_FOR(src,condExpr)) ; - AST_FOR(dest,loopExpr) = copyAst (AST_FOR(src,loopExpr)) ; + AST_FOR (dest, trueLabel) = copySymbol (AST_FOR (src, trueLabel)); + AST_FOR (dest, continueLabel) = copySymbol (AST_FOR (src, continueLabel)); + AST_FOR (dest, falseLabel) = copySymbol (AST_FOR (src, falseLabel)); + AST_FOR (dest, condLabel) = copySymbol (AST_FOR (src, condLabel)); + AST_FOR (dest, initExpr) = copyAst (AST_FOR (src, initExpr)); + AST_FOR (dest, condExpr) = copyAst (AST_FOR (src, condExpr)); + AST_FOR (dest, loopExpr) = copyAst (AST_FOR (src, loopExpr)); } } @@ -225,237 +240,259 @@ void copyAstValues (ast *dest,ast *src) /*-----------------------------------------------------------------*/ /* copyAst - makes a copy of a given astession */ /*-----------------------------------------------------------------*/ -ast *copyAst (ast *src) +ast * +copyAst (ast * src) { - ast *dest; + ast *dest; - if (!src) return NULL ; + if (!src) + return NULL; - dest = Safe_calloc(1,sizeof(ast)); + dest = Safe_calloc (1, sizeof (ast)); - dest->type = src->type ; - dest->lineno = src->lineno ; - dest->level = src->level ; - dest->funcName = src->funcName; - dest->argSym = src->argSym; + dest->type = src->type; + dest->lineno = src->lineno; + dest->level = src->level; + dest->funcName = src->funcName; + dest->argSym = src->argSym; - /* if this is a leaf */ - /* if value */ - if (src->type == EX_VALUE) { - dest->opval.val = copyValue(src->opval.val); - goto exit; + /* if this is a leaf */ + /* if value */ + if (src->type == EX_VALUE) + { + dest->opval.val = copyValue (src->opval.val); + goto exit; } - /* if link */ - if (src->type == EX_LINK) { - dest->opval.lnk = copyLinkChain(src->opval.lnk); - goto exit ; + /* if link */ + if (src->type == EX_LINK) + { + dest->opval.lnk = copyLinkChain (src->opval.lnk); + goto exit; } - dest->opval.op = src->opval.op ; + dest->opval.op = src->opval.op; - /* if this is a node that has special values */ - copyAstValues (dest,src); + /* if this is a node that has special values */ + copyAstValues (dest, src); - if ( src->ftype ) - dest->etype = getSpec(dest->ftype = copyLinkChain(src->ftype)) ; + if (src->ftype) + dest->etype = getSpec (dest->ftype = copyLinkChain (src->ftype)); - dest->trueLabel = copySymbol (src->trueLabel); - dest->falseLabel= copySymbol (src->falseLabel); - dest->left = copyAst(src->left); - dest->right= copyAst(src->right); - exit: - return dest ; + dest->trueLabel = copySymbol (src->trueLabel); + dest->falseLabel = copySymbol (src->falseLabel); + dest->left = copyAst (src->left); + dest->right = copyAst (src->right); +exit: + return dest; } /*-----------------------------------------------------------------*/ /* hasSEFcalls - returns TRUE if tree has a function call */ /*-----------------------------------------------------------------*/ -bool hasSEFcalls ( ast *tree) +bool +hasSEFcalls (ast * tree) { - if (!tree) - return FALSE ; - - if (tree->type == EX_OP && - ( tree->opval.op == CALL || - tree->opval.op == PCALL || - tree->opval.op == '=' || - tree->opval.op == INC_OP || - tree->opval.op == DEC_OP )) - return TRUE; - - return ( hasSEFcalls(tree->left) | - hasSEFcalls(tree->right)); + if (!tree) + return FALSE; + + if (tree->type == EX_OP && + (tree->opval.op == CALL || + tree->opval.op == PCALL || + tree->opval.op == '=' || + tree->opval.op == INC_OP || + tree->opval.op == DEC_OP)) + return TRUE; + + return (hasSEFcalls (tree->left) | + hasSEFcalls (tree->right)); } /*-----------------------------------------------------------------*/ /* isAstEqual - compares two asts & returns 1 if they are equal */ /*-----------------------------------------------------------------*/ -int isAstEqual (ast *t1, ast *t2) +int +isAstEqual (ast * t1, ast * t2) { - if (!t1 && !t2) - return 1; + if (!t1 && !t2) + return 1; - if (!t1 || !t2) - return 0; + if (!t1 || !t2) + return 0; - /* match type */ - if (t1->type != t2->type) - return 0; + /* match type */ + if (t1->type != t2->type) + return 0; - switch (t1->type) { + switch (t1->type) + { case EX_OP: - if (t1->opval.op != t2->opval.op) - return 0; - return ( isAstEqual(t1->left,t2->left) && - isAstEqual(t1->right,t2->right)); - break; + if (t1->opval.op != t2->opval.op) + return 0; + return (isAstEqual (t1->left, t2->left) && + isAstEqual (t1->right, t2->right)); + break; case EX_VALUE: - if (t1->opval.val->sym) { - if (!t2->opval.val->sym) - return 0; - else - return isSymbolEqual(t1->opval.val->sym, - t2->opval.val->sym); - } - else { - if (t2->opval.val->sym) - return 0; + if (t1->opval.val->sym) + { + if (!t2->opval.val->sym) + return 0; + else + return isSymbolEqual (t1->opval.val->sym, + t2->opval.val->sym); + } else - return (floatFromVal(t1->opval.val) == - floatFromVal(t2->opval.val)); - } - break; + { + if (t2->opval.val->sym) + return 0; + else + return (floatFromVal (t1->opval.val) == + floatFromVal (t2->opval.val)); + } + break; - /* only compare these two types */ - default : - return 0; + /* only compare these two types */ + default: + return 0; } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* resolveSymbols - resolve symbols from the symbol table */ /*-----------------------------------------------------------------*/ -ast *resolveSymbols (ast *tree) +ast * +resolveSymbols (ast * tree) { - /* walk the entire tree and check for values */ - /* with symbols if we find one then replace */ - /* symbol with that from the symbol table */ - - if ( tree == NULL ) - return tree ; - - /* print the line */ - /* if not block & function */ - if ( tree->type == EX_OP && - ( tree->opval.op != FUNCTION && - tree->opval.op != BLOCK && - tree->opval.op != NULLOP )) { - filename = tree->filename ; - lineno = tree->lineno ; - } - - /* make sure we resolve the true & false labels for ifx */ - if (tree->type == EX_OP && tree->opval.op == IFX ) { - symbol *csym ; - - if (tree->trueLabel) { - if (( csym = findSym(LabelTab,tree->trueLabel, - tree->trueLabel->name))) - tree->trueLabel = csym ; - else - werror(E_LABEL_UNDEF,tree->trueLabel->name); - } + /* walk the entire tree and check for values */ + /* with symbols if we find one then replace */ + /* symbol with that from the symbol table */ - if (tree->falseLabel) { - if (( csym = findSym(LabelTab, - tree->falseLabel, - tree->falseLabel->name))) - tree->falseLabel = csym ; - else - werror(E_LABEL_UNDEF,tree->falseLabel->name); - } + if (tree == NULL) + return tree; + /* print the line */ + /* if not block & function */ + if (tree->type == EX_OP && + (tree->opval.op != FUNCTION && + tree->opval.op != BLOCK && + tree->opval.op != NULLOP)) + { + filename = tree->filename; + lineno = tree->lineno; } - /* if this is a label resolve it from the labelTab*/ - if (IS_AST_VALUE(tree) && - tree->opval.val->sym && - tree->opval.val->sym->islbl) { + /* make sure we resolve the true & false labels for ifx */ + if (tree->type == EX_OP && tree->opval.op == IFX) + { + symbol *csym; + + if (tree->trueLabel) + { + if ((csym = findSym (LabelTab, tree->trueLabel, + tree->trueLabel->name))) + tree->trueLabel = csym; + else + werror (E_LABEL_UNDEF, tree->trueLabel->name); + } + + if (tree->falseLabel) + { + if ((csym = findSym (LabelTab, + tree->falseLabel, + tree->falseLabel->name))) + tree->falseLabel = csym; + else + werror (E_LABEL_UNDEF, tree->falseLabel->name); + } - symbol *csym = findSym (LabelTab, tree->opval.val->sym , - tree->opval.val->sym->name); + } - if (!csym) - werror (E_LABEL_UNDEF,tree->opval.val->sym->name); - else - tree->opval.val->sym = csym ; + /* if this is a label resolve it from the labelTab */ + if (IS_AST_VALUE (tree) && + tree->opval.val->sym && + tree->opval.val->sym->islbl) + { - goto resolveChildren ; - } + symbol *csym = findSym (LabelTab, tree->opval.val->sym, + tree->opval.val->sym->name); - /* do only for leafs */ - if (IS_AST_VALUE(tree) && - tree->opval.val->sym && - ! tree->opval.val->sym->implicit ) { + if (!csym) + werror (E_LABEL_UNDEF, tree->opval.val->sym->name); + else + tree->opval.val->sym = csym; - symbol *csym = findSymWithLevel (SymbolTab,tree->opval.val->sym); + goto resolveChildren; + } - /* if found in the symbol table & they r not the same */ - if (csym && tree->opval.val->sym != csym ) { - tree->opval.val->sym = csym ; - tree->opval.val->type = csym->type; - tree->opval.val->etype = csym->etype; - } + /* do only for leafs */ + if (IS_AST_VALUE (tree) && + tree->opval.val->sym && + !tree->opval.val->sym->implicit) + { - /* if not found in the symbol table */ - /* mark it as undefined assume it is*/ - /* an integer in data space */ - if (!csym && !tree->opval.val->sym->implicit) { - - /* if this is a function name then */ - /* mark it as returning an int */ - if (tree->funcName) { - tree->opval.val->sym->type = newLink(); - DCL_TYPE(tree->opval.val->sym->type) = FUNCTION; - tree->opval.val->sym->type->next = - tree->opval.val->sym->etype = newIntLink(); - tree->opval.val->etype = tree->opval.val->etype; - tree->opval.val->type = tree->opval.val->sym->type; - werror(W_IMPLICIT_FUNC,tree->opval.val->sym->name); - } else { - tree->opval.val->sym->undefined =1 ; - tree->opval.val->type = - tree->opval.val->etype = newIntLink(); - tree->opval.val->sym->type = - tree->opval.val->sym->etype = newIntLink(); - } - } + symbol *csym = findSymWithLevel (SymbolTab, tree->opval.val->sym); + + /* if found in the symbol table & they r not the same */ + if (csym && tree->opval.val->sym != csym) + { + tree->opval.val->sym = csym; + tree->opval.val->type = csym->type; + tree->opval.val->etype = csym->etype; + } + + /* if not found in the symbol table */ + /* mark it as undefined assume it is */ + /* an integer in data space */ + if (!csym && !tree->opval.val->sym->implicit) + { + + /* if this is a function name then */ + /* mark it as returning an int */ + if (tree->funcName) + { + tree->opval.val->sym->type = newLink (); + DCL_TYPE (tree->opval.val->sym->type) = FUNCTION; + tree->opval.val->sym->type->next = + tree->opval.val->sym->etype = newIntLink (); + tree->opval.val->etype = tree->opval.val->etype; + tree->opval.val->type = tree->opval.val->sym->type; + werror (W_IMPLICIT_FUNC, tree->opval.val->sym->name); + } + else + { + tree->opval.val->sym->undefined = 1; + tree->opval.val->type = + tree->opval.val->etype = newIntLink (); + tree->opval.val->sym->type = + tree->opval.val->sym->etype = newIntLink (); + } + } } - resolveChildren: - resolveSymbols (tree->left); - resolveSymbols (tree->right); +resolveChildren: + resolveSymbols (tree->left); + resolveSymbols (tree->right); - return tree; + return tree; } /*-----------------------------------------------------------------*/ /* setAstLineno - walks a ast tree & sets the line number */ /*-----------------------------------------------------------------*/ -int setAstLineno ( ast *tree, int lineno) +int +setAstLineno (ast * tree, int lineno) { - if (!tree) - return 0; - - tree->lineno = lineno ; - setAstLineno ( tree->left, lineno); - setAstLineno ( tree->right, lineno); + if (!tree) return 0; + + tree->lineno = lineno; + setAstLineno (tree->left, lineno); + setAstLineno (tree->right, lineno); + return 0; } #if 0 @@ -464,554 +501,588 @@ int setAstLineno ( ast *tree, int lineno) /*-----------------------------------------------------------------*/ /* resolveFromTable - will return the symbal table value */ /*-----------------------------------------------------------------*/ -value *resolveFromTable (value *val) +value * +resolveFromTable (value * val) { - symbol *csym ; + symbol *csym; - if (!val->sym) - return val; + if (!val->sym) + return val; - csym = findSymWithLevel (SymbolTab,val->sym); + csym = findSymWithLevel (SymbolTab, val->sym); - /* if found in the symbol table & they r not the same */ - if (csym && val->sym != csym && - csym->level == val->sym->level && - csym->_isparm && - !csym->ismyparm) { + /* if found in the symbol table & they r not the same */ + if (csym && val->sym != csym && + csym->level == val->sym->level && + csym->_isparm && + !csym->ismyparm) + { - val->sym = csym ; - val->type = csym->type; - val->etype = csym->etype; + val->sym = csym; + val->type = csym->type; + val->etype = csym->etype; } - return val; + return val; } #endif /*-----------------------------------------------------------------*/ /* funcOfType :- function of type with name */ /*-----------------------------------------------------------------*/ -symbol *funcOfType (char *name, sym_link *type, sym_link *argType, - int nArgs , int rent) +symbol * +funcOfType (char *name, sym_link * type, sym_link * argType, + int nArgs, int rent) { - symbol *sym; - int argStack = 0; - /* create the symbol */ - sym = newSymbol (name,0); - - /* if arguments required */ - if (nArgs) { - - value *args ; - args = sym->args = newValue(); - - while (nArgs--) { - argStack += getSize(type); - args->type = copyLinkChain(argType); - args->etype = getSpec(args->type); - if (!nArgs) - break; - args = args->next = newValue(); - } + symbol *sym; + int argStack = 0; + /* create the symbol */ + sym = newSymbol (name, 0); + + /* if arguments required */ + if (nArgs) + { + + value *args; + args = sym->args = newValue (); + + while (nArgs--) + { + argStack += getSize (type); + args->type = copyLinkChain (argType); + args->etype = getSpec (args->type); + if (!nArgs) + break; + args = args->next = newValue (); + } } - /* setup return value */ - sym->type = newLink(); - DCL_TYPE(sym->type) = FUNCTION; - sym->type->next = copyLinkChain(type); - sym->etype = getSpec(sym->type); - SPEC_RENT(sym->etype) = rent; + /* setup return value */ + sym->type = newLink (); + DCL_TYPE (sym->type) = FUNCTION; + sym->type->next = copyLinkChain (type); + sym->etype = getSpec (sym->type); + SPEC_RENT (sym->etype) = rent; - /* save it */ - addSymChain(sym); - sym->cdef = 1; - sym->argStack = (rent ? argStack : 0); - allocVariables (sym); - return sym; + /* save it */ + addSymChain (sym); + sym->cdef = 1; + sym->argStack = (rent ? argStack : 0); + allocVariables (sym); + return sym; } /*-----------------------------------------------------------------*/ /* reverseParms - will reverse a parameter tree */ /*-----------------------------------------------------------------*/ -void reverseParms (ast *ptree) +void +reverseParms (ast * ptree) { - ast *ttree; - if (!ptree) - return ; + ast *ttree; + if (!ptree) + return; - /* top down if we find a nonParm tree then quit */ - if (ptree->type == EX_OP && ptree->opval.op == PARAM ) { - ttree = ptree->left; - ptree->left = ptree->right; - ptree->right = ttree; - reverseParms(ptree->left); - reverseParms(ptree->right); + /* top down if we find a nonParm tree then quit */ + if (ptree->type == EX_OP && ptree->opval.op == PARAM) + { + ttree = ptree->left; + ptree->left = ptree->right; + ptree->right = ttree; + reverseParms (ptree->left); + reverseParms (ptree->right); } - return ; + return; } /*-----------------------------------------------------------------*/ /* processParms - makes sure the parameters are okay and do some */ /* processing with them */ /*-----------------------------------------------------------------*/ -int processParms (ast *func, - value *defParm, - ast *actParm, - int *parmNumber, - bool rightmost) +int +processParms (ast * func, + value * defParm, + ast * actParm, + int *parmNumber, + bool rightmost) { - sym_link *fetype = func->etype; + sym_link *fetype = func->etype; - /* if none of them exist */ - if ( !defParm && !actParm) - return 0; + /* if none of them exist */ + if (!defParm && !actParm) + return 0; - /* if the function is being called via a pointer & */ - /* it has not been defined a reentrant then we cannot*/ - /* have parameters */ - if (func->type != EX_VALUE && !IS_RENT(fetype) && !options.stackAuto) { - werror (E_NONRENT_ARGS); - return 1; + /* if the function is being called via a pointer & */ + /* it has not been defined a reentrant then we cannot */ + /* have parameters */ + if (func->type != EX_VALUE && !IS_RENT (fetype) && !options.stackAuto) + { + werror (E_NONRENT_ARGS); + return 1; } - /* if defined parameters ended but actual parameters */ - /* exist and this is not defined as a variable arg */ - /* also check if statckAuto option is specified */ - if ((! defParm) && actParm && (!func->hasVargs ) && - !options.stackAuto && !IS_RENT(fetype)) { - werror(E_TOO_MANY_PARMS); - return 1; + /* if defined parameters ended but actual parameters */ + /* exist and this is not defined as a variable arg */ + /* also check if statckAuto option is specified */ + if ((!defParm) && actParm && (!func->hasVargs) && + !options.stackAuto && !IS_RENT (fetype)) + { + werror (E_TOO_MANY_PARMS); + return 1; } - /* if defined parameters present but no actual parameters */ - if ( defParm && ! actParm) { - werror(E_TOO_FEW_PARMS); + /* if defined parameters present but no actual parameters */ + if (defParm && !actParm) + { + werror (E_TOO_FEW_PARMS); return 1; } - /* If this is a varargs function... */ - if (!defParm && actParm && func->hasVargs ) + /* If this is a varargs function... */ + if (!defParm && actParm && func->hasVargs) { - ast *newType = NULL; + ast *newType = NULL; + + if (IS_CAST_OP (actParm) + || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast)) + { + /* Parameter was explicitly typecast; don't touch it. */ + return 0; + } + + /* If it's a small integer, upcast to int. */ + if (IS_INTEGRAL (actParm->ftype) + && getSize (actParm->ftype) < (unsigned) INTSIZE) + { + newType = newAst_LINK (INTTYPE); + } + + if (IS_PTR (actParm->ftype) && !IS_GENPTR (actParm->ftype)) + { + newType = newAst_LINK (copyLinkChain (actParm->ftype)); + DCL_TYPE (newType->opval.lnk) = GPOINTER; + } + + if (IS_AGGREGATE (actParm->ftype)) + { + newType = newAst_LINK (copyLinkChain (actParm->ftype)); + DCL_TYPE (newType->opval.lnk) = GPOINTER; + } + + if (newType) + { + /* cast required; change this op to a cast. */ + ast *parmCopy = resolveSymbols (copyAst (actParm)); + + actParm->type = EX_OP; + actParm->opval.op = CAST; + actParm->left = newType; + actParm->right = parmCopy; + decorateType (actParm); + } + else if (actParm->type == EX_OP && actParm->opval.op == PARAM) + { + return (processParms (func, NULL, actParm->left, parmNumber, FALSE) || + processParms (func, NULL, actParm->right, parmNumber, rightmost)); + } + return 0; + } - if (IS_CAST_OP(actParm) - || (IS_AST_LIT_VALUE(actParm) && actParm->values.literalFromCast)) - { - /* Parameter was explicitly typecast; don't touch it. */ - return 0; - } + /* if defined parameters ended but actual has not & */ + /* stackAuto */ + if (!defParm && actParm && + (options.stackAuto || IS_RENT (fetype))) + return 0; - /* If it's a small integer, upcast to int. */ - if (IS_INTEGRAL(actParm->ftype) - && getSize(actParm->ftype) < (unsigned) INTSIZE) - { - newType = newAst_LINK(INTTYPE); - } - - if (IS_PTR(actParm->ftype) && !IS_GENPTR(actParm->ftype)) - { - newType = newAst_LINK(copyLinkChain(actParm->ftype)); - DCL_TYPE(newType->opval.lnk) = GPOINTER; - } - - if (IS_AGGREGATE(actParm->ftype)) - { - newType = newAst_LINK(copyLinkChain(actParm->ftype)); - DCL_TYPE(newType->opval.lnk) = GPOINTER; - } - - if (newType) - { - /* cast required; change this op to a cast. */ - ast *parmCopy = resolveSymbols(copyAst(actParm)); + resolveSymbols (actParm); + /* if this is a PARAM node then match left & right */ + if (actParm->type == EX_OP && actParm->opval.op == PARAM) + { + return (processParms (func, defParm, actParm->left, parmNumber, FALSE) || + processParms (func, defParm->next, actParm->right, parmNumber, rightmost)); + } + else + { + /* If we have found a value node by following only right-hand links, + * then we know that there are no more values after us. + * + * Therefore, if there are more defined parameters, the caller didn't + * supply enough. + */ + if (rightmost && defParm->next) + { + werror (E_TOO_FEW_PARMS); + return 1; + } + } - actParm->type = EX_OP; - actParm->opval.op = CAST; - actParm->left = newType; - actParm->right= parmCopy; - decorateType(actParm); - } - else if ( actParm->type == EX_OP && actParm->opval.op == PARAM) - { - return (processParms(func,NULL,actParm->left,parmNumber,FALSE) || - processParms(func,NULL,actParm->right,parmNumber,rightmost)); - } - return 0; + /* the parameter type must be at least castable */ + if (checkType (defParm->type, actParm->ftype) == 0) + { + werror (E_TYPE_MISMATCH_PARM, *parmNumber); + werror (E_CONTINUE, "defined type "); + printTypeChain (defParm->type, stderr); + fprintf (stderr, "\n"); + werror (E_CONTINUE, "actual type "); + printTypeChain (actParm->ftype, stderr); + fprintf (stderr, "\n"); } - /* if defined parameters ended but actual has not & */ - /* stackAuto */ - if (! defParm && actParm && - (options.stackAuto || IS_RENT(fetype))) - return 0; + /* if the parameter is castable then add the cast */ + if (checkType (defParm->type, actParm->ftype) < 0) + { + ast *pTree = resolveSymbols (copyAst (actParm)); - resolveSymbols(actParm); - /* if this is a PARAM node then match left & right */ - if ( actParm->type == EX_OP && actParm->opval.op == PARAM) - { - return (processParms(func,defParm,actParm->left,parmNumber,FALSE) || - processParms(func,defParm->next, actParm->right,parmNumber,rightmost)); - } - else - { - /* If we have found a value node by following only right-hand links, - * then we know that there are no more values after us. - * - * Therefore, if there are more defined parameters, the caller didn't - * supply enough. - */ - if (rightmost && defParm->next) - { - werror(E_TOO_FEW_PARMS); - return 1; - } - } - - /* the parameter type must be at least castable */ - if (checkType(defParm->type,actParm->ftype) == 0) { - werror(E_TYPE_MISMATCH_PARM,*parmNumber); - werror(E_CONTINUE,"defined type "); - printTypeChain(defParm->type,stderr);fprintf(stderr,"\n"); - werror(E_CONTINUE,"actual type "); - printTypeChain(actParm->ftype,stderr);fprintf(stderr,"\n"); - } - - /* if the parameter is castable then add the cast */ - if ( checkType (defParm->type,actParm->ftype) < 0) { - ast *pTree = resolveSymbols(copyAst(actParm)); - - /* now change the current one to a cast */ - actParm->type = EX_OP ; - actParm->opval.op = CAST ; - actParm->left = newAst_LINK(defParm->type); - actParm->right= pTree ; - actParm->etype= defParm->etype; - actParm->ftype= defParm->type; + /* now change the current one to a cast */ + actParm->type = EX_OP; + actParm->opval.op = CAST; + actParm->left = newAst_LINK (defParm->type); + actParm->right = pTree; + actParm->etype = defParm->etype; + actParm->ftype = defParm->type; } /* actParm->argSym = resolveFromTable(defParm)->sym ; */ - actParm->argSym = defParm->sym; - /* make a copy and change the regparm type to the defined parm */ - actParm->etype = getSpec(actParm->ftype = copyLinkChain(actParm->ftype)); - SPEC_REGPARM(actParm->etype) = SPEC_REGPARM(defParm->etype); - (*parmNumber)++; - return 0; + actParm->argSym = defParm->sym; + /* make a copy and change the regparm type to the defined parm */ + actParm->etype = getSpec (actParm->ftype = copyLinkChain (actParm->ftype)); + SPEC_REGPARM (actParm->etype) = SPEC_REGPARM (defParm->etype); + (*parmNumber)++; + return 0; } /*-----------------------------------------------------------------*/ /* createIvalType - generates ival for basic types */ /*-----------------------------------------------------------------*/ -ast *createIvalType ( ast *sym,sym_link *type, initList *ilist) +ast * +createIvalType (ast * sym, sym_link * type, initList * ilist) { - ast *iExpr; + ast *iExpr; - /* if initList is deep */ - if ( ilist->type == INIT_DEEP ) - ilist = ilist->init.deep ; + /* if initList is deep */ + if (ilist->type == INIT_DEEP) + ilist = ilist->init.deep; - iExpr = decorateType(resolveSymbols(list2expr(ilist))); - return decorateType(newNode('=',sym,iExpr)); + iExpr = decorateType (resolveSymbols (list2expr (ilist))); + return decorateType (newNode ('=', sym, iExpr)); } /*-----------------------------------------------------------------*/ /* createIvalStruct - generates initial value for structures */ /*-----------------------------------------------------------------*/ -ast *createIvalStruct (ast *sym,sym_link *type,initList *ilist) +ast * +createIvalStruct (ast * sym, sym_link * type, initList * ilist) { - ast *rast = NULL ; - symbol *sflds ; - initList *iloop ; + ast *rast = NULL; + symbol *sflds; + initList *iloop; - sflds = SPEC_STRUCT(type)->fields ; - if (ilist->type != INIT_DEEP) { - werror(E_INIT_STRUCT,""); - return NULL ; + sflds = SPEC_STRUCT (type)->fields; + if (ilist->type != INIT_DEEP) + { + werror (E_INIT_STRUCT, ""); + return NULL; } - iloop = ilist->init.deep; - - for ( ; sflds ; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL )) { - ast *lAst ; + iloop = ilist->init.deep; - /* if we have come to end */ - if (!iloop) - break; - sflds->implicit = 1; - lAst = newNode(PTR_OP,newNode('&',sym,NULL),newAst_VALUE(symbolVal(sflds))); - lAst = decorateType(resolveSymbols(lAst)); - rast = decorateType(resolveSymbols(createIval (lAst, sflds->type, iloop,rast))); + for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) + { + ast *lAst; + + /* if we have come to end */ + if (!iloop) + break; + sflds->implicit = 1; + lAst = newNode (PTR_OP, newNode ('&', sym, NULL), newAst_VALUE (symbolVal (sflds))); + lAst = decorateType (resolveSymbols (lAst)); + rast = decorateType (resolveSymbols (createIval (lAst, sflds->type, iloop, rast))); } - return rast ; + return rast; } /*-----------------------------------------------------------------*/ /* createIvalArray - generates code for array initialization */ /*-----------------------------------------------------------------*/ -ast *createIvalArray (ast *sym, sym_link *type, initList *ilist) +ast * +createIvalArray (ast * sym, sym_link * type, initList * ilist) { - ast *rast = NULL; - initList *iloop ; - int lcnt = 0, size =0 ; - - /* take care of the special case */ - /* array of characters can be init */ - /* by a string */ - if ( IS_CHAR(type->next) ) - if ( (rast = createIvalCharPtr(sym, - type, - decorateType(resolveSymbols(list2expr(ilist)))))) - - return decorateType(resolveSymbols(rast)); - - /* not the special case */ - if (ilist->type != INIT_DEEP) { - werror(E_INIT_STRUCT,""); - return NULL; + ast *rast = NULL; + initList *iloop; + int lcnt = 0, size = 0; + + /* take care of the special case */ + /* array of characters can be init */ + /* by a string */ + if (IS_CHAR (type->next)) + if ((rast = createIvalCharPtr (sym, + type, + decorateType (resolveSymbols (list2expr (ilist)))))) + + return decorateType (resolveSymbols (rast)); + + /* not the special case */ + if (ilist->type != INIT_DEEP) + { + werror (E_INIT_STRUCT, ""); + return NULL; } - iloop = ilist->init.deep ; - lcnt = DCL_ELEM(type); - - for (;;) { - ast *aSym ; - size++ ; - - aSym = newNode('[',sym,newAst_VALUE(valueFromLit((float) (size-1)))); - aSym = decorateType(resolveSymbols(aSym)); - rast = createIval (aSym,type->next,iloop,rast) ; - iloop = (iloop ? iloop->next : NULL) ; - if (!iloop) - break; - /* if not array limits given & we */ - /* are out of initialisers then */ - if (!DCL_ELEM(type) && !iloop) - break ; + iloop = ilist->init.deep; + lcnt = DCL_ELEM (type); - /* no of elements given and we */ - /* have generated for all of them */ - if (!--lcnt) - break ; + for (;;) + { + ast *aSym; + size++; + + aSym = newNode ('[', sym, newAst_VALUE (valueFromLit ((float) (size - 1)))); + aSym = decorateType (resolveSymbols (aSym)); + rast = createIval (aSym, type->next, iloop, rast); + iloop = (iloop ? iloop->next : NULL); + if (!iloop) + break; + /* if not array limits given & we */ + /* are out of initialisers then */ + if (!DCL_ELEM (type) && !iloop) + break; + + /* no of elements given and we */ + /* have generated for all of them */ + if (!--lcnt) + break; } - /* if we have not been given a size */ - if (!DCL_ELEM(type)) - DCL_ELEM(type) = size; + /* if we have not been given a size */ + if (!DCL_ELEM (type)) + DCL_ELEM (type) = size; - return decorateType(resolveSymbols(rast)); + return decorateType (resolveSymbols (rast)); } /*-----------------------------------------------------------------*/ /* createIvalCharPtr - generates initial values for char pointers */ /*-----------------------------------------------------------------*/ -ast *createIvalCharPtr (ast *sym, sym_link *type, ast *iexpr) +ast * +createIvalCharPtr (ast * sym, sym_link * type, ast * iexpr) { - ast *rast = NULL ; - - /* if this is a pointer & right is a literal array then */ - /* just assignment will do */ - if ( IS_PTR(type) && (( IS_LITERAL(iexpr->etype) || - SPEC_SCLS(iexpr->etype) == S_CODE ) - && IS_ARRAY(iexpr->ftype))) - return newNode('=',sym,iexpr); - - /* left side is an array so we have to assign each */ - /* element */ - if (( IS_LITERAL(iexpr->etype) || - SPEC_SCLS(iexpr->etype) == S_CODE ) - && IS_ARRAY(iexpr->ftype)) { - - /* for each character generate an assignment */ - /* to the array element */ - char *s = SPEC_CVAL(iexpr->etype).v_char ; - int i = 0 ; - - while (*s) { - rast = newNode(NULLOP, - rast, - newNode('=', - newNode('[', sym, - newAst_VALUE(valueFromLit((float) i))), - newAst_VALUE(valueFromLit(*s)))); - i++; - s++; - } - rast = newNode(NULLOP, - rast, - newNode('=', - newNode('[', sym, - newAst_VALUE(valueFromLit((float) i))), - newAst_VALUE(valueFromLit(*s)))); - return decorateType(resolveSymbols(rast)); + ast *rast = NULL; + + /* if this is a pointer & right is a literal array then */ + /* just assignment will do */ + if (IS_PTR (type) && ((IS_LITERAL (iexpr->etype) || + SPEC_SCLS (iexpr->etype) == S_CODE) + && IS_ARRAY (iexpr->ftype))) + return newNode ('=', sym, iexpr); + + /* left side is an array so we have to assign each */ + /* element */ + if ((IS_LITERAL (iexpr->etype) || + SPEC_SCLS (iexpr->etype) == S_CODE) + && IS_ARRAY (iexpr->ftype)) + { + + /* for each character generate an assignment */ + /* to the array element */ + char *s = SPEC_CVAL (iexpr->etype).v_char; + int i = 0; + + while (*s) + { + rast = newNode (NULLOP, + rast, + newNode ('=', + newNode ('[', sym, + newAst_VALUE (valueFromLit ((float) i))), + newAst_VALUE (valueFromLit (*s)))); + i++; + s++; + } + rast = newNode (NULLOP, + rast, + newNode ('=', + newNode ('[', sym, + newAst_VALUE (valueFromLit ((float) i))), + newAst_VALUE (valueFromLit (*s)))); + return decorateType (resolveSymbols (rast)); } - return NULL ; + return NULL; } /*-----------------------------------------------------------------*/ /* createIvalPtr - generates initial value for pointers */ /*-----------------------------------------------------------------*/ -ast *createIvalPtr (ast *sym,sym_link *type,initList *ilist) +ast * +createIvalPtr (ast * sym, sym_link * type, initList * ilist) { - ast *rast; - ast *iexpr ; + ast *rast; + ast *iexpr; - /* if deep then */ - if ( ilist->type == INIT_DEEP ) - ilist = ilist->init.deep ; + /* if deep then */ + if (ilist->type == INIT_DEEP) + ilist = ilist->init.deep; - iexpr = decorateType(resolveSymbols(list2expr(ilist))); + iexpr = decorateType (resolveSymbols (list2expr (ilist))); - /* if character pointer */ - if (IS_CHAR(type->next)) - if ((rast = createIvalCharPtr (sym,type,iexpr))) + /* if character pointer */ + if (IS_CHAR (type->next)) + if ((rast = createIvalCharPtr (sym, type, iexpr))) return rast; - return newNode('=',sym,iexpr); + return newNode ('=', sym, iexpr); } /*-----------------------------------------------------------------*/ /* createIval - generates code for initial value */ /*-----------------------------------------------------------------*/ -ast *createIval (ast *sym, sym_link *type, initList *ilist, ast *wid) +ast * +createIval (ast * sym, sym_link * type, initList * ilist, ast * wid) { - ast *rast = NULL; - - if (!ilist) - return NULL ; - - /* if structure then */ - if (IS_STRUCT(type)) - rast = createIvalStruct(sym, type,ilist); - else - /* if this is a pointer */ - if (IS_PTR(type)) - rast = createIvalPtr(sym, type,ilist); + ast *rast = NULL; + + if (!ilist) + return NULL; + + /* if structure then */ + if (IS_STRUCT (type)) + rast = createIvalStruct (sym, type, ilist); + else + /* if this is a pointer */ + if (IS_PTR (type)) + rast = createIvalPtr (sym, type, ilist); + else + /* if this is an array */ + if (IS_ARRAY (type)) + rast = createIvalArray (sym, type, ilist); else - /* if this is an array */ - if (IS_ARRAY(type)) - rast = createIvalArray(sym, type,ilist); - else /* if type is SPECIFIER */ - if (IS_SPEC(type)) - rast = createIvalType (sym,type,ilist); - if ( wid ) - return decorateType(resolveSymbols(newNode(NULLOP,wid,rast))); - else - return decorateType(resolveSymbols(rast)) ; + if (IS_SPEC (type)) + rast = createIvalType (sym, type, ilist); + if (wid) + return decorateType (resolveSymbols (newNode (NULLOP, wid, rast))); + else + return decorateType (resolveSymbols (rast)); } /*-----------------------------------------------------------------*/ /* initAggregates - initialises aggregate variables with initv */ /*-----------------------------------------------------------------*/ -ast *initAggregates ( symbol *sym, initList *ival, ast *wid) +ast * +initAggregates (symbol * sym, initList * ival, ast * wid) { - return createIval (newAst_VALUE(symbolVal(sym)),sym->type,ival,wid); + return createIval (newAst_VALUE (symbolVal (sym)), sym->type, ival, wid); } /*-----------------------------------------------------------------*/ /* gatherAutoInit - creates assignment expressions for initial */ /* values */ /*-----------------------------------------------------------------*/ -ast *gatherAutoInit ( symbol *autoChain ) +ast * +gatherAutoInit (symbol * autoChain) { - ast *init = NULL ; - ast *work ; - symbol *sym; - - inInitMode =1; - for ( sym = autoChain ; sym ; sym = sym->next ) { - - /* resolve the symbols in the ival */ - if (sym->ival) - resolveIvalSym(sym->ival); - - /* if this is a static variable & has an */ - /* initial value the code needs to be lifted */ - /* here to the main portion since they can be */ - /* initialised only once at the start */ - if ( IS_STATIC(sym->etype) && sym->ival && - SPEC_SCLS(sym->etype) != S_CODE) { - symbol *newSym ; - - /* insert the symbol into the symbol table */ - /* with level = 0 & name = rname */ - newSym = copySymbol (sym); - addSym (SymbolTab,newSym,newSym->name,0,0); - - /* now lift the code to main */ - if (IS_AGGREGATE(sym->type)) - work = initAggregates (sym, sym->ival,NULL); - else - work = newNode('=' ,newAst_VALUE(symbolVal(newSym)), - list2expr(sym->ival)); - - setAstLineno(work,sym->lineDef); - - sym->ival = NULL ; - if ( staticAutos ) - staticAutos = newNode(NULLOP,staticAutos,work); - else - staticAutos = work ; + ast *init = NULL; + ast *work; + symbol *sym; - continue; - } - - /* if there is an initial value */ - if ( sym->ival && SPEC_SCLS(sym->etype)!=S_CODE) { - if (IS_AGGREGATE(sym->type)) - work = initAggregates (sym,sym->ival,NULL); - else - work = newNode('=' ,newAst_VALUE(symbolVal(sym)), - list2expr(sym->ival)); + inInitMode = 1; + for (sym = autoChain; sym; sym = sym->next) + { - setAstLineno (work,sym->lineDef); - sym->ival = NULL ; - if ( init ) - init = newNode(NULLOP,init,work); - else - init = work ; - } + /* resolve the symbols in the ival */ + if (sym->ival) + resolveIvalSym (sym->ival); + + /* if this is a static variable & has an */ + /* initial value the code needs to be lifted */ + /* here to the main portion since they can be */ + /* initialised only once at the start */ + if (IS_STATIC (sym->etype) && sym->ival && + SPEC_SCLS (sym->etype) != S_CODE) + { + symbol *newSym; + + /* insert the symbol into the symbol table */ + /* with level = 0 & name = rname */ + newSym = copySymbol (sym); + addSym (SymbolTab, newSym, newSym->name, 0, 0); + + /* now lift the code to main */ + if (IS_AGGREGATE (sym->type)) + work = initAggregates (sym, sym->ival, NULL); + else + work = newNode ('=', newAst_VALUE (symbolVal (newSym)), + list2expr (sym->ival)); + + setAstLineno (work, sym->lineDef); + + sym->ival = NULL; + if (staticAutos) + staticAutos = newNode (NULLOP, staticAutos, work); + else + staticAutos = work; + + continue; + } + + /* if there is an initial value */ + if (sym->ival && SPEC_SCLS (sym->etype) != S_CODE) + { + if (IS_AGGREGATE (sym->type)) + work = initAggregates (sym, sym->ival, NULL); + else + work = newNode ('=', newAst_VALUE (symbolVal (sym)), + list2expr (sym->ival)); + + setAstLineno (work, sym->lineDef); + sym->ival = NULL; + if (init) + init = newNode (NULLOP, init, work); + else + init = work; + } } - inInitMode = 0; - return init ; + inInitMode = 0; + return init; } /*-----------------------------------------------------------------*/ /* stringToSymbol - creates a symbol from a literal string */ /*-----------------------------------------------------------------*/ -static value *stringToSymbol (value *val) +static value * +stringToSymbol (value * val) { - char name[SDCC_NAME_MAX+1]; - static int charLbl = 0; - symbol *sym ; - - sprintf(name,"_str_%d",charLbl++); - sym = newSymbol(name,0); /* make it @ level 0 */ - strcpy(sym->rname,name); - - /* copy the type from the value passed */ - sym->type = copyLinkChain(val->type); - sym->etype = getSpec(sym->type); - /* change to storage class & output class */ - SPEC_SCLS(sym->etype) = S_CODE ; - SPEC_CVAL(sym->etype).v_char = SPEC_CVAL(val->etype).v_char ; - SPEC_STAT(sym->etype) = 1; - /* make the level & block = 0 */ - sym->block = sym->level = 0; - sym->isstrlit = 1; - /* create an ival */ - sym->ival = newiList(INIT_NODE,newAst_VALUE(val)); - if (noAlloc == 0) { - /* allocate it */ - addSymChain(sym); - allocVariables(sym); - } - sym->ival = NULL; - return symbolVal(sym); + char name[SDCC_NAME_MAX + 1]; + static int charLbl = 0; + symbol *sym; + + sprintf (name, "_str_%d", charLbl++); + sym = newSymbol (name, 0); /* make it @ level 0 */ + strcpy (sym->rname, name); + + /* copy the type from the value passed */ + sym->type = copyLinkChain (val->type); + sym->etype = getSpec (sym->type); + /* change to storage class & output class */ + SPEC_SCLS (sym->etype) = S_CODE; + SPEC_CVAL (sym->etype).v_char = SPEC_CVAL (val->etype).v_char; + SPEC_STAT (sym->etype) = 1; + /* make the level & block = 0 */ + sym->block = sym->level = 0; + sym->isstrlit = 1; + /* create an ival */ + sym->ival = newiList (INIT_NODE, newAst_VALUE (val)); + if (noAlloc == 0) + { + /* allocate it */ + addSymChain (sym); + allocVariables (sym); + } + sym->ival = NULL; + return symbolVal (sym); } @@ -1020,90 +1091,98 @@ static value *stringToSymbol (value *val) /* a block is found then will allocate the syms */ /* will also gather the auto inits present */ /*-----------------------------------------------------------------*/ -ast *processBlockVars ( ast *tree , int *stack, int action) +ast * +processBlockVars (ast * tree, int *stack, int action) { - if (! tree) - return NULL ; + if (!tree) + return NULL; - /* if this is a block */ - if (tree->type == EX_OP && tree->opval.op == BLOCK ) { - ast *autoInit ; - - if (action == ALLOCATE) { - autoInit = gatherAutoInit (tree->values.sym); - *stack += allocVariables (tree->values.sym); - - /* if there are auto inits then do them */ - if (autoInit) - tree->left = newNode(NULLOP,autoInit,tree->left); - } else /* action is deallocate */ - deallocLocal (tree->values.sym) ; + /* if this is a block */ + if (tree->type == EX_OP && tree->opval.op == BLOCK) + { + ast *autoInit; + + if (action == ALLOCATE) + { + autoInit = gatherAutoInit (tree->values.sym); + *stack += allocVariables (tree->values.sym); + + /* if there are auto inits then do them */ + if (autoInit) + tree->left = newNode (NULLOP, autoInit, tree->left); + } + else /* action is deallocate */ + deallocLocal (tree->values.sym); } - processBlockVars (tree->left, stack, action); - processBlockVars (tree->right, stack, action); - return tree ; + processBlockVars (tree->left, stack, action); + processBlockVars (tree->right, stack, action); + return tree; } /*-----------------------------------------------------------------*/ /* constExprValue - returns the value of a constant expression */ /*-----------------------------------------------------------------*/ -value *constExprValue (ast *cexpr, int check) +value * +constExprValue (ast * cexpr, int check) { - cexpr = decorateType(resolveSymbols(cexpr)); - - /* if this is not a constant then */ - if (!IS_LITERAL(cexpr->ftype)) { - /* then check if this is a literal array - in code segment */ - if (SPEC_SCLS(cexpr->etype) == S_CODE && - SPEC_CVAL(cexpr->etype).v_char && - IS_ARRAY(cexpr->ftype)) { - value *val = valFromType(cexpr->ftype); - SPEC_SCLS(val->etype) = S_LITERAL; - val->sym =cexpr->opval.val->sym ; - val->sym->type = copyLinkChain(cexpr->ftype); - val->sym->etype = getSpec(val->sym->type); - strcpy(val->name,cexpr->opval.val->sym->rname); - return val; - } - - /* if we are casting a literal value then */ - if (IS_AST_OP(cexpr) && - cexpr->opval.op == CAST && - IS_LITERAL(cexpr->left->ftype)) - return valCastLiteral(cexpr->ftype, - floatFromVal(cexpr->left->opval.val)); - - if (IS_AST_VALUE(cexpr)) - return cexpr->opval.val; - - if (check) - werror(E_CONST_EXPECTED,"found expression"); + cexpr = decorateType (resolveSymbols (cexpr)); - return NULL ; + /* if this is not a constant then */ + if (!IS_LITERAL (cexpr->ftype)) + { + /* then check if this is a literal array + in code segment */ + if (SPEC_SCLS (cexpr->etype) == S_CODE && + SPEC_CVAL (cexpr->etype).v_char && + IS_ARRAY (cexpr->ftype)) + { + value *val = valFromType (cexpr->ftype); + SPEC_SCLS (val->etype) = S_LITERAL; + val->sym = cexpr->opval.val->sym; + val->sym->type = copyLinkChain (cexpr->ftype); + val->sym->etype = getSpec (val->sym->type); + strcpy (val->name, cexpr->opval.val->sym->rname); + return val; + } + + /* if we are casting a literal value then */ + if (IS_AST_OP (cexpr) && + cexpr->opval.op == CAST && + IS_LITERAL (cexpr->left->ftype)) + return valCastLiteral (cexpr->ftype, + floatFromVal (cexpr->left->opval.val)); + + if (IS_AST_VALUE (cexpr)) + return cexpr->opval.val; + + if (check) + werror (E_CONST_EXPECTED, "found expression"); + + return NULL; } - /* return the value */ - return cexpr->opval.val ; + /* return the value */ + return cexpr->opval.val; } /*-----------------------------------------------------------------*/ /* isLabelInAst - will return true if a given label is found */ /*-----------------------------------------------------------------*/ -bool isLabelInAst (symbol *label, ast *tree) +bool +isLabelInAst (symbol * label, ast * tree) { - if (!tree || IS_AST_VALUE(tree) || IS_AST_LINK(tree)) - return FALSE ; + if (!tree || IS_AST_VALUE (tree) || IS_AST_LINK (tree)) + return FALSE; - if (IS_AST_OP(tree) && - tree->opval.op == LABEL && - isSymbolEqual(AST_SYMBOL(tree->left),label)) - return TRUE; + if (IS_AST_OP (tree) && + tree->opval.op == LABEL && + isSymbolEqual (AST_SYMBOL (tree->left), label)) + return TRUE; - return isLabelInAst(label,tree->right) && - isLabelInAst(label,tree->left); + return isLabelInAst (label, tree->right) && + isLabelInAst (label, tree->left); } @@ -1111,311 +1190,332 @@ bool isLabelInAst (symbol *label, ast *tree) /* isLoopCountable - return true if the loop count can be determi- */ /* -ned at compile time . */ /*-----------------------------------------------------------------*/ -bool isLoopCountable (ast *initExpr, ast *condExpr, ast *loopExpr, - symbol **sym,ast **init, ast **end) +bool +isLoopCountable (ast * initExpr, ast * condExpr, ast * loopExpr, + symbol ** sym, ast ** init, ast ** end) { - /* the loop is considered countable if the following - conditions are true :- + /* the loop is considered countable if the following + conditions are true :- - a) initExpr :- = - b) condExpr :- < - c) loopExpr :- ++ - */ + a) initExpr :- = + b) condExpr :- < + c) loopExpr :- ++ + */ - /* first check the initExpr */ - if ( IS_AST_OP(initExpr) && - initExpr->opval.op == '=' && /* is assignment */ - IS_AST_SYM_VALUE(initExpr->left)) { /* left is a symbol */ + /* first check the initExpr */ + if (IS_AST_OP (initExpr) && + initExpr->opval.op == '=' && /* is assignment */ + IS_AST_SYM_VALUE (initExpr->left)) + { /* left is a symbol */ - *sym = AST_SYMBOL(initExpr->left); - *init= initExpr->right; + *sym = AST_SYMBOL (initExpr->left); + *init = initExpr->right; } - else - return FALSE; - - /* for now the symbol has to be of - integral type */ - if (!IS_INTEGRAL((*sym)->type)) - return FALSE; - - /* now check condExpr */ - if (IS_AST_OP(condExpr)) { - - switch (condExpr->opval.op) { - case '<': - if (IS_AST_SYM_VALUE(condExpr->left) && - isSymbolEqual (*sym,AST_SYMBOL(condExpr->left)) && - IS_AST_LIT_VALUE(condExpr->right)) { - *end = condExpr->right; - break; - } - return FALSE; + else + return FALSE; - case '!': - if (IS_AST_OP(condExpr->left) && - condExpr->left->opval.op == '>' && - IS_AST_LIT_VALUE(condExpr->left->right) && - IS_AST_SYM_VALUE(condExpr->left->left)&& - isSymbolEqual (*sym,AST_SYMBOL(condExpr->left->left))) { + /* for now the symbol has to be of + integral type */ + if (!IS_INTEGRAL ((*sym)->type)) + return FALSE; - *end = newNode('+', condExpr->left->right, - newAst_VALUE(constVal("1"))); - break; - } - return FALSE ; + /* now check condExpr */ + if (IS_AST_OP (condExpr)) + { - default: - return FALSE ; - } + switch (condExpr->opval.op) + { + case '<': + if (IS_AST_SYM_VALUE (condExpr->left) && + isSymbolEqual (*sym, AST_SYMBOL (condExpr->left)) && + IS_AST_LIT_VALUE (condExpr->right)) + { + *end = condExpr->right; + break; + } + return FALSE; + + case '!': + if (IS_AST_OP (condExpr->left) && + condExpr->left->opval.op == '>' && + IS_AST_LIT_VALUE (condExpr->left->right) && + IS_AST_SYM_VALUE (condExpr->left->left) && + isSymbolEqual (*sym, AST_SYMBOL (condExpr->left->left))) + { + + *end = newNode ('+', condExpr->left->right, + newAst_VALUE (constVal ("1"))); + break; + } + return FALSE; + + default: + return FALSE; + } } - /* check loop expression is of the form ++ */ - if (!IS_AST_OP(loopExpr)) - return FALSE ; + /* check loop expression is of the form ++ */ + if (!IS_AST_OP (loopExpr)) + return FALSE; - /* check if ++ */ - if (loopExpr->opval.op == INC_OP) { + /* check if ++ */ + if (loopExpr->opval.op == INC_OP) + { - if (loopExpr->left) { - /* pre */ - if (IS_AST_SYM_VALUE(loopExpr->left) && - isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left))) - return TRUE ; + if (loopExpr->left) + { + /* pre */ + if (IS_AST_SYM_VALUE (loopExpr->left) && + isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left))) + return TRUE; - } else { - /* post */ - if (IS_AST_SYM_VALUE(loopExpr->right) && - isSymbolEqual(*sym,AST_SYMBOL(loopExpr->right))) - return TRUE ; - } + } + else + { + /* post */ + if (IS_AST_SYM_VALUE (loopExpr->right) && + isSymbolEqual (*sym, AST_SYMBOL (loopExpr->right))) + return TRUE; + } } - else { - /* check for += */ - if ( loopExpr->opval.op == ADD_ASSIGN ) { - - if (IS_AST_SYM_VALUE(loopExpr->left) && - isSymbolEqual(*sym,AST_SYMBOL(loopExpr->left)) && - IS_AST_LIT_VALUE(loopExpr->right) && - (int)AST_LIT_VALUE(loopExpr->right) != 1) - return TRUE ; - } + else + { + /* check for += */ + if (loopExpr->opval.op == ADD_ASSIGN) + { + + if (IS_AST_SYM_VALUE (loopExpr->left) && + isSymbolEqual (*sym, AST_SYMBOL (loopExpr->left)) && + IS_AST_LIT_VALUE (loopExpr->right) && + (int) AST_LIT_VALUE (loopExpr->right) != 1) + return TRUE; + } } - return FALSE; + return FALSE; } /*-----------------------------------------------------------------*/ /* astHasVolatile - returns true if ast contains any volatile */ /*-----------------------------------------------------------------*/ -bool astHasVolatile (ast *tree) +bool +astHasVolatile (ast * tree) { - if (!tree) - return FALSE ; + if (!tree) + return FALSE; - if (TETYPE(tree) && IS_VOLATILE(TETYPE(tree))) - return TRUE; + if (TETYPE (tree) && IS_VOLATILE (TETYPE (tree))) + return TRUE; - if (IS_AST_OP(tree)) - return astHasVolatile(tree->left) || - astHasVolatile(tree->right); - else - return FALSE ; + if (IS_AST_OP (tree)) + return astHasVolatile (tree->left) || + astHasVolatile (tree->right); + else + return FALSE; } /*-----------------------------------------------------------------*/ -/* astHasPointer - return true if the ast contains any ptr variable*/ +/* astHasPointer - return true if the ast contains any ptr variable */ /*-----------------------------------------------------------------*/ -bool astHasPointer (ast *tree) +bool +astHasPointer (ast * tree) { - if (!tree) - return FALSE ; + if (!tree) + return FALSE; - if (IS_AST_LINK(tree)) - return TRUE; + if (IS_AST_LINK (tree)) + return TRUE; - /* if we hit an array expression then check - only the left side */ - if (IS_AST_OP(tree) && tree->opval.op == '[') - return astHasPointer(tree->left); + /* if we hit an array expression then check + only the left side */ + if (IS_AST_OP (tree) && tree->opval.op == '[') + return astHasPointer (tree->left); - if (IS_AST_VALUE(tree)) - return IS_PTR(tree->ftype) || IS_ARRAY(tree->ftype); + if (IS_AST_VALUE (tree)) + return IS_PTR (tree->ftype) || IS_ARRAY (tree->ftype); - return astHasPointer(tree->left) || - astHasPointer(tree->right); + return astHasPointer (tree->left) || + astHasPointer (tree->right); } /*-----------------------------------------------------------------*/ /* astHasSymbol - return true if the ast has the given symbol */ /*-----------------------------------------------------------------*/ -bool astHasSymbol (ast *tree, symbol *sym) +bool +astHasSymbol (ast * tree, symbol * sym) { - if (!tree || IS_AST_LINK(tree)) - return FALSE ; + if (!tree || IS_AST_LINK (tree)) + return FALSE; - if (IS_AST_VALUE(tree)) { - if (IS_AST_SYM_VALUE(tree)) - return isSymbolEqual(AST_SYMBOL(tree),sym); - else - return FALSE; + if (IS_AST_VALUE (tree)) + { + if (IS_AST_SYM_VALUE (tree)) + return isSymbolEqual (AST_SYMBOL (tree), sym); + else + return FALSE; } - return astHasSymbol(tree->left,sym) || - astHasSymbol(tree->right,sym); + return astHasSymbol (tree->left, sym) || + astHasSymbol (tree->right, sym); } /*-----------------------------------------------------------------*/ /* isConformingBody - the loop body has to conform to a set of rules */ /* for the loop to be considered reversible read on for rules */ /*-----------------------------------------------------------------*/ -bool isConformingBody (ast *pbody, symbol *sym, ast *body) +bool +isConformingBody (ast * pbody, symbol * sym, ast * body) { - /* we are going to do a pre-order traversal of the - tree && check for the following conditions. (essentially - a set of very shallow tests ) - a) the sym passed does not participate in - any arithmetic operation - b) There are no function calls - c) all jumps are within the body - d) address of loop control variable not taken - e) if an assignment has a pointer on the - left hand side make sure right does not have - loop control variable */ - - /* if we reach the end or a leaf then true */ - if (!pbody || IS_AST_LINK(pbody) || IS_AST_VALUE(pbody)) - return TRUE ; - - - /* if anything else is "volatile" */ - if (IS_VOLATILE(TETYPE(pbody))) - return FALSE; - - /* we will walk the body in a pre-order traversal for - efficiency sake */ - switch (pbody->opval.op) { - /*------------------------------------------------------------------*/ - case '[' : - return isConformingBody (pbody->right,sym,body); - - /*------------------------------------------------------------------*/ - case PTR_OP: - case '.' : - return TRUE; - - /*------------------------------------------------------------------*/ - case INC_OP: /* incerement operator unary so left only */ - case DEC_OP: - - /* sure we are not sym is not modified */ - if (pbody->left && - IS_AST_SYM_VALUE(pbody->left) && - isSymbolEqual(AST_SYMBOL(pbody->left),sym)) - return FALSE; - - if (pbody->right && - IS_AST_SYM_VALUE(pbody->right) && - isSymbolEqual(AST_SYMBOL(pbody->right),sym)) - return FALSE; - - return TRUE; - - /*------------------------------------------------------------------*/ - - case '*' : /* can be unary : if right is null then unary operation */ - case '+' : - case '-' : - case '&': - - /* if right is NULL then unary operation */ - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* address of */ - /*----------------------------*/ - if ( ! pbody->right ) { - if (IS_AST_SYM_VALUE(pbody->left) && - isSymbolEqual(AST_SYMBOL(pbody->left),sym)) - return FALSE; - else - return isConformingBody(pbody->left,sym,body) ; - } else { - if (astHasSymbol(pbody->left,sym) || - astHasSymbol(pbody->right,sym)) + /* we are going to do a pre-order traversal of the + tree && check for the following conditions. (essentially + a set of very shallow tests ) + a) the sym passed does not participate in + any arithmetic operation + b) There are no function calls + c) all jumps are within the body + d) address of loop control variable not taken + e) if an assignment has a pointer on the + left hand side make sure right does not have + loop control variable */ + + /* if we reach the end or a leaf then true */ + if (!pbody || IS_AST_LINK (pbody) || IS_AST_VALUE (pbody)) + return TRUE; + + + /* if anything else is "volatile" */ + if (IS_VOLATILE (TETYPE (pbody))) return FALSE; - } - - /*------------------------------------------------------------------*/ - case '|': - case '^': - case '/': - case '%': + /* we will walk the body in a pre-order traversal for + efficiency sake */ + switch (pbody->opval.op) + { +/*------------------------------------------------------------------*/ + case '[': + return isConformingBody (pbody->right, sym, body); + +/*------------------------------------------------------------------*/ + case PTR_OP: + case '.': + return TRUE; + +/*------------------------------------------------------------------*/ + case INC_OP: /* incerement operator unary so left only */ + case DEC_OP: + + /* sure we are not sym is not modified */ + if (pbody->left && + IS_AST_SYM_VALUE (pbody->left) && + isSymbolEqual (AST_SYMBOL (pbody->left), sym)) + return FALSE; + + if (pbody->right && + IS_AST_SYM_VALUE (pbody->right) && + isSymbolEqual (AST_SYMBOL (pbody->right), sym)) + return FALSE; + + return TRUE; + +/*------------------------------------------------------------------*/ + + case '*': /* can be unary : if right is null then unary operation */ + case '+': + case '-': + case '&': + + /* if right is NULL then unary operation */ +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* address of */ +/*----------------------------*/ + if (!pbody->right) + { + if (IS_AST_SYM_VALUE (pbody->left) && + isSymbolEqual (AST_SYMBOL (pbody->left), sym)) + return FALSE; + else + return isConformingBody (pbody->left, sym, body); + } + else + { + if (astHasSymbol (pbody->left, sym) || + astHasSymbol (pbody->right, sym)) + return FALSE; + } + + +/*------------------------------------------------------------------*/ + case '|': + case '^': + case '/': + case '%': case LEFT_OP: case RIGHT_OP: - if (IS_AST_SYM_VALUE(pbody->left) && - isSymbolEqual(AST_SYMBOL(pbody->left),sym)) - return FALSE ; + if (IS_AST_SYM_VALUE (pbody->left) && + isSymbolEqual (AST_SYMBOL (pbody->left), sym)) + return FALSE; - if (IS_AST_SYM_VALUE(pbody->right) && - isSymbolEqual(AST_SYMBOL(pbody->right),sym)) - return FALSE ; + if (IS_AST_SYM_VALUE (pbody->right) && + isSymbolEqual (AST_SYMBOL (pbody->right), sym)) + return FALSE; - return isConformingBody(pbody->left,sym,body) && - isConformingBody(pbody->right,sym,body); + return isConformingBody (pbody->left, sym, body) && + isConformingBody (pbody->right, sym, body); - case '~' : - case '!' : + case '~': + case '!': case RRC: case RLC: case GETHBIT: - if (IS_AST_SYM_VALUE(pbody->left) && - isSymbolEqual(AST_SYMBOL(pbody->left),sym)) - return FALSE; - return isConformingBody (pbody->left,sym,body); + if (IS_AST_SYM_VALUE (pbody->left) && + isSymbolEqual (AST_SYMBOL (pbody->left), sym)) + return FALSE; + return isConformingBody (pbody->left, sym, body); - /*------------------------------------------------------------------*/ +/*------------------------------------------------------------------*/ case AND_OP: case OR_OP: - case '>' : - case '<' : + case '>': + case '<': case LE_OP: case GE_OP: case EQ_OP: case NE_OP: - case '?' : - case ':' : - case SIZEOF: /* evaluate wihout code generation */ + case '?': + case ':': + case SIZEOF: /* evaluate wihout code generation */ - return isConformingBody(pbody->left,sym,body) && - isConformingBody(pbody->right,sym,body); + return isConformingBody (pbody->left, sym, body) && + isConformingBody (pbody->right, sym, body); - /*------------------------------------------------------------------*/ - case '=' : +/*------------------------------------------------------------------*/ + case '=': - /* if left has a pointer & right has loop - control variable then we cannot */ - if (astHasPointer(pbody->left) && - astHasSymbol (pbody->right,sym)) - return FALSE ; - if (astHasVolatile(pbody->left)) - return FALSE ; + /* if left has a pointer & right has loop + control variable then we cannot */ + if (astHasPointer (pbody->left) && + astHasSymbol (pbody->right, sym)) + return FALSE; + if (astHasVolatile (pbody->left)) + return FALSE; - if (IS_AST_SYM_VALUE(pbody->left) && - isSymbolEqual(AST_SYMBOL(pbody->left),sym)) - return FALSE ; + if (IS_AST_SYM_VALUE (pbody->left) && + isSymbolEqual (AST_SYMBOL (pbody->left), sym)) + return FALSE; - if (astHasVolatile(pbody->left)) - return FALSE; + if (astHasVolatile (pbody->left)) + return FALSE; - return isConformingBody(pbody->left,sym,body) && - isConformingBody(pbody->right,sym,body); + return isConformingBody (pbody->left, sym, body) && + isConformingBody (pbody->right, sym, body); case MUL_ASSIGN: case DIV_ASSIGN: @@ -1426,45 +1526,45 @@ bool isConformingBody (ast *pbody, symbol *sym, ast *body) case LEFT_ASSIGN: case SUB_ASSIGN: case ADD_ASSIGN: - assert("Parser should not have generated this\n"); - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* comma operator */ - /*----------------------------*/ - case ',' : - return isConformingBody(pbody->left,sym,body) && - isConformingBody(pbody->right,sym,body); - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* function call */ - /*----------------------------*/ + assert ("Parser should not have generated this\n"); + +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* comma operator */ +/*----------------------------*/ + case ',': + return isConformingBody (pbody->left, sym, body) && + isConformingBody (pbody->right, sym, body); + +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* function call */ +/*----------------------------*/ case CALL: - return FALSE; + return FALSE; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* return statement */ - /*----------------------------*/ +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* return statement */ +/*----------------------------*/ case RETURN: - return FALSE ; + return FALSE; case GOTO: - if (isLabelInAst (AST_SYMBOL(pbody->left),body)) - return TRUE ; - else - return FALSE; + if (isLabelInAst (AST_SYMBOL (pbody->left), body)) + return TRUE; + else + return FALSE; case SWITCH: - if (astHasSymbol(pbody->left,sym)) - return FALSE ; + if (astHasSymbol (pbody->left, sym)) + return FALSE; default: - break; + break; } - return isConformingBody(pbody->left,sym,body) && - isConformingBody(pbody->right,sym,body); + return isConformingBody (pbody->left, sym, body) && + isConformingBody (pbody->right, sym, body); @@ -1475,102 +1575,107 @@ bool isConformingBody (ast *pbody, symbol *sym, ast *body) /* if the for loop is reversible. If yes will set the value of */ /* the loop control var & init value & termination value */ /*-----------------------------------------------------------------*/ -bool isLoopReversible (ast *loop, symbol **loopCntrl, - ast **init, ast **end ) +bool +isLoopReversible (ast * loop, symbol ** loopCntrl, + ast ** init, ast ** end) { - /* if option says don't do it then don't */ - if (optimize.noLoopReverse) - return 0; - /* there are several tests to determine this */ - - /* for loop has to be of the form - for ( = ; - [ < ] ; - [++] | [ += 1] | [ = + 1] ) - forBody */ - if (! isLoopCountable (AST_FOR(loop,initExpr), - AST_FOR(loop,condExpr), - AST_FOR(loop,loopExpr), - loopCntrl,init,end)) - return 0; + /* if option says don't do it then don't */ + if (optimize.noLoopReverse) + return 0; + /* there are several tests to determine this */ + + /* for loop has to be of the form + for ( = ; + [ < ] ; + [++] | [ += 1] | [ = + 1] ) + forBody */ + if (!isLoopCountable (AST_FOR (loop, initExpr), + AST_FOR (loop, condExpr), + AST_FOR (loop, loopExpr), + loopCntrl, init, end)) + return 0; - /* now do some serious checking on the body of the loop - */ + /* now do some serious checking on the body of the loop + */ - return isConformingBody(loop->left,*loopCntrl,loop->left); + return isConformingBody (loop->left, *loopCntrl, loop->left); } /*-----------------------------------------------------------------*/ /* replLoopSym - replace the loop sym by loop sym -1 */ /*-----------------------------------------------------------------*/ -static void replLoopSym ( ast *body, symbol *sym) +static void +replLoopSym (ast * body, symbol * sym) { - /* reached end */ - if (!body || IS_AST_LINK(body)) - return ; + /* reached end */ + if (!body || IS_AST_LINK (body)) + return; - if (IS_AST_SYM_VALUE(body)) { + if (IS_AST_SYM_VALUE (body)) + { - if (isSymbolEqual(AST_SYMBOL(body),sym)) { + if (isSymbolEqual (AST_SYMBOL (body), sym)) + { - body->type = EX_OP; - body->opval.op = '-'; - body->left = newAst_VALUE(symbolVal(sym)); - body->right= newAst_VALUE(constVal("1")); + body->type = EX_OP; + body->opval.op = '-'; + body->left = newAst_VALUE (symbolVal (sym)); + body->right = newAst_VALUE (constVal ("1")); - } + } - return; + return; } - replLoopSym(body->left,sym); - replLoopSym(body->right,sym); + replLoopSym (body->left, sym); + replLoopSym (body->right, sym); } /*-----------------------------------------------------------------*/ /* reverseLoop - do the actual loop reversal */ /*-----------------------------------------------------------------*/ -ast *reverseLoop (ast *loop, symbol *sym, ast *init, ast *end) +ast * +reverseLoop (ast * loop, symbol * sym, ast * init, ast * end) { - ast *rloop ; - - /* create the following tree - = loopCount ; - for_continue: - forbody - -= 1; - if (sym) goto for_continue ; - = end */ - - /* put it together piece by piece */ - rloop = newNode (NULLOP, - createIf(newAst_VALUE(symbolVal(sym)), - newNode(GOTO, - newAst_VALUE(symbolVal(AST_FOR(loop,continueLabel))), - NULL),NULL), - newNode('=', - newAst_VALUE(symbolVal(sym)), - end)); - - replLoopSym(loop->left, sym); - - rloop = newNode(NULLOP, - newNode('=', - newAst_VALUE(symbolVal(sym)), - newNode('-',end,init)), - createLabel(AST_FOR(loop,continueLabel), - newNode(NULLOP, - loop->left, - newNode(NULLOP, - newNode(SUB_ASSIGN, - newAst_VALUE(symbolVal(sym)), - newAst_VALUE(constVal("1"))), - rloop )))); - - return decorateType(rloop); + ast *rloop; + + /* create the following tree + = loopCount ; + for_continue: + forbody + -= 1; + if (sym) goto for_continue ; + = end */ + + /* put it together piece by piece */ + rloop = newNode (NULLOP, + createIf (newAst_VALUE (symbolVal (sym)), + newNode (GOTO, + newAst_VALUE (symbolVal (AST_FOR (loop, continueLabel))), + NULL), NULL), + newNode ('=', + newAst_VALUE (symbolVal (sym)), + end)); + + replLoopSym (loop->left, sym); + + rloop = newNode (NULLOP, + newNode ('=', + newAst_VALUE (symbolVal (sym)), + newNode ('-', end, init)), + createLabel (AST_FOR (loop, continueLabel), + newNode (NULLOP, + loop->left, + newNode (NULLOP, + newNode (SUB_ASSIGN, + newAst_VALUE (symbolVal (sym)), + newAst_VALUE (constVal ("1"))), + rloop)))); + + return decorateType (rloop); } @@ -1582,34 +1687,35 @@ ast *reverseLoop (ast *loop, symbol *sym, ast *init, ast *end) /* walk a tree looking for the leaves. Add a typecast to the given */ /* type to each value leaf node. */ /*-----------------------------------------------------------------*/ -void pushTypeCastToLeaves(sym_link *type, ast *node, ast **parentPtr) +void +pushTypeCastToLeaves (sym_link * type, ast * node, ast ** parentPtr) { - if (!node) + if (!node) { - /* WTF? We should never get here. */ - return; + /* WTF? We should never get here. */ + return; } - if (!node->left && !node->right) + if (!node->left && !node->right) { - /* We're at a leaf; if it's a value, apply the typecast */ - if (node->type == EX_VALUE && IS_INTEGRAL(TTYPE(node))) - { - *parentPtr = decorateType(newNode(CAST, - newAst_LINK(copyLinkChain(type)), - node)); - } + /* We're at a leaf; if it's a value, apply the typecast */ + if (node->type == EX_VALUE && IS_INTEGRAL (TTYPE (node))) + { + *parentPtr = decorateType (newNode (CAST, + newAst_LINK (copyLinkChain (type)), + node)); + } } - else + else { if (node->left) - { - pushTypeCastToLeaves(type, node->left, &(node->left)); - } + { + pushTypeCastToLeaves (type, node->left, &(node->left)); + } if (node->right) - { - pushTypeCastToLeaves(type, node->right, &(node->right)); - } + { + pushTypeCastToLeaves (type, node->right, &(node->right)); + } } } @@ -1621,1303 +1727,1408 @@ void pushTypeCastToLeaves(sym_link *type, ast *node, ast **parentPtr) /* If so, walk the RHS and add a typecast to the type of the LHS */ /* to all leaf nodes. */ /*-----------------------------------------------------------------*/ -void propAsgType(ast *tree) +void +propAsgType (ast * tree) { #ifdef DEMAND_INTEGER_PROMOTION - if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) + if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) { /* Nothing to do here... */ return; } - if (getSize(LTYPE(tree)) > getSize(RTYPE(tree))) + if (getSize (LTYPE (tree)) > getSize (RTYPE (tree))) { - pushTypeCastToLeaves(LTYPE(tree), tree->right, &(tree->right)); + pushTypeCastToLeaves (LTYPE (tree), tree->right, &(tree->right)); } #else - (void)tree; + (void) tree; #endif } /*-----------------------------------------------------------------*/ -/* decorateType - compute type for this tree also does type cheking*/ -/* this is done bottom up, since type have to flow upwards*/ +/* decorateType - compute type for this tree also does type cheking */ +/* this is done bottom up, since type have to flow upwards */ /* it also does constant folding, and paramater checking */ /*-----------------------------------------------------------------*/ -ast *decorateType (ast *tree) +ast * +decorateType (ast * tree) { - int parmNumber ; - sym_link *p; - - if ( ! tree ) - return tree ; - - /* if already has type then do nothing */ - if ( tree->decorated ) - return tree ; - - tree->decorated = 1; - - /* print the line */ - /* if not block & function */ - if ( tree->type == EX_OP && - ( tree->opval.op != FUNCTION && - tree->opval.op != BLOCK && - tree->opval.op != NULLOP )) { - filename = tree->filename ; - lineno = tree->lineno ; - } - - /* if any child is an error | this one is an error do nothing */ - if ( tree->isError || - ( tree->left && tree->left->isError) || - ( tree->right && tree->right->isError )) - return tree ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* leaf has been reached */ - /*----------------------------*/ - /* if this is of type value */ - /* just get the type */ - if ( tree->type == EX_VALUE ) { - - if ( IS_LITERAL(tree->opval.val->etype) ) { - - /* if this is a character array then declare it */ - if (IS_ARRAY(tree->opval.val->type)) - tree->opval.val = stringToSymbol(tree->opval.val); - - /* otherwise just copy the type information */ - COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type); - if (funcInChain(tree->opval.val->type)) { - tree->hasVargs = tree->opval.val->sym->hasVargs; - tree->args = copyValueChain(tree->opval.val->sym->args) ; - } - return tree ; - } + int parmNumber; + sym_link *p; - if ( tree->opval.val->sym ) { - /* if the undefined flag is set then give error message */ - if (tree->opval.val->sym->undefined ) { - werror(E_ID_UNDEF,tree->opval.val->sym->name) ; - /* assume int */ - TTYPE(tree) = TETYPE(tree) = - tree->opval.val->type = tree->opval.val->sym->type = - tree->opval.val->etype = tree->opval.val->sym->etype = - copyLinkChain(INTTYPE); - } - else { + if (!tree) + return tree; - /* if impilicit i.e. struct/union member then no type */ - if (tree->opval.val->sym->implicit ) - TTYPE(tree) = TETYPE(tree) = NULL ; + /* if already has type then do nothing */ + if (tree->decorated) + return tree; - else { + tree->decorated = 1; - /* else copy the type */ - COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.val->type); + /* print the line */ + /* if not block & function */ + if (tree->type == EX_OP && + (tree->opval.op != FUNCTION && + tree->opval.op != BLOCK && + tree->opval.op != NULLOP)) + { + filename = tree->filename; + lineno = tree->lineno; + } - /* and mark it as referenced */ - tree->opval.val->sym->isref = 1; - /* if this is of type function or function pointer */ - if (funcInChain(tree->opval.val->type)) { - tree->hasVargs = tree->opval.val->sym->hasVargs; - tree->args = copyValueChain(tree->opval.val->sym->args) ; + /* if any child is an error | this one is an error do nothing */ + if (tree->isError || + (tree->left && tree->left->isError) || + (tree->right && tree->right->isError)) + return tree; - } - } - } - } +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* leaf has been reached */ +/*----------------------------*/ + /* if this is of type value */ + /* just get the type */ + if (tree->type == EX_VALUE) + { - return tree ; - } + if (IS_LITERAL (tree->opval.val->etype)) + { + + /* if this is a character array then declare it */ + if (IS_ARRAY (tree->opval.val->type)) + tree->opval.val = stringToSymbol (tree->opval.val); + + /* otherwise just copy the type information */ + COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type); + if (funcInChain (tree->opval.val->type)) + { + tree->hasVargs = tree->opval.val->sym->hasVargs; + tree->args = copyValueChain (tree->opval.val->sym->args); + } + return tree; + } + + if (tree->opval.val->sym) + { + /* if the undefined flag is set then give error message */ + if (tree->opval.val->sym->undefined) + { + werror (E_ID_UNDEF, tree->opval.val->sym->name); + /* assume int */ + TTYPE (tree) = TETYPE (tree) = + tree->opval.val->type = tree->opval.val->sym->type = + tree->opval.val->etype = tree->opval.val->sym->etype = + copyLinkChain (INTTYPE); + } + else + { + + /* if impilicit i.e. struct/union member then no type */ + if (tree->opval.val->sym->implicit) + TTYPE (tree) = TETYPE (tree) = NULL; + + else + { + + /* else copy the type */ + COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.val->type); + + /* and mark it as referenced */ + tree->opval.val->sym->isref = 1; + /* if this is of type function or function pointer */ + if (funcInChain (tree->opval.val->type)) + { + tree->hasVargs = tree->opval.val->sym->hasVargs; + tree->args = copyValueChain (tree->opval.val->sym->args); + + } + } + } + } - /* if type link for the case of cast */ - if ( tree->type == EX_LINK ) { - COPYTYPE(TTYPE(tree),TETYPE(tree),tree->opval.lnk); - return tree ; + return tree; } + /* if type link for the case of cast */ + if (tree->type == EX_LINK) { - ast *dtl, *dtr; + COPYTYPE (TTYPE (tree), TETYPE (tree), tree->opval.lnk); + return tree; + } + + { + ast *dtl, *dtr; - dtl = decorateType (tree->left); - dtr = decorateType (tree->right); + dtl = decorateType (tree->left); + dtr = decorateType (tree->right); - /* this is to take care of situations - when the tree gets rewritten */ - if (dtl != tree->left) + /* this is to take care of situations + when the tree gets rewritten */ + if (dtl != tree->left) tree->left = dtl; - if (dtr != tree->right) + if (dtr != tree->right) tree->right = dtr; - } + } - /* depending on type of operator do */ + /* depending on type of operator do */ - switch (tree->opval.op) { - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* array node */ - /*----------------------------*/ - case '[' : + switch (tree->opval.op) + { +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* array node */ +/*----------------------------*/ + case '[': + + /* determine which is the array & which the index */ + if ((IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree))) && IS_INTEGRAL (LTYPE (tree))) + { + + ast *tempTree = tree->left; + tree->left = tree->right; + tree->right = tempTree; + } + + /* first check if this is a array or a pointer */ + if ((!IS_ARRAY (LTYPE (tree))) && (!IS_PTR (LTYPE (tree)))) + { + werror (E_NEED_ARRAY_PTR, "[]"); + goto errorTreeReturn; + } + + /* check if the type of the idx */ + if (!IS_INTEGRAL (RTYPE (tree))) + { + werror (E_IDX_NOT_INT); + goto errorTreeReturn; + } + + /* if the left is an rvalue then error */ + if (LRVAL (tree)) + { + werror (E_LVALUE_REQUIRED, "array access"); + goto errorTreeReturn; + } + RRVAL (tree) = 1; + COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)->next); + return tree; - /* determine which is the array & which the index */ - if ((IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree))) && IS_INTEGRAL(LTYPE(tree))) { +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* struct/union */ +/*----------------------------*/ + case '.': + /* if this is not a structure */ + if (!IS_STRUCT (LTYPE (tree))) + { + werror (E_STRUCT_UNION, "."); + goto errorTreeReturn; + } + TTYPE (tree) = structElemType (LTYPE (tree), + (tree->right->type == EX_VALUE ? + tree->right->opval.val : NULL), &tree->args); + TETYPE (tree) = getSpec (TTYPE (tree)); + return tree; - ast *tempTree = tree->left ; - tree->left = tree->right ; - tree->right= tempTree ; - } +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* struct/union pointer */ +/*----------------------------*/ + case PTR_OP: + /* if not pointer to a structure */ + if (!IS_PTR (LTYPE (tree))) + { + werror (E_PTR_REQD); + goto errorTreeReturn; + } + + if (!IS_STRUCT (LTYPE (tree)->next)) + { + werror (E_STRUCT_UNION, "->"); + goto errorTreeReturn; + } + + TTYPE (tree) = structElemType (LTYPE (tree)->next, + (tree->right->type == EX_VALUE ? + tree->right->opval.val : NULL), &tree->args); + TETYPE (tree) = getSpec (TTYPE (tree)); + return tree; - /* first check if this is a array or a pointer */ - if ( (!IS_ARRAY(LTYPE(tree))) && (!IS_PTR(LTYPE(tree)))) { - werror(E_NEED_ARRAY_PTR,"[]"); - goto errorTreeReturn ; - } +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* ++/-- operation */ +/*----------------------------*/ + case INC_OP: /* incerement operator unary so left only */ + case DEC_OP: + { + sym_link *ltc = (tree->right ? RTYPE (tree) : LTYPE (tree)); + COPYTYPE (TTYPE (tree), TETYPE (tree), ltc); + if (!tree->initMode && IS_CONSTANT (TETYPE (tree))) + werror (E_CODE_WRITE, "++/--"); + + if (tree->right) + RLVAL (tree) = 1; + else + LLVAL (tree) = 1; + return tree; + } - /* check if the type of the idx */ - if (!IS_INTEGRAL(RTYPE(tree))) { - werror(E_IDX_NOT_INT); - goto errorTreeReturn ; - } +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* bitwise and */ +/*----------------------------*/ + case '&': /* can be unary */ + /* if right is NULL then unary operation */ + if (tree->right) /* not an unary operation */ + { + + if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) + { + werror (E_BITWISE_OP); + werror (E_CONTINUE, "left & right types are "); + printTypeChain (LTYPE (tree), stderr); + fprintf (stderr, ","); + printTypeChain (RTYPE (tree), stderr); + fprintf (stderr, "\n"); + goto errorTreeReturn; + } + + /* if they are both literal */ + if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valBitwise (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree)), '&'); + + tree->right = tree->left = NULL; + TETYPE (tree) = tree->opval.val->etype; + TTYPE (tree) = tree->opval.val->type; + return tree; + } + + /* see if this is a GETHBIT operation if yes + then return that */ + { + ast *otree = optimizeGetHbit (tree); + + if (otree != tree) + return decorateType (otree); + } + + /* if right or left is literal then result of that type */ + if (IS_LITERAL (RTYPE (tree))) + { + + TTYPE (tree) = copyLinkChain (RTYPE (tree)); + TETYPE (tree) = getSpec (TTYPE (tree)); + SPEC_SCLS (TETYPE (tree)) = S_AUTO; + } + else + { + if (IS_LITERAL (LTYPE (tree))) + { + TTYPE (tree) = copyLinkChain (LTYPE (tree)); + TETYPE (tree) = getSpec (TTYPE (tree)); + SPEC_SCLS (TETYPE (tree)) = S_AUTO; + + } + else + { + TTYPE (tree) = + computeType (LTYPE (tree), RTYPE (tree)); + TETYPE (tree) = getSpec (TTYPE (tree)); + } + } + LRVAL (tree) = RRVAL (tree) = 1; + return tree; + } + +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* address of */ +/*----------------------------*/ + p = newLink (); + p->class = DECLARATOR; + /* if bit field then error */ + if (IS_BITVAR (tree->left->etype)) + { + werror (E_ILLEGAL_ADDR, "addrress of bit variable"); + goto errorTreeReturn; + } + + if (SPEC_SCLS (tree->left->etype) == S_REGISTER) + { + werror (E_ILLEGAL_ADDR, "address of register variable"); + goto errorTreeReturn; + } + + if (IS_FUNC (LTYPE (tree))) + { + werror (E_ILLEGAL_ADDR, "address of function"); + goto errorTreeReturn; + } + + if (LRVAL (tree)) + { + werror (E_LVALUE_REQUIRED, "address of"); + goto errorTreeReturn; + } + if (SPEC_SCLS (tree->left->etype) == S_CODE) + { + DCL_TYPE (p) = CPOINTER; + DCL_PTR_CONST (p) = port->mem.code_ro; + } + else if (SPEC_SCLS (tree->left->etype) == S_XDATA) + DCL_TYPE (p) = FPOINTER; + else if (SPEC_SCLS (tree->left->etype) == S_XSTACK) + DCL_TYPE (p) = PPOINTER; + else if (SPEC_SCLS (tree->left->etype) == S_IDATA) + DCL_TYPE (p) = IPOINTER; + else if (SPEC_SCLS (tree->left->etype) == S_EEPROM) + DCL_TYPE (p) = EEPPOINTER; + else + DCL_TYPE (p) = POINTER; + + if (IS_AST_SYM_VALUE (tree->left)) + { + AST_SYMBOL (tree->left)->addrtaken = 1; + AST_SYMBOL (tree->left)->allocreq = 1; + } + + p->next = LTYPE (tree); + TTYPE (tree) = p; + TETYPE (tree) = getSpec (TTYPE (tree)); + DCL_PTR_CONST (p) = SPEC_CONST (TETYPE (tree)); + DCL_PTR_VOLATILE (p) = SPEC_VOLATILE (TETYPE (tree)); + LLVAL (tree) = 1; + TLVAL (tree) = 1; + return tree; - /* if the left is an rvalue then error */ - if (LRVAL(tree)) { - werror(E_LVALUE_REQUIRED,"array access"); - goto errorTreeReturn ; - } - RRVAL(tree) = 1; - COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)->next); - return tree; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* struct/union */ - /*----------------------------*/ - case '.' : - /* if this is not a structure */ - if (!IS_STRUCT(LTYPE(tree))) { - werror(E_STRUCT_UNION,"."); - goto errorTreeReturn ; - } - TTYPE(tree) = structElemType (LTYPE(tree), - (tree->right->type == EX_VALUE ? - tree->right->opval.val : NULL ),&tree->args); - TETYPE(tree) = getSpec(TTYPE(tree)); - return tree ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* struct/union pointer */ - /*----------------------------*/ - case PTR_OP: - /* if not pointer to a structure */ - if (!IS_PTR(LTYPE(tree))) { - werror(E_PTR_REQD); - goto errorTreeReturn ; - } - - if (!IS_STRUCT(LTYPE(tree)->next)) { - werror(E_STRUCT_UNION,"->"); - goto errorTreeReturn ; - } - - TTYPE(tree) = structElemType (LTYPE(tree)->next, - (tree->right->type == EX_VALUE ? - tree->right->opval.val : NULL ),&tree->args); - TETYPE(tree) = getSpec(TTYPE(tree)); - return tree ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* ++/-- operation */ - /*----------------------------*/ - case INC_OP: /* incerement operator unary so left only */ - case DEC_OP: - { - sym_link *ltc = (tree->right ? RTYPE(tree) : LTYPE(tree) ); - COPYTYPE(TTYPE(tree),TETYPE(tree),ltc); - if (!tree->initMode && IS_CONSTANT(TETYPE(tree))) - werror(E_CODE_WRITE,"++/--"); - - if (tree->right) - RLVAL(tree) = 1; - else - LLVAL(tree) = 1; - return tree ; - } - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* bitwise and */ - /*----------------------------*/ - case '&': /* can be unary */ - /* if right is NULL then unary operation */ - if ( tree->right ) /* not an unary operation */ { - - if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) { - werror(E_BITWISE_OP); - werror(E_CONTINUE,"left & right types are "); - printTypeChain(LTYPE(tree),stderr); - fprintf(stderr,","); - printTypeChain(RTYPE(tree),stderr); - fprintf(stderr,"\n"); - goto errorTreeReturn ; - } - - /* if they are both literal */ - if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) { - tree->type = EX_VALUE ; - tree->opval.val = valBitwise (valFromType(LETYPE(tree)), - valFromType(RETYPE(tree)),'&'); - - tree->right = tree->left = NULL; - TETYPE(tree) = tree->opval.val->etype ; - TTYPE(tree) = tree->opval.val->type; - return tree ; - } - - /* see if this is a GETHBIT operation if yes - then return that */ +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* bitwise or */ +/*----------------------------*/ + case '|': + /* if the rewrite succeeds then don't go any furthur */ { - ast *otree = optimizeGetHbit(tree); - - if (otree != tree) - return decorateType(otree); - } - - /* if right or left is literal then result of that type*/ - if (IS_LITERAL(RTYPE(tree))) { - - TTYPE(tree) = copyLinkChain(RTYPE(tree)); - TETYPE(tree) = getSpec(TTYPE(tree)); - SPEC_SCLS(TETYPE(tree)) = S_AUTO; - } - else { - if (IS_LITERAL(LTYPE(tree))) { - TTYPE(tree) = copyLinkChain(LTYPE(tree)); - TETYPE(tree) = getSpec(TTYPE(tree)); - SPEC_SCLS(TETYPE(tree)) = S_AUTO; - - } - else { - TTYPE(tree) = - computeType (LTYPE(tree), RTYPE(tree)); - TETYPE(tree) = getSpec(TTYPE(tree)); - } + ast *wtree = optimizeRRCRLC (tree); + if (wtree != tree) + return decorateType (wtree); } - LRVAL(tree) = RRVAL(tree) = 1; - return tree ; - } +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* bitwise xor */ +/*----------------------------*/ + case '^': + if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) + { + werror (E_BITWISE_OP); + werror (E_CONTINUE, "left & right types are "); + printTypeChain (LTYPE (tree), stderr); + fprintf (stderr, ","); + printTypeChain (RTYPE (tree), stderr); + fprintf (stderr, "\n"); + goto errorTreeReturn; + } + + /* if they are both literal then */ + /* rewrite the tree */ + if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valBitwise (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree)), + tree->opval.op); + tree->right = tree->left = NULL; + TETYPE (tree) = tree->opval.val->etype; + TTYPE (tree) = tree->opval.val->type; + return tree; + } + LRVAL (tree) = RRVAL (tree) = 1; + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + RTYPE (tree))); + +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* division */ +/*----------------------------*/ + case '/': + if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree))) + { + werror (E_INVALID_OP, "divide"); + goto errorTreeReturn; + } + /* if they are both literal then */ + /* rewrite the tree */ + if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valDiv (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree))); + tree->right = tree->left = NULL; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + return tree; + } + LRVAL (tree) = RRVAL (tree) = 1; + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + RTYPE (tree))); + return tree; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* address of */ - /*----------------------------*/ - p = newLink(); - p->class = DECLARATOR; - /* if bit field then error */ - if (IS_BITVAR(tree->left->etype)) { - werror (E_ILLEGAL_ADDR,"addrress of bit variable"); - goto errorTreeReturn ; - } +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* modulus */ +/*----------------------------*/ + case '%': + if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree))) + { + werror (E_BITWISE_OP); + werror (E_CONTINUE, "left & right types are "); + printTypeChain (LTYPE (tree), stderr); + fprintf (stderr, ","); + printTypeChain (RTYPE (tree), stderr); + fprintf (stderr, "\n"); + goto errorTreeReturn; + } + /* if they are both literal then */ + /* rewrite the tree */ + if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valMod (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree))); + tree->right = tree->left = NULL; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + return tree; + } + LRVAL (tree) = RRVAL (tree) = 1; + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + RTYPE (tree))); + return tree; - if (SPEC_SCLS(tree->left->etype)== S_REGISTER ) { - werror (E_ILLEGAL_ADDR,"address of register variable"); - goto errorTreeReturn; - } +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* address dereference */ +/*----------------------------*/ + case '*': /* can be unary : if right is null then unary operation */ + if (!tree->right) + { + if (!IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree))) + { + werror (E_PTR_REQD); + goto errorTreeReturn; + } + + if (LRVAL (tree)) + { + werror (E_LVALUE_REQUIRED, "pointer deref"); + goto errorTreeReturn; + } + TTYPE (tree) = copyLinkChain ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) ? + LTYPE (tree)->next : NULL); + TETYPE (tree) = getSpec (TTYPE (tree)); + tree->args = tree->left->args; + tree->hasVargs = tree->left->hasVargs; + SPEC_CONST (TETYPE (tree)) = DCL_PTR_CONST (LTYPE (tree)); + return tree; + } + +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* multiplication */ +/*----------------------------*/ + if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree))) + { + werror (E_INVALID_OP, "multiplication"); + goto errorTreeReturn; + } + + /* if they are both literal then */ + /* rewrite the tree */ + if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valMult (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree))); + tree->right = tree->left = NULL; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + return tree; + } + + /* if left is a literal exchange left & right */ + if (IS_LITERAL (LTYPE (tree))) + { + ast *tTree = tree->left; + tree->left = tree->right; + tree->right = tTree; + } + + LRVAL (tree) = RRVAL (tree) = 1; + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + RTYPE (tree))); + return tree; - if (IS_FUNC(LTYPE(tree))) { - werror(E_ILLEGAL_ADDR,"address of function"); - goto errorTreeReturn ; - } +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* unary '+' operator */ +/*----------------------------*/ + case '+': + /* if unary plus */ + if (!tree->right) + { + if (!IS_INTEGRAL (LTYPE (tree))) + { + werror (E_UNARY_OP, '+'); + goto errorTreeReturn; + } + + /* if left is a literal then do it */ + if (IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valFromType (LETYPE (tree)); + tree->left = NULL; + TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; + return tree; + } + LRVAL (tree) = 1; + COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)); + return tree; + } + +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* addition */ +/*----------------------------*/ + + /* this is not a unary operation */ + /* if both pointers then problem */ + if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) && + (IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)))) + { + werror (E_PTR_PLUS_PTR); + goto errorTreeReturn; + } + + if (!IS_ARITHMETIC (LTYPE (tree)) && + !IS_PTR (LTYPE (tree)) && !IS_ARRAY (LTYPE (tree))) + { + werror (E_PLUS_INVALID, "+"); + goto errorTreeReturn; + } + + if (!IS_ARITHMETIC (RTYPE (tree)) && + !IS_PTR (RTYPE (tree)) && !IS_ARRAY (RTYPE (tree))) + { + werror (E_PLUS_INVALID, "+"); + goto errorTreeReturn; + } + /* if they are both literal then */ + /* rewrite the tree */ + if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valPlus (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree))); + tree->right = tree->left = NULL; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + return tree; + } + + /* if the right is a pointer or left is a literal + xchange left & right */ + if (IS_ARRAY (RTYPE (tree)) || + IS_PTR (RTYPE (tree)) || + IS_LITERAL (LTYPE (tree))) + { + ast *tTree = tree->left; + tree->left = tree->right; + tree->right = tTree; + } + + LRVAL (tree) = RRVAL (tree) = 1; + /* if the left is a pointer */ + if (IS_PTR (LTYPE (tree))) + TETYPE (tree) = getSpec (TTYPE (tree) = + LTYPE (tree)); + else + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + RTYPE (tree))); + return tree; - if (LRVAL(tree)) { - werror(E_LVALUE_REQUIRED,"address of"); - goto errorTreeReturn ; - } - if (SPEC_SCLS(tree->left->etype) == S_CODE) { - DCL_TYPE(p) = CPOINTER ; - DCL_PTR_CONST(p) = port->mem.code_ro; - } - else - if (SPEC_SCLS(tree->left->etype) == S_XDATA) - DCL_TYPE(p) = FPOINTER; +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* unary '-' */ +/*----------------------------*/ + case '-': /* can be unary */ + /* if right is null then unary */ + if (!tree->right) + { + + if (!IS_ARITHMETIC (LTYPE (tree))) + { + werror (E_UNARY_OP, tree->opval.op); + goto errorTreeReturn; + } + + /* if left is a literal then do it */ + if (IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valUnaryPM (valFromType (LETYPE (tree))); + tree->left = NULL; + TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; + return tree; + } + LRVAL (tree) = 1; + TTYPE (tree) = LTYPE (tree); + return tree; + } + +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* subtraction */ +/*----------------------------*/ + + if (!(IS_PTR (LTYPE (tree)) || + IS_ARRAY (LTYPE (tree)) || + IS_ARITHMETIC (LTYPE (tree)))) + { + werror (E_PLUS_INVALID, "-"); + goto errorTreeReturn; + } + + if (!(IS_PTR (RTYPE (tree)) || + IS_ARRAY (RTYPE (tree)) || + IS_ARITHMETIC (RTYPE (tree)))) + { + werror (E_PLUS_INVALID, "-"); + goto errorTreeReturn; + } + + if ((IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) && + !(IS_PTR (RTYPE (tree)) || IS_ARRAY (RTYPE (tree)) || + IS_INTEGRAL (RTYPE (tree)))) + { + werror (E_PLUS_INVALID, "-"); + goto errorTreeReturn; + } + + /* if they are both literal then */ + /* rewrite the tree */ + if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valMinus (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree))); + tree->right = tree->left = NULL; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + return tree; + } + + /* if the left & right are equal then zero */ + if (isAstEqual (tree->left, tree->right)) + { + tree->type = EX_VALUE; + tree->left = tree->right = NULL; + tree->opval.val = constVal ("0"); + TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; + return tree; + } + + /* if both of them are pointers or arrays then */ + /* the result is going to be an integer */ + if ((IS_ARRAY (LTYPE (tree)) || IS_PTR (LTYPE (tree))) && + (IS_ARRAY (RTYPE (tree)) || IS_PTR (RTYPE (tree)))) + TETYPE (tree) = TTYPE (tree) = newIntLink (); else - if (SPEC_SCLS(tree->left->etype) == S_XSTACK ) - DCL_TYPE(p) = PPOINTER ; - else - if (SPEC_SCLS(tree->left->etype) == S_IDATA) - DCL_TYPE(p) = IPOINTER ; - else - if (SPEC_SCLS(tree->left->etype) == S_EEPROM) - DCL_TYPE(p) = EEPPOINTER ; + /* if only the left is a pointer */ + /* then result is a pointer */ + if (IS_PTR (LTYPE (tree)) || IS_ARRAY (LTYPE (tree))) + TETYPE (tree) = getSpec (TTYPE (tree) = + LTYPE (tree)); else - DCL_TYPE(p) = POINTER ; - - if (IS_AST_SYM_VALUE(tree->left)) { - AST_SYMBOL(tree->left)->addrtaken = 1; - AST_SYMBOL(tree->left)->allocreq = 1; - } - - p->next = LTYPE(tree); - TTYPE(tree) = p; - TETYPE(tree) = getSpec(TTYPE(tree)); - DCL_PTR_CONST(p) = SPEC_CONST(TETYPE(tree)); - DCL_PTR_VOLATILE(p) = SPEC_VOLATILE(TETYPE(tree)); - LLVAL(tree) = 1; - TLVAL(tree) = 1; - return tree ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* bitwise or */ - /*----------------------------*/ - case '|': - /* if the rewrite succeeds then don't go any furthur */ - { - ast *wtree = optimizeRRCRLC ( tree ); - if (wtree != tree) - return decorateType(wtree) ; - } - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* bitwise xor */ - /*----------------------------*/ - case '^': - if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) { - werror(E_BITWISE_OP); - werror(E_CONTINUE,"left & right types are "); - printTypeChain(LTYPE(tree),stderr); - fprintf(stderr,","); - printTypeChain(RTYPE(tree),stderr); - fprintf(stderr,"\n"); - goto errorTreeReturn ; - } - - /* if they are both literal then */ - /* rewrite the tree */ - if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) { - tree->type = EX_VALUE ; - tree->opval.val = valBitwise (valFromType(LETYPE(tree)), - valFromType(RETYPE(tree)), - tree->opval.op); - tree->right = tree->left = NULL; - TETYPE(tree) = tree->opval.val->etype; - TTYPE(tree) = tree->opval.val->type; - return tree ; - } - LRVAL(tree) = RRVAL(tree) = 1; - TETYPE(tree) = getSpec (TTYPE(tree) = - computeType(LTYPE(tree), - RTYPE(tree))); - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* division */ - /*----------------------------*/ - case '/': - if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) { - werror(E_INVALID_OP,"divide"); - goto errorTreeReturn ; - } - /* if they are both literal then */ - /* rewrite the tree */ - if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) { - tree->type = EX_VALUE ; - tree->opval.val = valDiv (valFromType(LETYPE(tree)), - valFromType(RETYPE(tree))); - tree->right = tree->left = NULL; - TETYPE(tree) = getSpec(TTYPE(tree) = - tree->opval.val->type); - return tree ; - } - LRVAL(tree) = RRVAL(tree) = 1; - TETYPE(tree) = getSpec (TTYPE(tree) = - computeType(LTYPE(tree), - RTYPE(tree))); - return tree; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* modulus */ - /*----------------------------*/ - case '%': - if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(RTYPE(tree))) { - werror(E_BITWISE_OP); - werror(E_CONTINUE,"left & right types are "); - printTypeChain(LTYPE(tree),stderr); - fprintf(stderr,","); - printTypeChain(RTYPE(tree),stderr); - fprintf(stderr,"\n"); - goto errorTreeReturn ; - } - /* if they are both literal then */ - /* rewrite the tree */ - if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) { - tree->type = EX_VALUE ; - tree->opval.val = valMod (valFromType(LETYPE(tree)), - valFromType(RETYPE(tree))); - tree->right = tree->left = NULL; - TETYPE(tree) = getSpec(TTYPE(tree) = - tree->opval.val->type); - return tree ; - } - LRVAL(tree) = RRVAL(tree) = 1; - TETYPE(tree) = getSpec (TTYPE(tree) = - computeType(LTYPE(tree), - RTYPE(tree))); - return tree; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* address dereference */ - /*----------------------------*/ - case '*': /* can be unary : if right is null then unary operation */ - if ( ! tree->right ) { - if (!IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) { - werror(E_PTR_REQD); - goto errorTreeReturn ; - } - - if (LRVAL(tree)) { - werror(E_LVALUE_REQUIRED,"pointer deref"); - goto errorTreeReturn ; - } - TTYPE(tree) = copyLinkChain ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) ? - LTYPE(tree)->next : NULL ); - TETYPE(tree) = getSpec(TTYPE(tree)); - tree->args = tree->left->args ; - tree->hasVargs = tree->left->hasVargs ; - SPEC_CONST(TETYPE(tree)) = DCL_PTR_CONST(LTYPE(tree)); - return tree ; - } - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* multiplication */ - /*----------------------------*/ - if (!IS_ARITHMETIC(LTYPE(tree)) || !IS_ARITHMETIC(RTYPE(tree))) { - werror(E_INVALID_OP,"multiplication"); - goto errorTreeReturn ; - } - - /* if they are both literal then */ - /* rewrite the tree */ - if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) { - tree->type = EX_VALUE ; - tree->opval.val = valMult (valFromType(LETYPE(tree)), - valFromType(RETYPE(tree))); - tree->right = tree->left = NULL; - TETYPE(tree) = getSpec(TTYPE(tree) = - tree->opval.val->type); - return tree ; - } + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + RTYPE (tree))); + LRVAL (tree) = RRVAL (tree) = 1; + return tree; - /* if left is a literal exchange left & right */ - if (IS_LITERAL(LTYPE(tree))) { - ast *tTree = tree->left ; - tree->left = tree->right ; - tree->right= tTree ; - } - - LRVAL(tree) = RRVAL(tree) = 1; - TETYPE(tree) = getSpec (TTYPE(tree) = - computeType(LTYPE(tree), - RTYPE(tree))); - return tree ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* unary '+' operator */ - /*----------------------------*/ - case '+' : - /* if unary plus */ - if ( ! tree->right ) { - if (!IS_INTEGRAL(LTYPE(tree))) { - werror(E_UNARY_OP,'+'); - goto errorTreeReturn ; - } +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* compliment */ +/*----------------------------*/ + case '~': + /* can be only integral type */ + if (!IS_INTEGRAL (LTYPE (tree))) + { + werror (E_UNARY_OP, tree->opval.op); + goto errorTreeReturn; + } /* if left is a literal then do it */ - if (IS_LITERAL(LTYPE(tree))) { - tree->type = EX_VALUE ; - tree->opval.val = valFromType(LETYPE(tree)); - tree->left = NULL ; - TETYPE(tree) = TTYPE(tree) = tree->opval.val->type; - return tree ; - } - LRVAL(tree) = 1; - COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)); - return tree ; - } - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* addition */ - /*----------------------------*/ - - /* this is not a unary operation */ - /* if both pointers then problem */ - if ((IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) && - (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)))) { - werror(E_PTR_PLUS_PTR); - goto errorTreeReturn ; - } - - if (!IS_ARITHMETIC(LTYPE(tree)) && - !IS_PTR(LTYPE(tree)) && !IS_ARRAY(LTYPE(tree))) { - werror(E_PLUS_INVALID,"+"); - goto errorTreeReturn ; - } - - if (!IS_ARITHMETIC(RTYPE(tree)) && - !IS_PTR(RTYPE(tree)) && !IS_ARRAY(RTYPE(tree))) { - werror(E_PLUS_INVALID,"+"); - goto errorTreeReturn; - } - /* if they are both literal then */ - /* rewrite the tree */ - if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) { - tree->type = EX_VALUE ; - tree->opval.val = valPlus (valFromType(LETYPE(tree)), - valFromType(RETYPE(tree))); - tree->right = tree->left = NULL; - TETYPE(tree) = getSpec(TTYPE(tree) = - tree->opval.val->type); - return tree ; - } + if (IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valComplement (valFromType (LETYPE (tree))); + tree->left = NULL; + TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; + return tree; + } + LRVAL (tree) = 1; + COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)); + return tree; - /* if the right is a pointer or left is a literal - xchange left & right */ - if (IS_ARRAY(RTYPE(tree)) || - IS_PTR(RTYPE(tree)) || - IS_LITERAL(LTYPE(tree))) { - ast *tTree = tree->left ; - tree->left = tree->right ; - tree->right= tTree ; - } - - LRVAL(tree) = RRVAL(tree) = 1; - /* if the left is a pointer */ - if (IS_PTR(LTYPE(tree))) - TETYPE(tree) = getSpec(TTYPE(tree) = - LTYPE(tree)); - else - TETYPE(tree) = getSpec(TTYPE(tree) = - computeType(LTYPE(tree), - RTYPE(tree))); - return tree ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* unary '-' */ - /*----------------------------*/ - case '-' : /* can be unary */ - /* if right is null then unary */ - if ( ! tree->right ) { - - if (!IS_ARITHMETIC(LTYPE(tree))) { - werror(E_UNARY_OP,tree->opval.op); - goto errorTreeReturn ; - } +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* not */ +/*----------------------------*/ + case '!': + /* can be pointer */ + if (!IS_ARITHMETIC (LTYPE (tree)) && + !IS_PTR (LTYPE (tree)) && + !IS_ARRAY (LTYPE (tree))) + { + werror (E_UNARY_OP, tree->opval.op); + goto errorTreeReturn; + } /* if left is a literal then do it */ - if (IS_LITERAL(LTYPE(tree))) { - tree->type = EX_VALUE ; - tree->opval.val = valUnaryPM(valFromType(LETYPE(tree))); - tree->left = NULL ; - TETYPE(tree) = TTYPE(tree) = tree->opval.val->type; - return tree ; - } - LRVAL(tree) = 1; - TTYPE(tree) = LTYPE(tree); - return tree ; - } - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* subtraction */ - /*----------------------------*/ - - if (!(IS_PTR(LTYPE(tree)) || - IS_ARRAY(LTYPE(tree)) || - IS_ARITHMETIC(LTYPE(tree)))) { - werror(E_PLUS_INVALID,"-"); - goto errorTreeReturn ; - } - - if (!(IS_PTR(RTYPE(tree)) || - IS_ARRAY(RTYPE(tree)) || - IS_ARITHMETIC(RTYPE(tree)))) { - werror(E_PLUS_INVALID,"-"); - goto errorTreeReturn ; - } - - if ( (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) && - ! (IS_PTR(RTYPE(tree)) || IS_ARRAY(RTYPE(tree)) || - IS_INTEGRAL(RTYPE(tree))) ) { - werror(E_PLUS_INVALID,"-"); - goto errorTreeReturn ; - } - - /* if they are both literal then */ - /* rewrite the tree */ - if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) { - tree->type = EX_VALUE ; - tree->opval.val = valMinus (valFromType(LETYPE(tree)), - valFromType(RETYPE(tree))); - tree->right = tree->left = NULL; - TETYPE(tree) = getSpec(TTYPE(tree) = - tree->opval.val->type); - return tree ; - } - - /* if the left & right are equal then zero */ - if (isAstEqual(tree->left,tree->right)) { - tree->type = EX_VALUE; - tree->left = tree->right = NULL; - tree->opval.val = constVal("0"); - TETYPE(tree) = TTYPE(tree) = tree->opval.val->type; + if (IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valNot (valFromType (LETYPE (tree))); + tree->left = NULL; + TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; + return tree; + } + LRVAL (tree) = 1; + TTYPE (tree) = TETYPE (tree) = newCharLink (); return tree; - } - - /* if both of them are pointers or arrays then */ - /* the result is going to be an integer */ - if (( IS_ARRAY(LTYPE(tree)) || IS_PTR(LTYPE(tree))) && - ( IS_ARRAY(RTYPE(tree)) || IS_PTR(RTYPE(tree)))) - TETYPE(tree) = TTYPE(tree) = newIntLink(); - else - /* if only the left is a pointer */ - /* then result is a pointer */ - if (IS_PTR(LTYPE(tree)) || IS_ARRAY(LTYPE(tree))) - TETYPE(tree) = getSpec(TTYPE(tree) = - LTYPE(tree)); - else - TETYPE(tree) = getSpec (TTYPE(tree) = - computeType(LTYPE(tree), - RTYPE(tree))); - LRVAL(tree) = RRVAL(tree) = 1; - return tree ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* compliment */ - /*----------------------------*/ - case '~' : - /* can be only integral type */ - if (!IS_INTEGRAL(LTYPE(tree))) { - werror(E_UNARY_OP,tree->opval.op); - goto errorTreeReturn ; - } - - /* if left is a literal then do it */ - if (IS_LITERAL(LTYPE(tree))) { - tree->type = EX_VALUE ; - tree->opval.val = valComplement(valFromType(LETYPE(tree))); - tree->left = NULL ; - TETYPE(tree) = TTYPE(tree) = tree->opval.val->type; - return tree ; - } - LRVAL(tree) = 1; - COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)); - return tree ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* not */ - /*----------------------------*/ - case '!' : - /* can be pointer */ - if (!IS_ARITHMETIC(LTYPE(tree)) && - !IS_PTR(LTYPE(tree)) && - !IS_ARRAY(LTYPE(tree))) { - werror(E_UNARY_OP,tree->opval.op); - goto errorTreeReturn ; - } - /* if left is a literal then do it */ - if (IS_LITERAL(LTYPE(tree))) { - tree->type = EX_VALUE ; - tree->opval.val = valNot(valFromType(LETYPE(tree))); - tree->left = NULL ; - TETYPE(tree) = TTYPE(tree) = tree->opval.val->type; - return tree ; - } - LRVAL(tree) = 1; - TTYPE(tree) = TETYPE(tree) = newCharLink(); - return tree ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* shift */ - /*----------------------------*/ +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* shift */ +/*----------------------------*/ case RRC: case RLC: - TTYPE(tree) = LTYPE(tree); - TETYPE(tree) = LETYPE(tree); - return tree ; + TTYPE (tree) = LTYPE (tree); + TETYPE (tree) = LETYPE (tree); + return tree; case GETHBIT: - TTYPE(tree) = TETYPE(tree) = newCharLink(); - return tree; + TTYPE (tree) = TETYPE (tree) = newCharLink (); + return tree; case LEFT_OP: case RIGHT_OP: - if (!IS_INTEGRAL(LTYPE(tree)) || !IS_INTEGRAL(tree->left->etype)) { - werror(E_SHIFT_OP_INVALID); - werror(E_CONTINUE,"left & right types are "); - printTypeChain(LTYPE(tree),stderr); - fprintf(stderr,","); - printTypeChain(RTYPE(tree),stderr); - fprintf(stderr,"\n"); - goto errorTreeReturn ; - } - - /* if they are both literal then */ - /* rewrite the tree */ - if (IS_LITERAL(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))) { - tree->type = EX_VALUE ; - tree->opval.val = valShift (valFromType(LETYPE(tree)), - valFromType(RETYPE(tree)), - (tree->opval.op == LEFT_OP ? 1 : 0)); - tree->right = tree->left = NULL; - TETYPE(tree) = getSpec(TTYPE(tree) = - tree->opval.val->type); - return tree ; - } - /* if only the right side is a literal & we are - shifting more than size of the left operand then zero */ - if (IS_LITERAL(RTYPE(tree)) && - ((unsigned)floatFromVal( valFromType(RETYPE(tree)))) >= - (getSize(LTYPE(tree))*8)) { - werror(W_SHIFT_CHANGED, - (tree->opval.op == LEFT_OP ? "left" : "right")); - tree->type = EX_VALUE; - tree->left = tree->right = NULL; - tree->opval.val = constVal("0"); - TETYPE(tree) = TTYPE(tree) = tree->opval.val->type; + if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (tree->left->etype)) + { + werror (E_SHIFT_OP_INVALID); + werror (E_CONTINUE, "left & right types are "); + printTypeChain (LTYPE (tree), stderr); + fprintf (stderr, ","); + printTypeChain (RTYPE (tree), stderr); + fprintf (stderr, "\n"); + goto errorTreeReturn; + } + + /* if they are both literal then */ + /* rewrite the tree */ + if (IS_LITERAL (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valShift (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree)), + (tree->opval.op == LEFT_OP ? 1 : 0)); + tree->right = tree->left = NULL; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + return tree; + } + /* if only the right side is a literal & we are + shifting more than size of the left operand then zero */ + if (IS_LITERAL (RTYPE (tree)) && + ((unsigned) floatFromVal (valFromType (RETYPE (tree)))) >= + (getSize (LTYPE (tree)) * 8)) + { + werror (W_SHIFT_CHANGED, + (tree->opval.op == LEFT_OP ? "left" : "right")); + tree->type = EX_VALUE; + tree->left = tree->right = NULL; + tree->opval.val = constVal ("0"); + TETYPE (tree) = TTYPE (tree) = tree->opval.val->type; + return tree; + } + LRVAL (tree) = RRVAL (tree) = 1; + if (IS_LITERAL (LTYPE (tree)) && !IS_LITERAL (RTYPE (tree))) + { + COPYTYPE (TTYPE (tree), TETYPE (tree), RTYPE (tree)); + } + else + { + COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree)); + } return tree; - } - LRVAL(tree) = RRVAL(tree) = 1; - if (IS_LITERAL(LTYPE(tree)) && !IS_LITERAL(RTYPE(tree))) { - COPYTYPE(TTYPE(tree),TETYPE(tree),RTYPE(tree)); - } else { - COPYTYPE(TTYPE(tree),TETYPE(tree),LTYPE(tree)); - } - return tree ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* casting */ - /*----------------------------*/ - case CAST: /* change the type */ - /* cannot cast to an aggregate type */ - if (IS_AGGREGATE(LTYPE(tree))) { - werror(E_CAST_ILLEGAL); - goto errorTreeReturn ; - } - /* if the right is a literal replace the tree */ - if (IS_LITERAL(RETYPE(tree)) && !IS_PTR(LTYPE(tree))) { - tree->type = EX_VALUE ; - tree->opval.val = - valCastLiteral(LTYPE(tree), - floatFromVal(valFromType(RETYPE(tree)))); - tree->left = NULL; - tree->right = NULL; - TTYPE(tree) = tree->opval.val->type; - tree->values.literalFromCast = 1; - } - else { - TTYPE(tree) = LTYPE(tree); - LRVAL(tree) = 1; - } +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* casting */ +/*----------------------------*/ + case CAST: /* change the type */ + /* cannot cast to an aggregate type */ + if (IS_AGGREGATE (LTYPE (tree))) + { + werror (E_CAST_ILLEGAL); + goto errorTreeReturn; + } + + /* if the right is a literal replace the tree */ + if (IS_LITERAL (RETYPE (tree)) && !IS_PTR (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = + valCastLiteral (LTYPE (tree), + floatFromVal (valFromType (RETYPE (tree)))); + tree->left = NULL; + tree->right = NULL; + TTYPE (tree) = tree->opval.val->type; + tree->values.literalFromCast = 1; + } + else + { + TTYPE (tree) = LTYPE (tree); + LRVAL (tree) = 1; + } - TETYPE(tree) = getSpec(TTYPE(tree)); + TETYPE (tree) = getSpec (TTYPE (tree)); - return tree; + return tree; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* logical &&, || */ - /*----------------------------*/ +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* logical &&, || */ +/*----------------------------*/ case AND_OP: case OR_OP: - /* each must me arithmetic type or be a pointer */ - if (!IS_PTR(LTYPE(tree)) && - !IS_ARRAY(LTYPE(tree)) && - !IS_INTEGRAL(LTYPE(tree))) { - werror(E_COMPARE_OP); - goto errorTreeReturn ; - } - - if (!IS_PTR(RTYPE(tree)) && - !IS_ARRAY(RTYPE(tree)) && - !IS_INTEGRAL(RTYPE(tree))) { - werror(E_COMPARE_OP); - goto errorTreeReturn ; - } - /* if they are both literal then */ - /* rewrite the tree */ - if (IS_LITERAL(RTYPE(tree)) && - IS_LITERAL(LTYPE(tree))) { - tree->type = EX_VALUE ; - tree->opval.val = valLogicAndOr (valFromType(LETYPE(tree)), - valFromType(RETYPE(tree)), - tree->opval.op); - tree->right = tree->left = NULL; - TETYPE(tree) = getSpec(TTYPE(tree) = - tree->opval.val->type); - return tree ; - } - LRVAL(tree) = RRVAL(tree) = 1; - TTYPE(tree) = TETYPE(tree) = newCharLink(); - return tree ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* comparison operators */ - /*----------------------------*/ - case '>' : - case '<' : - case LE_OP : - case GE_OP : - case EQ_OP : - case NE_OP : - { - ast *lt = optimizeCompare(tree); + /* each must me arithmetic type or be a pointer */ + if (!IS_PTR (LTYPE (tree)) && + !IS_ARRAY (LTYPE (tree)) && + !IS_INTEGRAL (LTYPE (tree))) + { + werror (E_COMPARE_OP); + goto errorTreeReturn; + } + + if (!IS_PTR (RTYPE (tree)) && + !IS_ARRAY (RTYPE (tree)) && + !IS_INTEGRAL (RTYPE (tree))) + { + werror (E_COMPARE_OP); + goto errorTreeReturn; + } + /* if they are both literal then */ + /* rewrite the tree */ + if (IS_LITERAL (RTYPE (tree)) && + IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valLogicAndOr (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree)), + tree->opval.op); + tree->right = tree->left = NULL; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + return tree; + } + LRVAL (tree) = RRVAL (tree) = 1; + TTYPE (tree) = TETYPE (tree) = newCharLink (); + return tree; - if ( tree != lt ) - return lt; - } +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* comparison operators */ +/*----------------------------*/ + case '>': + case '<': + case LE_OP: + case GE_OP: + case EQ_OP: + case NE_OP: + { + ast *lt = optimizeCompare (tree); - /* if they are pointers they must be castable */ - if ( IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree))) { - if (checkType(LTYPE(tree),RTYPE(tree)) == 0) { - werror(E_COMPARE_OP); - fprintf(stderr,"comparing type "); - printTypeChain(LTYPE(tree),stderr); - fprintf(stderr,"to type "); - printTypeChain(RTYPE(tree),stderr); - fprintf(stderr,"\n"); - goto errorTreeReturn ; + if (tree != lt) + return lt; } - } - /* else they should be promotable to one another */ - else { - if (!( ( IS_PTR(LTYPE(tree)) && IS_LITERAL(RTYPE(tree))) || - ( IS_PTR(RTYPE(tree)) && IS_LITERAL(LTYPE(tree))))) - - if (checkType (LTYPE(tree),RTYPE(tree)) == 0 ) { - werror(E_COMPARE_OP); - fprintf(stderr,"comparing type "); - printTypeChain(LTYPE(tree),stderr); - fprintf(stderr,"to type "); - printTypeChain(RTYPE(tree),stderr); - fprintf(stderr,"\n"); - goto errorTreeReturn ; - } - } - /* if they are both literal then */ - /* rewrite the tree */ - if (IS_LITERAL(RTYPE(tree)) && - IS_LITERAL(LTYPE(tree))) { - tree->type = EX_VALUE ; - tree->opval.val = valCompare (valFromType(LETYPE(tree)), - valFromType(RETYPE(tree)), - tree->opval.op); + /* if they are pointers they must be castable */ + if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree))) + { + if (checkType (LTYPE (tree), RTYPE (tree)) == 0) + { + werror (E_COMPARE_OP); + fprintf (stderr, "comparing type "); + printTypeChain (LTYPE (tree), stderr); + fprintf (stderr, "to type "); + printTypeChain (RTYPE (tree), stderr); + fprintf (stderr, "\n"); + goto errorTreeReturn; + } + } + /* else they should be promotable to one another */ + else + { + if (!((IS_PTR (LTYPE (tree)) && IS_LITERAL (RTYPE (tree))) || + (IS_PTR (RTYPE (tree)) && IS_LITERAL (LTYPE (tree))))) + + if (checkType (LTYPE (tree), RTYPE (tree)) == 0) + { + werror (E_COMPARE_OP); + fprintf (stderr, "comparing type "); + printTypeChain (LTYPE (tree), stderr); + fprintf (stderr, "to type "); + printTypeChain (RTYPE (tree), stderr); + fprintf (stderr, "\n"); + goto errorTreeReturn; + } + } + + /* if they are both literal then */ + /* rewrite the tree */ + if (IS_LITERAL (RTYPE (tree)) && + IS_LITERAL (LTYPE (tree))) + { + tree->type = EX_VALUE; + tree->opval.val = valCompare (valFromType (LETYPE (tree)), + valFromType (RETYPE (tree)), + tree->opval.op); + tree->right = tree->left = NULL; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + return tree; + } + LRVAL (tree) = RRVAL (tree) = 1; + TTYPE (tree) = TETYPE (tree) = newCharLink (); + return tree; + +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* sizeof */ +/*----------------------------*/ + case SIZEOF: /* evaluate wihout code generation */ + /* change the type to a integer */ + tree->type = EX_VALUE; + sprintf (buffer, "%d", (getSize (tree->right->ftype))); + tree->opval.val = constVal (buffer); tree->right = tree->left = NULL; - TETYPE(tree) = getSpec(TTYPE(tree) = - tree->opval.val->type); - return tree ; - } - LRVAL(tree) = RRVAL(tree) = 1; - TTYPE(tree) = TETYPE(tree) = newCharLink(); - return tree ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* sizeof */ - /*----------------------------*/ - case SIZEOF : /* evaluate wihout code generation */ - /* change the type to a integer */ - tree->type = EX_VALUE; - sprintf(buffer,"%d",(getSize(tree->right->ftype))); - tree->opval.val = constVal(buffer); - tree->right = tree->left = NULL; - TETYPE(tree) = getSpec(TTYPE(tree) = - tree->opval.val->type); - return tree; + TETYPE (tree) = getSpec (TTYPE (tree) = + tree->opval.val->type); + return tree; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* conditional operator '?' */ - /*----------------------------*/ - case '?' : - /* the type is one on the left */ - TTYPE(tree) = LTYPE(tree); - TETYPE(tree)= getSpec (TTYPE(tree)); - return tree ; - - case ':' : - /* if they don't match we have a problem */ - if (checkType( LTYPE(tree), RTYPE(tree)) == 0) { - werror(E_TYPE_MISMATCH,"conditional operator"," "); - goto errorTreeReturn ; - } +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* conditional operator '?' */ +/*----------------------------*/ + case '?': + /* the type is one on the left */ + TTYPE (tree) = LTYPE (tree); + TETYPE (tree) = getSpec (TTYPE (tree)); + return tree; - TTYPE(tree) = computeType(LTYPE(tree),RTYPE(tree)); - TETYPE(tree)= getSpec(TTYPE(tree)); - return tree ; + case ':': + /* if they don't match we have a problem */ + if (checkType (LTYPE (tree), RTYPE (tree)) == 0) + { + werror (E_TYPE_MISMATCH, "conditional operator", " "); + goto errorTreeReturn; + } + + TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree)); + TETYPE (tree) = getSpec (TTYPE (tree)); + return tree; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* assignment operators */ - /*----------------------------*/ +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* assignment operators */ +/*----------------------------*/ case MUL_ASSIGN: case DIV_ASSIGN: - /* for these it must be both must be integral */ - if (!IS_ARITHMETIC(LTYPE(tree)) || - !IS_ARITHMETIC(RTYPE(tree))) { - werror (E_OPS_INTEGRAL); - goto errorTreeReturn ; - } - RRVAL(tree) = 1; - TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree)); - - if (!tree->initMode && IS_CONSTANT(LETYPE(tree))) - werror(E_CODE_WRITE," "); - - if (LRVAL(tree)) { - werror(E_LVALUE_REQUIRED,"*= or /="); - goto errorTreeReturn ; - } - LLVAL(tree) = 1; - - propAsgType(tree); + /* for these it must be both must be integral */ + if (!IS_ARITHMETIC (LTYPE (tree)) || + !IS_ARITHMETIC (RTYPE (tree))) + { + werror (E_OPS_INTEGRAL); + goto errorTreeReturn; + } + RRVAL (tree) = 1; + TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)); + + if (!tree->initMode && IS_CONSTANT (LETYPE (tree))) + werror (E_CODE_WRITE, " "); + + if (LRVAL (tree)) + { + werror (E_LVALUE_REQUIRED, "*= or /="); + goto errorTreeReturn; + } + LLVAL (tree) = 1; + + propAsgType (tree); - return tree ; + return tree; case AND_ASSIGN: case OR_ASSIGN: case XOR_ASSIGN: case RIGHT_ASSIGN: case LEFT_ASSIGN: - /* for these it must be both must be integral */ - if (!IS_INTEGRAL(LTYPE(tree)) || - !IS_INTEGRAL(RTYPE(tree))) { - werror (E_OPS_INTEGRAL); - goto errorTreeReturn ; - } - RRVAL(tree) = 1; - TETYPE(tree) = getSpec(TTYPE(tree) = LTYPE(tree)); - - if (!tree->initMode && IS_CONSTANT(LETYPE(tree))) - werror(E_CODE_WRITE," "); - - if (LRVAL(tree)) { - werror(E_LVALUE_REQUIRED,"&= or |= or ^= or >>= or <<="); - goto errorTreeReturn ; - } - LLVAL(tree) = 1; + /* for these it must be both must be integral */ + if (!IS_INTEGRAL (LTYPE (tree)) || + !IS_INTEGRAL (RTYPE (tree))) + { + werror (E_OPS_INTEGRAL); + goto errorTreeReturn; + } + RRVAL (tree) = 1; + TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)); + + if (!tree->initMode && IS_CONSTANT (LETYPE (tree))) + werror (E_CODE_WRITE, " "); + + if (LRVAL (tree)) + { + werror (E_LVALUE_REQUIRED, "&= or |= or ^= or >>= or <<="); + goto errorTreeReturn; + } + LLVAL (tree) = 1; + + propAsgType (tree); - propAsgType(tree); - - return tree ; + return tree; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* -= operator */ - /*----------------------------*/ +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* -= operator */ +/*----------------------------*/ case SUB_ASSIGN: - if (!(IS_PTR(LTYPE(tree)) || - IS_ARITHMETIC(LTYPE(tree)))) { - werror(E_PLUS_INVALID,"-="); - goto errorTreeReturn ; - } - - if (!(IS_PTR(RTYPE(tree)) || - IS_ARITHMETIC(RTYPE(tree)))) { - werror(E_PLUS_INVALID,"-="); - goto errorTreeReturn ; - } - RRVAL(tree) = 1; - TETYPE(tree) = getSpec (TTYPE(tree) = - computeType(LTYPE(tree), - RTYPE(tree))); + if (!(IS_PTR (LTYPE (tree)) || + IS_ARITHMETIC (LTYPE (tree)))) + { + werror (E_PLUS_INVALID, "-="); + goto errorTreeReturn; + } + + if (!(IS_PTR (RTYPE (tree)) || + IS_ARITHMETIC (RTYPE (tree)))) + { + werror (E_PLUS_INVALID, "-="); + goto errorTreeReturn; + } + RRVAL (tree) = 1; + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + RTYPE (tree))); + + if (!tree->initMode && IS_CONSTANT (LETYPE (tree))) + werror (E_CODE_WRITE, " "); + + if (LRVAL (tree)) + { + werror (E_LVALUE_REQUIRED, "-="); + goto errorTreeReturn; + } + LLVAL (tree) = 1; + + propAsgType (tree); - if (!tree->initMode && IS_CONSTANT(LETYPE(tree))) - werror(E_CODE_WRITE," "); - - if (LRVAL(tree)) { - werror(E_LVALUE_REQUIRED,"-="); - goto errorTreeReturn ; - } - LLVAL(tree) = 1; - - propAsgType(tree); - - return tree; + return tree; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* += operator */ - /*----------------------------*/ +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* += operator */ +/*----------------------------*/ case ADD_ASSIGN: - /* this is not a unary operation */ - /* if both pointers then problem */ - if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) ) { - werror(E_PTR_PLUS_PTR); - goto errorTreeReturn ; - } - - if (!IS_ARITHMETIC(LTYPE(tree)) && !IS_PTR(LTYPE(tree))) { - werror(E_PLUS_INVALID,"+="); - goto errorTreeReturn ; - } - - if (!IS_ARITHMETIC(RTYPE(tree)) && !IS_PTR(RTYPE(tree))) { - werror(E_PLUS_INVALID,"+="); - goto errorTreeReturn; - } - RRVAL(tree) = 1; - TETYPE(tree) = getSpec (TTYPE(tree) = - computeType(LTYPE(tree), - RTYPE(tree))); - - if (!tree->initMode && IS_CONSTANT(LETYPE(tree))) - werror(E_CODE_WRITE," "); - - if (LRVAL(tree)) { - werror(E_LVALUE_REQUIRED,"+="); - goto errorTreeReturn ; - } - - tree->right = decorateType(newNode('+',copyAst(tree->left),tree->right)); - tree->opval.op = '='; - - propAsgType(tree); - - return tree; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* straight assignemnt */ - /*----------------------------*/ - case '=' : - /* cannot be an aggregate */ - if (IS_AGGREGATE(LTYPE(tree))) { - werror(E_AGGR_ASSIGN); - goto errorTreeReturn; - } - - /* they should either match or be castable */ - if (checkType (LTYPE(tree),RTYPE(tree)) == 0) { - werror(E_TYPE_MISMATCH,"assignment"," "); - fprintf(stderr,"type --> '"); - printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' "); - fprintf(stderr,"assigned to type --> '"); - printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n"); - goto errorTreeReturn ; - } + /* this is not a unary operation */ + /* if both pointers then problem */ + if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree))) + { + werror (E_PTR_PLUS_PTR); + goto errorTreeReturn; + } + + if (!IS_ARITHMETIC (LTYPE (tree)) && !IS_PTR (LTYPE (tree))) + { + werror (E_PLUS_INVALID, "+="); + goto errorTreeReturn; + } + + if (!IS_ARITHMETIC (RTYPE (tree)) && !IS_PTR (RTYPE (tree))) + { + werror (E_PLUS_INVALID, "+="); + goto errorTreeReturn; + } + RRVAL (tree) = 1; + TETYPE (tree) = getSpec (TTYPE (tree) = + computeType (LTYPE (tree), + RTYPE (tree))); + + if (!tree->initMode && IS_CONSTANT (LETYPE (tree))) + werror (E_CODE_WRITE, " "); + + if (LRVAL (tree)) + { + werror (E_LVALUE_REQUIRED, "+="); + goto errorTreeReturn; + } + + tree->right = decorateType (newNode ('+', copyAst (tree->left), tree->right)); + tree->opval.op = '='; + + propAsgType (tree); - /* if the left side of the tree is of type void - then report error */ - if (IS_VOID(LTYPE(tree))) { - werror(E_CAST_ZERO); - fprintf(stderr,"type --> '"); - printTypeChain (RTYPE(tree),stderr); fprintf(stderr,"' "); - fprintf(stderr,"assigned to type --> '"); - printTypeChain (LTYPE(tree),stderr); fprintf(stderr,"'\n"); - } + return tree; - /* extra checks for pointer types */ - if (IS_PTR(LTYPE(tree)) && IS_PTR(RTYPE(tree)) && - !IS_GENPTR(LTYPE(tree))) { - if (DCL_TYPE(LTYPE(tree)) != DCL_TYPE(RTYPE(tree))) - werror(W_PTR_ASSIGN); - } +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* straight assignemnt */ +/*----------------------------*/ + case '=': + /* cannot be an aggregate */ + if (IS_AGGREGATE (LTYPE (tree))) + { + werror (E_AGGR_ASSIGN); + goto errorTreeReturn; + } + + /* they should either match or be castable */ + if (checkType (LTYPE (tree), RTYPE (tree)) == 0) + { + werror (E_TYPE_MISMATCH, "assignment", " "); + fprintf (stderr, "type --> '"); + printTypeChain (RTYPE (tree), stderr); + fprintf (stderr, "' "); + fprintf (stderr, "assigned to type --> '"); + printTypeChain (LTYPE (tree), stderr); + fprintf (stderr, "'\n"); + goto errorTreeReturn; + } + + /* if the left side of the tree is of type void + then report error */ + if (IS_VOID (LTYPE (tree))) + { + werror (E_CAST_ZERO); + fprintf (stderr, "type --> '"); + printTypeChain (RTYPE (tree), stderr); + fprintf (stderr, "' "); + fprintf (stderr, "assigned to type --> '"); + printTypeChain (LTYPE (tree), stderr); + fprintf (stderr, "'\n"); + } + + /* extra checks for pointer types */ + if (IS_PTR (LTYPE (tree)) && IS_PTR (RTYPE (tree)) && + !IS_GENPTR (LTYPE (tree))) + { + if (DCL_TYPE (LTYPE (tree)) != DCL_TYPE (RTYPE (tree))) + werror (W_PTR_ASSIGN); + } + + TETYPE (tree) = getSpec (TTYPE (tree) = + LTYPE (tree)); + RRVAL (tree) = 1; + LLVAL (tree) = 1; + if (!tree->initMode && IS_CONSTANT (LETYPE (tree))) + werror (E_CODE_WRITE, " "); + + if (LRVAL (tree)) + { + werror (E_LVALUE_REQUIRED, "="); + goto errorTreeReturn; + } + + propAsgType (tree); - TETYPE(tree) = getSpec(TTYPE(tree) = - LTYPE(tree)); - RRVAL(tree) = 1; - LLVAL(tree) = 1; - if (!tree->initMode && IS_CONSTANT(LETYPE(tree))) - werror(E_CODE_WRITE," "); + return tree; - if (LRVAL(tree)) { - werror(E_LVALUE_REQUIRED,"="); - goto errorTreeReturn ; - } +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* comma operator */ +/*----------------------------*/ + case ',': + TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree)); + return tree; - propAsgType(tree); - - return tree ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* comma operator */ - /*----------------------------*/ - case ',' : - TETYPE(tree) = getSpec(TTYPE(tree) = RTYPE(tree)); - return tree ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* function call */ - /*----------------------------*/ - case CALL : - parmNumber = 1; - - if (processParms (tree->left, - tree->left->args, - tree->right,&parmNumber,TRUE)) - goto errorTreeReturn ; - - if (options.stackAuto || IS_RENT(LETYPE(tree))) { - tree->left->args = reverseVal(tree->left->args); - reverseParms(tree->right); - } +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* function call */ +/*----------------------------*/ + case CALL: + parmNumber = 1; - tree->args = tree->left->args ; - TETYPE(tree) = getSpec (TTYPE(tree) = LTYPE(tree)->next); - return tree; + if (processParms (tree->left, + tree->left->args, + tree->right, &parmNumber, TRUE)) + goto errorTreeReturn; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* return statement */ - /*----------------------------*/ - case RETURN : - if (!tree->right) - goto voidcheck ; - - if (checkType(currFunc->type->next,RTYPE(tree)) == 0) { - werror(E_RETURN_MISMATCH); - goto errorTreeReturn ; - } + if (options.stackAuto || IS_RENT (LETYPE (tree))) + { + tree->left->args = reverseVal (tree->left->args); + reverseParms (tree->right); + } - if (IS_VOID(currFunc->type->next) - && tree->right && - !IS_VOID(RTYPE(tree))) { - werror(E_FUNC_VOID); - goto errorTreeReturn ; - } + tree->args = tree->left->args; + TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next); + return tree; - /* if there is going to be a casing required then add it */ - if (checkType(currFunc->type->next,RTYPE(tree)) < 0 ) - { +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* return statement */ +/*----------------------------*/ + case RETURN: + if (!tree->right) + goto voidcheck; + + if (checkType (currFunc->type->next, RTYPE (tree)) == 0) + { + werror (E_RETURN_MISMATCH); + goto errorTreeReturn; + } + + if (IS_VOID (currFunc->type->next) + && tree->right && + !IS_VOID (RTYPE (tree))) + { + werror (E_FUNC_VOID); + goto errorTreeReturn; + } + + /* if there is going to be a casing required then add it */ + if (checkType (currFunc->type->next, RTYPE (tree)) < 0) + { #if 0 && defined DEMAND_INTEGER_PROMOTION - if (IS_INTEGRAL(currFunc->type->next)) - { - pushTypeCastToLeaves(currFunc->type->next, tree->right, &(tree->right)); - } - else + if (IS_INTEGRAL (currFunc->type->next)) + { + pushTypeCastToLeaves (currFunc->type->next, tree->right, &(tree->right)); + } + else #endif - { - tree->right = - decorateType(newNode(CAST, - newAst_LINK(copyLinkChain(currFunc->type->next)), - tree->right)); - } - } - - RRVAL(tree) = 1; - return tree; + { + tree->right = + decorateType (newNode (CAST, + newAst_LINK (copyLinkChain (currFunc->type->next)), + tree->right)); + } + } + + RRVAL (tree) = 1; + return tree; - voidcheck : + voidcheck: - if (!IS_VOID(currFunc->type->next) && tree->right == NULL ) { - werror(E_VOID_FUNC,currFunc->name); - goto errorTreeReturn ; - } + if (!IS_VOID (currFunc->type->next) && tree->right == NULL) + { + werror (E_VOID_FUNC, currFunc->name); + goto errorTreeReturn; + } - TTYPE(tree) = TETYPE(tree) = NULL ; - return tree ; + TTYPE (tree) = TETYPE (tree) = NULL; + return tree; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* switch statement */ - /*----------------------------*/ +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* switch statement */ +/*----------------------------*/ case SWITCH: - /* the switch value must be an integer */ - if (!IS_INTEGRAL(LTYPE(tree))) { - werror (E_SWITCH_NON_INTEGER); - goto errorTreeReturn ; - } - LRVAL(tree) = 1; - TTYPE(tree) = TETYPE(tree) = NULL ; - return tree ; - - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* ifx Statement */ - /*----------------------------*/ + /* the switch value must be an integer */ + if (!IS_INTEGRAL (LTYPE (tree))) + { + werror (E_SWITCH_NON_INTEGER); + goto errorTreeReturn; + } + LRVAL (tree) = 1; + TTYPE (tree) = TETYPE (tree) = NULL; + return tree; + +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* ifx Statement */ +/*----------------------------*/ case IFX: - tree->left = backPatchLabels(tree->left, - tree->trueLabel, - tree->falseLabel); - TTYPE(tree) = TETYPE(tree) = NULL; - return tree; + tree->left = backPatchLabels (tree->left, + tree->trueLabel, + tree->falseLabel); + TTYPE (tree) = TETYPE (tree) = NULL; + return tree; - /*------------------------------------------------------------------*/ - /*----------------------------*/ - /* for Statement */ - /*----------------------------*/ +/*------------------------------------------------------------------*/ +/*----------------------------*/ + /* for Statement */ +/*----------------------------*/ case FOR: - decorateType(resolveSymbols(AST_FOR(tree,initExpr))); - decorateType(resolveSymbols(AST_FOR(tree,condExpr))); - decorateType(resolveSymbols(AST_FOR(tree,loopExpr))); + decorateType (resolveSymbols (AST_FOR (tree, initExpr))); + decorateType (resolveSymbols (AST_FOR (tree, condExpr))); + decorateType (resolveSymbols (AST_FOR (tree, loopExpr))); - /* if the for loop is reversible then - reverse it otherwise do what we normally - do */ - { - symbol *sym ; - ast *init, *end; - - if (isLoopReversible (tree,&sym,&init,&end)) - return reverseLoop (tree,sym,init,end); - else - return decorateType(createFor ( AST_FOR(tree,trueLabel), - AST_FOR(tree,continueLabel) , - AST_FOR(tree,falseLabel) , - AST_FOR(tree,condLabel) , - AST_FOR(tree,initExpr) , - AST_FOR(tree,condExpr) , - AST_FOR(tree,loopExpr), - tree->left ) ); - } - default : - TTYPE(tree) = TETYPE(tree) = NULL ; - return tree ; + /* if the for loop is reversible then + reverse it otherwise do what we normally + do */ + { + symbol *sym; + ast *init, *end; + + if (isLoopReversible (tree, &sym, &init, &end)) + return reverseLoop (tree, sym, init, end); + else + return decorateType (createFor (AST_FOR (tree, trueLabel), + AST_FOR (tree, continueLabel), + AST_FOR (tree, falseLabel), + AST_FOR (tree, condLabel), + AST_FOR (tree, initExpr), + AST_FOR (tree, condExpr), + AST_FOR (tree, loopExpr), + tree->left)); + } + default: + TTYPE (tree) = TETYPE (tree) = NULL; + return tree; } - /* some error found this tree will be killed */ - errorTreeReturn : - TTYPE(tree) = TETYPE(tree) = newCharLink(); - tree->opval.op = NULLOP ; - tree->isError = 1; + /* some error found this tree will be killed */ +errorTreeReturn: + TTYPE (tree) = TETYPE (tree) = newCharLink (); + tree->opval.op = NULLOP; + tree->isError = 1; - return tree ; + return tree; } /*-----------------------------------------------------------------*/ /* sizeofOp - processes size of operation */ /*-----------------------------------------------------------------*/ -value *sizeofOp( sym_link *type) +value * +sizeofOp (sym_link * type) { char buff[10]; /* get the size and convert it to character */ - sprintf (buff,"%d", getSize(type)); + sprintf (buff, "%d", getSize (type)); /* now convert into value */ - return constVal (buff); + return constVal (buff); } @@ -2932,296 +3143,321 @@ value *sizeofOp( sym_link *type) /*-----------------------------------------------------------------*/ /* backPatchLabels - change and or not operators to flow control */ /*-----------------------------------------------------------------*/ -ast *backPatchLabels (ast *tree, symbol *trueLabel, symbol *falseLabel ) +ast * +backPatchLabels (ast * tree, symbol * trueLabel, symbol * falseLabel) { - if ( ! tree ) - return NULL ; + if (!tree) + return NULL; - if ( ! (IS_ANDORNOT(tree))) - return tree ; + if (!(IS_ANDORNOT (tree))) + return tree; - /* if this an and */ - if (IS_AND(tree)) { - static int localLbl = 0 ; - symbol *localLabel ; + /* if this an and */ + if (IS_AND (tree)) + { + static int localLbl = 0; + symbol *localLabel; - sprintf (buffer,"_and_%d",localLbl++); - localLabel = newSymbol(buffer,NestLevel); + sprintf (buffer, "_and_%d", localLbl++); + localLabel = newSymbol (buffer, NestLevel); - tree->left = backPatchLabels (tree->left, localLabel,falseLabel); + tree->left = backPatchLabels (tree->left, localLabel, falseLabel); - /* if left is already a IFX then just change the if true label in that */ - if (!IS_IFX(tree->left)) - tree->left = newIfxNode(tree->left,localLabel,falseLabel); + /* if left is already a IFX then just change the if true label in that */ + if (!IS_IFX (tree->left)) + tree->left = newIfxNode (tree->left, localLabel, falseLabel); - tree->right = backPatchLabels(tree->right,trueLabel,falseLabel); - /* right is a IFX then just join */ - if (IS_IFX(tree->right)) - return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right)); + tree->right = backPatchLabels (tree->right, trueLabel, falseLabel); + /* right is a IFX then just join */ + if (IS_IFX (tree->right)) + return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right)); - tree->right = createLabel(localLabel,tree->right); - tree->right = newIfxNode(tree->right,trueLabel,falseLabel); + tree->right = createLabel (localLabel, tree->right); + tree->right = newIfxNode (tree->right, trueLabel, falseLabel); - return newNode(NULLOP,tree->left,tree->right); + return newNode (NULLOP, tree->left, tree->right); } - /* if this is an or operation */ - if (IS_OR(tree)) { - static int localLbl = 0 ; - symbol *localLabel ; + /* if this is an or operation */ + if (IS_OR (tree)) + { + static int localLbl = 0; + symbol *localLabel; - sprintf (buffer,"_or_%d",localLbl++); - localLabel = newSymbol(buffer,NestLevel); + sprintf (buffer, "_or_%d", localLbl++); + localLabel = newSymbol (buffer, NestLevel); - tree->left = backPatchLabels (tree->left, trueLabel,localLabel); + tree->left = backPatchLabels (tree->left, trueLabel, localLabel); - /* if left is already a IFX then just change the if true label in that */ - if (!IS_IFX(tree->left)) - tree->left = newIfxNode(tree->left,trueLabel,localLabel); + /* if left is already a IFX then just change the if true label in that */ + if (!IS_IFX (tree->left)) + tree->left = newIfxNode (tree->left, trueLabel, localLabel); - tree->right = backPatchLabels(tree->right,trueLabel,falseLabel); - /* right is a IFX then just join */ - if (IS_IFX(tree->right)) - return newNode(NULLOP,tree->left,createLabel(localLabel,tree->right)); + tree->right = backPatchLabels (tree->right, trueLabel, falseLabel); + /* right is a IFX then just join */ + if (IS_IFX (tree->right)) + return newNode (NULLOP, tree->left, createLabel (localLabel, tree->right)); - tree->right = createLabel(localLabel,tree->right); - tree->right = newIfxNode(tree->right,trueLabel,falseLabel); + tree->right = createLabel (localLabel, tree->right); + tree->right = newIfxNode (tree->right, trueLabel, falseLabel); - return newNode(NULLOP,tree->left,tree->right); + return newNode (NULLOP, tree->left, tree->right); } - /* change not */ - if (IS_NOT(tree)) { - int wasnot = IS_NOT(tree->left); - tree->left = backPatchLabels (tree->left,falseLabel,trueLabel); - - /* if the left is already a IFX */ - if ( ! IS_IFX(tree->left) ) - tree->left = newNode (IFX,tree->left,NULL); - - if (wasnot) { - tree->left->trueLabel = trueLabel ; - tree->left->falseLabel= falseLabel ; - } else { - tree->left->trueLabel = falseLabel ; - tree->left->falseLabel= trueLabel ; - } - return tree->left ; + /* change not */ + if (IS_NOT (tree)) + { + int wasnot = IS_NOT (tree->left); + tree->left = backPatchLabels (tree->left, falseLabel, trueLabel); + + /* if the left is already a IFX */ + if (!IS_IFX (tree->left)) + tree->left = newNode (IFX, tree->left, NULL); + + if (wasnot) + { + tree->left->trueLabel = trueLabel; + tree->left->falseLabel = falseLabel; + } + else + { + tree->left->trueLabel = falseLabel; + tree->left->falseLabel = trueLabel; + } + return tree->left; } - if (IS_IFX(tree)) { - tree->trueLabel = trueLabel ; - tree->falseLabel= falseLabel; + if (IS_IFX (tree)) + { + tree->trueLabel = trueLabel; + tree->falseLabel = falseLabel; } - return tree ; + return tree; } /*-----------------------------------------------------------------*/ /* createBlock - create expression tree for block */ /*-----------------------------------------------------------------*/ -ast *createBlock ( symbol *decl, ast *body ) +ast * +createBlock (symbol * decl, ast * body) { - ast *ex ; + ast *ex; - /* if the block has nothing */ - if (!body) - return NULL; + /* if the block has nothing */ + if (!body) + return NULL; - ex = newNode(BLOCK,NULL,body); - ex->values.sym = decl ; + ex = newNode (BLOCK, NULL, body); + ex->values.sym = decl; - ex->right = ex->right ; - ex->level++ ; - ex->lineno = 0 ; - return ex; + ex->right = ex->right; + ex->level++; + ex->lineno = 0; + return ex; } /*-----------------------------------------------------------------*/ /* createLabel - creates the expression tree for labels */ /*-----------------------------------------------------------------*/ -ast *createLabel ( symbol *label, ast *stmnt ) +ast * +createLabel (symbol * label, ast * stmnt) { - symbol *csym; - char name[SDCC_NAME_MAX+1]; - ast *rValue ; - - /* must create fresh symbol if the symbol name */ - /* exists in the symbol table, since there can */ - /* be a variable with the same name as the labl */ - if ((csym = findSym (SymbolTab,NULL,label->name)) && - (csym->level == label->level)) - label = newSymbol(label->name,label->level); - - /* change the name before putting it in add _*/ - sprintf (name,"%s",label->name); - - /* put the label in the LabelSymbol table */ - /* but first check if a label of the same */ - /* name exists */ - if ( (csym = findSym(LabelTab,NULL,name))) - werror(E_DUPLICATE_LABEL,label->name); - else - addSym (LabelTab, label, name,label->level,0); - - label->islbl = 1; - label->key = labelKey++ ; - rValue = newNode (LABEL,newAst_VALUE(symbolVal(label)),stmnt); - rValue->lineno = 0; - - return rValue ; + symbol *csym; + char name[SDCC_NAME_MAX + 1]; + ast *rValue; + + /* must create fresh symbol if the symbol name */ + /* exists in the symbol table, since there can */ + /* be a variable with the same name as the labl */ + if ((csym = findSym (SymbolTab, NULL, label->name)) && + (csym->level == label->level)) + label = newSymbol (label->name, label->level); + + /* change the name before putting it in add _ */ + sprintf (name, "%s", label->name); + + /* put the label in the LabelSymbol table */ + /* but first check if a label of the same */ + /* name exists */ + if ((csym = findSym (LabelTab, NULL, name))) + werror (E_DUPLICATE_LABEL, label->name); + else + addSym (LabelTab, label, name, label->level, 0); + + label->islbl = 1; + label->key = labelKey++; + rValue = newNode (LABEL, newAst_VALUE (symbolVal (label)), stmnt); + rValue->lineno = 0; + + return rValue; } /*-----------------------------------------------------------------*/ /* createCase - generates the parsetree for a case statement */ /*-----------------------------------------------------------------*/ -ast *createCase (ast *swStat, ast *caseVal, ast *stmnt ) +ast * +createCase (ast * swStat, ast * caseVal, ast * stmnt) { - char caseLbl[SDCC_NAME_MAX+1]; - ast *rexpr; - value *val; + char caseLbl[SDCC_NAME_MAX + 1]; + ast *rexpr; + value *val; - /* if the switch statement does not exist */ - /* then case is out of context */ - if (!swStat) { - werror(E_CASE_CONTEXT); - return NULL ; + /* if the switch statement does not exist */ + /* then case is out of context */ + if (!swStat) + { + werror (E_CASE_CONTEXT); + return NULL; } - caseVal = decorateType(resolveSymbols(caseVal)); - /* if not a constant then error */ - if (!IS_LITERAL(caseVal->ftype)) { - werror(E_CASE_CONSTANT); - return NULL ; + caseVal = decorateType (resolveSymbols (caseVal)); + /* if not a constant then error */ + if (!IS_LITERAL (caseVal->ftype)) + { + werror (E_CASE_CONSTANT); + return NULL; } - /* if not a integer than error */ - if (!IS_INTEGRAL(caseVal->ftype)) { - werror(E_CASE_NON_INTEGER); - return NULL; + /* if not a integer than error */ + if (!IS_INTEGRAL (caseVal->ftype)) + { + werror (E_CASE_NON_INTEGER); + return NULL; } - /* find the end of the switch values chain */ - if (!(val = swStat->values.switchVals.swVals)) - swStat->values.switchVals.swVals = caseVal->opval.val ; - else { - /* also order the cases according to value */ - value *pval = NULL; - int cVal = (int) floatFromVal(caseVal->opval.val); - while (val && (int) floatFromVal(val) < cVal) { - pval = val; - val = val->next ; - } - - /* if we reached the end then */ - if (!val) { - pval->next = caseVal->opval.val; - } else { - /* we found a value greater than */ - /* the current value we must add this */ - /* before the value */ - caseVal->opval.val->next = val; - - /* if this was the first in chain */ - if (swStat->values.switchVals.swVals == val) - swStat->values.switchVals.swVals = - caseVal->opval.val; + /* find the end of the switch values chain */ + if (!(val = swStat->values.switchVals.swVals)) + swStat->values.switchVals.swVals = caseVal->opval.val; + else + { + /* also order the cases according to value */ + value *pval = NULL; + int cVal = (int) floatFromVal (caseVal->opval.val); + while (val && (int) floatFromVal (val) < cVal) + { + pval = val; + val = val->next; + } + + /* if we reached the end then */ + if (!val) + { + pval->next = caseVal->opval.val; + } else - pval->next = caseVal->opval.val; - } + { + /* we found a value greater than */ + /* the current value we must add this */ + /* before the value */ + caseVal->opval.val->next = val; + + /* if this was the first in chain */ + if (swStat->values.switchVals.swVals == val) + swStat->values.switchVals.swVals = + caseVal->opval.val; + else + pval->next = caseVal->opval.val; + } } - /* create the case label */ - sprintf(caseLbl,"_case_%d_%d", - swStat->values.switchVals.swNum, - (int) floatFromVal(caseVal->opval.val)); + /* create the case label */ + sprintf (caseLbl, "_case_%d_%d", + swStat->values.switchVals.swNum, + (int) floatFromVal (caseVal->opval.val)); - rexpr = createLabel(newSymbol(caseLbl,0),stmnt); - rexpr->lineno = 0; - return rexpr; + rexpr = createLabel (newSymbol (caseLbl, 0), stmnt); + rexpr->lineno = 0; + return rexpr; } /*-----------------------------------------------------------------*/ -/* createDefault - creates the parse tree for the default statement*/ +/* createDefault - creates the parse tree for the default statement */ /*-----------------------------------------------------------------*/ -ast *createDefault (ast *swStat, ast *stmnt) +ast * +createDefault (ast * swStat, ast * stmnt) { - char defLbl[SDCC_NAME_MAX+1]; + char defLbl[SDCC_NAME_MAX + 1]; - /* if the switch statement does not exist */ - /* then case is out of context */ - if (!swStat) { - werror(E_CASE_CONTEXT); - return NULL ; + /* if the switch statement does not exist */ + /* then case is out of context */ + if (!swStat) + { + werror (E_CASE_CONTEXT); + return NULL; } - /* turn on the default flag */ - swStat->values.switchVals.swDefault = 1 ; + /* turn on the default flag */ + swStat->values.switchVals.swDefault = 1; - /* create the label */ - sprintf (defLbl,"_default_%d",swStat->values.switchVals.swNum); - return createLabel(newSymbol(defLbl,0),stmnt); + /* create the label */ + sprintf (defLbl, "_default_%d", swStat->values.switchVals.swNum); + return createLabel (newSymbol (defLbl, 0), stmnt); } /*-----------------------------------------------------------------*/ /* createIf - creates the parsetree for the if statement */ /*-----------------------------------------------------------------*/ -ast *createIf ( ast *condAst, ast *ifBody, ast *elseBody ) +ast * +createIf (ast * condAst, ast * ifBody, ast * elseBody) { - static int Lblnum = 0 ; - ast *ifTree ; - symbol *ifTrue , *ifFalse, *ifEnd ; - - /* if neither exists */ - if (! elseBody && !ifBody) - return condAst ; - - /* create the labels */ - sprintf (buffer,"_iffalse_%d",Lblnum); - ifFalse = newSymbol (buffer,NestLevel); - /* if no else body then end == false */ - if ( ! elseBody ) - ifEnd = ifFalse ; - else { - sprintf (buffer,"_ifend_%d",Lblnum); - ifEnd = newSymbol (buffer,NestLevel); - } - - sprintf (buffer,"_iftrue_%d",Lblnum); - ifTrue = newSymbol (buffer,NestLevel); - - Lblnum++ ; - - /* attach the ifTrue label to the top of it body */ - ifBody = createLabel(ifTrue,ifBody); - /* attach a goto end to the ifBody if else is present */ - if ( elseBody ) { - ifBody = newNode(NULLOP,ifBody, - newNode(GOTO, - newAst_VALUE(symbolVal(ifEnd)), - NULL)); - /* put the elseLabel on the else body */ - elseBody = createLabel (ifFalse,elseBody); - /* out the end at the end of the body */ - elseBody = newNode(NULLOP, - elseBody, - createLabel(ifEnd,NULL)); - } - else { - ifBody = newNode(NULLOP,ifBody, - createLabel(ifFalse,NULL)); - } - condAst = backPatchLabels (condAst,ifTrue,ifFalse); - if (IS_IFX(condAst)) - ifTree = condAst; - else - ifTree = newIfxNode(condAst,ifTrue,ifFalse); - - return newNode(NULLOP,ifTree, - newNode(NULLOP,ifBody,elseBody)); + static int Lblnum = 0; + ast *ifTree; + symbol *ifTrue, *ifFalse, *ifEnd; + + /* if neither exists */ + if (!elseBody && !ifBody) + return condAst; + + /* create the labels */ + sprintf (buffer, "_iffalse_%d", Lblnum); + ifFalse = newSymbol (buffer, NestLevel); + /* if no else body then end == false */ + if (!elseBody) + ifEnd = ifFalse; + else + { + sprintf (buffer, "_ifend_%d", Lblnum); + ifEnd = newSymbol (buffer, NestLevel); + } + + sprintf (buffer, "_iftrue_%d", Lblnum); + ifTrue = newSymbol (buffer, NestLevel); + + Lblnum++; + + /* attach the ifTrue label to the top of it body */ + ifBody = createLabel (ifTrue, ifBody); + /* attach a goto end to the ifBody if else is present */ + if (elseBody) + { + ifBody = newNode (NULLOP, ifBody, + newNode (GOTO, + newAst_VALUE (symbolVal (ifEnd)), + NULL)); + /* put the elseLabel on the else body */ + elseBody = createLabel (ifFalse, elseBody); + /* out the end at the end of the body */ + elseBody = newNode (NULLOP, + elseBody, + createLabel (ifEnd, NULL)); + } + else + { + ifBody = newNode (NULLOP, ifBody, + createLabel (ifFalse, NULL)); + } + condAst = backPatchLabels (condAst, ifTrue, ifFalse); + if (IS_IFX (condAst)) + ifTree = condAst; + else + ifTree = newIfxNode (condAst, ifTrue, ifFalse); + + return newNode (NULLOP, ifTree, + newNode (NULLOP, ifBody, elseBody)); } @@ -3235,41 +3471,43 @@ ast *createIf ( ast *condAst, ast *ifBody, ast *elseBody ) /* +-> falseLabel-> _dobreak_n */ /* _dobreak_n: */ /*-----------------------------------------------------------------*/ -ast *createDo ( symbol *trueLabel, symbol *continueLabel, - symbol *falseLabel, ast *condAst, ast *doBody ) +ast * +createDo (symbol * trueLabel, symbol * continueLabel, + symbol * falseLabel, ast * condAst, ast * doBody) { - ast *doTree ; + ast *doTree; - /* if the body does not exist then it is simple */ - if ( ! doBody ) { - condAst = backPatchLabels(condAst,continueLabel,NULL); - doTree = (IS_IFX(condAst) ? createLabel(continueLabel,condAst) - : newNode(IFX,createLabel(continueLabel,condAst),NULL)); - doTree->trueLabel = continueLabel ; - doTree->falseLabel= NULL ; - return doTree ; + /* if the body does not exist then it is simple */ + if (!doBody) + { + condAst = backPatchLabels (condAst, continueLabel, NULL); + doTree = (IS_IFX (condAst) ? createLabel (continueLabel, condAst) + : newNode (IFX, createLabel (continueLabel, condAst), NULL)); + doTree->trueLabel = continueLabel; + doTree->falseLabel = NULL; + return doTree; } - /* otherwise we have a body */ - condAst = backPatchLabels(condAst,trueLabel,falseLabel); + /* otherwise we have a body */ + condAst = backPatchLabels (condAst, trueLabel, falseLabel); - /* attach the body label to the top */ - doBody = createLabel(trueLabel,doBody); - /* attach the continue label to end of body */ - doBody = newNode(NULLOP, doBody, - createLabel(continueLabel,NULL)); + /* attach the body label to the top */ + doBody = createLabel (trueLabel, doBody); + /* attach the continue label to end of body */ + doBody = newNode (NULLOP, doBody, + createLabel (continueLabel, NULL)); - /* now put the break label at the end */ - if (IS_IFX(condAst)) - doTree = condAst; - else - doTree = newIfxNode(condAst,trueLabel,falseLabel); + /* now put the break label at the end */ + if (IS_IFX (condAst)) + doTree = condAst; + else + doTree = newIfxNode (condAst, trueLabel, falseLabel); - doTree = newNode(NULLOP,doTree,createLabel(falseLabel,NULL)); + doTree = newNode (NULLOP, doTree, createLabel (falseLabel, NULL)); - /* putting it together */ - return newNode(NULLOP,doBody,doTree); + /* putting it together */ + return newNode (NULLOP, doBody, doTree); } /*-----------------------------------------------------------------*/ @@ -3286,48 +3524,49 @@ ast *createDo ( symbol *trueLabel, symbol *continueLabel, /* goto _forcond_n ; */ /* _forbreak_n: */ /*-----------------------------------------------------------------*/ -ast *createFor ( symbol *trueLabel, symbol *continueLabel , - symbol *falseLabel,symbol *condLabel , - ast *initExpr, ast *condExpr, ast *loopExpr, - ast *forBody ) +ast * +createFor (symbol * trueLabel, symbol * continueLabel, + symbol * falseLabel, symbol * condLabel, + ast * initExpr, ast * condExpr, ast * loopExpr, + ast * forBody) { - ast *forTree ; - - /* if loopexpression not present then we can generate it */ - /* the same way as a while */ - if ( ! loopExpr ) - return newNode(NULLOP,initExpr, - createWhile (trueLabel, continueLabel, - falseLabel,condExpr, forBody )); - /* vanilla for statement */ - condExpr = backPatchLabels(condExpr,trueLabel,falseLabel); - - if (condExpr && !IS_IFX(condExpr)) - condExpr = newIfxNode(condExpr,trueLabel,falseLabel); - - - /* attach condition label to condition */ - condExpr = createLabel(condLabel,condExpr); - - /* attach body label to body */ - forBody = createLabel(trueLabel,forBody); - - /* attach continue to forLoop expression & attach */ - /* goto the forcond @ and of loopExpression */ - loopExpr = createLabel(continueLabel, - newNode(NULLOP, - loopExpr, - newNode(GOTO, - newAst_VALUE(symbolVal(condLabel)), - NULL))); - /* now start putting them together */ - forTree = newNode(NULLOP,initExpr,condExpr); - forTree = newNode(NULLOP,forTree,forBody); - forTree = newNode(NULLOP,forTree,loopExpr); - /* finally add the break label */ - forTree = newNode(NULLOP,forTree, - createLabel(falseLabel,NULL)); - return forTree ; + ast *forTree; + + /* if loopexpression not present then we can generate it */ + /* the same way as a while */ + if (!loopExpr) + return newNode (NULLOP, initExpr, + createWhile (trueLabel, continueLabel, + falseLabel, condExpr, forBody)); + /* vanilla for statement */ + condExpr = backPatchLabels (condExpr, trueLabel, falseLabel); + + if (condExpr && !IS_IFX (condExpr)) + condExpr = newIfxNode (condExpr, trueLabel, falseLabel); + + + /* attach condition label to condition */ + condExpr = createLabel (condLabel, condExpr); + + /* attach body label to body */ + forBody = createLabel (trueLabel, forBody); + + /* attach continue to forLoop expression & attach */ + /* goto the forcond @ and of loopExpression */ + loopExpr = createLabel (continueLabel, + newNode (NULLOP, + loopExpr, + newNode (GOTO, + newAst_VALUE (symbolVal (condLabel)), + NULL))); + /* now start putting them together */ + forTree = newNode (NULLOP, initExpr, condExpr); + forTree = newNode (NULLOP, forTree, forBody); + forTree = newNode (NULLOP, forTree, loopExpr); + /* finally add the break label */ + forTree = newNode (NULLOP, forTree, + createLabel (falseLabel, NULL)); + return forTree; } /*-----------------------------------------------------------------*/ @@ -3337,378 +3576,401 @@ ast *createFor ( symbol *trueLabel, symbol *continueLabel , /* _while_continue_n: */ /* condition_expression +-> trueLabel -> _while_boby_n */ /* | */ -/* +-> falseLabel -> _while_break_n*/ +/* +-> falseLabel -> _while_break_n */ /* _while_body_n: */ /* statements */ /* goto _while_continue_n */ /* _while_break_n: */ /*-----------------------------------------------------------------*/ -ast *createWhile (symbol *trueLabel, symbol *continueLabel, - symbol *falseLabel,ast *condExpr, ast *whileBody ) +ast * +createWhile (symbol * trueLabel, symbol * continueLabel, + symbol * falseLabel, ast * condExpr, ast * whileBody) { - ast *whileTree ; - - /* put the continue label */ - condExpr = backPatchLabels (condExpr,trueLabel,falseLabel); - condExpr = createLabel(continueLabel,condExpr); - condExpr->lineno = 0; - - /* put the body label in front of the body */ - whileBody = createLabel(trueLabel,whileBody); - whileBody->lineno = 0; - /* put a jump to continue at the end of the body */ - /* and put break label at the end of the body */ - whileBody = newNode(NULLOP, - whileBody, - newNode(GOTO, - newAst_VALUE(symbolVal(continueLabel)), - createLabel(falseLabel,NULL))); - - /* put it all together */ - if ( IS_IFX(condExpr) ) - whileTree = condExpr ; - else { - whileTree = newNode (IFX, condExpr,NULL ); - /* put the true & false labels in place */ - whileTree->trueLabel = trueLabel ; - whileTree->falseLabel= falseLabel; - } - - return newNode(NULLOP,whileTree,whileBody ); + ast *whileTree; + + /* put the continue label */ + condExpr = backPatchLabels (condExpr, trueLabel, falseLabel); + condExpr = createLabel (continueLabel, condExpr); + condExpr->lineno = 0; + + /* put the body label in front of the body */ + whileBody = createLabel (trueLabel, whileBody); + whileBody->lineno = 0; + /* put a jump to continue at the end of the body */ + /* and put break label at the end of the body */ + whileBody = newNode (NULLOP, + whileBody, + newNode (GOTO, + newAst_VALUE (symbolVal (continueLabel)), + createLabel (falseLabel, NULL))); + + /* put it all together */ + if (IS_IFX (condExpr)) + whileTree = condExpr; + else + { + whileTree = newNode (IFX, condExpr, NULL); + /* put the true & false labels in place */ + whileTree->trueLabel = trueLabel; + whileTree->falseLabel = falseLabel; + } + + return newNode (NULLOP, whileTree, whileBody); } /*-----------------------------------------------------------------*/ /* optimizeGetHbit - get highest order bit of the expression */ /*-----------------------------------------------------------------*/ -ast *optimizeGetHbit (ast *tree) +ast * +optimizeGetHbit (ast * tree) { - int i,j; - /* if this is not a bit and */ - if (!IS_BITAND(tree)) - return tree; + int i, j; + /* if this is not a bit and */ + if (!IS_BITAND (tree)) + return tree; - /* will look for tree of the form - ( expr >> ((sizeof expr) -1) ) & 1 */ - if (!IS_AST_LIT_VALUE(tree->right)) - return tree; + /* will look for tree of the form + ( expr >> ((sizeof expr) -1) ) & 1 */ + if (!IS_AST_LIT_VALUE (tree->right)) + return tree; - if (AST_LIT_VALUE(tree->right) != 1) - return tree; + if (AST_LIT_VALUE (tree->right) != 1) + return tree; - if (!IS_RIGHT_OP(tree->left)) - return tree; + if (!IS_RIGHT_OP (tree->left)) + return tree; - if (!IS_AST_LIT_VALUE(tree->left->right)) - return tree; + if (!IS_AST_LIT_VALUE (tree->left->right)) + return tree; - if ((i = (int) AST_LIT_VALUE(tree->left->right)) != - ( j = (getSize(TTYPE(tree->left->left))*8 - 1))) - return tree; + if ((i = (int) AST_LIT_VALUE (tree->left->right)) != + (j = (getSize (TTYPE (tree->left->left)) * 8 - 1))) + return tree; - return decorateType(newNode(GETHBIT,tree->left->left,NULL)); + return decorateType (newNode (GETHBIT, tree->left->left, NULL)); } /*-----------------------------------------------------------------*/ /* optimizeRRCRLC :- optimize for Rotate Left/Right with carry */ /*-----------------------------------------------------------------*/ -ast *optimizeRRCRLC ( ast *root ) +ast * +optimizeRRCRLC (ast * root) { - /* will look for trees of the form - (?expr << 1) | (?expr >> 7) or - (?expr >> 7) | (?expr << 1) will make that - into a RLC : operation .. - Will also look for - (?expr >> 1) | (?expr << 7) or - (?expr << 7) | (?expr >> 1) will make that - into a RRC operation - note : by 7 I mean (number of bits required to hold the - variable -1 ) */ - /* if the root operations is not a | operation the not */ - if (!IS_BITOR(root)) - return root ; - - /* I have to think of a better way to match patterns this sucks */ - /* that aside let start looking for the first case : I use a the - negative check a lot to improve the efficiency */ - /* (?expr << 1) | (?expr >> 7) */ - if (IS_LEFT_OP(root->left) && - IS_RIGHT_OP(root->right) ) { - - if (!SPEC_USIGN(TETYPE(root->left->left))) - return root; + /* will look for trees of the form + (?expr << 1) | (?expr >> 7) or + (?expr >> 7) | (?expr << 1) will make that + into a RLC : operation .. + Will also look for + (?expr >> 1) | (?expr << 7) or + (?expr << 7) | (?expr >> 1) will make that + into a RRC operation + note : by 7 I mean (number of bits required to hold the + variable -1 ) */ + /* if the root operations is not a | operation the not */ + if (!IS_BITOR (root)) + return root; + + /* I have to think of a better way to match patterns this sucks */ + /* that aside let start looking for the first case : I use a the + negative check a lot to improve the efficiency */ + /* (?expr << 1) | (?expr >> 7) */ + if (IS_LEFT_OP (root->left) && + IS_RIGHT_OP (root->right)) + { + + if (!SPEC_USIGN (TETYPE (root->left->left))) + return root; - if (!IS_AST_LIT_VALUE(root->left->right) || - !IS_AST_LIT_VALUE(root->right->right)) - goto tryNext0; + if (!IS_AST_LIT_VALUE (root->left->right) || + !IS_AST_LIT_VALUE (root->right->right)) + goto tryNext0; - /* make sure it is the same expression */ - if (!isAstEqual(root->left->left, - root->right->left)) - goto tryNext0; + /* make sure it is the same expression */ + if (!isAstEqual (root->left->left, + root->right->left)) + goto tryNext0; - if (AST_LIT_VALUE(root->left->right) != 1 ) - goto tryNext0 ; + if (AST_LIT_VALUE (root->left->right) != 1) + goto tryNext0; - if (AST_LIT_VALUE(root->right->right) != - (getSize(TTYPE(root->left->left))*8 - 1)) - goto tryNext0 ; + if (AST_LIT_VALUE (root->right->right) != + (getSize (TTYPE (root->left->left)) * 8 - 1)) + goto tryNext0; - /* whew got the first case : create the AST */ - return newNode(RLC,root->left->left,NULL); + /* whew got the first case : create the AST */ + return newNode (RLC, root->left->left, NULL); } - tryNext0: - /* check for second case */ - /* (?expr >> 7) | (?expr << 1) */ - if (IS_LEFT_OP(root->right) && - IS_RIGHT_OP(root->left) ) { +tryNext0: + /* check for second case */ + /* (?expr >> 7) | (?expr << 1) */ + if (IS_LEFT_OP (root->right) && + IS_RIGHT_OP (root->left)) + { - if (!SPEC_USIGN(TETYPE(root->left->left))) - return root; + if (!SPEC_USIGN (TETYPE (root->left->left))) + return root; - if (!IS_AST_LIT_VALUE(root->left->right) || - !IS_AST_LIT_VALUE(root->right->right)) - goto tryNext1 ; + if (!IS_AST_LIT_VALUE (root->left->right) || + !IS_AST_LIT_VALUE (root->right->right)) + goto tryNext1; - /* make sure it is the same symbol */ - if (!isAstEqual(root->left->left, - root->right->left)) - goto tryNext1 ; + /* make sure it is the same symbol */ + if (!isAstEqual (root->left->left, + root->right->left)) + goto tryNext1; - if (AST_LIT_VALUE(root->right->right) != 1 ) - goto tryNext1 ; + if (AST_LIT_VALUE (root->right->right) != 1) + goto tryNext1; - if (AST_LIT_VALUE(root->left->right) != - (getSize(TTYPE(root->left->left))*8 - 1)) - goto tryNext1 ; + if (AST_LIT_VALUE (root->left->right) != + (getSize (TTYPE (root->left->left)) * 8 - 1)) + goto tryNext1; - /* whew got the first case : create the AST */ - return newNode(RLC,root->left->left,NULL); + /* whew got the first case : create the AST */ + return newNode (RLC, root->left->left, NULL); } - tryNext1: - /* third case for RRC */ - /* (?symbol >> 1) | (?symbol << 7) */ - if (IS_LEFT_OP(root->right) && - IS_RIGHT_OP(root->left) ) { +tryNext1: + /* third case for RRC */ + /* (?symbol >> 1) | (?symbol << 7) */ + if (IS_LEFT_OP (root->right) && + IS_RIGHT_OP (root->left)) + { - if (!SPEC_USIGN(TETYPE(root->left->left))) - return root; + if (!SPEC_USIGN (TETYPE (root->left->left))) + return root; - if (!IS_AST_LIT_VALUE(root->left->right) || - !IS_AST_LIT_VALUE(root->right->right)) - goto tryNext2; + if (!IS_AST_LIT_VALUE (root->left->right) || + !IS_AST_LIT_VALUE (root->right->right)) + goto tryNext2; - /* make sure it is the same symbol */ - if (!isAstEqual(root->left->left, - root->right->left)) - goto tryNext2; + /* make sure it is the same symbol */ + if (!isAstEqual (root->left->left, + root->right->left)) + goto tryNext2; - if (AST_LIT_VALUE(root->left->right) != 1 ) - goto tryNext2; + if (AST_LIT_VALUE (root->left->right) != 1) + goto tryNext2; - if (AST_LIT_VALUE(root->right->right) != - (getSize(TTYPE(root->left->left))*8 - 1)) - goto tryNext2; + if (AST_LIT_VALUE (root->right->right) != + (getSize (TTYPE (root->left->left)) * 8 - 1)) + goto tryNext2; - /* whew got the first case : create the AST */ - return newNode(RRC,root->left->left,NULL); + /* whew got the first case : create the AST */ + return newNode (RRC, root->left->left, NULL); } - tryNext2: - /* fourth and last case for now */ - /* (?symbol << 7) | (?symbol >> 1) */ - if (IS_RIGHT_OP(root->right) && - IS_LEFT_OP(root->left) ) { +tryNext2: + /* fourth and last case for now */ + /* (?symbol << 7) | (?symbol >> 1) */ + if (IS_RIGHT_OP (root->right) && + IS_LEFT_OP (root->left)) + { - if (!SPEC_USIGN(TETYPE(root->left->left))) - return root; + if (!SPEC_USIGN (TETYPE (root->left->left))) + return root; - if (!IS_AST_LIT_VALUE(root->left->right) || - !IS_AST_LIT_VALUE(root->right->right)) - return root; + if (!IS_AST_LIT_VALUE (root->left->right) || + !IS_AST_LIT_VALUE (root->right->right)) + return root; - /* make sure it is the same symbol */ - if (!isAstEqual(root->left->left, - root->right->left)) - return root; + /* make sure it is the same symbol */ + if (!isAstEqual (root->left->left, + root->right->left)) + return root; - if (AST_LIT_VALUE(root->right->right) != 1 ) - return root ; + if (AST_LIT_VALUE (root->right->right) != 1) + return root; - if (AST_LIT_VALUE(root->left->right) != - (getSize(TTYPE(root->left->left))*8 - 1)) - return root ; + if (AST_LIT_VALUE (root->left->right) != + (getSize (TTYPE (root->left->left)) * 8 - 1)) + return root; - /* whew got the first case : create the AST */ - return newNode(RRC,root->left->left,NULL); + /* whew got the first case : create the AST */ + return newNode (RRC, root->left->left, NULL); } - /* not found return root */ - return root; + /* not found return root */ + return root; } /*-----------------------------------------------------------------*/ /* optimizeCompare - otimizes compares for bit variables */ /*-----------------------------------------------------------------*/ -ast *optimizeCompare ( ast *root ) +ast * +optimizeCompare (ast * root) { - ast *optExpr = NULL; - value *vleft; - value *vright; - unsigned int litValue ; - - /* if nothing then return nothing */ - if (!root) - return NULL ; - - /* if not a compare op then do leaves */ - if (!IS_COMPARE_OP(root)) { - root->left = optimizeCompare (root->left); - root->right= optimizeCompare (root->right); - return root ; - } - - /* if left & right are the same then depending - of the operation do */ - if (isAstEqual(root->left,root->right)) { - switch (root->opval.op) { - case '>' : - case '<' : - case NE_OP : - optExpr = newAst_VALUE(constVal("0")); - break; - case GE_OP : - case LE_OP : - case EQ_OP : - optExpr = newAst_VALUE(constVal("1")); - break; - } + ast *optExpr = NULL; + value *vleft; + value *vright; + unsigned int litValue; - return decorateType(optExpr); - } + /* if nothing then return nothing */ + if (!root) + return NULL; - vleft = (root->left->type == EX_VALUE ? - root->left->opval.val : NULL ); + /* if not a compare op then do leaves */ + if (!IS_COMPARE_OP (root)) + { + root->left = optimizeCompare (root->left); + root->right = optimizeCompare (root->right); + return root; + } - vright = (root->right->type == EX_VALUE ? - root->right->opval.val : NULL); + /* if left & right are the same then depending + of the operation do */ + if (isAstEqual (root->left, root->right)) + { + switch (root->opval.op) + { + case '>': + case '<': + case NE_OP: + optExpr = newAst_VALUE (constVal ("0")); + break; + case GE_OP: + case LE_OP: + case EQ_OP: + optExpr = newAst_VALUE (constVal ("1")); + break; + } + + return decorateType (optExpr); + } - /* if left is a BITVAR in BITSPACE */ - /* and right is a LITERAL then opt-*/ - /* imize else do nothing */ - if (vleft && vright && - IS_BITVAR(vleft->etype) && - IN_BITSPACE(SPEC_OCLS(vleft->etype)) && - IS_LITERAL(vright->etype)) { + vleft = (root->left->type == EX_VALUE ? + root->left->opval.val : NULL); - /* if right side > 1 then comparison may never succeed */ - if ( (litValue = (int) floatFromVal(vright)) > 1 ) { - werror(W_BAD_COMPARE); - goto noOptimize ; - } + vright = (root->right->type == EX_VALUE ? + root->right->opval.val : NULL); - if ( litValue ) { - switch (root->opval.op) { - case '>' : /* bit value greater than 1 cannot be */ - werror(W_BAD_COMPARE); - goto noOptimize ; - break; - - case '<' : /* bit value < 1 means 0 */ - case NE_OP : - optExpr = newNode('!',newAst_VALUE(vleft),NULL); - break; - - case LE_OP : /* bit value <= 1 means no check */ - optExpr = newAst_VALUE(vright); - break; - - case GE_OP : /* bit value >= 1 means only check for = */ - case EQ_OP : - optExpr = newAst_VALUE(vleft); - break; - } - } else { /* literal is zero */ - switch (root->opval.op) { - case '<' : /* bit value < 0 cannot be */ - werror(W_BAD_COMPARE); - goto noOptimize ; - break; - - case '>' : /* bit value > 0 means 1 */ - case NE_OP : - optExpr = newAst_VALUE(vleft); - break; - - case LE_OP : /* bit value <= 0 means no check */ - case GE_OP : /* bit value >= 0 means no check */ - werror(W_BAD_COMPARE); - goto noOptimize ; - break; - - case EQ_OP : /* bit == 0 means ! of bit */ - optExpr = newNode('!',newAst_VALUE(vleft),NULL); - break; - } - } - return decorateType(resolveSymbols(optExpr)); - } /* end-of-if of BITVAR */ + /* if left is a BITVAR in BITSPACE */ + /* and right is a LITERAL then opt- */ + /* imize else do nothing */ + if (vleft && vright && + IS_BITVAR (vleft->etype) && + IN_BITSPACE (SPEC_OCLS (vleft->etype)) && + IS_LITERAL (vright->etype)) + { - noOptimize : + /* if right side > 1 then comparison may never succeed */ + if ((litValue = (int) floatFromVal (vright)) > 1) + { + werror (W_BAD_COMPARE); + goto noOptimize; + } + + if (litValue) + { + switch (root->opval.op) + { + case '>': /* bit value greater than 1 cannot be */ + werror (W_BAD_COMPARE); + goto noOptimize; + break; + + case '<': /* bit value < 1 means 0 */ + case NE_OP: + optExpr = newNode ('!', newAst_VALUE (vleft), NULL); + break; + + case LE_OP: /* bit value <= 1 means no check */ + optExpr = newAst_VALUE (vright); + break; + + case GE_OP: /* bit value >= 1 means only check for = */ + case EQ_OP: + optExpr = newAst_VALUE (vleft); + break; + } + } + else + { /* literal is zero */ + switch (root->opval.op) + { + case '<': /* bit value < 0 cannot be */ + werror (W_BAD_COMPARE); + goto noOptimize; + break; + + case '>': /* bit value > 0 means 1 */ + case NE_OP: + optExpr = newAst_VALUE (vleft); + break; + + case LE_OP: /* bit value <= 0 means no check */ + case GE_OP: /* bit value >= 0 means no check */ + werror (W_BAD_COMPARE); + goto noOptimize; + break; + + case EQ_OP: /* bit == 0 means ! of bit */ + optExpr = newNode ('!', newAst_VALUE (vleft), NULL); + break; + } + } + return decorateType (resolveSymbols (optExpr)); + } /* end-of-if of BITVAR */ + +noOptimize: return root; } /*-----------------------------------------------------------------*/ /* addSymToBlock : adds the symbol to the first block we find */ /*-----------------------------------------------------------------*/ -void addSymToBlock (symbol *sym, ast *tree) +void +addSymToBlock (symbol * sym, ast * tree) { - /* reached end of tree or a leaf */ - if (!tree || IS_AST_LINK(tree) || IS_AST_VALUE(tree)) - return ; + /* reached end of tree or a leaf */ + if (!tree || IS_AST_LINK (tree) || IS_AST_VALUE (tree)) + return; - /* found a block */ - if (IS_AST_OP(tree) && - tree->opval.op == BLOCK ) { + /* found a block */ + if (IS_AST_OP (tree) && + tree->opval.op == BLOCK) + { - symbol *lsym = copySymbol(sym); + symbol *lsym = copySymbol (sym); - lsym->next = AST_VALUES(tree,sym); - AST_VALUES(tree,sym) = lsym ; - return ; + lsym->next = AST_VALUES (tree, sym); + AST_VALUES (tree, sym) = lsym; + return; } - addSymToBlock(sym,tree->left); - addSymToBlock(sym,tree->right); + addSymToBlock (sym, tree->left); + addSymToBlock (sym, tree->right); } /*-----------------------------------------------------------------*/ /* processRegParms - do processing for register parameters */ /*-----------------------------------------------------------------*/ -static void processRegParms (value *args, ast *body) +static void +processRegParms (value * args, ast * body) { - while (args) { - if (IS_REGPARM(args->etype)) - addSymToBlock(args->sym,body); - args = args->next; + while (args) + { + if (IS_REGPARM (args->etype)) + addSymToBlock (args->sym, body); + args = args->next; } } /*-----------------------------------------------------------------*/ /* resetParmKey - resets the operandkeys for the symbols */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(resetParmKey) +DEFSETFUNC (resetParmKey) { - symbol *sym = item; + symbol *sym = item; - sym->key = 0 ; - sym->defs = NULL ; - sym->uses = NULL ; - sym->remat= 0; - return 1; + sym->key = 0; + sym->defs = NULL; + sym->uses = NULL; + sym->remat = 0; + return 1; } /*-----------------------------------------------------------------*/ @@ -3717,137 +3979,142 @@ DEFSETFUNC(resetParmKey) /* is generated function by function, later when */ /* add inter-procedural analysis this will change */ /*-----------------------------------------------------------------*/ -ast *createFunction (symbol *name, ast *body ) +ast * +createFunction (symbol * name, ast * body) { - ast *ex ; - symbol *csym; - int stack = 0 ; - sym_link *fetype; - iCode *piCode = NULL; - - /* if check function return 0 then some problem */ - if (checkFunction (name) == 0) - return NULL; + ast *ex; + symbol *csym; + int stack = 0; + sym_link *fetype; + iCode *piCode = NULL; - /* create a dummy block if none exists */ - if (!body) - body = newNode(BLOCK,NULL,NULL); - - noLineno++ ; - - /* check if the function name already in the symbol table */ - if ((csym = findSym (SymbolTab,NULL,name->name))) { - name = csym ; - /* special case for compiler defined functions - we need to add the name to the publics list : this - actually means we are now compiling the compiler - support routine */ - if (name->cdef) { - addSet(&publics,name); - } + /* if check function return 0 then some problem */ + if (checkFunction (name) == 0) + return NULL; + + /* create a dummy block if none exists */ + if (!body) + body = newNode (BLOCK, NULL, NULL); + + noLineno++; + + /* check if the function name already in the symbol table */ + if ((csym = findSym (SymbolTab, NULL, name->name))) + { + name = csym; + /* special case for compiler defined functions + we need to add the name to the publics list : this + actually means we are now compiling the compiler + support routine */ + if (name->cdef) + { + addSet (&publics, name); + } } - else { - addSymChain(name); - allocVariables(name); + else + { + addSymChain (name); + allocVariables (name); } - name->lastLine = yylineno; - currFunc = name ; - processFuncArgs(currFunc,0); + name->lastLine = yylineno; + currFunc = name; + processFuncArgs (currFunc, 0); - /* set the stack pointer */ - /* PENDING: check this for the mcs51 */ - stackPtr = -port->stack.direction * port->stack.call_overhead; - if (IS_ISR(name->etype)) - stackPtr -= port->stack.direction * port->stack.isr_overhead; - if (IS_RENT(name->etype) || options.stackAuto) - stackPtr -= port->stack.direction * port->stack.reent_overhead; + /* set the stack pointer */ + /* PENDING: check this for the mcs51 */ + stackPtr = -port->stack.direction * port->stack.call_overhead; + if (IS_ISR (name->etype)) + stackPtr -= port->stack.direction * port->stack.isr_overhead; + if (IS_RENT (name->etype) || options.stackAuto) + stackPtr -= port->stack.direction * port->stack.reent_overhead; - xstackPtr = -port->stack.direction * port->stack.call_overhead; + xstackPtr = -port->stack.direction * port->stack.call_overhead; - fetype = getSpec(name->type); /* get the specifier for the function */ - /* if this is a reentrant function then */ - if (IS_RENT(fetype)) - reentrant++ ; + fetype = getSpec (name->type); /* get the specifier for the function */ + /* if this is a reentrant function then */ + if (IS_RENT (fetype)) + reentrant++; - allocParms (name->args); /* allocate the parameters */ + allocParms (name->args); /* allocate the parameters */ - /* do processing for parameters that are passed in registers */ - processRegParms (name->args,body); + /* do processing for parameters that are passed in registers */ + processRegParms (name->args, body); - /* set the stack pointer */ - stackPtr = 0; - xstackPtr= -1; + /* set the stack pointer */ + stackPtr = 0; + xstackPtr = -1; - /* allocate & autoinit the block variables */ - processBlockVars (body, &stack,ALLOCATE); + /* allocate & autoinit the block variables */ + processBlockVars (body, &stack, ALLOCATE); - /* save the stack information */ - if (options.useXstack) - name->xstack = SPEC_STAK(fetype) = stack; - else - name->stack = SPEC_STAK(fetype) = stack; + /* save the stack information */ + if (options.useXstack) + name->xstack = SPEC_STAK (fetype) = stack; + else + name->stack = SPEC_STAK (fetype) = stack; - /* name needs to be mangled */ - sprintf (name->rname,"%s%s", port->fun_prefix, name->name); + /* name needs to be mangled */ + sprintf (name->rname, "%s%s", port->fun_prefix, name->name); - body = resolveSymbols(body); /* resolve the symbols */ - body = decorateType (body); /* propagateType & do semantic checks */ + body = resolveSymbols (body); /* resolve the symbols */ + body = decorateType (body); /* propagateType & do semantic checks */ - ex = newAst_VALUE(symbolVal(name)); /* create name */ - ex = newNode (FUNCTION,ex,body); - ex->values.args = name->args ; + ex = newAst_VALUE (symbolVal (name)); /* create name */ + ex = newNode (FUNCTION, ex, body); + ex->values.args = name->args; - if (fatalError) { - werror(E_FUNC_NO_CODE,name->name); - goto skipall ; + if (fatalError) + { + werror (E_FUNC_NO_CODE, name->name); + goto skipall; } - /* create the node & generate intermediate code */ - codeOutFile = code->oFile; - piCode = iCodeFromAst(ex); + /* create the node & generate intermediate code */ + codeOutFile = code->oFile; + piCode = iCodeFromAst (ex); - if (fatalError) { - werror(E_FUNC_NO_CODE,name->name); - goto skipall ; - } + if (fatalError) + { + werror (E_FUNC_NO_CODE, name->name); + goto skipall; + } - eBBlockFromiCode(piCode); + eBBlockFromiCode (piCode); - /* if there are any statics then do them */ - if (staticAutos) { - codeOutFile = statsg->oFile; - eBBlockFromiCode (iCodeFromAst (decorateType(resolveSymbols(staticAutos)))); - staticAutos = NULL; + /* if there are any statics then do them */ + if (staticAutos) + { + codeOutFile = statsg->oFile; + eBBlockFromiCode (iCodeFromAst (decorateType (resolveSymbols (staticAutos)))); + staticAutos = NULL; } - skipall: +skipall: - /* dealloc the block variables */ - processBlockVars(body, &stack,DEALLOCATE); - /* deallocate paramaters */ - deallocParms(name->args); + /* dealloc the block variables */ + processBlockVars (body, &stack, DEALLOCATE); + /* deallocate paramaters */ + deallocParms (name->args); - if (IS_RENT(fetype)) - reentrant-- ; + if (IS_RENT (fetype)) + reentrant--; - /* we are done freeup memory & cleanup */ - noLineno-- ; - labelKey = 1 ; - name->key = 0; - name->fbody = 1; - addSet(&operKeyReset,name); - applyToSet(operKeyReset,resetParmKey); + /* we are done freeup memory & cleanup */ + noLineno--; + labelKey = 1; + name->key = 0; + name->fbody = 1; + addSet (&operKeyReset, name); + applyToSet (operKeyReset, resetParmKey); - if (options.debug && !options.nodebug) - cdbStructBlock(1,cdbFile); + if (options.debug && !options.nodebug) + cdbStructBlock (1, cdbFile); - cleanUpLevel(LabelTab,0); - cleanUpBlock(StructTab,1); - cleanUpBlock(TypedefTab,1); + cleanUpLevel (LabelTab, 0); + cleanUpBlock (StructTab, 1); + cleanUpBlock (TypedefTab, 1); - xstack->syms = NULL; - istack->syms = NULL; - return NULL ; + xstack->syms = NULL; + istack->syms = NULL; + return NULL; } - - diff --git a/src/SDCCast.h b/src/SDCCast.h index 617b944d..44d12425 100644 --- a/src/SDCCast.h +++ b/src/SDCCast.h @@ -37,66 +37,76 @@ #define EX_OPERAND 4 /* expression tree */ -typedef struct ast { - - unsigned type :3 ; - unsigned decorated :1 ; - unsigned hasVargs :1 ; - unsigned isError :1 ; - unsigned funcName :1 ; - unsigned rvalue :1 ; - unsigned lvalue :1 ; - unsigned initMode :1 ; - int level ; /* level for expr */ - int block ; /* block number */ +typedef struct ast + { + + unsigned type:3; + unsigned decorated:1; + unsigned hasVargs:1; + unsigned isError:1; + unsigned funcName:1; + unsigned rvalue:1; + unsigned lvalue:1; + unsigned initMode:1; + int level; /* level for expr */ + int block; /* block number */ /* union of values expression can have */ - union { - value *val ; /* value if type = EX_VALUE */ - sym_link *lnk ; /* sym_link * if type= EX_LINK */ - struct operand *oprnd; /* used only for side effecting function calls */ - unsigned stmnt ; /* statement if type=EX_STMNT */ - unsigned op ; /* operator if type= EX_OP */ - } opval ; - + union + { + value *val; /* value if type = EX_VALUE */ + sym_link *lnk; /* sym_link * if type= EX_LINK */ + struct operand *oprnd; /* used only for side effecting function calls */ + unsigned stmnt; /* statement if type=EX_STMNT */ + unsigned op; /* operator if type= EX_OP */ + } + opval; + /* union for special processing */ - union { - char *inlineasm ; /* pointer to inline assembler code */ - symbol *sym ; /* if block then -> symbols */ - value *args ; /* if function then args */ + union + { + char *inlineasm; /* pointer to inline assembler code */ + symbol *sym; /* if block then -> symbols */ + value *args; /* if function then args */ /* if switch then switch values */ - struct { - value *swVals ; /* switch comparison values */ - int swDefault ; /* default if present */ - int swNum ; /* switch number */ - } switchVals ; + struct + { + value *swVals; /* switch comparison values */ + int swDefault; /* default if present */ + int swNum; /* switch number */ + } + switchVals; /* if for then for values */ - struct { - struct ast *initExpr ; /* init portion */ - struct ast *condExpr ; /* conditional portion */ - struct ast *loopExpr ; /* iteration portion */ - symbol *trueLabel; /* entry point into body */ - symbol *falseLabel; /* exit point */ - symbol *continueLabel; /* conditional check */ - symbol *condLabel; /* conditional label */ - } forVals ; - unsigned literalFromCast; /* true if this is an EX_VALUE of LITERAL - * type resulting from a typecast. - */ - } values ; - - int lineno ; /* source file line number */ - char *filename ; /* filename of the source file */ - - sym_link *ftype ; /* start of type chain for this subtree */ - sym_link *etype ; /* end of type chain for this subtree */ - - symbol *argSym ; /* argument symbols */ - value *args ; /* args of a function */ - struct ast *left ; /* pointer to left tree */ - struct ast *right; /* pointer to right tree */ - symbol *trueLabel ; /* if statement trueLabel */ - symbol *falseLabel ; /* if statement falseLabel */ -} ast ; + struct + { + struct ast *initExpr; /* init portion */ + struct ast *condExpr; /* conditional portion */ + struct ast *loopExpr; /* iteration portion */ + symbol *trueLabel; /* entry point into body */ + symbol *falseLabel; /* exit point */ + symbol *continueLabel; /* conditional check */ + symbol *condLabel; /* conditional label */ + } + forVals; + unsigned literalFromCast; /* true if this is an EX_VALUE of LITERAL + * type resulting from a typecast. + */ + } + values; + + int lineno; /* source file line number */ + char *filename; /* filename of the source file */ + + sym_link *ftype; /* start of type chain for this subtree */ + sym_link *etype; /* end of type chain for this subtree */ + + symbol *argSym; /* argument symbols */ + value *args; /* args of a function */ + struct ast *left; /* pointer to left tree */ + struct ast *right; /* pointer to right tree */ + symbol *trueLabel; /* if statement trueLabel */ + symbol *falseLabel; /* if statement falseLabel */ + } +ast; /* easy access macros */ @@ -108,7 +118,7 @@ typedef struct ast { #define IS_LEFT_OP(x) (IS_AST_OP(x) && x->opval.op == LEFT_OP) #define IS_RIGHT_OP(x) (IS_AST_OP(x) && x->opval.op == RIGHT_OP) #define IS_AST_VALUE(x) (x && x->type == EX_VALUE && x->opval.val) -#define IS_AST_LINK(x) (x->type == EX_LINK) +#define IS_AST_LINK(x) (x->type == EX_LINK) #define IS_AST_NOT_OPER(x) (x && IS_AST_OP(x) && x->opval.op == '!') #define IS_ARRAY_OP(x) (IS_AST_OP(x) && x->opval.op == '[') #define IS_COMPARE_OP(x) (IS_AST_OP(x) && \ @@ -154,43 +164,43 @@ typedef struct ast { #define IS_DEREF_OP(x) (( x->opval.op == '*' && x->right == NULL) || x->opval.op == '.') /* forward declarations for global variables */ -extern ast *staticAutos ; +extern ast *staticAutos; extern FILE *codeOutFile; /* forward definitions for functions */ -ast* newAst_VALUE(value*val); -ast* newAst_OP (unsigned op); -ast* newAst_LINK (sym_link*val); -ast* newAst_STMNT(unsigned val); - -void initAst ( ); -ast *newNode (long ,ast * ,ast * ); -ast *copyAst (ast * ); -value *sizeofOp (sym_link * ); -value *evalStmnt (ast * ); -ast *createFunction(symbol *,ast * ); -ast *createBlock (symbol *,ast * ); -ast *createLabel (symbol *,ast * ); -ast *createCase (ast *,ast *,ast *); -ast *createDefault (ast *,ast * ); -ast *optimizeCompare (ast * ); -ast *forLoopOptForm( ast * ); -ast *argAst ( ast * ); -ast *resolveSymbols (ast *) ; -ast *decorateType (ast *) ; -ast *createWhile (symbol *, symbol *, symbol *, ast *, ast *); -ast *createIf (ast *, ast *, ast *); -ast *createDo (symbol *,symbol *,symbol *,ast *,ast *); -ast *createFor (symbol *,symbol *,symbol *,symbol *,ast *,ast *,ast *, ast *); -void eval2icode (ast *); -value *constExprValue (ast *,int); -symbol *funcOfType (char *,sym_link *,sym_link *,int,int); -ast *initAggregates ( symbol *,initList *, ast *); -bool hasSEFcalls ( ast *); -void addSymToBlock (symbol *, ast *) ; +ast *newAst_VALUE (value * val); +ast *newAst_OP (unsigned op); +ast *newAst_LINK (sym_link * val); +ast *newAst_STMNT (unsigned val); + +void initAst (); +ast *newNode (long, ast *, ast *); +ast *copyAst (ast *); +value *sizeofOp (sym_link *); +value *evalStmnt (ast *); +ast *createFunction (symbol *, ast *); +ast *createBlock (symbol *, ast *); +ast *createLabel (symbol *, ast *); +ast *createCase (ast *, ast *, ast *); +ast *createDefault (ast *, ast *); +ast *optimizeCompare (ast *); +ast *forLoopOptForm (ast *); +ast *argAst (ast *); +ast *resolveSymbols (ast *); +ast *decorateType (ast *); +ast *createWhile (symbol *, symbol *, symbol *, ast *, ast *); +ast *createIf (ast *, ast *, ast *); +ast *createDo (symbol *, symbol *, symbol *, ast *, ast *); +ast *createFor (symbol *, symbol *, symbol *, symbol *, ast *, ast *, ast *, ast *); +void eval2icode (ast *); +value *constExprValue (ast *, int); +symbol *funcOfType (char *, sym_link *, sym_link *, int, int); +ast *initAggregates (symbol *, initList *, ast *); +bool hasSEFcalls (ast *); +void addSymToBlock (symbol *, ast *); // exported variables extern set *operKeyReset; extern int noAlloc; -#endif +#endif diff --git a/src/SDCCbitv.c b/src/SDCCbitv.c index 78b8f287..c2d5d64f 100644 --- a/src/SDCCbitv.c +++ b/src/SDCCbitv.c @@ -31,325 +31,343 @@ int bitVectDefault = 1024; /* genernal note about a bitvectors: bit vectors are stored from left to right i.e. bit position 0 is the MS bit of the first byte - this also means that bit positions must start from 0*/ + this also means that bit positions must start from 0 */ /*-----------------------------------------------------------------*/ /* newBitVect - returns a new bitvector of size */ /*-----------------------------------------------------------------*/ -bitVect *newBitVect (int size) +bitVect * +newBitVect (int size) { - bitVect *bvp; - int byteSize ; + bitVect *bvp; + int byteSize; - bvp = Safe_calloc(1,sizeof (bitVect)); + bvp = Safe_calloc (1, sizeof (bitVect)); - bvp->size = size; - bvp->bSize = byteSize = ( size / 8) + 1 ; - bvp->vect = Safe_calloc(1,byteSize); - return bvp; + bvp->size = size; + bvp->bSize = byteSize = (size / 8) + 1; + bvp->vect = Safe_calloc (1, byteSize); + return bvp; } /*-----------------------------------------------------------------*/ /* bitVectResize - changes the size of a bit vector */ /*-----------------------------------------------------------------*/ -bitVect *bitVectResize (bitVect *bvp, int size) +bitVect * +bitVectResize (bitVect * bvp, int size) { - int bSize = ( size / 8) + 1 ; - - if (!bvp) - return newBitVect (size); + int bSize = (size / 8) + 1; - /* if we already have enough space */ - if (bvp->bSize >= bSize ) { - if (size > bvp->size) - bvp->size = size ; - return bvp; + if (!bvp) + return newBitVect (size); + + /* if we already have enough space */ + if (bvp->bSize >= bSize) + { + if (size > bvp->size) + bvp->size = size; + return bvp; } - bvp->vect = Clear_realloc(bvp->vect, bvp -> bSize, bSize); - bvp->size = size; - bvp->bSize= bSize; + bvp->vect = Clear_realloc (bvp->vect, bvp->bSize, bSize); + bvp->size = size; + bvp->bSize = bSize; - return bvp; + return bvp; } /*-----------------------------------------------------------------*/ /* bitVectSetBit - sets a given bit in the bit vector */ /*-----------------------------------------------------------------*/ -bitVect *bitVectSetBit (bitVect *bvp, int pos) +bitVect * +bitVectSetBit (bitVect * bvp, int pos) { - int byteSize; - int offset ; + int byteSize; + int offset; - /* if set is null then allocate it */ - if (!bvp) - bvp = newBitVect(bitVectDefault) ; /* allocate for twice the size */ + /* if set is null then allocate it */ + if (!bvp) + bvp = newBitVect (bitVectDefault); /* allocate for twice the size */ - if (bvp->size <= pos ) - bvp = bitVectResize (bvp,pos+2); /* conservatively resize */ + if (bvp->size <= pos) + bvp = bitVectResize (bvp, pos + 2); /* conservatively resize */ - byteSize = pos / 8 ; - offset = pos % 8; - bvp->vect[byteSize] |= (((unsigned char)1) << - (7 - offset)); - return bvp; + byteSize = pos / 8; + offset = pos % 8; + bvp->vect[byteSize] |= (((unsigned char) 1) << + (7 - offset)); + return bvp; } /*-----------------------------------------------------------------*/ /* bitVectUnSetBit - unsets the value of a bit in a bitvector */ /*-----------------------------------------------------------------*/ -void bitVectUnSetBit (bitVect *bvp, int pos) +void +bitVectUnSetBit (bitVect * bvp, int pos) { - int byteSize ; - int offset ; + int byteSize; + int offset; - if (! bvp) - return ; + if (!bvp) + return; - byteSize = pos /8; - if (bvp->bSize <= byteSize) - return ; + byteSize = pos / 8; + if (bvp->bSize <= byteSize) + return; - offset = pos % 8 ; + offset = pos % 8; - bvp->vect[byteSize] &= ~ (((unsigned char)1) << - (7 - offset)); + bvp->vect[byteSize] &= ~(((unsigned char) 1) << + (7 - offset)); } /*-----------------------------------------------------------------*/ /* bitVectBitValue - returns value value at bit position */ /*-----------------------------------------------------------------*/ -int bitVectBitValue (bitVect *bvp, int pos) +int +bitVectBitValue (bitVect * bvp, int pos) { - int byteSize; - int offset ; + int byteSize; + int offset; - if (! bvp) - return 0; + if (!bvp) + return 0; - byteSize = pos /8; + byteSize = pos / 8; - if ( bvp->bSize <= byteSize ) - return 0; + if (bvp->bSize <= byteSize) + return 0; - offset = pos % 8 ; + offset = pos % 8; - return ((bvp->vect[byteSize] >> (7-offset)) & ((unsigned char)1) ); + return ((bvp->vect[byteSize] >> (7 - offset)) & ((unsigned char) 1)); } /*-----------------------------------------------------------------*/ /* bitVectUnion - unions two bitvectors */ /*-----------------------------------------------------------------*/ -bitVect *bitVectUnion ( bitVect *bvp1, bitVect *bvp2) +bitVect * +bitVectUnion (bitVect * bvp1, bitVect * bvp2) { - int i; - bitVect *newBvp; + int i; + bitVect *newBvp; - /* if both null */ - if (!bvp1 && !bvp2) - return NULL ; + /* if both null */ + if (!bvp1 && !bvp2) + return NULL; - /* if one of them null then return the other */ - if (! bvp1 && bvp2 ) - return bitVectCopy (bvp2); + /* if one of them null then return the other */ + if (!bvp1 && bvp2) + return bitVectCopy (bvp2); - if ( bvp1 && ! bvp2 ) - return bitVectCopy (bvp1); + if (bvp1 && !bvp2) + return bitVectCopy (bvp1); - /* if they are not the same size */ - /* make them the same size */ - if (bvp1->bSize < bvp2->bSize) - bvp1 = bitVectResize (bvp1,bvp2->size); - else - if (bvp2->bSize < bvp1->bSize) - bvp2 = bitVectResize (bvp2,bvp1->size); + /* if they are not the same size */ + /* make them the same size */ + if (bvp1->bSize < bvp2->bSize) + bvp1 = bitVectResize (bvp1, bvp2->size); + else if (bvp2->bSize < bvp1->bSize) + bvp2 = bitVectResize (bvp2, bvp1->size); - newBvp = newBitVect(bvp1->size); + newBvp = newBitVect (bvp1->size); - for ( i = 0 ; i < bvp1->bSize ;i++) - newBvp->vect[i] = bvp1->vect[i] | bvp2->vect[i]; + for (i = 0; i < bvp1->bSize; i++) + newBvp->vect[i] = bvp1->vect[i] | bvp2->vect[i]; - return newBvp; + return newBvp; } /*-----------------------------------------------------------------*/ /* bitVectIntersect - intersect two bitvectors */ /*-----------------------------------------------------------------*/ -bitVect *bitVectIntersect ( bitVect *bvp1, bitVect *bvp2) +bitVect * +bitVectIntersect (bitVect * bvp1, bitVect * bvp2) { - int i; - bitVect *newBvp; + int i; + bitVect *newBvp; - if (! bvp2 || ! bvp1 ) - return NULL ; + if (!bvp2 || !bvp1) + return NULL; - /* if they are not the same size */ - /* make them the same size */ - if (bvp1->bSize < bvp2->bSize) - bvp1 = bitVectResize (bvp1,bvp2->bSize); - else - if (bvp2->size < bvp1->size) - bvp2 = bitVectResize (bvp2,bvp1->size); + /* if they are not the same size */ + /* make them the same size */ + if (bvp1->bSize < bvp2->bSize) + bvp1 = bitVectResize (bvp1, bvp2->bSize); + else if (bvp2->size < bvp1->size) + bvp2 = bitVectResize (bvp2, bvp1->size); - newBvp = newBitVect(bvp1->size); + newBvp = newBitVect (bvp1->size); - for ( i = 0 ; i < bvp1->bSize ;i++) - newBvp->vect[i] = bvp1->vect[i] & bvp2->vect[i]; + for (i = 0; i < bvp1->bSize; i++) + newBvp->vect[i] = bvp1->vect[i] & bvp2->vect[i]; - return newBvp; + return newBvp; } /*-----------------------------------------------------------------*/ /* bitVectBitsInCommon - special case of intersection determines */ /* if the vectors have any common bits set */ /*-----------------------------------------------------------------*/ -int bitVectBitsInCommon ( bitVect *bvp1, bitVect *bvp2 ) +int +bitVectBitsInCommon (bitVect * bvp1, bitVect * bvp2) { - int i ; + int i; - if ( ! bvp1 || ! bvp2 ) - return 0; + if (!bvp1 || !bvp2) + return 0; - for ( i = 0 ; i < min(bvp1->bSize,bvp2->bSize) ; i ++ ) - if ( bvp1->vect[i] & bvp2->vect[i] ) + for (i = 0; i < min (bvp1->bSize, bvp2->bSize); i++) + if (bvp1->vect[i] & bvp2->vect[i]) return 1; - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* bitVectCplAnd - complement the second & and it with the first */ /*-----------------------------------------------------------------*/ -bitVect *bitVectCplAnd ( bitVect *bvp1, bitVect *bvp2) +bitVect * +bitVectCplAnd (bitVect * bvp1, bitVect * bvp2) { - int i; + int i; - if ( ! bvp2 ) - return bvp1 ; + if (!bvp2) + return bvp1; - if ( ! bvp1 ) - return bvp1 ; + if (!bvp1) + return bvp1; - /* if they are not the same size */ - /* make them the same size */ - if (bvp1->bSize < bvp2->bSize) - bvp1 = bitVectResize (bvp1,bvp2->bSize); - else - if (bvp2->size < bvp1->size) - bvp2 = bitVectResize (bvp2,bvp1->size); + /* if they are not the same size */ + /* make them the same size */ + if (bvp1->bSize < bvp2->bSize) + bvp1 = bitVectResize (bvp1, bvp2->bSize); + else if (bvp2->size < bvp1->size) + bvp2 = bitVectResize (bvp2, bvp1->size); - for ( i = 0 ; i < bvp1->bSize ;i++) - bvp1->vect[i] = bvp1->vect[i] & (~ bvp2->vect[i]); + for (i = 0; i < bvp1->bSize; i++) + bvp1->vect[i] = bvp1->vect[i] & (~bvp2->vect[i]); - return bvp1; + return bvp1; } /*-----------------------------------------------------------------*/ /* bitVectIsZero - bit vector has all bits turned off */ /*-----------------------------------------------------------------*/ -int bitVectIsZero (bitVect *bvp) +int +bitVectIsZero (bitVect * bvp) { - int i ; + int i; - if (!bvp) - return 1; + if (!bvp) + return 1; - for ( i = 0 ; i < bvp->bSize ; i++ ) - if (bvp->vect[i] != 0) + for (i = 0; i < bvp->bSize; i++) + if (bvp->vect[i] != 0) return 0; - return 1; + return 1; } /*-----------------------------------------------------------------*/ /* bitVectsEqual - returns 1 if the two bit vectors are equal */ /*-----------------------------------------------------------------*/ -int bitVectEqual ( bitVect *bvp1, bitVect *bvp2) +int +bitVectEqual (bitVect * bvp1, bitVect * bvp2) { - int i ; + int i; - if ( !bvp1 || !bvp1) - return 0; + if (!bvp1 || !bvp1) + return 0; - if (bvp1 == bvp2) - return 1; + if (bvp1 == bvp2) + return 1; - if (bvp1->bSize != bvp2->bSize) - return 0; + if (bvp1->bSize != bvp2->bSize) + return 0; - for (i = 0 ; i < bvp1->bSize ; i++ ) - if ( bvp1->vect[i] != bvp2->vect[i] ) + for (i = 0; i < bvp1->bSize; i++) + if (bvp1->vect[i] != bvp2->vect[i]) return 0; - return 1; + return 1; } /*-----------------------------------------------------------------*/ /* bitVectCopy - creates a bitvector from another bit Vector */ /*-----------------------------------------------------------------*/ -bitVect *bitVectCopy (bitVect *bvp) +bitVect * +bitVectCopy (bitVect * bvp) { - bitVect *newBvp; - int i; + bitVect *newBvp; + int i; - if (!bvp) - return NULL; + if (!bvp) + return NULL; - newBvp = newBitVect(bvp->size); - for ( i = 0 ; i < bvp->bSize; i++ ) - newBvp->vect[i] = bvp->vect[i]; + newBvp = newBitVect (bvp->size); + for (i = 0; i < bvp->bSize; i++) + newBvp->vect[i] = bvp->vect[i]; - return newBvp; + return newBvp; } /*-----------------------------------------------------------------*/ /* bitVectnBitsOn - returns the number of bits that are on */ /*-----------------------------------------------------------------*/ -int bitVectnBitsOn (bitVect *bvp) +int +bitVectnBitsOn (bitVect * bvp) { - int i, j, k; - unsigned char byte; - int count = 0 ; + int i, j, k; + unsigned char byte; + int count = 0; - if (!bvp) - return 0; + if (!bvp) + return 0; - /* rip through most of the data in byte sized chunks */ - j = (bvp->size)/8; - for (i = 0 ; i < j; i++) { - byte = bvp->vect[i]; - for (k=0; k<8; k++) { count += byte&1; byte = byte>>1; } - } + /* rip through most of the data in byte sized chunks */ + j = (bvp->size) / 8; + for (i = 0; i < j; i++) + { + byte = bvp->vect[i]; + for (k = 0; k < 8; k++) + { + count += byte & 1; + byte = byte >> 1; + } + } - /* finish up the last fractional byte, if any */ - for (i = j*8 ; i < bvp->size; i++) - count += bitVectBitValue(bvp,i); + /* finish up the last fractional byte, if any */ + for (i = j * 8; i < bvp->size; i++) + count += bitVectBitValue (bvp, i); - return count; + return count; } /*-----------------------------------------------------------------*/ /* bitVectFirstBit - returns the key for the first bit that is on */ /*-----------------------------------------------------------------*/ -int bitVectFirstBit (bitVect *bvp) +int +bitVectFirstBit (bitVect * bvp) { - int i; + int i; - if (!bvp) - return -1; - for (i = 0; i < bvp->size ; i++ ) - if (bitVectBitValue(bvp,i)) + if (!bvp) + return -1; + for (i = 0; i < bvp->size; i++) + if (bitVectBitValue (bvp, i)) return i; - return -1; + return -1; } /*-----------------------------------------------------------------*/ /* bitVectDebugOn - prints bits that are on */ /*-----------------------------------------------------------------*/ -void bitVectDebugOn (bitVect *bvp, FILE *of) +void +bitVectDebugOn (bitVect * bvp, FILE * of) { int i; @@ -358,11 +376,12 @@ void bitVectDebugOn (bitVect *bvp, FILE *of) if (!bvp) return; - fprintf(of,"bitvector Size = %d bSize = %d\n",bvp->size,bvp->bSize); - fprintf(of,"Bits on { "); - for (i = 0 ; i < bvp->size ; i++) { - if (bitVectBitValue(bvp,i)) - fprintf(of,"(%d) ",i); - } - fprintf(of,"}\n"); + fprintf (of, "bitvector Size = %d bSize = %d\n", bvp->size, bvp->bSize); + fprintf (of, "Bits on { "); + for (i = 0; i < bvp->size; i++) + { + if (bitVectBitValue (bvp, i)) + fprintf (of, "(%d) ", i); + } + fprintf (of, "}\n"); } diff --git a/src/SDCCbitv.h b/src/SDCCbitv.h index 78f120eb..c6115cac 100644 --- a/src/SDCCbitv.h +++ b/src/SDCCbitv.h @@ -30,31 +30,32 @@ /* bitvector */ typedef struct bitVect -{ - int size ; + { + int size; int bSize; - unsigned char *vect ; -} bitVect ; + unsigned char *vect; + } +bitVect; -extern int bitVectDefault ; +extern int bitVectDefault; /*-----------------------------------------------------------------*/ -/* Forward definition for functions */ +/* Forward definition for functions */ /*-----------------------------------------------------------------*/ /* bitvector related functions */ -bitVect *newBitVect (int); -bitVect *bitVectResize (bitVect *, int ); -bitVect *bitVectSetBit (bitVect *,int ); -void bitVectUnSetBit (bitVect *,int); -int bitVectBitValue (bitVect *,int); -bitVect *bitVectUnion (bitVect *,bitVect *); -bitVect *bitVectIntersect (bitVect *,bitVect *); -int bitVectBitsInCommon ( bitVect *, bitVect * ); -bitVect *bitVectCplAnd ( bitVect *, bitVect *); -int bitVectEqual (bitVect *,bitVect *); -bitVect *bitVectCopy (bitVect *); -int bitVectIsZero (bitVect *); -int bitVectnBitsOn(bitVect *); -int bitVectFirstBit (bitVect *); -void bitVectDebugOn (bitVect *, FILE *); +bitVect *newBitVect (int); +bitVect *bitVectResize (bitVect *, int); +bitVect *bitVectSetBit (bitVect *, int); +void bitVectUnSetBit (bitVect *, int); +int bitVectBitValue (bitVect *, int); +bitVect *bitVectUnion (bitVect *, bitVect *); +bitVect *bitVectIntersect (bitVect *, bitVect *); +int bitVectBitsInCommon (bitVect *, bitVect *); +bitVect *bitVectCplAnd (bitVect *, bitVect *); +int bitVectEqual (bitVect *, bitVect *); +bitVect *bitVectCopy (bitVect *); +int bitVectIsZero (bitVect *); +int bitVectnBitsOn (bitVect *); +int bitVectFirstBit (bitVect *); +void bitVectDebugOn (bitVect *, FILE *); #endif diff --git a/src/SDCCcflow.c b/src/SDCCcflow.c index 9c6ac3bb..2dc53135 100644 --- a/src/SDCCcflow.c +++ b/src/SDCCcflow.c @@ -28,18 +28,19 @@ /*-----------------------------------------------------------------*/ /* domSetFromVect - creates a domset from the vector */ /*-----------------------------------------------------------------*/ -set *domSetFromVect (eBBlock **ebbs, bitVect *domVect) +set * +domSetFromVect (eBBlock ** ebbs, bitVect * domVect) { - int i = 0 ; - set *domSet = NULL; + int i = 0; + set *domSet = NULL; - if (!domVect) - return NULL ; + if (!domVect) + return NULL; - for (i = 0 ; i < domVect->size ;i++ ) - if (bitVectBitValue(domVect,i)) - addSet(&domSet,ebbs[i]); - return domSet; + for (i = 0; i < domVect->size; i++) + if (bitVectBitValue (domVect, i)) + addSet (&domSet, ebbs[i]); + return domSet; } @@ -47,125 +48,139 @@ set *domSetFromVect (eBBlock **ebbs, bitVect *domVect) /* addSuccessor - will add bb to succ also add it to the pred of */ /* the next one : */ /*-----------------------------------------------------------------*/ -void addSuccessor (eBBlock *thisBlock, eBBlock *succ ) +void +addSuccessor (eBBlock * thisBlock, eBBlock * succ) { - /* check for boundary conditions */ - if ( ! thisBlock || ! succ ) - return ; - - /* add it to the succ of thisBlock */ - addSetIfnotP (&thisBlock->succList,succ); - - thisBlock->succVect = - bitVectSetBit(thisBlock->succVect,succ->bbnum); - /* add this edge to the list of edges */ - addSet(&graphEdges,newEdge(thisBlock,succ)); + /* check for boundary conditions */ + if (!thisBlock || !succ) + return; + + /* add it to the succ of thisBlock */ + addSetIfnotP (&thisBlock->succList, succ); + + thisBlock->succVect = + bitVectSetBit (thisBlock->succVect, succ->bbnum); + /* add this edge to the list of edges */ + addSet (&graphEdges, newEdge (thisBlock, succ)); } /*-----------------------------------------------------------------*/ /* eBBPredecessors - find the predecessors for each block */ /*-----------------------------------------------------------------*/ -void eBBPredecessors ( eBBlock **ebbs, int count) +void +eBBPredecessors (eBBlock ** ebbs, int count) { - int i = 0, j ; - - /* for each block do */ - for ( i = 0 ; i < count ; i++ ) { - - /* if there is no path to this then continue */ - if (ebbs[i]->noPath) - continue; - - /* for each successor of this block if */ - /* it has depth first number > this block */ - /* then this block precedes the successor */ - for (j = 0; j < ebbs[i]->succVect->size ; j++) - - if ( bitVectBitValue(ebbs[i]->succVect,j) && - ebbs[j]->dfnum > ebbs[i]->dfnum ) - - addSet(&ebbs[j]->predList,ebbs[i]); + int i = 0, j; + + /* for each block do */ + for (i = 0; i < count; i++) + { + + /* if there is no path to this then continue */ + if (ebbs[i]->noPath) + continue; + + /* for each successor of this block if */ + /* it has depth first number > this block */ + /* then this block precedes the successor */ + for (j = 0; j < ebbs[i]->succVect->size; j++) + + if (bitVectBitValue (ebbs[i]->succVect, j) && + ebbs[j]->dfnum > ebbs[i]->dfnum) + + addSet (&ebbs[j]->predList, ebbs[i]); } } /*-----------------------------------------------------------------*/ /* eBBSuccessors- find out the successors of all the nodes */ /*-----------------------------------------------------------------*/ -void eBBSuccessors ( eBBlock **ebbs , int count ) +void +eBBSuccessors (eBBlock ** ebbs, int count) { - int i = 0 ; - - /* for all the blocks do */ - for (; i < count; i++ ) { - iCode *ic; - - if (ebbs[i]->noPath) - continue; - - ebbs[i]->succVect = newBitVect(count); - - /* if the next on exists & this one does not */ - /* end in a GOTO or RETURN then the next is */ - /* a natural successor of this. Note we have */ - /* consider eBBlocks with no instructions */ - if (ebbs[i+1]) { - - if (ebbs[i]->ech) { - - if (ebbs[i]->ech->op != GOTO && - ebbs[i]->ech->op != RETURN && - ebbs[i]->ech->op != JUMPTABLE) { - int j = i + 1; - - while (ebbs[j] && ebbs[j]->noPath) j++; - - addSuccessor (ebbs[i],ebbs[j]); /* add it */ + int i = 0; + + /* for all the blocks do */ + for (; i < count; i++) + { + iCode *ic; + + if (ebbs[i]->noPath) + continue; + + ebbs[i]->succVect = newBitVect (count); + + /* if the next on exists & this one does not */ + /* end in a GOTO or RETURN then the next is */ + /* a natural successor of this. Note we have */ + /* consider eBBlocks with no instructions */ + if (ebbs[i + 1]) + { + + if (ebbs[i]->ech) + { + + if (ebbs[i]->ech->op != GOTO && + ebbs[i]->ech->op != RETURN && + ebbs[i]->ech->op != JUMPTABLE) + { + int j = i + 1; + + while (ebbs[j] && ebbs[j]->noPath) + j++; + + addSuccessor (ebbs[i], ebbs[j]); /* add it */ } - } /* no instructions in the block */ - /* could happen for dummy blocks*/ - else - addSuccessor (ebbs[i],ebbs[i+1]); + } /* no instructions in the block */ + /* could happen for dummy blocks */ + else + addSuccessor (ebbs[i], ebbs[i + 1]); } - /* go thru all the instructions: if we find a */ - /* goto or ifx or a return then we have a succ*/ - if ((ic = ebbs[i]->ech)) { - eBBlock *succ ; - - /* special case for jumptable */ - if (ic->op == JUMPTABLE ) { - symbol *lbl ; - for (lbl = setFirstItem(IC_JTLABELS(ic)); lbl; - lbl = setNextItem(IC_JTLABELS(ic))) - addSuccessor(ebbs[i], - eBBWithEntryLabel(ebbs,lbl,count)); - } else { - - succ = NULL ; - /* depending on the instruction operator */ - switch (ic->op) { - case GOTO : /* goto has edge to label */ - succ = eBBWithEntryLabel (ebbs,ic->argLabel.label,count); - break; - - case IFX : /* conditional jump */ - /* if true label is present */ - if (IC_TRUE(ic)) - succ = eBBWithEntryLabel (ebbs,IC_TRUE(ic),count); - else - succ = eBBWithEntryLabel (ebbs,IC_FALSE(ic),count); - break; - - case RETURN : /* block with return */ - succ = eBBWithEntryLabel (ebbs,returnLabel,count); - break; + /* go thru all the instructions: if we find a */ + /* goto or ifx or a return then we have a succ */ + if ((ic = ebbs[i]->ech)) + { + eBBlock *succ; + + /* special case for jumptable */ + if (ic->op == JUMPTABLE) + { + symbol *lbl; + for (lbl = setFirstItem (IC_JTLABELS (ic)); lbl; + lbl = setNextItem (IC_JTLABELS (ic))) + addSuccessor (ebbs[i], + eBBWithEntryLabel (ebbs, lbl, count)); + } + else + { + + succ = NULL; + /* depending on the instruction operator */ + switch (ic->op) + { + case GOTO: /* goto has edge to label */ + succ = eBBWithEntryLabel (ebbs, ic->argLabel.label, count); + break; + + case IFX: /* conditional jump */ + /* if true label is present */ + if (IC_TRUE (ic)) + succ = eBBWithEntryLabel (ebbs, IC_TRUE (ic), count); + else + succ = eBBWithEntryLabel (ebbs, IC_FALSE (ic), count); + break; + + case RETURN: /* block with return */ + succ = eBBWithEntryLabel (ebbs, returnLabel, count); + break; } - - /* if there is a successor add to the list */ - /* if it is not already present in the list*/ - if (succ) - addSuccessor(ebbs[i],succ); + + /* if there is a successor add to the list */ + /* if it is not already present in the list */ + if (succ) + addSuccessor (ebbs[i], succ); } } } @@ -175,225 +190,238 @@ void eBBSuccessors ( eBBlock **ebbs , int count ) /* computeDominance - computes the dominance graph */ /* for algorithm look at Dragon book section 10.10, algo 10.16 */ /*-----------------------------------------------------------------*/ -void computeDominance ( eBBlock **ebbs, int count ) -{ - int i , j ; - - /* now do the initialisation */ - /* D(n0) := { n0 } */ - ebbs[0]->domVect = - bitVectSetBit(ebbs[0]->domVect = newBitVect(count),ebbs[0]->bbnum); - - - /* for n in N - { n0 } do D(n) = N */ - for (i = 1 ; i < count ; i++ ) { - ebbs[i]->domVect = newBitVect(count); - for (j = 0 ; j < count ; j++ ) { - ebbs[i]->domVect = - bitVectSetBit(ebbs[i]->domVect,ebbs[j]->bbnum); +void +computeDominance (eBBlock ** ebbs, int count) +{ + int i, j; + + /* now do the initialisation */ + /* D(n0) := { n0 } */ + ebbs[0]->domVect = + bitVectSetBit (ebbs[0]->domVect = newBitVect (count), ebbs[0]->bbnum); + + + /* for n in N - { n0 } do D(n) = N */ + for (i = 1; i < count; i++) + { + ebbs[i]->domVect = newBitVect (count); + for (j = 0; j < count; j++) + { + ebbs[i]->domVect = + bitVectSetBit (ebbs[i]->domVect, ebbs[j]->bbnum); } - } - - /* end of initialisation */ - - /* while changes to any D(n) occur do */ - /* for n in N - { n0 } do */ - /* D(n) := { n } U (intersection of D( all predecessors of n)) */ - while (1) { - int change ; - - change = 0 ; - for ( i = 1 ; i < count ; i++ ) { - bitVect *cDomVect ; - eBBlock *pred ; - - cDomVect = NULL; - - /* get the intersection of the dominance of all predecessors */ - for (pred = setFirstItem(ebbs[i]->predList) , - cDomVect = (pred ? bitVectCopy(pred->domVect) : NULL) ; - pred ; - pred = setNextItem(ebbs[i]->predList)) { - cDomVect = bitVectIntersect(cDomVect,pred->domVect); + } + + /* end of initialisation */ + + /* while changes to any D(n) occur do */ + /* for n in N - { n0 } do */ + /* D(n) := { n } U (intersection of D( all predecessors of n)) */ + while (1) + { + int change; + + change = 0; + for (i = 1; i < count; i++) + { + bitVect *cDomVect; + eBBlock *pred; + + cDomVect = NULL; + + /* get the intersection of the dominance of all predecessors */ + for (pred = setFirstItem (ebbs[i]->predList), + cDomVect = (pred ? bitVectCopy (pred->domVect) : NULL); + pred; + pred = setNextItem (ebbs[i]->predList)) + { + cDomVect = bitVectIntersect (cDomVect, pred->domVect); } - if (!cDomVect) - cDomVect = newBitVect(count); - /* this node to the list */ - cDomVect = bitVectSetBit(cDomVect,ebbs[i]->bbnum); + if (!cDomVect) + cDomVect = newBitVect (count); + /* this node to the list */ + cDomVect = bitVectSetBit (cDomVect, ebbs[i]->bbnum); - if (!bitVectEqual(cDomVect,ebbs[i]->domVect)) { - ebbs[i]->domVect = cDomVect; - change = 1; - } - } + if (!bitVectEqual (cDomVect, ebbs[i]->domVect)) + { + ebbs[i]->domVect = cDomVect; + change = 1; + } + } - /* if no change then exit */ - if (!change) - break ; + /* if no change then exit */ + if (!change) + break; } } /*-----------------------------------------------------------------*/ /* immedDom - returns the immediate dominator of a block */ /*-----------------------------------------------------------------*/ -eBBlock *immedDom (eBBlock **ebbs,eBBlock *ebp) +eBBlock * +immedDom (eBBlock ** ebbs, eBBlock * ebp) { - /* first delete self from the list */ - set *iset = domSetFromVect(ebbs,ebp->domVect); - eBBlock *loop; - eBBlock *idom = NULL; - - deleteSetItem(&iset,ebp); - /* then just return the one with the greatest */ - /* depthfirst number, this will be the immed dominator */ - if ((loop = setFirstItem(iset))) - idom = loop; - for (; loop; loop = setNextItem(iset)) - if (loop->dfnum > idom->dfnum) - idom = loop ; - - setToNull ((void **)&iset); - return idom; - + /* first delete self from the list */ + set *iset = domSetFromVect (ebbs, ebp->domVect); + eBBlock *loop; + eBBlock *idom = NULL; + + deleteSetItem (&iset, ebp); + /* then just return the one with the greatest */ + /* depthfirst number, this will be the immed dominator */ + if ((loop = setFirstItem (iset))) + idom = loop; + for (; loop; loop = setNextItem (iset)) + if (loop->dfnum > idom->dfnum) + idom = loop; + + setToNull ((void **) &iset); + return idom; + } /*-----------------------------------------------------------------*/ /* DFOrdering - is visited then nothing else call DFOrdering this */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(DFOrdering) +DEFSETFUNC (DFOrdering) { - eBBlock *ebbp = item ; - V_ARG(int *,count); - - if (ebbp->visited) - return 0; - - computeDFOrdering (ebbp,count); /* depthfirst */ - + eBBlock *ebbp = item; + V_ARG (int *, count); + + if (ebbp->visited) return 0; + + computeDFOrdering (ebbp, count); /* depthfirst */ + + return 0; } /*-----------------------------------------------------------------*/ /* computeDFOrdering - computes the depth first ordering of the */ /* flowgraph */ /*-----------------------------------------------------------------*/ -void computeDFOrdering ( eBBlock *ebbp , int *count) +void +computeDFOrdering (eBBlock * ebbp, int *count) { - ebbp->visited = 1; - /* for each successor that is not visited */ - applyToSet(ebbp->succList,DFOrdering,count); + ebbp->visited = 1; + /* for each successor that is not visited */ + applyToSet (ebbp->succList, DFOrdering, count); - /* set the depth first number */ - ebbp->dfnum = *count ; - *count -= 1; + /* set the depth first number */ + ebbp->dfnum = *count; + *count -= 1; } /*-----------------------------------------------------------------*/ /* disconBBlock - removes all control flow links for a block */ /*-----------------------------------------------------------------*/ -void disconBBlock (eBBlock *ebp, eBBlock **ebbs, int count) -{ - /* mark this block as noPath & recompute control flow */ - ebp->noPath = 1; - computeControlFlow (ebbs,count,TRUE); +void +disconBBlock (eBBlock * ebp, eBBlock ** ebbs, int count) +{ + /* mark this block as noPath & recompute control flow */ + ebp->noPath = 1; + computeControlFlow (ebbs, count, TRUE); } /*-----------------------------------------------------------------*/ -/* markNoPath - marks those blocks which cannot be reached from top*/ +/* markNoPath - marks those blocks which cannot be reached from top */ /*-----------------------------------------------------------------*/ -void markNoPath ( eBBlock **ebbs, int count ) +void +markNoPath (eBBlock ** ebbs, int count) { - int i; + int i; - /* for all blocks if the visited flag is not set : then there */ - /* is no path from _entry to this block push them down in the */ - /* depth first order */ - for ( i = 0 ; i < count ; i++ ) - if (!ebbs[i]->visited) - ebbs[i]->noPath = 1; + /* for all blocks if the visited flag is not set : then there */ + /* is no path from _entry to this block push them down in the */ + /* depth first order */ + for (i = 0; i < count; i++) + if (!ebbs[i]->visited) + ebbs[i]->noPath = 1; } /*-----------------------------------------------------------------*/ /* dfNumCompare - used by qsort to sort by dfNumber */ /*-----------------------------------------------------------------*/ -int dfNumCompare (const void *a, const void *b) +int +dfNumCompare (const void *a, const void *b) { - const eBBlock * const *i = a; - const eBBlock * const *j = b; + const eBBlock *const *i = a; + const eBBlock *const *j = b; - if ( (*i)->dfnum > (*j)->dfnum ) - return 1; + if ((*i)->dfnum > (*j)->dfnum) + return 1; - if ( (*i)->dfnum < (*j)->dfnum ) - return -1; + if ((*i)->dfnum < (*j)->dfnum) + return -1; - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* bbNumCompare - used by qsort to sort by bbNumber */ /*-----------------------------------------------------------------*/ -int bbNumCompare (const void *a, const void *b) +int +bbNumCompare (const void *a, const void *b) { - const eBBlock * const *i = a; - const eBBlock * const *j = b; + const eBBlock *const *i = a; + const eBBlock *const *j = b; - if ( (*i)->bbnum > (*j)->bbnum ) - return 1; + if ((*i)->bbnum > (*j)->bbnum) + return 1; - if ( (*i)->bbnum < (*j)->bbnum ) - return -1; + if ((*i)->bbnum < (*j)->bbnum) + return -1; - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* computeControlFlow - does the control flow computation */ /*-----------------------------------------------------------------*/ -void computeControlFlow (eBBlock **ebbs,int count, int reSort) +void +computeControlFlow (eBBlock ** ebbs, int count, int reSort) { - int saveCount = count; - int i; - - /* initialise some things */ - - for ( i = 0 ; i < count ; i++ ) { - setToNull((void **)&ebbs[i]->predList); - setToNull((void **)&ebbs[i]->domVect); - setToNull((void **)&ebbs[i]->succList); - setToNull((void **)&ebbs[i]->succVect); - ebbs[i]->visited = 0; - ebbs[i]->dfnum = 0 ; + int saveCount = count; + int i; + + /* initialise some things */ + + for (i = 0; i < count; i++) + { + setToNull ((void **) &ebbs[i]->predList); + setToNull ((void **) &ebbs[i]->domVect); + setToNull ((void **) &ebbs[i]->succList); + setToNull ((void **) &ebbs[i]->succVect); + ebbs[i]->visited = 0; + ebbs[i]->dfnum = 0; } - - if (reSort) - /* sort it back by block number */ - qsort (ebbs,saveCount,sizeof(eBBlock *),bbNumCompare); - - setToNull ((void **)&graphEdges); - /* this will put in the */ - /* successor information for each blk */ - eBBSuccessors (ebbs,count); - - /* compute the depth first ordering */ - computeDFOrdering (ebbs[0],&count); - - /* mark blocks with no paths to them */ - markNoPath (ebbs,saveCount); - - /* with the depth first info in place */ - /* add the predecessors for the blocks*/ - eBBPredecessors (ebbs,saveCount); - - /* compute the dominance graph */ - computeDominance (ebbs,saveCount); - - /* sort it by dfnumber */ - qsort (ebbs,saveCount,sizeof(eBBlock *),dfNumCompare); - -} + if (reSort) + /* sort it back by block number */ + qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare); + + setToNull ((void **) &graphEdges); + /* this will put in the */ + /* successor information for each blk */ + eBBSuccessors (ebbs, count); + + /* compute the depth first ordering */ + computeDFOrdering (ebbs[0], &count); + + /* mark blocks with no paths to them */ + markNoPath (ebbs, saveCount); + /* with the depth first info in place */ + /* add the predecessors for the blocks */ + eBBPredecessors (ebbs, saveCount); + + /* compute the dominance graph */ + computeDominance (ebbs, saveCount); + + /* sort it by dfnumber */ + qsort (ebbs, saveCount, sizeof (eBBlock *), dfNumCompare); + +} diff --git a/src/SDCCcflow.h b/src/SDCCcflow.h index 4ba55bdf..949c9b5c 100644 --- a/src/SDCCcflow.h +++ b/src/SDCCcflow.h @@ -28,17 +28,17 @@ #ifndef SDCCCFLOW_H #define SDCCCFLOW_H 1 -void computeDFOrdering ( eBBlock * , int *) ; +void computeDFOrdering (eBBlock *, int *); set *domSetFromVect (eBBlock **, bitVect *); void addSuccessor (eBBlock *, eBBlock *); -void eBBSuccessors ( eBBlock **, int ); -void eBBPredecessors ( eBBlock **, int ); -eBBlock *immedDom (eBBlock **,eBBlock *); -DEFSETFUNC(DFOrdering); -void markNoPath ( eBBlock **, int); -void computeControlFlow (eBBlock **,int , int); +void eBBSuccessors (eBBlock **, int); +void eBBPredecessors (eBBlock **, int); +eBBlock *immedDom (eBBlock **, eBBlock *); +DEFSETFUNC (DFOrdering); +void markNoPath (eBBlock **, int); +void computeControlFlow (eBBlock **, int, int); int dfNumCompare (const void *, const void *); int bbNumCompare (const void *, const void *); -void disconBBlock (eBBlock *,eBBlock **,int); +void disconBBlock (eBBlock *, eBBlock **, int); #endif diff --git a/src/SDCCcse.c b/src/SDCCcse.c index e0fd0d9b..5e09ba08 100644 --- a/src/SDCCcse.c +++ b/src/SDCCcse.c @@ -28,18 +28,19 @@ /*-----------------------------------------------------------------*/ /* newCseDef - new cseDef */ /*-----------------------------------------------------------------*/ -cseDef *newCseDef (operand *sym, iCode *ic) +cseDef * +newCseDef (operand * sym, iCode * ic) { - cseDef *cdp ; + cseDef *cdp; - assert (sym); - cdp = Safe_calloc(1,sizeof(cseDef)); + assert (sym); + cdp = Safe_calloc (1, sizeof (cseDef)); - cdp->sym = sym; - cdp->diCode = ic; - cdp->key = sym->key; + cdp->sym = sym; + cdp->diCode = ic; + cdp->key = sym->key; - return cdp; + return cdp; } @@ -47,414 +48,441 @@ cseDef *newCseDef (operand *sym, iCode *ic) /*-----------------------------------------------------------------*/ /* int isCseDefEqual - two definitions are equal */ /*-----------------------------------------------------------------*/ -int isCseDefEqual ( void *vsrc, void *vdest) +int +isCseDefEqual (void *vsrc, void *vdest) { - cseDef *src = vsrc; - cseDef *dest = vdest; + cseDef *src = vsrc; + cseDef *dest = vdest; - if (src == dest) - return 1; + if (src == dest) + return 1; - return (src->key == dest->key && - src->diCode == dest->diCode ) ; + return (src->key == dest->key && + src->diCode == dest->diCode); } /*-----------------------------------------------------------------*/ /* pcseDef - in the cseDef */ /*-----------------------------------------------------------------*/ -int pcseDef (void *item, va_list ap) +int +pcseDef (void *item, va_list ap) { - cseDef *cdp = item; - iCodeTable *icTab ; + cseDef *cdp = item; + iCodeTable *icTab; - (void)ap; + (void) ap; - if (!cdp->sym) - fprintf(stdout,"**null op**"); - printOperand(cdp->sym,stdout); - icTab = getTableEntry(cdp->diCode->op) ; - icTab->iCodePrint(stdout,cdp->diCode,icTab->printName); - return 1; + if (!cdp->sym) + fprintf (stdout, "**null op**"); + printOperand (cdp->sym, stdout); + icTab = getTableEntry (cdp->diCode->op); + icTab->iCodePrint (stdout, cdp->diCode, icTab->printName); + return 1; } /*-----------------------------------------------------------------*/ /* replaceAllSymBySym - replaces all operands by operand in an */ /* instruction chain */ /*-----------------------------------------------------------------*/ -void replaceAllSymBySym (iCode *ic, operand *from , operand *to, bitVect **ndpset) +void +replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset) { - iCode *lic; - - for (lic = ic ; lic ; lic = lic->next ) { - int siaddr ; - - /* do the special cases first */ - if (lic->op == IFX) { - if (IS_SYMOP(to) && - IC_COND(lic)->key == from->key) { - - bitVectUnSetBit (OP_USES(from),lic->key); - OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key); - siaddr = IC_COND(lic)->isaddr ; - IC_COND(lic) = operandFromOperand(to); - IC_COND(lic)->isaddr = siaddr ; - - } - continue ; - } - - if (lic->op == JUMPTABLE) { - if (IS_SYMOP(to) && - IC_JTCOND(lic)->key == from->key) { - - bitVectUnSetBit (OP_USES(from),lic->key); - OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key); - siaddr = IC_COND(lic)->isaddr ; - IC_JTCOND(lic) = operandFromOperand(to); - IC_JTCOND(lic)->isaddr = siaddr ; - - } - continue ; - } - - if (IC_RESULT(lic) && IC_RESULT(lic)->key == from->key ) { - /* maintain du chains */ - if (POINTER_SET(lic)) { - bitVectUnSetBit (OP_USES(from),lic->key); - OP_USES(to) = bitVectSetBit (OP_USES(to),lic->key); - - /* also check if the "from" was in the non-dominating - pointer sets and replace it with "to" in the bitVector */ - if (bitVectBitValue(*ndpset,from->key)) { - bitVectUnSetBit(*ndpset,from->key); - bitVectSetBit(*ndpset,to->key); - } - - } - else { - bitVectUnSetBit (OP_DEFS(from),lic->key); - OP_DEFS(to) = bitVectSetBit (OP_DEFS(to),lic->key); - } - siaddr = IC_RESULT(lic)->isaddr ; - IC_RESULT(lic) = operandFromOperand(to); - IC_RESULT(lic)->isaddr = siaddr ; - } - - if (IS_SYMOP(to) && - IC_RIGHT(lic) && IC_RIGHT(lic)->key == from->key ) { - bitVectUnSetBit (OP_USES(from),lic->key); - OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key); - siaddr = IC_RIGHT(lic)->isaddr ; - IC_RIGHT(lic) = operandFromOperand(to); - IC_RIGHT(lic)->isaddr = siaddr ; - } - - if (IS_SYMOP(to) && - IC_LEFT(lic) && IC_LEFT(lic)->key == from->key ) { - bitVectUnSetBit (OP_USES(from),lic->key); - OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key); - siaddr = IC_LEFT(lic)->isaddr ; - IC_LEFT(lic) = operandFromOperand(to); - IC_LEFT(lic)->isaddr = siaddr ; - } + iCode *lic; + + for (lic = ic; lic; lic = lic->next) + { + int siaddr; + + /* do the special cases first */ + if (lic->op == IFX) + { + if (IS_SYMOP (to) && + IC_COND (lic)->key == from->key) + { + + bitVectUnSetBit (OP_USES (from), lic->key); + OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key); + siaddr = IC_COND (lic)->isaddr; + IC_COND (lic) = operandFromOperand (to); + IC_COND (lic)->isaddr = siaddr; + + } + continue; + } + + if (lic->op == JUMPTABLE) + { + if (IS_SYMOP (to) && + IC_JTCOND (lic)->key == from->key) + { + + bitVectUnSetBit (OP_USES (from), lic->key); + OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key); + siaddr = IC_COND (lic)->isaddr; + IC_JTCOND (lic) = operandFromOperand (to); + IC_JTCOND (lic)->isaddr = siaddr; + + } + continue; + } + + if (IC_RESULT (lic) && IC_RESULT (lic)->key == from->key) + { + /* maintain du chains */ + if (POINTER_SET (lic)) + { + bitVectUnSetBit (OP_USES (from), lic->key); + OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key); + + /* also check if the "from" was in the non-dominating + pointer sets and replace it with "to" in the bitVector */ + if (bitVectBitValue (*ndpset, from->key)) + { + bitVectUnSetBit (*ndpset, from->key); + bitVectSetBit (*ndpset, to->key); + } + + } + else + { + bitVectUnSetBit (OP_DEFS (from), lic->key); + OP_DEFS (to) = bitVectSetBit (OP_DEFS (to), lic->key); + } + siaddr = IC_RESULT (lic)->isaddr; + IC_RESULT (lic) = operandFromOperand (to); + IC_RESULT (lic)->isaddr = siaddr; + } + + if (IS_SYMOP (to) && + IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key) + { + bitVectUnSetBit (OP_USES (from), lic->key); + OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key); + siaddr = IC_RIGHT (lic)->isaddr; + IC_RIGHT (lic) = operandFromOperand (to); + IC_RIGHT (lic)->isaddr = siaddr; + } + + if (IS_SYMOP (to) && + IC_LEFT (lic) && IC_LEFT (lic)->key == from->key) + { + bitVectUnSetBit (OP_USES (from), lic->key); + OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key); + siaddr = IC_LEFT (lic)->isaddr; + IC_LEFT (lic) = operandFromOperand (to); + IC_LEFT (lic)->isaddr = siaddr; + } } } /*-----------------------------------------------------------------*/ /* iCodeKeyIs - if the icode keys match then return 1 */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(iCodeKeyIs) +DEFSETFUNC (iCodeKeyIs) { - cseDef *cdp = item; - V_ARG(int,key); + cseDef *cdp = item; + V_ARG (int, key); - if (cdp->diCode->key == key) - return 1; - else - return 0; + if (cdp->diCode->key == key) + return 1; + else + return 0; } /*-----------------------------------------------------------------*/ /* removeFromInExprs - removes an icode from inexpressions */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(removeFromInExprs) +DEFSETFUNC (removeFromInExprs) { - eBBlock *ebp = item; - V_ARG(iCode *,ic); - V_ARG(operand *,from); - V_ARG(operand *,to); - V_ARG(eBBlock *,cbp); + eBBlock *ebp = item; + V_ARG (iCode *, ic); + V_ARG (operand *, from); + V_ARG (operand *, to); + V_ARG (eBBlock *, cbp); - if (ebp->visited) - return 0; + if (ebp->visited) + return 0; - ebp->visited = 1; - deleteItemIf(&ebp->inExprs,iCodeKeyIs,ic->key); - if (ebp != cbp && !bitVectBitValue(cbp->domVect,ebp->bbnum)) - replaceAllSymBySym(ebp->sch,from,to,&ebp->ndompset); + ebp->visited = 1; + deleteItemIf (&ebp->inExprs, iCodeKeyIs, ic->key); + if (ebp != cbp && !bitVectBitValue (cbp->domVect, ebp->bbnum)) + replaceAllSymBySym (ebp->sch, from, to, &ebp->ndompset); - applyToSet(ebp->succList,removeFromInExprs,ic,from,to,cbp); - return 0; + applyToSet (ebp->succList, removeFromInExprs, ic, from, to, cbp); + return 0; } /*-----------------------------------------------------------------*/ /* isGlobalInNearSpace - return TRUE if valriable is a globalin data */ /*-----------------------------------------------------------------*/ -static bool isGlobalInNearSpace (operand *op) +static bool +isGlobalInNearSpace (operand * op) { - sym_link *type = getSpec(operandType(op)); - /* this is 8051 specific: optimization - suggested by Jean-Louis VERN, with 8051s we have no - advantage of putting variables in near space into - registers */ - if (isOperandGlobal(op) && !IN_FARSPACE(SPEC_OCLS(type)) && - IN_DIRSPACE(SPEC_OCLS(type))) - return TRUE; - else - return FALSE; + sym_link *type = getSpec (operandType (op)); + /* this is 8051 specific: optimization + suggested by Jean-Louis VERN, with 8051s we have no + advantage of putting variables in near space into + registers */ + if (isOperandGlobal (op) && !IN_FARSPACE (SPEC_OCLS (type)) && + IN_DIRSPACE (SPEC_OCLS (type))) + return TRUE; + else + return FALSE; } /*-----------------------------------------------------------------*/ /* findCheaperOp - cseBBlock support routine, will check to see if */ /* we have a operand previously defined */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(findCheaperOp) +DEFSETFUNC (findCheaperOp) { - cseDef *cdp = item ; - V_ARG(operand *,cop); - V_ARG(operand **,opp); + cseDef *cdp = item; + V_ARG (operand *, cop); + V_ARG (operand **, opp); - /* if we have already found it */ - if (*opp) - return 1; + /* if we have already found it */ + if (*opp) + return 1; - /* not found it yet check if this is the one */ - /* and this is not the defining one */ - if (cop->key == cdp->key) { - - /* do a special check this will help in */ - /* constant propagation & dead code elim*/ - /* for assignments only */ - if (cdp->diCode->op == '=') { - /* if the result is volatile then return result */ - if (IS_OP_VOLATILE (IC_RESULT(cdp->diCode))) - *opp = IC_RESULT(cdp->diCode); + /* not found it yet check if this is the one */ + /* and this is not the defining one */ + if (cop->key == cdp->key) + { + + /* do a special check this will help in */ + /* constant propagation & dead code elim */ + /* for assignments only */ + if (cdp->diCode->op == '=') + { + /* if the result is volatile then return result */ + if (IS_OP_VOLATILE (IC_RESULT (cdp->diCode))) + *opp = IC_RESULT (cdp->diCode); + else + /* if this is a straight assignment and + left is a temp then prefer the temporary to the + true symbol */ + if (!POINTER_SET (cdp->diCode) && + IS_ITEMP (IC_RESULT (cdp->diCode)) && + IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode))) + *opp = IC_RESULT (cdp->diCode); + else + /* if straight assignement && and both + are temps then prefer the one that + will not need extra space to spil, also + take into consideration if right side + an induction variable + */ + if (!POINTER_SET (cdp->diCode) && + IS_ITEMP (IC_RESULT (cdp->diCode)) && + IS_ITEMP (IC_RIGHT (cdp->diCode)) && + !OP_SYMBOL (IC_RIGHT (cdp->diCode))->isind && + ((!SPIL_LOC (IC_RIGHT (cdp->diCode)) && + SPIL_LOC (IC_RESULT (cdp->diCode))) || + (SPIL_LOC (IC_RESULT (cdp->diCode)) && + SPIL_LOC (IC_RESULT (cdp->diCode)) == + SPIL_LOC (IC_RIGHT (cdp->diCode)))) + ) + *opp = IC_RESULT (cdp->diCode); + else + *opp = IC_RIGHT (cdp->diCode); + } else - /* if this is a straight assignment and - left is a temp then prefer the temporary to the - true symbol */ - if (!POINTER_SET(cdp->diCode) && - IS_ITEMP(IC_RESULT(cdp->diCode)) && - IS_TRUE_SYMOP(IC_RIGHT(cdp->diCode))) - *opp = IC_RESULT(cdp->diCode); - else - /* if straight assignement && and both - are temps then prefer the one that - will not need extra space to spil, also - take into consideration if right side - an induction variable - */ - if (!POINTER_SET(cdp->diCode) && - IS_ITEMP(IC_RESULT(cdp->diCode)) && - IS_ITEMP(IC_RIGHT(cdp->diCode)) && - !OP_SYMBOL(IC_RIGHT(cdp->diCode))->isind && - ( (!SPIL_LOC(IC_RIGHT(cdp->diCode)) && - SPIL_LOC(IC_RESULT(cdp->diCode))) || - ( SPIL_LOC(IC_RESULT(cdp->diCode)) && - SPIL_LOC(IC_RESULT(cdp->diCode)) == - SPIL_LOC(IC_RIGHT(cdp->diCode))) ) - ) - *opp = IC_RESULT(cdp->diCode); - else - *opp = IC_RIGHT(cdp->diCode); - } - else - *opp = IC_RESULT(cdp->diCode) ; + *opp = IC_RESULT (cdp->diCode); } - /* if this is an assign to a temp. then check - if the right side is this then return this */ - if (IS_TRUE_SYMOP(cop) && - cdp->diCode->op == '=' && - !POINTER_SET(cdp->diCode) && - cop->key == IC_RIGHT(cdp->diCode)->key && - !isGlobalInNearSpace (IC_RIGHT(cdp->diCode)) && - IS_ITEMP(IC_RESULT(cdp->diCode))) - *opp = IC_RESULT(cdp->diCode); - - if (*opp) { - - if ((isGlobalInNearSpace(cop) && - !isOperandLiteral(*opp)) || - isOperandVolatile(*opp,FALSE) - ) { - *opp = NULL; - return 0; - } - - if (cop->key == (*opp)->key ) { - *opp = NULL ; - return 0; - } - - if ((*opp)->isaddr != cop->isaddr && IS_ITEMP(cop)) { - *opp = operandFromOperand(*opp); - (*opp)->isaddr = cop->isaddr; - } + /* if this is an assign to a temp. then check + if the right side is this then return this */ + if (IS_TRUE_SYMOP (cop) && + cdp->diCode->op == '=' && + !POINTER_SET (cdp->diCode) && + cop->key == IC_RIGHT (cdp->diCode)->key && + !isGlobalInNearSpace (IC_RIGHT (cdp->diCode)) && + IS_ITEMP (IC_RESULT (cdp->diCode))) + *opp = IC_RESULT (cdp->diCode); + + if (*opp) + { + + if ((isGlobalInNearSpace (cop) && + !isOperandLiteral (*opp)) || + isOperandVolatile (*opp, FALSE) + ) + { + *opp = NULL; + return 0; + } + + if (cop->key == (*opp)->key) + { + *opp = NULL; + return 0; + } + + if ((*opp)->isaddr != cop->isaddr && IS_ITEMP (cop)) + { + *opp = operandFromOperand (*opp); + (*opp)->isaddr = cop->isaddr; + } - return 1; + return 1; } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* findPointerSet - finds the right side of a pointer set op */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(findPointerSet) +DEFSETFUNC (findPointerSet) { - cseDef *cdp = item; - V_ARG(operand *,op); - V_ARG(operand **,opp); - V_ARG(operand *,rop); - - if (POINTER_SET(cdp->diCode) && - IC_RESULT(cdp->diCode)->key == op->key && - !isOperandVolatile(IC_RESULT(cdp->diCode),TRUE) && - !isOperandVolatile(IC_RIGHT(cdp->diCode),TRUE) && - getSize(operandType(IC_RIGHT(cdp->diCode))) == - getSize(operandType(rop))) { - *opp = IC_RIGHT(cdp->diCode); - return 1; + cseDef *cdp = item; + V_ARG (operand *, op); + V_ARG (operand **, opp); + V_ARG (operand *, rop); + + if (POINTER_SET (cdp->diCode) && + IC_RESULT (cdp->diCode)->key == op->key && + !isOperandVolatile (IC_RESULT (cdp->diCode), TRUE) && + !isOperandVolatile (IC_RIGHT (cdp->diCode), TRUE) && + getSize (operandType (IC_RIGHT (cdp->diCode))) == + getSize (operandType (rop))) + { + *opp = IC_RIGHT (cdp->diCode); + return 1; } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* findPrevIc - cseBBlock support function will return the iCode */ /* which matches the current one */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(findPrevIc) +DEFSETFUNC (findPrevIc) { - cseDef *cdp = item ; - V_ARG(iCode *,ic); - V_ARG(iCode **,icp); + cseDef *cdp = item; + V_ARG (iCode *, ic); + V_ARG (iCode **, icp); - /* if already found */ - if (*icp) - return 1; + /* if already found */ + if (*icp) + return 1; - /* if the iCodes are the same */ - if (isiCodeEqual(ic,cdp->diCode) && - isOperandEqual(cdp->sym,IC_RESULT(cdp->diCode))) { - *icp = cdp->diCode ; - return 1; + /* if the iCodes are the same */ + if (isiCodeEqual (ic, cdp->diCode) && + isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode))) + { + *icp = cdp->diCode; + return 1; } - /* if iCodes are not the same */ - /* see the operands maybe interchanged */ - if (ic->op == cdp->diCode->op && - ( ic->op == '+' || ic->op == '*' ) && - isOperandEqual(IC_LEFT(ic),IC_RIGHT(cdp->diCode)) && - isOperandEqual(IC_RIGHT(ic),IC_LEFT(cdp->diCode))) { - *icp = cdp->diCode ; - return 1; + /* if iCodes are not the same */ + /* see the operands maybe interchanged */ + if (ic->op == cdp->diCode->op && + (ic->op == '+' || ic->op == '*') && + isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) && + isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode))) + { + *icp = cdp->diCode; + return 1; } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* ifDefGlobal - if definition is global */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(ifDefGlobal) +DEFSETFUNC (ifDefGlobal) { - cseDef *cdp = item; + cseDef *cdp = item; - return (isOperandGlobal(cdp->sym)); + return (isOperandGlobal (cdp->sym)); } /*-----------------------------------------------------------------*/ /* ifAnyGetPointer - if get pointer icode */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(ifAnyGetPointer) +DEFSETFUNC (ifAnyGetPointer) { - cseDef *cdp = item; + cseDef *cdp = item; - if (cdp->diCode && POINTER_GET(cdp->diCode)) return 1; - return 0; + if (cdp->diCode && POINTER_GET (cdp->diCode)) + return 1; + return 0; } /*-----------------------------------------------------------------*/ /* ifOperandsHave - if any of the operand are the same as this */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(ifOperandsHave) +DEFSETFUNC (ifOperandsHave) { - cseDef *cdp = item; - V_ARG(operand *,op); + cseDef *cdp = item; + V_ARG (operand *, op); - if (IC_LEFT(cdp->diCode) && - IS_SYMOP(IC_LEFT(cdp->diCode)) && - IC_LEFT(cdp->diCode)->key == op->key) - return 1; + if (IC_LEFT (cdp->diCode) && + IS_SYMOP (IC_LEFT (cdp->diCode)) && + IC_LEFT (cdp->diCode)->key == op->key) + return 1; - if (IC_RIGHT(cdp->diCode) && - IS_SYMOP(IC_RIGHT(cdp->diCode)) && - IC_RIGHT(cdp->diCode)->key == op->key) - return 1; + if (IC_RIGHT (cdp->diCode) && + IS_SYMOP (IC_RIGHT (cdp->diCode)) && + IC_RIGHT (cdp->diCode)->key == op->key) + return 1; - /* or if any of the operands are volatile */ - if (IC_LEFT(cdp->diCode) && - IS_OP_VOLATILE(IC_LEFT(cdp->diCode))) - return 1; + /* or if any of the operands are volatile */ + if (IC_LEFT (cdp->diCode) && + IS_OP_VOLATILE (IC_LEFT (cdp->diCode))) + return 1; - if (IC_RIGHT(cdp->diCode) && - IS_OP_VOLATILE(IC_RIGHT(cdp->diCode))) - return 1; + if (IC_RIGHT (cdp->diCode) && + IS_OP_VOLATILE (IC_RIGHT (cdp->diCode))) + return 1; - if (IC_RESULT(cdp->diCode) && - IS_OP_VOLATILE(IC_RESULT(cdp->diCode))) - return 1; + if (IC_RESULT (cdp->diCode) && + IS_OP_VOLATILE (IC_RESULT (cdp->diCode))) + return 1; - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* ifDefSymIs - if a definition is found in the set */ /*-----------------------------------------------------------------*/ - int ifDefSymIs (set *cseSet, operand *sym) +int +ifDefSymIs (set * cseSet, operand * sym) { - cseDef *loop ; - set *sl ; + cseDef *loop; + set *sl; - if (!sym || !IS_SYMOP(sym)) - return 0; - for (sl = cseSet ; sl ; sl = sl->next ) { - loop = sl->item; - if (loop->sym->key == sym->key ) - return 1; - } + if (!sym || !IS_SYMOP (sym)) return 0; + for (sl = cseSet; sl; sl = sl->next) + { + loop = sl->item; + if (loop->sym->key == sym->key) + return 1; + } + return 0; } /*-----------------------------------------------------------------*/ /* ifDefSymIsX - will return 1 if the symbols match */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(ifDefSymIsX) +DEFSETFUNC (ifDefSymIsX) { - cseDef *cdp = item; - V_ARG(operand *,op); + cseDef *cdp = item; + V_ARG (operand *, op); - if (op && cdp->sym) - return cdp->sym->key == op->key ; - else - return ( isOperandEqual(cdp->sym,op) ); + if (op && cdp->sym) + return cdp->sym->key == op->key; + else + return (isOperandEqual (cdp->sym, op)); } @@ -462,590 +490,639 @@ DEFSETFUNC(ifDefSymIsX) /*-----------------------------------------------------------------*/ /* ifDiCodeIs - returns truw if diCode is same */ /*-----------------------------------------------------------------*/ - int ifDiCodeIs (set *cseSet, iCode *ic) +int +ifDiCodeIs (set * cseSet, iCode * ic) { - cseDef *loop; - set *sl; + cseDef *loop; + set *sl; - if (!ic) - return 0; + if (!ic) + return 0; - for (sl = cseSet ; sl ; sl = sl->next ) { - loop = sl->item ; - if (loop->diCode == ic) - return 1; + for (sl = cseSet; sl; sl = sl->next) + { + loop = sl->item; + if (loop->diCode == ic) + return 1; } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* ifPointerGet - returns true if the icode is pointer get sym */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(ifPointerGet) +DEFSETFUNC (ifPointerGet) { - cseDef *cdp = item; - V_ARG(operand *,op); - iCode *dic = cdp->diCode; - operand *left = IC_LEFT(cdp->diCode); + cseDef *cdp = item; + V_ARG (operand *, op); + iCode *dic = cdp->diCode; + operand *left = IC_LEFT (cdp->diCode); - if (POINTER_GET(dic) && left->key == op->key) - return 1; + if (POINTER_GET (dic) && left->key == op->key) + return 1; - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* ifPointerSet - returns true if the icode is pointer set sym */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(ifPointerSet) +DEFSETFUNC (ifPointerSet) { - cseDef *cdp = item; - V_ARG(operand *,op); + cseDef *cdp = item; + V_ARG (operand *, op); - if (POINTER_SET(cdp->diCode) && - IC_RESULT(cdp->diCode)->key == op->key) - return 1; + if (POINTER_SET (cdp->diCode) && + IC_RESULT (cdp->diCode)->key == op->key) + return 1; - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* ifDiCodeIsX - will return 1 if the symbols match */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(ifDiCodeIsX) +DEFSETFUNC (ifDiCodeIsX) { - cseDef *cdp = item; - V_ARG(iCode *,ic); + cseDef *cdp = item; + V_ARG (iCode *, ic); - return cdp->diCode == ic; + return cdp->diCode == ic; } /*-----------------------------------------------------------------*/ /* algebraicOpts - does some algebraic optimizations */ /*-----------------------------------------------------------------*/ -void algebraicOpts (iCode *ic) +void +algebraicOpts (iCode * ic) { - /* we don't deal with the following iCodes - here */ - if (ic->op == IFX || - ic->op == IPUSH || - ic->op == IPOP || - ic->op == CALL || - ic->op == PCALL || - ic->op == RETURN || - POINTER_GET(ic)) - return ; - - /* if both operands present & ! IFX */ - /* then if they are both literal we */ - /* perform the operation right now */ - if (IC_RESULT(ic) && - IC_RIGHT(ic) && - IC_LEFT(ic) && - IS_OP_LITERAL(IC_LEFT(ic)) && - IS_OP_LITERAL(IC_RIGHT(ic))) { - - IC_RIGHT(ic) = operandOperation (IC_LEFT(ic), - IC_RIGHT(ic), - ic->op, - operandType(IC_RESULT(ic))); - ic->op = '='; - IC_LEFT(ic) = NULL ; - SET_RESULT_RIGHT(ic); - return ; + /* we don't deal with the following iCodes + here */ + if (ic->op == IFX || + ic->op == IPUSH || + ic->op == IPOP || + ic->op == CALL || + ic->op == PCALL || + ic->op == RETURN || + POINTER_GET (ic)) + return; + + /* if both operands present & ! IFX */ + /* then if they are both literal we */ + /* perform the operation right now */ + if (IC_RESULT (ic) && + IC_RIGHT (ic) && + IC_LEFT (ic) && + IS_OP_LITERAL (IC_LEFT (ic)) && + IS_OP_LITERAL (IC_RIGHT (ic))) + { + + IC_RIGHT (ic) = operandOperation (IC_LEFT (ic), + IC_RIGHT (ic), + ic->op, + operandType (IC_RESULT (ic))); + ic->op = '='; + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + return; } - /* if not ifx & only one operand present */ - if (IC_RESULT(ic) && - IC_LEFT(ic) && - IS_OP_LITERAL(IC_LEFT(ic)) && - !IC_RIGHT(ic)) { - - IC_RIGHT(ic) = operandOperation (IC_LEFT(ic), - IC_RIGHT(ic), - ic->op, - operandType(IC_RESULT(ic))); - ic->op = '='; - IC_LEFT(ic) = NULL ; - SET_RESULT_RIGHT(ic); - return ; + /* if not ifx & only one operand present */ + if (IC_RESULT (ic) && + IC_LEFT (ic) && + IS_OP_LITERAL (IC_LEFT (ic)) && + !IC_RIGHT (ic)) + { + + IC_RIGHT (ic) = operandOperation (IC_LEFT (ic), + IC_RIGHT (ic), + ic->op, + operandType (IC_RESULT (ic))); + ic->op = '='; + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + return; } - /* a special case : or in short a kludgy solution will think - about a better solution over a glass of wine someday */ - if ( ic->op == GET_VALUE_AT_ADDRESS ) { + /* a special case : or in short a kludgy solution will think + about a better solution over a glass of wine someday */ + if (ic->op == GET_VALUE_AT_ADDRESS) + { - if (IS_ITEMP(IC_RESULT(ic)) && - IS_TRUE_SYMOP(IC_LEFT(ic))) { + if (IS_ITEMP (IC_RESULT (ic)) && + IS_TRUE_SYMOP (IC_LEFT (ic))) + { - ic->op = '=' ; - IC_RIGHT(ic) = operandFromOperand(IC_LEFT(ic)); - IC_RIGHT(ic)->isaddr = 0; - IC_LEFT(ic) = NULL; - IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic)); - IC_RESULT(ic)->isaddr = 0; - setOperandType(IC_RESULT(ic),operandType(IC_RIGHT(ic))); - return; - } + ic->op = '='; + IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic)); + IC_RIGHT (ic)->isaddr = 0; + IC_LEFT (ic) = NULL; + IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic)); + IC_RESULT (ic)->isaddr = 0; + setOperandType (IC_RESULT (ic), operandType (IC_RIGHT (ic))); + return; + } - if (IS_ITEMP(IC_LEFT(ic)) && - IS_ITEMP(IC_RESULT(ic)) && + if (IS_ITEMP (IC_LEFT (ic)) && + IS_ITEMP (IC_RESULT (ic)) && /* !OP_SYMBOL(IC_RESULT(ic))->isreqv && */ /* !OP_SYMBOL(IC_LEFT(ic))->isreqv && */ - !IC_LEFT(ic)->isaddr ) { - ic->op = '=' ; - IC_RIGHT(ic) = operandFromOperand(IC_LEFT(ic)); - IC_RIGHT(ic)->isaddr = 0; - IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic)); - IC_RESULT(ic)->isaddr = 0; - IC_LEFT(ic) = NULL; - return; - } + !IC_LEFT (ic)->isaddr) + { + ic->op = '='; + IC_RIGHT (ic) = operandFromOperand (IC_LEFT (ic)); + IC_RIGHT (ic)->isaddr = 0; + IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic)); + IC_RESULT (ic)->isaddr = 0; + IC_LEFT (ic) = NULL; + return; + } } - /* depending on the operation */ - switch (ic->op) { - case '+' : - /* if adding the same thing change to left shift by 1*/ - if (IC_LEFT(ic)->key == IC_RIGHT(ic)->key && - !IS_FLOAT(operandType(IC_RESULT(ic)))) { - ic->op = LEFT_OP ; - IC_RIGHT(ic) = operandFromLit(1); - return; - } - /* if addition then check if one of them is a zero */ - /* if yes turn it into assignmnt*/ - if (IS_OP_LITERAL(IC_LEFT(ic)) && - operandLitValue(IC_LEFT(ic)) == 0.0 ) { - - ic->op = '=' ; - IC_LEFT(ic) = NULL ; - SET_ISADDR(IC_RESULT(ic),0); - SET_ISADDR(IC_RIGHT(ic),0); - return ; - } - if (IS_OP_LITERAL(IC_RIGHT(ic)) && - operandLitValue(IC_RIGHT(ic)) == 0.0 ) { - - ic->op = '=' ; - IC_RIGHT(ic) = IC_LEFT(ic) ; - IC_LEFT(ic) = 0; - SET_ISADDR(IC_RIGHT(ic),0); - SET_ISADDR(IC_RESULT(ic),0); - return ; - } - break ; - case '-' : - /* if subtracting the the same thing then zero */ - if ( IC_LEFT(ic)->key == IC_RIGHT(ic)->key ) { - ic->op = '='; - IC_RIGHT(ic) = operandFromLit(0); - IC_LEFT(ic) = NULL ; - IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic)); - IC_RESULT(ic)->isaddr = 0; - return ; - } - - /* if subtraction then check if one of the operand */ - /* is zero then depending on which operand change */ - /* to assignment or unary minus */ - if (IS_OP_LITERAL(IC_RIGHT(ic)) && - operandLitValue(IC_RIGHT(ic)) == 0.0 ) { - /* right size zero change to assignment */ - ic->op = '=' ; - IC_RIGHT(ic) = IC_LEFT(ic); - IC_LEFT(ic) = NULL; - SET_ISADDR(IC_RIGHT(ic),0); - SET_ISADDR(IC_RESULT(ic),0); - return ; - } - if (IS_OP_LITERAL(IC_LEFT(ic)) && - operandLitValue (IC_LEFT(ic)) == 0.0) { - /* left zero turn into an unary minus */ - ic->op = UNARYMINUS ; - IC_LEFT(ic) = IC_RIGHT(ic); - IC_RIGHT(ic) = NULL ; - return ; - } - break; - /* if multiplication then check if either of */ - /* them is zero then the result is zero */ - /* if either of them is one then result is */ - /* the other one */ - case '*' : - if (IS_OP_LITERAL(IC_LEFT(ic))) { - - if (operandLitValue(IC_LEFT(ic)) == 0.0) { - ic->op = '=' ; - IC_RIGHT(ic) = IC_LEFT(ic); - IC_LEFT(ic) = NULL; - SET_RESULT_RIGHT(ic); - return ; - } - if ( operandLitValue(IC_LEFT(ic)) == 1.0) { - ic->op = '=' ; - IC_LEFT(ic) = NULL ; - SET_RESULT_RIGHT(ic); - return ; - } - } - - if (IS_OP_LITERAL(IC_RIGHT(ic))) { - - if (operandLitValue(IC_RIGHT(ic)) == 0.0 ) { - ic->op = '='; - IC_LEFT(ic) = NULL ; - SET_RESULT_RIGHT(ic); - return ; - } - - if (operandLitValue(IC_RIGHT(ic)) == 1.0) { - ic->op = '=' ; - IC_RIGHT(ic) = IC_LEFT(ic); - IC_LEFT(ic) = NULL ; - SET_RESULT_RIGHT(ic); - return ; - } - } - break ; + /* depending on the operation */ + switch (ic->op) + { + case '+': + /* if adding the same thing change to left shift by 1 */ + if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key && + !IS_FLOAT (operandType (IC_RESULT (ic)))) + { + ic->op = LEFT_OP; + IC_RIGHT (ic) = operandFromLit (1); + return; + } + /* if addition then check if one of them is a zero */ + /* if yes turn it into assignmnt */ + if (IS_OP_LITERAL (IC_LEFT (ic)) && + operandLitValue (IC_LEFT (ic)) == 0.0) + { + + ic->op = '='; + IC_LEFT (ic) = NULL; + SET_ISADDR (IC_RESULT (ic), 0); + SET_ISADDR (IC_RIGHT (ic), 0); + return; + } + if (IS_OP_LITERAL (IC_RIGHT (ic)) && + operandLitValue (IC_RIGHT (ic)) == 0.0) + { + + ic->op = '='; + IC_RIGHT (ic) = IC_LEFT (ic); + IC_LEFT (ic) = 0; + SET_ISADDR (IC_RIGHT (ic), 0); + SET_ISADDR (IC_RESULT (ic), 0); + return; + } + break; + case '-': + /* if subtracting the the same thing then zero */ + if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key) + { + ic->op = '='; + IC_RIGHT (ic) = operandFromLit (0); + IC_LEFT (ic) = NULL; + IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic)); + IC_RESULT (ic)->isaddr = 0; + return; + } + + /* if subtraction then check if one of the operand */ + /* is zero then depending on which operand change */ + /* to assignment or unary minus */ + if (IS_OP_LITERAL (IC_RIGHT (ic)) && + operandLitValue (IC_RIGHT (ic)) == 0.0) + { + /* right size zero change to assignment */ + ic->op = '='; + IC_RIGHT (ic) = IC_LEFT (ic); + IC_LEFT (ic) = NULL; + SET_ISADDR (IC_RIGHT (ic), 0); + SET_ISADDR (IC_RESULT (ic), 0); + return; + } + if (IS_OP_LITERAL (IC_LEFT (ic)) && + operandLitValue (IC_LEFT (ic)) == 0.0) + { + /* left zero turn into an unary minus */ + ic->op = UNARYMINUS; + IC_LEFT (ic) = IC_RIGHT (ic); + IC_RIGHT (ic) = NULL; + return; + } + break; + /* if multiplication then check if either of */ + /* them is zero then the result is zero */ + /* if either of them is one then result is */ + /* the other one */ + case '*': + if (IS_OP_LITERAL (IC_LEFT (ic))) + { + + if (operandLitValue (IC_LEFT (ic)) == 0.0) + { + ic->op = '='; + IC_RIGHT (ic) = IC_LEFT (ic); + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + return; + } + if (operandLitValue (IC_LEFT (ic)) == 1.0) + { + ic->op = '='; + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + return; + } + } + + if (IS_OP_LITERAL (IC_RIGHT (ic))) + { + + if (operandLitValue (IC_RIGHT (ic)) == 0.0) + { + ic->op = '='; + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + return; + } + + if (operandLitValue (IC_RIGHT (ic)) == 1.0) + { + ic->op = '='; + IC_RIGHT (ic) = IC_LEFT (ic); + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + return; + } + } + break; case '/': - /* if division by self then 1 */ - if (IC_LEFT(ic)->key == IC_RIGHT(ic)->key) { - ic->op = '='; - IC_RIGHT(ic) = operandFromLit(1); - IC_LEFT(ic) = NULL; - IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic)); - IC_RESULT(ic)->isaddr = 0; - } - /* if this is a division then check if right */ - /* is one then change it to an assignment */ - if (IS_OP_LITERAL(IC_RIGHT(ic)) && - operandLitValue(IC_RIGHT(ic)) == 1.0 ) { - - ic->op = '=' ; - IC_RIGHT(ic) = IC_LEFT(ic); - IC_LEFT(ic) = NULL; - SET_RESULT_RIGHT(ic); - return ; - } - break; - /* if both are the same for an comparison operators */ - case EQ_OP : - case LE_OP : - case GE_OP : - if (isOperandEqual(IC_LEFT(ic),IC_RIGHT(ic))) { - ic->op = '='; - IC_RIGHT(ic) = operandFromLit(1); - IC_LEFT(ic) = NULL; - SET_RESULT_RIGHT(ic); - } - break; - case NE_OP : - case '>' : - case '<' : - if (isOperandEqual(IC_LEFT(ic),IC_RIGHT(ic))) { - ic->op = '='; - IC_RIGHT(ic) = operandFromLit(0); - IC_LEFT(ic) = NULL ; - SET_RESULT_RIGHT(ic); - } - break ; - case CAST : - /* if this is a cast of a literal value */ - if ( IS_OP_LITERAL(IC_RIGHT(ic))) { - ic->op = '=' ; - IC_RIGHT(ic) = - operandFromValue (valCastLiteral(operandType(IC_LEFT(ic)), - operandLitValue(IC_RIGHT(ic)))); - IC_LEFT(ic) = NULL; - SET_ISADDR(IC_RESULT(ic),0); - } - /* if casting to the same */ - if ( checkType(operandType(IC_RESULT(ic)), - operandType(IC_RIGHT(ic))) == 1) { - ic->op = '='; - IC_LEFT(ic) = NULL; - SET_ISADDR(IC_RESULT(ic),0); - } - break; - case '!' : - if (IS_OP_LITERAL(IC_LEFT(ic))) { - ic->op = '=' ; - IC_RIGHT(ic) = - (operandLitValue(IC_LEFT(ic)) == 0 ? - operandFromLit(1) : operandFromLit(0)); - IC_LEFT(ic) = NULL; - SET_ISADDR(IC_RESULT(ic),0); - } + /* if division by self then 1 */ + if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key) + { + ic->op = '='; + IC_RIGHT (ic) = operandFromLit (1); + IC_LEFT (ic) = NULL; + IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic)); + IC_RESULT (ic)->isaddr = 0; + } + /* if this is a division then check if right */ + /* is one then change it to an assignment */ + if (IS_OP_LITERAL (IC_RIGHT (ic)) && + operandLitValue (IC_RIGHT (ic)) == 1.0) + { + + ic->op = '='; + IC_RIGHT (ic) = IC_LEFT (ic); + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + return; + } + break; + /* if both are the same for an comparison operators */ + case EQ_OP: + case LE_OP: + case GE_OP: + if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic))) + { + ic->op = '='; + IC_RIGHT (ic) = operandFromLit (1); + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + } + break; + case NE_OP: + case '>': + case '<': + if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic))) + { + ic->op = '='; + IC_RIGHT (ic) = operandFromLit (0); + IC_LEFT (ic) = NULL; + SET_RESULT_RIGHT (ic); + } + break; + case CAST: + /* if this is a cast of a literal value */ + if (IS_OP_LITERAL (IC_RIGHT (ic))) + { + ic->op = '='; + IC_RIGHT (ic) = + operandFromValue (valCastLiteral (operandType (IC_LEFT (ic)), + operandLitValue (IC_RIGHT (ic)))); + IC_LEFT (ic) = NULL; + SET_ISADDR (IC_RESULT (ic), 0); + } + /* if casting to the same */ + if (checkType (operandType (IC_RESULT (ic)), + operandType (IC_RIGHT (ic))) == 1) + { + ic->op = '='; + IC_LEFT (ic) = NULL; + SET_ISADDR (IC_RESULT (ic), 0); + } + break; + case '!': + if (IS_OP_LITERAL (IC_LEFT (ic))) + { + ic->op = '='; + IC_RIGHT (ic) = + (operandLitValue (IC_LEFT (ic)) == 0 ? + operandFromLit (1) : operandFromLit (0)); + IC_LEFT (ic) = NULL; + SET_ISADDR (IC_RESULT (ic), 0); + } } - return ; + return; } #define OTHERS_PARM(s) (s->_isparm && !s->ismyparm) /*-----------------------------------------------------------------*/ /* updateSpillLocation - keeps track of register spill location */ /*-----------------------------------------------------------------*/ -void updateSpillLocation ( iCode *ic) +void +updateSpillLocation (iCode * ic) { - sym_link *setype; + sym_link *setype; - if (POINTER_SET(ic)) - return; + if (POINTER_SET (ic)) + return; - if (ic->nosupdate) - return; + if (ic->nosupdate) + return; - /* for the form true_symbol := iTempNN */ - if (ASSIGN_ITEMP_TO_SYM(ic) - && !SPIL_LOC(IC_RIGHT(ic))) { + /* for the form true_symbol := iTempNN */ + if (ASSIGN_ITEMP_TO_SYM (ic) + && !SPIL_LOC (IC_RIGHT (ic))) + { - setype = getSpec(operandType(IC_RESULT(ic))); + setype = getSpec (operandType (IC_RESULT (ic))); - if (!IC_RIGHT(ic)->noSpilLoc && - !IS_VOLATILE(setype) && - !IN_FARSPACE(SPEC_OCLS(setype)) && - !OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) ) + if (!IC_RIGHT (ic)->noSpilLoc && + !IS_VOLATILE (setype) && + !IN_FARSPACE (SPEC_OCLS (setype)) && + !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic)))) - SPIL_LOC(IC_RIGHT(ic)) = - IC_RESULT(ic)->operand.symOperand; + SPIL_LOC (IC_RIGHT (ic)) = + IC_RESULT (ic)->operand.symOperand; } - if (ASSIGN_ITEMP_TO_ITEMP(ic) && - !SPIL_LOC(IC_RIGHT(ic)) && - !bitVectBitsInCommon(OP_DEFS(IC_RIGHT(ic)),OP_USES(IC_RESULT(ic))) && - OP_SYMBOL(IC_RESULT(ic))->isreqv) { + if (ASSIGN_ITEMP_TO_ITEMP (ic) && + !SPIL_LOC (IC_RIGHT (ic)) && + !bitVectBitsInCommon (OP_DEFS (IC_RIGHT (ic)), OP_USES (IC_RESULT (ic))) && + OP_SYMBOL (IC_RESULT (ic))->isreqv) + { - setype = getSpec(operandType(IC_RESULT(ic))); + setype = getSpec (operandType (IC_RESULT (ic))); - if (!IC_RIGHT(ic)->noSpilLoc && - !IS_VOLATILE(setype) && - !IN_FARSPACE(SPEC_OCLS(setype)) && - !OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) ) + if (!IC_RIGHT (ic)->noSpilLoc && + !IS_VOLATILE (setype) && + !IN_FARSPACE (SPEC_OCLS (setype)) && + !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic)))) - SPIL_LOC(IC_RIGHT(ic)) = - SPIL_LOC(IC_RESULT(ic)); + SPIL_LOC (IC_RIGHT (ic)) = + SPIL_LOC (IC_RESULT (ic)); } } /*-----------------------------------------------------------------*/ /* setUsesDef - sets the uses def bitvector for a given operand */ /*-----------------------------------------------------------------*/ -void setUsesDefs (operand *op, bitVect *bdefs, - bitVect *idefs, bitVect **oud) +void +setUsesDefs (operand * op, bitVect * bdefs, + bitVect * idefs, bitVect ** oud) { - /* compute the definitions alive at this point */ - bitVect *adefs = bitVectUnion(bdefs,idefs); + /* compute the definitions alive at this point */ + bitVect *adefs = bitVectUnion (bdefs, idefs); - /* of these definitions find the ones that are */ - /* for this operand */ - adefs = bitVectIntersect(adefs,OP_DEFS(op)); + /* of these definitions find the ones that are */ + /* for this operand */ + adefs = bitVectIntersect (adefs, OP_DEFS (op)); - /* these are the definitions that this operand can use */ - op->usesDefs = adefs; + /* these are the definitions that this operand can use */ + op->usesDefs = adefs; - /* the out defs is an union */ - *oud = bitVectUnion(*oud,adefs); + /* the out defs is an union */ + *oud = bitVectUnion (*oud, adefs); } /*-----------------------------------------------------------------*/ /* unsetDefsAndUses - clear this operation for the operands */ /*-----------------------------------------------------------------*/ -void unsetDefsAndUses ( iCode *ic ) +void +unsetDefsAndUses (iCode * ic) { - if ( ic->op == JUMPTABLE) - return ; - - /* take away this definition from the def chain of the */ - /* result & take away from use set of the operands */ - if (ic->op != IFX) { - /* turn off def set */ - if (IS_SYMOP(IC_RESULT(ic))) { - if ( !POINTER_SET(ic)) - bitVectUnSetBit(OP_DEFS(IC_RESULT(ic)),ic->key); - else - bitVectUnSetBit(OP_USES(IC_RESULT(ic)),ic->key); - } - /* turn off the useSet for the operands */ - if (IS_SYMOP(IC_LEFT(ic))) - bitVectUnSetBit (OP_USES(IC_LEFT(ic)),ic->key); - - if (IS_SYMOP(IC_RIGHT(ic))) - bitVectUnSetBit (OP_USES(IC_RIGHT(ic)),ic->key); + if (ic->op == JUMPTABLE) + return; + + /* take away this definition from the def chain of the */ + /* result & take away from use set of the operands */ + if (ic->op != IFX) + { + /* turn off def set */ + if (IS_SYMOP (IC_RESULT (ic))) + { + if (!POINTER_SET (ic)) + bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key); + else + bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key); + } + /* turn off the useSet for the operands */ + if (IS_SYMOP (IC_LEFT (ic))) + bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key); + + if (IS_SYMOP (IC_RIGHT (ic))) + bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key); } - else /* must be ifx turn off the use */ - if (IS_SYMOP(IC_COND(ic))) - bitVectUnSetBit (OP_USES(IC_COND(ic)),ic->key); + else + /* must be ifx turn off the use */ if (IS_SYMOP (IC_COND (ic))) + bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key); } /*-----------------------------------------------------------------*/ /* ifxOptimize - changes ifx conditions if it can */ /*-----------------------------------------------------------------*/ -void ifxOptimize (iCode *ic, set *cseSet, - int computeOnly , - eBBlock *ebb, int *change, - eBBlock **ebbs, int count) +void +ifxOptimize (iCode * ic, set * cseSet, + int computeOnly, + eBBlock * ebb, int *change, + eBBlock ** ebbs, int count) { - operand *pdop ; - symbol *label; - - /* if the condition can be replaced */ - if (!computeOnly) { - pdop = NULL ; - applyToSetFTrue (cseSet,findCheaperOp,IC_COND(ic),&pdop); - if (pdop) { - IC_COND(ic) = pdop ; - (*change)++; - } + operand *pdop; + symbol *label; + + /* if the condition can be replaced */ + if (!computeOnly) + { + pdop = NULL; + applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop); + if (pdop) + { + IC_COND (ic) = pdop; + (*change)++; + } } - /* if the conditional is a literal then */ - if (IS_OP_LITERAL(IC_COND(ic))) { - - if ( (operandLitValue(IC_COND(ic)) != 0.0) && IC_TRUE(ic)) { - - /* change to a goto */ - ic->op = GOTO ; - IC_LABEL(ic) = IC_TRUE(ic); - (*change)++; - - } else { - - if (!operandLitValue(IC_COND(ic)) && IC_FALSE(ic)) { - ic->op = GOTO ; - IC_LABEL(ic) = IC_FALSE(ic); - (*change)++; - - } else { - /* then kill this if condition */ - remiCodeFromeBBlock (ebb,ic); - } - } - - /* now we need to recompute the control flow */ - /* since the control flow has changed */ - /* this is very expensive but it does not happen */ - /* too often, if it does happen then the user pays */ - /* the price */ - computeControlFlow (ebbs,count,1); - werror (W_CONTROL_FLOW,ic->filename,ic->lineno); - return ; + /* if the conditional is a literal then */ + if (IS_OP_LITERAL (IC_COND (ic))) + { + + if ((operandLitValue (IC_COND (ic)) != 0.0) && IC_TRUE (ic)) + { + + /* change to a goto */ + ic->op = GOTO; + IC_LABEL (ic) = IC_TRUE (ic); + (*change)++; + + } + else + { + + if (!operandLitValue (IC_COND (ic)) && IC_FALSE (ic)) + { + ic->op = GOTO; + IC_LABEL (ic) = IC_FALSE (ic); + (*change)++; + + } + else + { + /* then kill this if condition */ + remiCodeFromeBBlock (ebb, ic); + } + } + + /* now we need to recompute the control flow */ + /* since the control flow has changed */ + /* this is very expensive but it does not happen */ + /* too often, if it does happen then the user pays */ + /* the price */ + computeControlFlow (ebbs, count, 1); + werror (W_CONTROL_FLOW, ic->filename, ic->lineno); + return; } - /* if there is only one successor and that successor - is the same one we are conditionally going to then - we can remove this conditional statement */ - label = (IC_TRUE(ic) ? IC_TRUE(ic) : IC_FALSE(ic)); - if (elementsInSet(ebb->succList) == 1 && - isinSet(ebb->succList,eBBWithEntryLabel(ebbs,label,count))) { - - remiCodeFromeBBlock(ebb,ic); - computeControlFlow (ebbs,count,1); - werror (W_CONTROL_FLOW,ic->filename,ic->lineno); - return ; + /* if there is only one successor and that successor + is the same one we are conditionally going to then + we can remove this conditional statement */ + label = (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic)); + if (elementsInSet (ebb->succList) == 1 && + isinSet (ebb->succList, eBBWithEntryLabel (ebbs, label, count))) + { + + remiCodeFromeBBlock (ebb, ic); + computeControlFlow (ebbs, count, 1); + werror (W_CONTROL_FLOW, ic->filename, ic->lineno); + return; } - /* if it remains an IFX the update the use Set */ - OP_USES(IC_COND(ic)) = bitVectSetBit(OP_USES(IC_COND(ic)),ic->key); - setUsesDefs(IC_COND(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs); - return ; + /* if it remains an IFX the update the use Set */ + OP_USES (IC_COND (ic)) = bitVectSetBit (OP_USES (IC_COND (ic)), ic->key); + setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs); + return; } /*-----------------------------------------------------------------*/ /* diCodeForSym - finds the definiting instruction for a symbol */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(diCodeForSym) +DEFSETFUNC (diCodeForSym) { - cseDef *cdp = item; - V_ARG(operand *,sym); - V_ARG(iCode **,dic); + cseDef *cdp = item; + V_ARG (operand *, sym); + V_ARG (iCode **, dic); - /* if already found */ - if (*dic) - return 0; + /* if already found */ + if (*dic) + return 0; - /* if not if this is the defining iCode */ - if (sym->key == cdp->key) { - *dic = cdp->diCode ; - return 1; + /* if not if this is the defining iCode */ + if (sym->key == cdp->key) + { + *dic = cdp->diCode; + return 1; } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* constFold - does some constant folding */ /*-----------------------------------------------------------------*/ -int constFold (iCode *ic, set *cseSet) +int +constFold (iCode * ic, set * cseSet) { - iCode *dic = NULL; - iCode *ldic= NULL; - /* this routine will change - a = b + 10; - c = a + 10; - to - c = b + 20; */ - - /* deal with only + & - */ - if (ic->op != '+' && - ic->op != '-' ) - return 0; + iCode *dic = NULL; + iCode *ldic = NULL; + /* this routine will change + a = b + 10; + c = a + 10; + to + c = b + 20; */ + + /* deal with only + & - */ + if (ic->op != '+' && + ic->op != '-') + return 0; - /* this check is a hueristic to prevent live ranges - from becoming too long */ - if (IS_PTR(operandType(IC_RESULT(ic)))) - return 0; + /* this check is a hueristic to prevent live ranges + from becoming too long */ + if (IS_PTR (operandType (IC_RESULT (ic)))) + return 0; - /* check if operation with a literal */ - if (!IS_OP_LITERAL(IC_RIGHT(ic))) - return 0; + /* check if operation with a literal */ + if (!IS_OP_LITERAL (IC_RIGHT (ic))) + return 0; - /* check if we can find a definition for the - right hand side */ - if (!(applyToSet(cseSet,diCodeForSym,IC_LEFT(ic),&dic))) - return 0; + /* check if we can find a definition for the + right hand side */ + if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic))) + return 0; - /* check that this is also a +/- */ - if (dic->op != '+' && dic->op != '-') - return 0; + /* check that this is also a +/- */ + if (dic->op != '+' && dic->op != '-') + return 0; - /* with a literal */ - if (!IS_OP_LITERAL(IC_RIGHT(dic))) - return 0; + /* with a literal */ + if (!IS_OP_LITERAL (IC_RIGHT (dic))) + return 0; - /* find the definition of the left operand - of dic.then check if this defined with a - get_pointer return 0 if the pointer size is - less than 2 (MCS51 specific) */ - if (!(applyToSet(cseSet,diCodeForSym,IC_LEFT(dic),&ldic))) - return 0; + /* find the definition of the left operand + of dic.then check if this defined with a + get_pointer return 0 if the pointer size is + less than 2 (MCS51 specific) */ + if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (dic), &ldic))) + return 0; - if (POINTER_GET(ldic) && getSize(operandType(IC_LEFT(ldic))) <= 1) - return 0; + if (POINTER_GET (ldic) && getSize (operandType (IC_LEFT (ldic))) <= 1) + return 0; - /* it is if the operations are the same*/ - /* the literal parts need to be added */ - IC_LEFT(ic) = operandFromOperand(IC_LEFT(dic)); - if (ic->op == dic->op ) - IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic))+ - operandLitValue(IC_RIGHT(dic))); - else - IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - - operandLitValue(IC_RIGHT(dic))); - - if (IS_ITEMP(IC_RESULT(ic))) { - SPIL_LOC(IC_RESULT(ic)) = NULL; - IC_RESULT(ic)->noSpilLoc = 1; + /* it is if the operations are the same */ + /* the literal parts need to be added */ + IC_LEFT (ic) = operandFromOperand (IC_LEFT (dic)); + if (ic->op == dic->op) + IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) + + operandLitValue (IC_RIGHT (dic))); + else + IC_RIGHT (ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) - + operandLitValue (IC_RIGHT (dic))); + + if (IS_ITEMP (IC_RESULT (ic))) + { + SPIL_LOC (IC_RESULT (ic)) = NULL; + IC_RESULT (ic)->noSpilLoc = 1; } - return 1; + return 1; } /*-----------------------------------------------------------------*/ @@ -1053,92 +1130,101 @@ int constFold (iCode *ic, set *cseSet) /* will delete from cseSet all get pointers computed from this */ /* pointer. A simple ifOperandsHave is not good enough here */ /*-----------------------------------------------------------------*/ -static void deleteGetPointers (set **cseSet, set **pss, operand *op,eBBlock *ebb) +static void +deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb) { - set *compItems = NULL; - cseDef *cdp ; - operand *cop; - - /* easy return */ - if (!*cseSet && !*pss) - return ; - - /* first find all items computed from this operand . - This done fairly simply go thru the list and find - those that are computed by arthimetic with this - op */ - for (cdp = setFirstItem(*cseSet); cdp ; cdp = setNextItem(*cseSet)) { - if (IS_ARITHMETIC_OP(cdp->diCode)) { - if (isOperandEqual(IC_LEFT(cdp->diCode),op) || - isOperandEqual(IC_RIGHT(cdp->diCode),op)) { - /* save it in our list of items */ - addSet(&compItems,IC_RESULT(cdp->diCode)); - } - /* also check for those computed from our computed - list . This will take care of situations like - iTemp1 = iTemp0 + 8; - iTemp2 = iTemp1 + 8; */ - if (isinSetWith(compItems,IC_LEFT(cdp->diCode),isOperandEqual) || - isinSetWith(compItems,IC_RIGHT(cdp->diCode),isOperandEqual)) { - addSet(&compItems,IC_RESULT(cdp->diCode)); - } - } + set *compItems = NULL; + cseDef *cdp; + operand *cop; + + /* easy return */ + if (!*cseSet && !*pss) + return; + + /* first find all items computed from this operand . + This done fairly simply go thru the list and find + those that are computed by arthimetic with this + op */ + for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet)) + { + if (IS_ARITHMETIC_OP (cdp->diCode)) + { + if (isOperandEqual (IC_LEFT (cdp->diCode), op) || + isOperandEqual (IC_RIGHT (cdp->diCode), op)) + { + /* save it in our list of items */ + addSet (&compItems, IC_RESULT (cdp->diCode)); + } + /* also check for those computed from our computed + list . This will take care of situations like + iTemp1 = iTemp0 + 8; + iTemp2 = iTemp1 + 8; */ + if (isinSetWith (compItems, IC_LEFT (cdp->diCode), isOperandEqual) || + isinSetWith (compItems, IC_RIGHT (cdp->diCode), isOperandEqual)) + { + addSet (&compItems, IC_RESULT (cdp->diCode)); + } + } } - /* now delete all pointer gets with this op */ - deleteItemIf(cseSet,ifPointerGet,op); - deleteItemIf(pss,ifPointerSet,op); - - /* set the bit vector used by dataFlow computation later */ - ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,op->key); - /* now for the computed items */ - for (cop = setFirstItem(compItems); cop ; cop = setNextItem(compItems)) { - ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,cop->key); - deleteItemIf(cseSet,ifPointerGet,cop); - deleteItemIf(pss,ifPointerSet,cop); + /* now delete all pointer gets with this op */ + deleteItemIf (cseSet, ifPointerGet, op); + deleteItemIf (pss, ifPointerSet, op); + + /* set the bit vector used by dataFlow computation later */ + ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, op->key); + /* now for the computed items */ + for (cop = setFirstItem (compItems); cop; cop = setNextItem (compItems)) + { + ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, cop->key); + deleteItemIf (cseSet, ifPointerGet, cop); + deleteItemIf (pss, ifPointerSet, cop); } } /*-----------------------------------------------------------------*/ -/* delGetPointerSucc - delete get pointer from inExprs of succ with*/ +/* delGetPointerSucc - delete get pointer from inExprs of succ with */ /* dfnum > supplied */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(delGetPointerSucc) +DEFSETFUNC (delGetPointerSucc) { - eBBlock *ebp = item; - V_ARG(operand *,op); - V_ARG(int,dfnum); + eBBlock *ebp = item; + V_ARG (operand *, op); + V_ARG (int, dfnum); - if (ebp->visited) - return 0; + if (ebp->visited) + return 0; - ebp->visited = 1; - if (ebp->dfnum > dfnum) { - deleteItemIf(&ebp->inExprs,ifPointerGet,op); + ebp->visited = 1; + if (ebp->dfnum > dfnum) + { + deleteItemIf (&ebp->inExprs, ifPointerGet, op); } - return applyToSet(ebp->succList,delGetPointerSucc,op,dfnum); + return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum); } /*-----------------------------------------------------------------*/ /* fixUpTypes - KLUGE HACK fixup a lowering problem */ /*-----------------------------------------------------------------*/ -static void fixUpTypes(iCode *ic) +static void +fixUpTypes (iCode * ic) { - sym_link *t1 = operandType(IC_LEFT(ic)) ,*t2; + sym_link *t1 = operandType (IC_LEFT (ic)), *t2; if (IS_DS390_PORT) - { + { /* hack-o-matic! */ return; - } + } /* for pointer_gets if the types of result & left r the same then change it type of result to next */ - if (IS_PTR(t1) && - checkType(t2=operandType(IC_RESULT(ic)),t1) == 1) { - setOperandType(IC_RESULT(ic),t2->next); - } + if (IS_PTR (t1) && + checkType (t2 = operandType (IC_RESULT (ic)), t1) == 1) + { + setOperandType (IC_RESULT (ic), t2->next); + } } /*-----------------------------------------------------------------*/ @@ -1147,407 +1233,447 @@ static void fixUpTypes(iCode *ic) /* system. also the most important, since almost all */ /* data flow related information is computed by it */ /*-----------------------------------------------------------------*/ -int cseBBlock ( eBBlock *ebb, int computeOnly, - eBBlock **ebbs, int count) +int +cseBBlock (eBBlock * ebb, int computeOnly, + eBBlock ** ebbs, int count) { - set *cseSet ; - iCode *ic ; - int change = 0 ; - int i; - set *ptrSetSet = NULL; - - /* if this block is not reachable */ - if (ebb->noPath) - return change; - - /* set of common subexpressions */ - cseSet = setFromSet (ebb->inExprs) ; - - /* these will be computed by this routine */ - setToNull ((void **)&ebb->outDefs); - setToNull ((void **)&ebb->defSet); - setToNull ((void **)&ebb->usesDefs); - setToNull ((void **)&ebb->ptrsSet); - setToNull ((void **)&ebb->addrOf); - setToNull ((void **)&ebb->ldefs); - - ebb->outDefs = bitVectCopy (ebb->inDefs); - bitVectDefault = iCodeKey; - ebb->defSet = newBitVect(iCodeKey); - ebb->usesDefs=newBitVect(iCodeKey); - - /* for all the instructions in this block do */ - for (ic = ebb->sch ; ic ; ic = ic->next ) { - - iCode *pdic; - operand *pdop ; - iCode *defic; - - if (SKIP_IC2(ic)) - continue ; - - /* if this is an assignment from true symbol - to a temp then do pointer post inc/dec optimzation */ - if (ic->op == '=' && !POINTER_SET(ic) && - IS_PTR(operandType(IC_RESULT(ic)))) { - ptrPostIncDecOpt(ic); - } - - /* clear the def & use chains for the operands involved */ - /* in this operation . since it can change due to opts */ - unsetDefsAndUses (ic); - - if ( ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE) { - /* add to defSet of the symbol */ - OP_DEFS(IC_RESULT(ic)) = - bitVectSetBit (OP_DEFS(IC_RESULT(ic)),ic->key); - /* add to the definition set of this block */ - ebb->defSet = bitVectSetBit (ebb->defSet,ic->key); - ebb->ldefs = bitVectSetBit (ebb->ldefs,ic->key); - ebb->outDefs= bitVectCplAnd (ebb->outDefs,OP_DEFS(IC_RESULT(ic))); - setUsesDefs(IC_RESULT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs); - /* delete global variables from the cseSet - since they can be modified by the function call */ - deleteItemIf(&cseSet,ifDefGlobal); - /* delete all getpointer iCodes from cseSet, this should - be done only for global arrays & pointers but at this - point we don't know if globals, so to be safe do all*/ - deleteItemIf(&cseSet,ifAnyGetPointer); - } - - /* for pcall & ipush we need to add to the useSet */ - if ((ic->op == PCALL || - ic->op == IPUSH || - ic->op == IPOP || - ic->op == SEND) && - IS_SYMOP(IC_LEFT(ic))) { - - /* check if they can be replaced */ - if ( !computeOnly ) { - pdop = NULL ; - applyToSetFTrue(cseSet,findCheaperOp,IC_LEFT(ic),&pdop); - if (pdop) - IC_LEFT(ic) = pdop ; - } - /* the lookup could have changed it*/ - if (IS_SYMOP(IC_LEFT(ic))) { - OP_USES(IC_LEFT(ic)) = - bitVectSetBit(OP_USES(IC_LEFT(ic)),ic->key); - setUsesDefs(IC_LEFT(ic),ebb->defSet, - ebb->outDefs,&ebb->usesDefs); - } - - - /* if we a sending a pointer as a parameter - then kill all cse since the pointed to item - might be changed in the function being called */ - if ((ic->op == IPUSH || ic->op == SEND) && - IS_PTR(operandType(IC_LEFT(ic)))) { - deleteGetPointers(&cseSet,&ptrSetSet,IC_LEFT(ic),ebb); - ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_LEFT(ic)->key); - for (i = 0 ; i < count ;ebbs[i++]->visited = 0); - applyToSet(ebb->succList,delGetPointerSucc, - IC_LEFT(ic),ebb->dfnum); - } - continue; - } - - /* if jumptable then mark the usage */ - if (ic->op == JUMPTABLE ) { - OP_USES(IC_JTCOND(ic)) = - bitVectSetBit(OP_USES(IC_JTCOND(ic)),ic->key); - setUsesDefs(IC_JTCOND(ic),ebb->defSet, - ebb->outDefs,&ebb->usesDefs); - continue; - } - - if (SKIP_IC(ic)) - continue ; - - /* do some algebraic optimizations if possible */ - algebraicOpts (ic); - while (constFold(ic,cseSet)); - - /* small klugde */ - if (POINTER_GET(ic) && !IS_PTR(operandType(IC_LEFT(ic)))) { - setOperandType(IC_LEFT(ic), - aggrToPtr(operandType(IC_LEFT(ic)),FALSE)); - fixUpTypes(ic); - - } - if (POINTER_SET(ic) && !IS_PTR(operandType(IC_RESULT(ic)))) { - setOperandType(IC_RESULT(ic), - aggrToPtr(operandType(IC_RESULT(ic)),FALSE)); - } - - /* if this is a condition statment then */ - /* check if the condition can be replaced */ - if (ic->op == IFX ) { - ifxOptimize (ic, cseSet, computeOnly, - ebb, &change, - ebbs, count); - continue ; - } - - /* if the assignment & result is a temp */ - /* see if we can replace it */ - if (ic->op == '=') { - - /* update the spill location for this */ - updateSpillLocation (ic); - - if (POINTER_SET(ic) && - !(IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype))) { - pdop = NULL ; - applyToSetFTrue (cseSet,findCheaperOp,IC_RESULT(ic),&pdop); - if (pdop && IS_ITEMP(pdop) && !computeOnly) - IC_RESULT(ic) = pdop; - } - } - - /* do the operand lookup i.e. for both the */ - /* right & left operand : check the cseSet */ - /* to see if they have been replaced if yes*/ - /* then replace them with those from cseSet*/ - /* left operand */ - /* and left is a symbol */ - if (IS_SYMOP(IC_LEFT(ic)) && - !computeOnly && ic->op != ADDRESS_OF ) { - - pdop = NULL; - applyToSetFTrue (cseSet,findCheaperOp,IC_LEFT(ic),&pdop) ; - if (pdop) { - if (POINTER_GET(ic)) { - if (IS_ITEMP(pdop) || IS_OP_LITERAL(pdop)) { - IC_LEFT(ic) = pdop; - change = 1; - } - /* check if there is a pointer set - for the same pointer visible if yes - then change this into an assignment */ - pdop = NULL; - if (applyToSetFTrue(cseSet,findPointerSet,IC_LEFT(ic),&pdop,IC_RESULT(ic)) && - !bitVectBitValue(ebb->ptrsSet,pdop->key)){ - ic->op = '='; - IC_LEFT(ic) = NULL; - IC_RIGHT(ic) = pdop; - SET_ISADDR(IC_RESULT(ic),0); - } + set *cseSet; + iCode *ic; + int change = 0; + int i; + set *ptrSetSet = NULL; + + /* if this block is not reachable */ + if (ebb->noPath) + return change; - } - else { - IC_LEFT(ic) = pdop ; - change = 1; - } - } - } - - /*right operand */ - if (IS_SYMOP(IC_RIGHT(ic)) && !computeOnly) { - - pdop = NULL ; - applyToSetFTrue (cseSet,findCheaperOp,IC_RIGHT(ic),&pdop); - if (pdop) { - - IC_RIGHT(ic) = pdop; - change = 1; - } - } - - /* if left or right changed then do algebraic */ - if (change) { - algebraicOpts(ic); - while(constFold(ic,cseSet)); - } - - /* if after all this it becomes a assignment to self - then delete it and continue */ - if (ASSIGNMENT_TO_SELF(ic)) { - remiCodeFromeBBlock(ebb,ic); - continue; - } - - /* now we will check to see if the entire */ - /* operation has been performed before */ - /* and is available */ - /* don't do assignments they will be killed */ - /* by dead code elimination if required do */ - /* it only if result is a temporary */ - pdic = NULL ; - if (!( POINTER_GET(ic) && - (IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype) || - isOperandVolatile(IC_LEFT(ic),TRUE) || - bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))) && - ! ASSIGNMENT(ic) && - IS_ITEMP(IC_RESULT(ic)) && - ! computeOnly) { - applyToSet (cseSet,findPrevIc,ic,&pdic); - if (pdic && checkType(operandType(IC_RESULT(pdic)), - operandType(IC_RESULT(ic))) != 1) - pdic = NULL; - } - - /* if found then eliminate this and add to*/ - /* to cseSet an element containing result */ - /* of this with previous opcode */ - if (pdic) { - - if (IS_ITEMP(IC_RESULT(ic))) { - - /* replace in the remaining of this block */ - replaceAllSymBySym(ic->next,IC_RESULT(ic),IC_RESULT(pdic),&ebb->ndompset); - /* remove this iCode from inexpressions of all - its successors, it cannot be in the in expressions - of any of the predecessors */ - for (i = 0 ; i < count ;ebbs[i++]->visited = 0); - applyToSet(ebb->succList,removeFromInExprs,ic,IC_RESULT(ic), - IC_RESULT(pdic),ebb); - - /* if this was moved from another block */ - /* then replace in those blocks too */ - if ( ic->movedFrom ) { - eBBlock *owner ; - for (owner = setFirstItem(ic->movedFrom); owner ; - owner = setNextItem(ic->movedFrom)) - replaceAllSymBySym(owner->sch,IC_RESULT(ic),IC_RESULT(pdic),&owner->ndompset); - } - pdic->movedFrom = unionSets(pdic->movedFrom,ic->movedFrom,THROW_NONE); - } + /* set of common subexpressions */ + cseSet = setFromSet (ebb->inExprs); + + /* these will be computed by this routine */ + setToNull ((void **) &ebb->outDefs); + setToNull ((void **) &ebb->defSet); + setToNull ((void **) &ebb->usesDefs); + setToNull ((void **) &ebb->ptrsSet); + setToNull ((void **) &ebb->addrOf); + setToNull ((void **) &ebb->ldefs); + + ebb->outDefs = bitVectCopy (ebb->inDefs); + bitVectDefault = iCodeKey; + ebb->defSet = newBitVect (iCodeKey); + ebb->usesDefs = newBitVect (iCodeKey); + + /* for all the instructions in this block do */ + for (ic = ebb->sch; ic; ic = ic->next) + { + + iCode *pdic; + operand *pdop; + iCode *defic; + + if (SKIP_IC2 (ic)) + continue; + + /* if this is an assignment from true symbol + to a temp then do pointer post inc/dec optimzation */ + if (ic->op == '=' && !POINTER_SET (ic) && + IS_PTR (operandType (IC_RESULT (ic)))) + { + ptrPostIncDecOpt (ic); + } + + /* clear the def & use chains for the operands involved */ + /* in this operation . since it can change due to opts */ + unsetDefsAndUses (ic); + + if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE) + { + /* add to defSet of the symbol */ + OP_DEFS (IC_RESULT (ic)) = + bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key); + /* add to the definition set of this block */ + ebb->defSet = bitVectSetBit (ebb->defSet, ic->key); + ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key); + ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic))); + setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs); + /* delete global variables from the cseSet + since they can be modified by the function call */ + deleteItemIf (&cseSet, ifDefGlobal); + /* delete all getpointer iCodes from cseSet, this should + be done only for global arrays & pointers but at this + point we don't know if globals, so to be safe do all */ + deleteItemIf (&cseSet, ifAnyGetPointer); + } + + /* for pcall & ipush we need to add to the useSet */ + if ((ic->op == PCALL || + ic->op == IPUSH || + ic->op == IPOP || + ic->op == SEND) && + IS_SYMOP (IC_LEFT (ic))) + { + + /* check if they can be replaced */ + if (!computeOnly) + { + pdop = NULL; + applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop); + if (pdop) + IC_LEFT (ic) = pdop; + } + /* the lookup could have changed it */ + if (IS_SYMOP (IC_LEFT (ic))) + { + OP_USES (IC_LEFT (ic)) = + bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key); + setUsesDefs (IC_LEFT (ic), ebb->defSet, + ebb->outDefs, &ebb->usesDefs); + } + + + /* if we a sending a pointer as a parameter + then kill all cse since the pointed to item + might be changed in the function being called */ + if ((ic->op == IPUSH || ic->op == SEND) && + IS_PTR (operandType (IC_LEFT (ic)))) + { + deleteGetPointers (&cseSet, &ptrSetSet, IC_LEFT (ic), ebb); + ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_LEFT (ic)->key); + for (i = 0; i < count; ebbs[i++]->visited = 0); + applyToSet (ebb->succList, delGetPointerSucc, + IC_LEFT (ic), ebb->dfnum); + } + continue; + } + + /* if jumptable then mark the usage */ + if (ic->op == JUMPTABLE) + { + OP_USES (IC_JTCOND (ic)) = + bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key); + setUsesDefs (IC_JTCOND (ic), ebb->defSet, + ebb->outDefs, &ebb->usesDefs); + continue; + } + + if (SKIP_IC (ic)) + continue; + + /* do some algebraic optimizations if possible */ + algebraicOpts (ic); + while (constFold (ic, cseSet)); + + /* small klugde */ + if (POINTER_GET (ic) && !IS_PTR (operandType (IC_LEFT (ic)))) + { + setOperandType (IC_LEFT (ic), + aggrToPtr (operandType (IC_LEFT (ic)), FALSE)); + fixUpTypes (ic); + + } + if (POINTER_SET (ic) && !IS_PTR (operandType (IC_RESULT (ic)))) + { + setOperandType (IC_RESULT (ic), + aggrToPtr (operandType (IC_RESULT (ic)), FALSE)); + } + + /* if this is a condition statment then */ + /* check if the condition can be replaced */ + if (ic->op == IFX) + { + ifxOptimize (ic, cseSet, computeOnly, + ebb, &change, + ebbs, count); + continue; + } + + /* if the assignment & result is a temp */ + /* see if we can replace it */ + if (ic->op == '=') + { + + /* update the spill location for this */ + updateSpillLocation (ic); + + if (POINTER_SET (ic) && + !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype))) + { + pdop = NULL; + applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop); + if (pdop && IS_ITEMP (pdop) && !computeOnly) + IC_RESULT (ic) = pdop; + } + } + + /* do the operand lookup i.e. for both the */ + /* right & left operand : check the cseSet */ + /* to see if they have been replaced if yes */ + /* then replace them with those from cseSet */ + /* left operand */ + /* and left is a symbol */ + if (IS_SYMOP (IC_LEFT (ic)) && + !computeOnly && ic->op != ADDRESS_OF) + { + + pdop = NULL; + applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop); + if (pdop) + { + if (POINTER_GET (ic)) + { + if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop)) + { + IC_LEFT (ic) = pdop; + change = 1; + } + /* check if there is a pointer set + for the same pointer visible if yes + then change this into an assignment */ + pdop = NULL; + if (applyToSetFTrue (cseSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)) && + !bitVectBitValue (ebb->ptrsSet, pdop->key)) + { + ic->op = '='; + IC_LEFT (ic) = NULL; + IC_RIGHT (ic) = pdop; + SET_ISADDR (IC_RESULT (ic), 0); + } + + } + else + { + IC_LEFT (ic) = pdop; + change = 1; + } + } + } + + /*right operand */ + if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly) + { + + pdop = NULL; + applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop); + if (pdop) + { + + IC_RIGHT (ic) = pdop; + change = 1; + } + } + + /* if left or right changed then do algebraic */ + if (change) + { + algebraicOpts (ic); + while (constFold (ic, cseSet)); + } + + /* if after all this it becomes a assignment to self + then delete it and continue */ + if (ASSIGNMENT_TO_SELF (ic)) + { + remiCodeFromeBBlock (ebb, ic); + continue; + } + + /* now we will check to see if the entire */ + /* operation has been performed before */ + /* and is available */ + /* don't do assignments they will be killed */ + /* by dead code elimination if required do */ + /* it only if result is a temporary */ + pdic = NULL; + if (!(POINTER_GET (ic) && + (IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) || + isOperandVolatile (IC_LEFT (ic), TRUE) || + bitVectBitValue (ebb->ndompset, IC_LEFT (ic)->key))) && + !ASSIGNMENT (ic) && + IS_ITEMP (IC_RESULT (ic)) && + !computeOnly) + { + applyToSet (cseSet, findPrevIc, ic, &pdic); + if (pdic && checkType (operandType (IC_RESULT (pdic)), + operandType (IC_RESULT (ic))) != 1) + pdic = NULL; + } + + /* if found then eliminate this and add to */ + /* to cseSet an element containing result */ + /* of this with previous opcode */ + if (pdic) + { + + if (IS_ITEMP (IC_RESULT (ic))) + { + + /* replace in the remaining of this block */ + replaceAllSymBySym (ic->next, IC_RESULT (ic), IC_RESULT (pdic), &ebb->ndompset); + /* remove this iCode from inexpressions of all + its successors, it cannot be in the in expressions + of any of the predecessors */ + for (i = 0; i < count; ebbs[i++]->visited = 0); + applyToSet (ebb->succList, removeFromInExprs, ic, IC_RESULT (ic), + IC_RESULT (pdic), ebb); + + /* if this was moved from another block */ + /* then replace in those blocks too */ + if (ic->movedFrom) + { + eBBlock *owner; + for (owner = setFirstItem (ic->movedFrom); owner; + owner = setNextItem (ic->movedFrom)) + replaceAllSymBySym (owner->sch, IC_RESULT (ic), IC_RESULT (pdic), &owner->ndompset); + } + pdic->movedFrom = unionSets (pdic->movedFrom, ic->movedFrom, THROW_NONE); + } + else + addSetHead (&cseSet, newCseDef (IC_RESULT (ic), pdic)); + + if (!computeOnly) + /* eliminate this */ + remiCodeFromeBBlock (ebb, ic); + + defic = pdic; + change++; + + if (IS_ITEMP (IC_RESULT (ic))) + continue; + + } else - addSetHead (&cseSet,newCseDef(IC_RESULT(ic),pdic)); - - if (!computeOnly) - /* eliminate this */ - remiCodeFromeBBlock (ebb,ic); - - defic = pdic ; - change++ ; - - if (IS_ITEMP(IC_RESULT(ic))) - continue ; - - } else { - - /* just add this as a previous expression except in */ - /* case of a pointer access in which case this is a */ - /* usage not a definition */ - if (! (POINTER_SET(ic)) && IC_RESULT(ic)){ - deleteItemIf (&cseSet, ifDefSymIsX,IC_RESULT(ic)); - addSetHead(&cseSet,newCseDef(IC_RESULT(ic),ic)); - } - defic = ic; - - } - - /* if assignment to a parameter which is not - mine and type is a pointer then delete - pointerGets to take care of aliasing */ - if (ASSIGNMENT(ic) && - OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) && - IS_PTR(operandType(IC_RESULT(ic)))) { - deleteGetPointers(&cseSet,&ptrSetSet,IC_RIGHT(ic),ebb); - for (i = 0 ; i < count ;ebbs[i++]->visited = 0); - applyToSet(ebb->succList,delGetPointerSucc,IC_RIGHT(ic),ebb->dfnum); - ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_RIGHT(ic)->key); - } - - /* if this is a pointerget then see if we can replace - this with a previously assigned pointer value */ - if (POINTER_GET(ic) && - !(IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype) || - isOperandVolatile(IC_LEFT(ic),TRUE))) { - pdop = NULL; - applyToSet(ptrSetSet,findPointerSet,IC_LEFT(ic),&pdop,IC_RESULT(ic)); - /* if we find it then locally replace all - references to the result with what we assigned */ - if (pdop) { - replaceAllSymBySym(ic->next,IC_RESULT(ic),pdop,&ebb->ndompset); - } - } - - /* delete from the cseSet anything that has */ - /* operands matching the result of this */ - /* except in case of pointer access */ - if (!(POINTER_SET(ic)) && IC_RESULT(ic)) { - deleteItemIf (&cseSet,ifOperandsHave,IC_RESULT(ic)); - /* delete any previous definitions */ - ebb->defSet = bitVectCplAnd (ebb->defSet,OP_DEFS(IC_RESULT(ic))); - - } - - /* add the left & right to the defUse set */ - if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic))) { - OP_USES(IC_LEFT(ic)) = - bitVectSetBit (OP_USES(IC_LEFT(ic)),ic->key); - setUsesDefs(IC_LEFT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs); - - } - - if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic))) { - OP_USES(IC_RIGHT(ic)) = - bitVectSetBit (OP_USES(IC_RIGHT(ic)),ic->key); - setUsesDefs(IC_RIGHT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs); - - } - - /* for the result it is special case, put the result */ - /* in the defuseSet if it a pointer or array access */ - if ( POINTER_SET(defic) ) { - OP_USES(IC_RESULT(ic)) = - bitVectSetBit (OP_USES(IC_RESULT(ic)),ic->key); - setUsesDefs(IC_RESULT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs); - deleteItemIf(&cseSet,ifPointerGet,IC_RESULT(ic)); - ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_RESULT(ic)->key); - /* delete from inexpressions of all successors which - have dfNum > than this block */ - for (i = 0 ; i < count ;ebbs[i++]->visited = 0); - applyToSet(ebb->succList,delGetPointerSucc,IC_RESULT(ic),ebb->dfnum); - - /* delete from cseSet all other pointer sets - for this operand */ - deleteItemIf(&ptrSetSet,ifPointerSet,IC_RESULT(ic)); - /* add to the local pointerset set */ - addSetHead(&ptrSetSet,newCseDef(IC_RESULT(ic),ic)); - } - else /* add the result to defintion set */ - if (IC_RESULT(ic)) { - OP_DEFS(IC_RESULT(ic)) = - bitVectSetBit (OP_DEFS(IC_RESULT(ic)),ic->key); - ebb->defSet = bitVectSetBit (ebb->defSet,ic->key); - ebb->outDefs= bitVectCplAnd (ebb->outDefs,OP_DEFS(IC_RESULT(ic))); - ebb->ldefs = bitVectSetBit (ebb->ldefs,ic->key); - } - - - /* if this is an addressof instruction then */ - /* put the symbol in the address of list & */ - /* delete it from the cseSet */ - if (defic->op == ADDRESS_OF) { - addSetHead (&ebb->addrOf, IC_LEFT(ic)); - deleteItemIf(&cseSet,ifDefSymIsX,IC_LEFT(ic)); - } + { + + /* just add this as a previous expression except in */ + /* case of a pointer access in which case this is a */ + /* usage not a definition */ + if (!(POINTER_SET (ic)) && IC_RESULT (ic)) + { + deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic)); + addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic)); + } + defic = ic; + + } + + /* if assignment to a parameter which is not + mine and type is a pointer then delete + pointerGets to take care of aliasing */ + if (ASSIGNMENT (ic) && + OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))) && + IS_PTR (operandType (IC_RESULT (ic)))) + { + deleteGetPointers (&cseSet, &ptrSetSet, IC_RIGHT (ic), ebb); + for (i = 0; i < count; ebbs[i++]->visited = 0); + applyToSet (ebb->succList, delGetPointerSucc, IC_RIGHT (ic), ebb->dfnum); + ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RIGHT (ic)->key); + } + + /* if this is a pointerget then see if we can replace + this with a previously assigned pointer value */ + if (POINTER_GET (ic) && + !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype) || + isOperandVolatile (IC_LEFT (ic), TRUE))) + { + pdop = NULL; + applyToSet (ptrSetSet, findPointerSet, IC_LEFT (ic), &pdop, IC_RESULT (ic)); + /* if we find it then locally replace all + references to the result with what we assigned */ + if (pdop) + { + replaceAllSymBySym (ic->next, IC_RESULT (ic), pdop, &ebb->ndompset); + } + } + + /* delete from the cseSet anything that has */ + /* operands matching the result of this */ + /* except in case of pointer access */ + if (!(POINTER_SET (ic)) && IC_RESULT (ic)) + { + deleteItemIf (&cseSet, ifOperandsHave, IC_RESULT (ic)); + /* delete any previous definitions */ + ebb->defSet = bitVectCplAnd (ebb->defSet, OP_DEFS (IC_RESULT (ic))); + + } + + /* add the left & right to the defUse set */ + if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic))) + { + OP_USES (IC_LEFT (ic)) = + bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key); + setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs); + + } + + if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic))) + { + OP_USES (IC_RIGHT (ic)) = + bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key); + setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs); + + } + + /* for the result it is special case, put the result */ + /* in the defuseSet if it a pointer or array access */ + if (POINTER_SET (defic)) + { + OP_USES (IC_RESULT (ic)) = + bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key); + setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs); + deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic)); + ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key); + /* delete from inexpressions of all successors which + have dfNum > than this block */ + for (i = 0; i < count; ebbs[i++]->visited = 0); + applyToSet (ebb->succList, delGetPointerSucc, IC_RESULT (ic), ebb->dfnum); + + /* delete from cseSet all other pointer sets + for this operand */ + deleteItemIf (&ptrSetSet, ifPointerSet, IC_RESULT (ic)); + /* add to the local pointerset set */ + addSetHead (&ptrSetSet, newCseDef (IC_RESULT (ic), ic)); + } + else + /* add the result to defintion set */ if (IC_RESULT (ic)) + { + OP_DEFS (IC_RESULT (ic)) = + bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key); + ebb->defSet = bitVectSetBit (ebb->defSet, ic->key); + ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic))); + ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key); + } + + + /* if this is an addressof instruction then */ + /* put the symbol in the address of list & */ + /* delete it from the cseSet */ + if (defic->op == ADDRESS_OF) + { + addSetHead (&ebb->addrOf, IC_LEFT (ic)); + deleteItemIf (&cseSet, ifDefSymIsX, IC_LEFT (ic)); + } } - setToNull ((void **)&ebb->outExprs); - ebb->outExprs = cseSet; - ebb->outDefs = bitVectUnion (ebb->outDefs,ebb->defSet); - ebb->ptrsSet = bitVectUnion (ebb->ptrsSet,ebb->inPtrsSet); - return change ; + setToNull ((void **) &ebb->outExprs); + ebb->outExprs = cseSet; + ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet); + ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet); + return change; } /*-----------------------------------------------------------------*/ -/* cseAllBlocks - will sequentially go thru & do cse for all blocks*/ +/* cseAllBlocks - will sequentially go thru & do cse for all blocks */ /*-----------------------------------------------------------------*/ -int cseAllBlocks (eBBlock **ebbs,int count) +int +cseAllBlocks (eBBlock ** ebbs, int count) { - int i; - int change = 0 ; + int i; + int change = 0; - /* if optimization turned off */ + /* if optimization turned off */ - for (i = 0 ; i < count ;i++ ) - change += cseBBlock (ebbs[i],FALSE,ebbs,count); + for (i = 0; i < count; i++) + change += cseBBlock (ebbs[i], FALSE, ebbs, count); - return change; + return change; } - diff --git a/src/SDCCcse.h b/src/SDCCcse.h index e398dcc9..51bfb41c 100644 --- a/src/SDCCcse.h +++ b/src/SDCCcse.h @@ -28,31 +28,33 @@ #ifndef SDCCCSE_H #define SDCCCSE_H 1 -typedef struct cseDef { - +typedef struct cseDef + { + unsigned int key; - operand *sym ; /* defining symbol */ - iCode *diCode ; /* defining instruction */ + operand *sym; /* defining symbol */ + iCode *diCode; /* defining instruction */ -} cseDef ; + } +cseDef; cseDef *newCseDef (operand *, iCode *); -int isCseDefEqual ( void *, void *); -int pcseDef (void *, va_list ); +int isCseDefEqual (void *, void *); +int pcseDef (void *, va_list); void algebraicOpts (iCode *); -DEFSETFUNC(ifDiCodeIsX); -int ifDiCodeIs (set *,iCode *); -DEFSETFUNC(ifDefSymIsX); -int ifDefSymIs (set *,operand *); -DEFSETFUNC(findPrevIc); -DEFSETFUNC(ifOperandsHave); -DEFSETFUNC(findCheaperOp) ; -int cseBBlock ( eBBlock *,int ,eBBlock **, int); -int cseAllBlocks (eBBlock **,int ); -void ifxOptimize (iCode *,set *,int,eBBlock *,int *,eBBlock **,int); -void unsetDefsAndUses ( iCode *) ; -void updateSpillLocation ( iCode *ic); -void setUsesDefs (operand *,bitVect *,bitVect *,bitVect **); -void replaceAllSymBySym (iCode *,operand *,operand *,bitVect **); +DEFSETFUNC (ifDiCodeIsX); +int ifDiCodeIs (set *, iCode *); +DEFSETFUNC (ifDefSymIsX); +int ifDefSymIs (set *, operand *); +DEFSETFUNC (findPrevIc); +DEFSETFUNC (ifOperandsHave); +DEFSETFUNC (findCheaperOp); +int cseBBlock (eBBlock *, int, eBBlock **, int); +int cseAllBlocks (eBBlock **, int); +void ifxOptimize (iCode *, set *, int, eBBlock *, int *, eBBlock **, int); +void unsetDefsAndUses (iCode *); +void updateSpillLocation (iCode * ic); +void setUsesDefs (operand *, bitVect *, bitVect *, bitVect **); +void replaceAllSymBySym (iCode *, operand *, operand *, bitVect **); #endif diff --git a/src/SDCCdflow.c b/src/SDCCdflow.c index 76c2267a..dee5cbb9 100644 --- a/src/SDCCdflow.c +++ b/src/SDCCdflow.c @@ -29,313 +29,327 @@ /*-----------------------------------------------------------------*/ /* ifKilledInBlock - will return 1 if the symbol is redefined in B */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(ifKilledInBlock) +DEFSETFUNC (ifKilledInBlock) { - cseDef *cdp = item; - V_ARG(eBBlock *,src); - bitVect *outs ; + cseDef *cdp = item; + V_ARG (eBBlock *, src); + bitVect *outs; + + /* if this is a global variable and this block + has a function call then delete it */ + if (isOperandGlobal (cdp->sym) && src->hasFcall) + return 1; + + /* if this is pointer get then it will be killed + if there is a pointer set for the same pointer + in this block */ + if (POINTER_GET (cdp->diCode) && + bitVectBitValue (src->ptrsSet, + IC_LEFT (cdp->diCode)->key)) + return 1; + + /* if assignment to iTmep then if right is defined + elsewhere kill this one */ + if (ASSIGNMENT (cdp->diCode) && + !POINTER_SET (cdp->diCode) && + IS_ITEMP (IC_RESULT (cdp->diCode)) && + IS_SYMOP (IC_RIGHT (cdp->diCode)) && + bitVectBitsInCommon (src->outDefs, OP_DEFS (IC_RIGHT (cdp->diCode)))) + return 1; + + /* if we find it in the defSet of this block */ + if (bitVectBitsInCommon (src->defSet, OP_DEFS (cdp->sym))) + return 1; + + /* if in the outdef we find a definition other than this one */ + /* to do this we make a copy of the out definitions and turn */ + /* this one off then check if there are other definitions */ + bitVectUnSetBit (outs = bitVectCopy (src->outDefs), + cdp->diCode->key); + if (bitVectBitsInCommon (outs, OP_DEFS (cdp->sym))) + { + setToNull ((void **) &outs); + return 1; + } - /* if this is a global variable and this block - has a function call then delete it */ - if (isOperandGlobal(cdp->sym) && src->hasFcall) - return 1; + setToNull ((void **) &outs); - /* if this is pointer get then it will be killed - if there is a pointer set for the same pointer - in this block */ - if (POINTER_GET(cdp->diCode) && - bitVectBitValue(src->ptrsSet, - IC_LEFT(cdp->diCode)->key)) - return 1; - - /* if assignment to iTmep then if right is defined - elsewhere kill this one */ - if (ASSIGNMENT(cdp->diCode) && - !POINTER_SET(cdp->diCode) && - IS_ITEMP(IC_RESULT(cdp->diCode)) && - IS_SYMOP(IC_RIGHT(cdp->diCode)) && - bitVectBitsInCommon(src->outDefs,OP_DEFS(IC_RIGHT(cdp->diCode)))) - return 1; + /* if the operands of this one was changed in the block */ + /* then delete it */ + if (cdp->diCode && + ((IS_SYMOP (IC_LEFT (cdp->diCode)) && + bitVectBitsInCommon (src->defSet, OP_DEFS (IC_LEFT (cdp->diCode)))) || + (IS_SYMOP (IC_RIGHT (cdp->diCode)) && + bitVectBitsInCommon (src->defSet, OP_DEFS (IC_RIGHT (cdp->diCode)))))) + return 1; - /* if we find it in the defSet of this block */ - if (bitVectBitsInCommon(src->defSet,OP_DEFS(cdp->sym))) - return 1; - - /* if in the outdef we find a definition other than this one */ - /* to do this we make a copy of the out definitions and turn */ - /* this one off then check if there are other definitions */ - bitVectUnSetBit (outs = bitVectCopy (src->outDefs), - cdp->diCode->key); - if (bitVectBitsInCommon (outs,OP_DEFS(cdp->sym))) { - setToNull((void **) &outs); - return 1; - } - - setToNull((void **) &outs); - - /* if the operands of this one was changed in the block */ - /* then delete it */ - if (cdp->diCode && - ( (IS_SYMOP(IC_LEFT(cdp->diCode)) && - bitVectBitsInCommon (src->defSet,OP_DEFS(IC_LEFT(cdp->diCode)))) || - (IS_SYMOP(IC_RIGHT(cdp->diCode)) && - bitVectBitsInCommon (src->defSet,OP_DEFS(IC_RIGHT(cdp->diCode)))) )) - return 1; - - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* mergeInExprs - copy the in expression if it dominates */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(mergeInExprs) +DEFSETFUNC (mergeInExprs) { - eBBlock *ebp = item; - V_ARG(eBBlock *,dest); - V_ARG(int *,firstTime); - - /* if in the dominator list then */ - if (bitVectBitValue(dest->domVect,ebp->bbnum) && dest != ebp) { - /* if already present then intersect */ - if (!dest->inExprs && *firstTime) { - dest->inExprs = setFromSet(ebp->outExprs); - /* copy the pointer set from the dominator */ - dest->inPtrsSet = bitVectCopy(ebp->ptrsSet); - dest->ndompset = bitVectCopy(ebp->ndompset); + eBBlock *ebp = item; + V_ARG (eBBlock *, dest); + V_ARG (int *, firstTime); + + /* if in the dominator list then */ + if (bitVectBitValue (dest->domVect, ebp->bbnum) && dest != ebp) + { + /* if already present then intersect */ + if (!dest->inExprs && *firstTime) + { + dest->inExprs = setFromSet (ebp->outExprs); + /* copy the pointer set from the dominator */ + dest->inPtrsSet = bitVectCopy (ebp->ptrsSet); + dest->ndompset = bitVectCopy (ebp->ndompset); } - else { - dest->inExprs = intersectSets (dest->inExprs, - ebp->outExprs, - THROW_DEST); - dest->inPtrsSet = bitVectUnion(dest->inPtrsSet,ebp->ptrsSet); - dest->ndompset = bitVectUnion(dest->ndompset,ebp->ndompset); + else + { + dest->inExprs = intersectSets (dest->inExprs, + ebp->outExprs, + THROW_DEST); + dest->inPtrsSet = bitVectUnion (dest->inPtrsSet, ebp->ptrsSet); + dest->ndompset = bitVectUnion (dest->ndompset, ebp->ndompset); } } - else { - /* delete only if killed in this block */ - deleteItemIf (&dest->inExprs,ifKilledInBlock, ebp); - /* union the ndompset with pointers set in this block*/ - dest->ndompset = bitVectUnion(dest->ndompset,ebp->ptrsSet); + else + { + /* delete only if killed in this block */ + deleteItemIf (&dest->inExprs, ifKilledInBlock, ebp); + /* union the ndompset with pointers set in this block */ + dest->ndompset = bitVectUnion (dest->ndompset, ebp->ptrsSet); } - - *firstTime = 0; - return 0; + *firstTime = 0; + + return 0; } /*-----------------------------------------------------------------*/ /* mergeInDefs - merge in incoming definitions */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(mergeInDefs) +DEFSETFUNC (mergeInDefs) { - eBBlock *ebp = item ; - V_ARG(eBBlock *,dest); - V_ARG(int *,firstTime); - - /* the in definition is the union of the out */ - /* of all blocks that come to this block */ - if (!dest->inDefs && *firstTime) - dest->inDefs = bitVectCopy (ebp->outDefs); - else - dest->inDefs = bitVectUnion (dest->inDefs, - ebp->outDefs) ; - - *firstTime = 0; - - return 0; - + eBBlock *ebp = item; + V_ARG (eBBlock *, dest); + V_ARG (int *, firstTime); + + /* the in definition is the union of the out */ + /* of all blocks that come to this block */ + if (!dest->inDefs && *firstTime) + dest->inDefs = bitVectCopy (ebp->outDefs); + else + dest->inDefs = bitVectUnion (dest->inDefs, + ebp->outDefs); + + *firstTime = 0; + + return 0; + } /*-----------------------------------------------------------------*/ -/* computeDataFlow - does computations for data flow accross blocks*/ +/* computeDataFlow - does computations for data flow accross blocks */ /*-----------------------------------------------------------------*/ -void computeDataFlow (eBBlock **ebbs, int count) +void +computeDataFlow (eBBlock ** ebbs, int count) { - int i; - int change = 1; - - while (change) { - - change = 0; - - /* for all blocks */ - for ( i = 0 ; i < count ; i++ ) { - - set *pred ; - set *oldOut; - int firstTime ; - eBBlock *pBlock ; - - /* if this is the entry block then continue */ - /* since entry block can never have any inExprs */ - if (ebbs[i]->noPath) - continue ; - - /* get blocks that can come to this block */ - pred = edgesTo(ebbs[i]); - - /* make a copy of the outExpressions : to be */ - /* used for iteration */ - oldOut = setFromSet(ebbs[i]->outExprs); - setToNull ((void **)&ebbs[i]->inDefs); - - /* indefitions are easy just merge them by union */ - /* these are the definitions that can possibly */ - /* reach this block */ - firstTime = 1; - applyToSet(pred,mergeInDefs,ebbs[i],&firstTime); - - /* if none of the edges coming to this block */ - /* dominate this block then add the immediate dominator */ - /* of this block to the list of predecessors */ - for ( pBlock = setFirstItem(pred); pBlock ; - pBlock = setNextItem(pred)) { - if (bitVectBitValue(ebbs[i]->domVect,pBlock->bbnum)) - break ; + int i; + int change = 1; + + while (change) + { + + change = 0; + + /* for all blocks */ + for (i = 0; i < count; i++) + { + + set *pred; + set *oldOut; + int firstTime; + eBBlock *pBlock; + + /* if this is the entry block then continue */ + /* since entry block can never have any inExprs */ + if (ebbs[i]->noPath) + continue; + + /* get blocks that can come to this block */ + pred = edgesTo (ebbs[i]); + + /* make a copy of the outExpressions : to be */ + /* used for iteration */ + oldOut = setFromSet (ebbs[i]->outExprs); + setToNull ((void **) &ebbs[i]->inDefs); + + /* indefitions are easy just merge them by union */ + /* these are the definitions that can possibly */ + /* reach this block */ + firstTime = 1; + applyToSet (pred, mergeInDefs, ebbs[i], &firstTime); + + /* if none of the edges coming to this block */ + /* dominate this block then add the immediate dominator */ + /* of this block to the list of predecessors */ + for (pBlock = setFirstItem (pred); pBlock; + pBlock = setNextItem (pred)) + { + if (bitVectBitValue (ebbs[i]->domVect, pBlock->bbnum)) + break; } - - /* get the immediate dominator and put it there */ - if (!pBlock) { - eBBlock *idom = immedDom(ebbs,ebbs[i]); - if (idom) - addSetHead (&pred,idom); + + /* get the immediate dominator and put it there */ + if (!pBlock) + { + eBBlock *idom = immedDom (ebbs, ebbs[i]); + if (idom) + addSetHead (&pred, idom); } - - /* figure out the incoming expressions */ - /* this is a little more complex */ - setToNull ((void **)&ebbs[i]->inExprs); - if (optimize.global_cse) { - firstTime = 1; - applyToSet(pred,mergeInExprs,ebbs[i],&firstTime); + + /* figure out the incoming expressions */ + /* this is a little more complex */ + setToNull ((void **) &ebbs[i]->inExprs); + if (optimize.global_cse) + { + firstTime = 1; + applyToSet (pred, mergeInExprs, ebbs[i], &firstTime); } - setToNull ((void **)&pred); - - /* do cse with computeOnly flag set to TRUE */ - /* this by far the quickest way of computing*/ - cseBBlock(ebbs[i],TRUE,ebbs,count); - - /* if it change we will need to iterate */ - change += ! isSetsEqualWith(ebbs[i]->outExprs,oldOut,isCseDefEqual); + setToNull ((void **) &pred); + + /* do cse with computeOnly flag set to TRUE */ + /* this by far the quickest way of computing */ + cseBBlock (ebbs[i], TRUE, ebbs, count); + + /* if it change we will need to iterate */ + change += !isSetsEqualWith (ebbs[i]->outExprs, oldOut, isCseDefEqual); } - if (!change) /* iterate till no change */ - break ; + if (!change) /* iterate till no change */ + break; } - return ; + return; } /*-----------------------------------------------------------------*/ /* usedBetweenPoints - used between start & end */ /*-----------------------------------------------------------------*/ -int usedBetweenPoints ( operand *op, iCode *start, iCode *end ) +int +usedBetweenPoints (operand * op, iCode * start, iCode * end) { - iCode *lic = start; - - for (;lic != end; lic = lic->next) { - - /* if the operand is a parameter */ - /* then check for calls and return */ - /* true if there is a call */ - if (IS_PARM(op) && - ( lic->op == CALL || - lic->op == PCALL )) - if ( isParameterToCall(IC_ARGS(lic),op)) - return 1; - - if (SKIP_IC2(lic)) - continue ; - - /* if ifx then check the condition */ - if (lic->op == IFX && - IC_COND(lic)->key == op->key ) - return 1; - - if (lic->op == JUMPTABLE && - IC_JTCOND(lic)->key == op->key ) - return 1; - - if (IC_RIGHT(lic) && - IC_RIGHT(lic)->key == op->key ) - return 1; - - if (IC_LEFT(lic) && - IC_LEFT(lic)->key == op->key ) - return 1; - - /* for a pointer assignment usage */ - if (POINTER_SET(lic) && - op->key == IC_RESULT(lic)->key ) - return 1; - else - if (IC_RESULT(lic) && op->key == IC_RESULT(lic)->key) - return 0; + iCode *lic = start; + + for (; lic != end; lic = lic->next) + { + + /* if the operand is a parameter */ + /* then check for calls and return */ + /* true if there is a call */ + if (IS_PARM (op) && + (lic->op == CALL || + lic->op == PCALL)) + if (isParameterToCall (IC_ARGS (lic), op)) + return 1; + + if (SKIP_IC2 (lic)) + continue; + + /* if ifx then check the condition */ + if (lic->op == IFX && + IC_COND (lic)->key == op->key) + return 1; + + if (lic->op == JUMPTABLE && + IC_JTCOND (lic)->key == op->key) + return 1; + + if (IC_RIGHT (lic) && + IC_RIGHT (lic)->key == op->key) + return 1; + + if (IC_LEFT (lic) && + IC_LEFT (lic)->key == op->key) + return 1; + + /* for a pointer assignment usage */ + if (POINTER_SET (lic) && + op->key == IC_RESULT (lic)->key) + return 1; + else if (IC_RESULT (lic) && op->key == IC_RESULT (lic)->key) + return 0; } - return 0; - + return 0; + } /*-----------------------------------------------------------------*/ -/* usedInRemaining - returns point of usage for an operand if found*/ +/* usedInRemaining - returns point of usage for an operand if found */ /*-----------------------------------------------------------------*/ -iCode *usedInRemaining (operand *op, iCode *ic) +iCode * +usedInRemaining (operand * op, iCode * ic) { - iCode *lic = ic; + iCode *lic = ic; - if (!IS_SYMOP(op)) - return 0; + if (!IS_SYMOP (op)) + return 0; - for (;lic; lic = lic->next) { - - /* if the operand is a parameter */ - /* then check for calls and return */ - /* true if there is a call */ - /* if this is a global variable then - return true */ - if ( lic->op == CALL || lic->op == PCALL ) { - - if ((IS_PARM(op) && - isParameterToCall(IC_ARGS(lic),op)) || - isOperandGlobal (op)) - return lic; - } - - if (ic->op == SEND && - isOperandEqual (IC_LEFT(lic),op)) - return lic; + for (; lic; lic = lic->next) + { - if (SKIP_IC1(lic)) - continue ; + /* if the operand is a parameter */ + /* then check for calls and return */ + /* true if there is a call */ + /* if this is a global variable then + return true */ + if (lic->op == CALL || lic->op == PCALL) + { - /* if ifx then check the condition */ - if (lic->op == IFX && - isOperandEqual (IC_COND(lic),op)) - return lic; - - if (lic->op == JUMPTABLE && - isOperandEqual (IC_JTCOND(lic),op) ) + if ((IS_PARM (op) && + isParameterToCall (IC_ARGS (lic), op)) || + isOperandGlobal (op)) return lic; + } - if (IC_RIGHT(lic) && - isOperandEqual(IC_RIGHT(lic),op)) - return lic; - - if (IC_LEFT(lic) && - isOperandEqual(IC_LEFT(lic),op) ) - return lic; + if (ic->op == SEND && + isOperandEqual (IC_LEFT (lic), op)) + return lic; + + if (SKIP_IC1 (lic)) + continue; + + /* if ifx then check the condition */ + if (lic->op == IFX && + isOperandEqual (IC_COND (lic), op)) + return lic; + + if (lic->op == JUMPTABLE && + isOperandEqual (IC_JTCOND (lic), op)) + return lic; + + if (IC_RIGHT (lic) && + isOperandEqual (IC_RIGHT (lic), op)) + return lic; - /* for a pointer assignment usage */ - if (POINTER_SET(lic) && - isOperandEqual (op,IC_RESULT(lic))) - return lic; - else - if (IC_RESULT(lic) && isOperandEqual(IC_RESULT(lic),op)) - return NULL; + if (IC_LEFT (lic) && + isOperandEqual (IC_LEFT (lic), op)) + return lic; + + /* for a pointer assignment usage */ + if (POINTER_SET (lic) && + isOperandEqual (op, IC_RESULT (lic))) + return lic; + else if (IC_RESULT (lic) && isOperandEqual (IC_RESULT (lic), op)) + return NULL; } - return NULL; + return NULL; } @@ -343,20 +357,19 @@ iCode *usedInRemaining (operand *op, iCode *ic) /*-----------------------------------------------------------------*/ /* isDefAlive - will return true if definiton reaches a block & used */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(isDefAlive) +DEFSETFUNC (isDefAlive) { - eBBlock *ebp = item; - V_ARG(iCode *,diCode); + eBBlock *ebp = item; + V_ARG (iCode *, diCode); - if (ebp->visited) - return 0; + if (ebp->visited) + return 0; - ebp->visited = 1; - - /* if this definition is used in the block */ - if (bitVectBitValue(ebp->usesDefs,diCode->key)) - return 1; - - return applyToSet(ebp->succList,isDefAlive,diCode); -} + ebp->visited = 1; + + /* if this definition is used in the block */ + if (bitVectBitValue (ebp->usesDefs, diCode->key)) + return 1; + return applyToSet (ebp->succList, isDefAlive, diCode); +} diff --git a/src/SDCCdflow.h b/src/SDCCdflow.h index 225d65e3..02fafaaf 100644 --- a/src/SDCCdflow.h +++ b/src/SDCCdflow.h @@ -29,11 +29,11 @@ #ifndef SDCCDFLOW_H #define SDCCDFLOW_H 1 -DEFSETFUNC(mergeInExprs); -DEFSETFUNC(ifKilledInBlock) ; -void computeDataFlow (eBBlock **, int ); -DEFSETFUNC(mergeInDefs); -DEFSETFUNC(isDefAlive); -iCode *usedInRemaining (operand *,iCode *); -int usedBetweenPoints ( operand *,iCode *,iCode *); +DEFSETFUNC (mergeInExprs); +DEFSETFUNC (ifKilledInBlock); +void computeDataFlow (eBBlock **, int); +DEFSETFUNC (mergeInDefs); +DEFSETFUNC (isDefAlive); +iCode *usedInRemaining (operand *, iCode *); +int usedBetweenPoints (operand *, iCode *, iCode *); #endif diff --git a/src/SDCCglobl.h b/src/SDCCglobl.h index 2339f7fe..86f6bc58 100644 --- a/src/SDCCglobl.h +++ b/src/SDCCglobl.h @@ -11,37 +11,37 @@ * Define host port dependant constants etc. */ -# define DOS_DIR_SEPARATOR_CHAR '\\' -# define DOS_DIR_SEPARATOR_STRING "\\" -# define UNIX_DIR_SEPARATOR_CHAR '/' -# define UNIX_DIR_SEPARATOR_STRING "/" +#define DOS_DIR_SEPARATOR_CHAR '\\' +#define DOS_DIR_SEPARATOR_STRING "\\" +#define UNIX_DIR_SEPARATOR_CHAR '/' +#define UNIX_DIR_SEPARATOR_STRING "/" #if defined(__BORLANDC__) /* Borland Turbo C/Win32 Host */ -# define NATIVE_WIN32 1 -# define DIR_SEPARATOR_CHAR DOS_DIR_SEPARATOR_CHAR -# define DIR_SEPARATOR_STRING DOS_DIR_SEPARATOR_STRING +#define NATIVE_WIN32 1 +#define DIR_SEPARATOR_CHAR DOS_DIR_SEPARATOR_CHAR +#define DIR_SEPARATOR_STRING DOS_DIR_SEPARATOR_STRING #elif defined(_MSC_VER) /* Miscosoft VC6/Win32 Host */ -# define NATIVE_WIN32 1 -# include "sdcc_vc.h" -# define DIR_SEPARATOR_CHAR DOS_DIR_SEPARATOR_CHAR -# define DIR_SEPARATOR_STRING DOS_DIR_SEPARATOR_STRING +#define NATIVE_WIN32 1 +#include "sdcc_vc.h" +#define DIR_SEPARATOR_CHAR DOS_DIR_SEPARATOR_CHAR +#define DIR_SEPARATOR_STRING DOS_DIR_SEPARATOR_STRING #elif defined(__MINGW32__) /* MINGW32 DOS Host */ -# define NATIVE_WIN32 1 -# define DIR_SEPARATOR_CHAR DOS_DIR_SEPARATOR_CHAR -# define DIR_SEPARATOR_STRING DOS_DIR_SEPARATOR_STRING +#define NATIVE_WIN32 1 +#define DIR_SEPARATOR_CHAR DOS_DIR_SEPARATOR_CHAR +#define DIR_SEPARATOR_STRING DOS_DIR_SEPARATOR_STRING -#else /* Assume Un*x style system */ +#else /* Assume Un*x style system */ -# include "sdccconf.h" -# define DIR_SEPARATOR_CHAR UNIX_DIR_SEPARATOR_CHAR -# define DIR_SEPARATOR_STRING UNIX_DIR_SEPARATOR_STRING +#include "sdccconf.h" +#define DIR_SEPARATOR_CHAR UNIX_DIR_SEPARATOR_CHAR +#define DIR_SEPARATOR_STRING UNIX_DIR_SEPARATOR_STRING -#endif // _MSC_VER +#endif // _MSC_VER #include "SDCCerr.h" @@ -62,8 +62,8 @@ typedef int bool; #ifndef THROWS #define THROWS -#define THROW_NONE 0 -#define THROW_SRC 1 +#define THROW_NONE 0 +#define THROW_SRC 1 #define THROW_DEST 2 #define THROW_BOTH 3 #endif @@ -108,9 +108,9 @@ typedef int bool; #define PUSH(x,y) x##FreeStack[x##StackPtr++] = y #define PEEK(x) x##FreeStack[x##StackPtr-1] -#define POP(type) type##FreeStack[--type##StackPtr] +#define POP(type) type##FreeStack[--type##StackPtr] /* #define POP(x) (x##StackPtr ? x##FreeStack[--x##StackPtr] : \ - (assert(x##StackPtr),0)) */ + (assert(x##StackPtr),0)) */ #ifdef UNIX #define EMPTY(x) (x##StackPtr <= 1 ? 1 : 0) #else @@ -131,11 +131,11 @@ typedef int bool; #define EXTERN_STACK_DCL(stack,type,size) \ typedef type t_##stack ; \ extern t_##stack stack[size] ; \ - extern t_##stack *p_##stack; + extern t_##stack *p_##stack; #define STACK_FULL(stack) ((p_##stack) <= stack ) #define STACK_EMPTY(stack) ((p_##stack) >= (stack + \ - sizeof(stack)/sizeof(*stack)) ) + sizeof(stack)/sizeof(*stack)) ) #define STACK_PUSH_(stack,x) (*--p_##stack = (x)) #define STACK_POP_(stack) (*p_##stack++) @@ -157,127 +157,130 @@ typedef int bool; : fprintf(stderr,"stack underflow\n")) /* optimization options */ -struct optimize { - unsigned global_cse : 1 ; - unsigned ptrArithmetic :1; - unsigned label1 : 1 ; - unsigned label2 : 1 ; - unsigned label3 : 1 ; - unsigned label4 : 1 ; - unsigned loopInvariant: 1; - unsigned loopInduction: 1; - unsigned noJTabBoundary:1; - unsigned noLoopReverse :1; -} ; +struct optimize + { + unsigned global_cse:1; + unsigned ptrArithmetic:1; + unsigned label1:1; + unsigned label2:1; + unsigned label3:1; + unsigned label4:1; + unsigned loopInvariant:1; + unsigned loopInduction:1; + unsigned noJTabBoundary:1; + unsigned noLoopReverse:1; + }; /** Build model. Used in options.model.A bit each as port.supported_models is an OR of these. */ -enum { - MODEL_SMALL = 1, - MODEL_COMPACT = 2, - MODEL_MEDIUM = 4, - MODEL_LARGE = 8, - MODEL_FLAT24 = 16 -}; +enum + { + MODEL_SMALL = 1, + MODEL_COMPACT = 2, + MODEL_MEDIUM = 4, + MODEL_LARGE = 8, + MODEL_FLAT24 = 16 + }; /* other command line options */ -struct options { - int model; /* see MODEL_* defines above */ - int stackAuto : 3 ; /* Stack Automatic */ - int useXstack : 3 ; /* use Xternal Stack */ - int stack10bit : 3; /* use 10 bit stack (flat24 model only) */ - int genericPtr: 1 ; /* use generic pointers */ - int regExtend : 1 ; /* don't use extended registers */ - int dump_raw : 1 ; /* dump after intermediate code generation */ - int dump_gcse : 1 ; /* dump after gcse */ - int dump_loop : 1 ; /* dump after loop optimizations */ - int dump_kill : 1 ; /* dump after dead code elimination */ - int dump_range: 1 ; /* dump after live range analysis */ - int dump_pack : 1 ; /* dump after register packing */ - int dump_rassgn:1 ; /* dump after register assignment */ - int cc_only : 1 ; /* compile only flag */ - int intlong_rent:1 ; /* integer & long support routines reentrant */ - int float_rent: 1 ; /* floating point routines are reentrant */ - int out_fmt : 1 ; /* 1 = motorola S19 format 0 = intel Hex format */ - int cyclomatic: 1 ; /* print cyclomatic information */ - int noOverlay : 1 ; /* don't overlay local variables & parameters */ - int mainreturn: 1 ; /* issue a return after main */ - int nopeep : 1 ; /* no peep hole optimization */ - int asmpeep : 1 ; /* pass inline assembler thru peep hole */ - int debug : 1 ; /* generate extra debug info */ - int nodebug : 1 ; /* Generate no debug info. */ - int stackOnData:1 ; /* stack after data segment */ - int noregparms: 1 ; /* do not pass parameters in registers */ - int c1mode : 1 ; /* Act like c1 - no pre-proc, asm or link */ - char *peep_file ; /* additional rules for peep hole */ - char *out_name ; /* Asm output name for c1 mode */ - int nostdlib : 1 ; /* Don't use standard lib files */ - int nostdinc : 1 ; /* Don't use standard include files */ - int verbose : 1 ; /* Show what the compiler is doing */ - int ANSIint : 1 ; /* Use ANSI integer promotion rules in expressions. */ - - char *calleeSaves[128]; /* list of functions using callee save */ - char *excludeRegs[32] ; /* registers excluded from saving */ +struct options + { + int model; /* see MODEL_* defines above */ + int stackAuto:3; /* Stack Automatic */ + int useXstack:3; /* use Xternal Stack */ + int stack10bit:3; /* use 10 bit stack (flat24 model only) */ + int genericPtr:1; /* use generic pointers */ + int regExtend:1; /* don't use extended registers */ + int dump_raw:1; /* dump after intermediate code generation */ + int dump_gcse:1; /* dump after gcse */ + int dump_loop:1; /* dump after loop optimizations */ + int dump_kill:1; /* dump after dead code elimination */ + int dump_range:1; /* dump after live range analysis */ + int dump_pack:1; /* dump after register packing */ + int dump_rassgn:1; /* dump after register assignment */ + int cc_only:1; /* compile only flag */ + int intlong_rent:1; /* integer & long support routines reentrant */ + int float_rent:1; /* floating point routines are reentrant */ + int out_fmt:1; /* 1 = motorola S19 format 0 = intel Hex format */ + int cyclomatic:1; /* print cyclomatic information */ + int noOverlay:1; /* don't overlay local variables & parameters */ + int mainreturn:1; /* issue a return after main */ + int nopeep:1; /* no peep hole optimization */ + int asmpeep:1; /* pass inline assembler thru peep hole */ + int debug:1; /* generate extra debug info */ + int nodebug:1; /* Generate no debug info. */ + int stackOnData:1; /* stack after data segment */ + int noregparms:1; /* do not pass parameters in registers */ + int c1mode:1; /* Act like c1 - no pre-proc, asm or link */ + char *peep_file; /* additional rules for peep hole */ + char *out_name; /* Asm output name for c1 mode */ + int nostdlib:1; /* Don't use standard lib files */ + int nostdinc:1; /* Don't use standard include files */ + int verbose:1; /* Show what the compiler is doing */ + int ANSIint:1; /* Use ANSI integer promotion rules in expressions. */ + + char *calleeSaves[128]; /* list of functions using callee save */ + char *excludeRegs[32]; /* registers excluded from saving */ /* starting address of the segments */ - int xstack_loc ; /* initial location of external stack */ - int stack_loc ; /* initial value of internal stack pointer */ - int xdata_loc ; /* xternal ram starts at address */ - int data_loc ; /* interram start location */ - int idata_loc ; /* indirect address space */ - int code_loc ; /* code location start */ - int iram_size ; /* internal ram size (used only for error checking) */ -} ; + int xstack_loc; /* initial location of external stack */ + int stack_loc; /* initial value of internal stack pointer */ + int xdata_loc; /* xternal ram starts at address */ + int data_loc; /* interram start location */ + int idata_loc; /* indirect address space */ + int code_loc; /* code location start */ + int iram_size; /* internal ram size (used only for error checking) */ + }; /* forward definition for variables accessed globally */ -extern char *currFname ; -extern char *srcFileName; /* source file name without the extenstion */ -extern char *moduleName ; /* source file name without path & extension */ -extern int currLineno ; /* current line number */ -extern int yylineno ; /* line number of the current file SDCC.lex */ -extern FILE *yyin ; /* */ -extern FILE *asmFile ; /* assembly output file */ -extern FILE *cdbFile ; /* debugger symbol file */ -extern int NestLevel ; /* NestLevel SDCC.y */ -extern int stackPtr ; /* stack pointer SDCC.y */ -extern int xstackPtr ; /* external stack pointer SDCC.y */ -extern int reentrant ; /* /X flag has been sent SDCC.y */ -extern char buffer[] ;/* general buffer SDCCgen.c */ -extern int currRegBank; /* register bank being used SDCCgens.c */ -extern struct symbol *currFunc; /* current function SDCCgens.c */ -extern int cNestLevel; /* block nest level SDCCval.c */ -extern int currBlockno; /* sequentail block number */ -extern struct optimize optimize ; +extern char *currFname; +extern char *srcFileName; /* source file name without the extenstion */ +extern char *moduleName; /* source file name without path & extension */ +extern int currLineno; /* current line number */ +extern int yylineno; /* line number of the current file SDCC.lex */ +extern FILE *yyin; /* */ +extern FILE *asmFile; /* assembly output file */ +extern FILE *cdbFile; /* debugger symbol file */ +extern int NestLevel; /* NestLevel SDCC.y */ +extern int stackPtr; /* stack pointer SDCC.y */ +extern int xstackPtr; /* external stack pointer SDCC.y */ +extern int reentrant; /* /X flag has been sent SDCC.y */ +extern char buffer[]; /* general buffer SDCCgen.c */ +extern int currRegBank; /* register bank being used SDCCgens.c */ +extern struct symbol *currFunc; /* current function SDCCgens.c */ +extern int cNestLevel; /* block nest level SDCCval.c */ +extern int currBlockno; /* sequentail block number */ +extern struct optimize optimize; extern struct options options; extern int maxInterrupts; /* Visible from SDCCmain.c */ extern int nrelFiles; extern char *relFiles[128]; -extern char *libFiles[128] ; +extern char *libFiles[128]; extern int nlibFiles; /* -void buildCmdLine(char *into, char **args, const char **cmds, - const char *p1, const char *p2, - const char *p3, const char **list); -int my_system (const char *cmd, char **cmd_argv); -*/ + void buildCmdLine(char *into, char **args, const char **cmds, + const char *p1, const char *p2, + const char *p3, const char **list); + int my_system (const char *cmd, char **cmd_argv); + */ -void parseWithComma (char **,char *) ; +void parseWithComma (char **, char *); /** Creates a temporary file a'la tmpfile which avoids the bugs in cygwin wrt c:\tmp. Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile(). */ -FILE *tempfile(void); +FILE *tempfile (void); /** Creates a duplicate of the string 'sz' a'la strdup but using libgc. */ -char *gc_strdup(const char *sz); +char *gc_strdup (const char *sz); /** An assert() macro that will go out through sdcc's error system. diff --git a/src/SDCCglue.c b/src/SDCCglue.c index 45ecee2f..31c1394a 100644 --- a/src/SDCCglue.c +++ b/src/SDCCglue.c @@ -28,7 +28,7 @@ #include "newalloc.h" #if !defined(__BORLANDC__) && !defined(_MSC_VER) -#if 0 /* This should no longer be necessary. */ +#if 0 /* This should no longer be necessary. */ // This is a bit messy because we define link ourself #define link NoLiNk #include @@ -44,1341 +44,1440 @@ symbol *interrupts[256]; void printIval (symbol *, sym_link *, initList *, FILE *); -set *publics = NULL; /* public variables */ -set *externs = NULL; /* Varibles that are declared as extern */ +set *publics = NULL; /* public variables */ +set *externs = NULL; /* Varibles that are declared as extern */ /* TODO: this should be configurable (DS803C90 uses more than 6) */ int maxInterrupts = 6; int allocInfo = 1; symbol *mainf; extern char *VersionString; -set *tmpfileSet = NULL; /* set of tmp file created by the compiler */ -set *tmpfileNameSet = NULL; /* All are unlinked at close. */ +set *tmpfileSet = NULL; /* set of tmp file created by the compiler */ +set *tmpfileNameSet = NULL; /* All are unlinked at close. */ /*-----------------------------------------------------------------*/ /* closeTmpFiles - closes all tmp files created by the compiler */ /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(closeTmpFiles) +DEFSETFUNC (closeTmpFiles) { - FILE *tfile = item; + FILE *tfile = item; - if (tfile) - fclose(tfile); + if (tfile) + fclose (tfile); - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* rmTmpFiles - closes all tmp files created by the compiler */ /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(rmTmpFiles) +DEFSETFUNC (rmTmpFiles) { - char *name = item; + char *name = item; - if (name) { - unlink(name); - free(name); + if (name) + { + unlink (name); + free (name); } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* copyFile - copies source file to destination file */ /*-----------------------------------------------------------------*/ -void copyFile (FILE * dest, FILE * src) +void +copyFile (FILE * dest, FILE * src) { - int ch; + int ch; - rewind (src); - while (!feof (src)) - if ((ch = fgetc (src)) != EOF) + rewind (src); + while (!feof (src)) + if ((ch = fgetc (src)) != EOF) fputc (ch, dest); } -char *aopLiteralLong(value *val, int offset, int size) +char * +aopLiteralLong (value * val, int offset, int size) { - char *rs; - union { - float f; - unsigned char c[4]; - } fl; - - /* if it is a float then it gets tricky */ - /* otherwise it is fairly simple */ - if (!IS_FLOAT(val->type)) { - unsigned long v = floatFromVal(val); - - v >>= (offset * 8); - switch (size) { - case 1: - tsprintf(buffer, "!immedbyte", (unsigned int)v & 0xff); - break; - case 2: - tsprintf(buffer, "!immedword", (unsigned int)v & 0xffff); - break; - default: - /* Hmm. Too big for now. */ - assert(0); - } - rs = Safe_calloc(1,strlen(buffer)+1); - return strcpy (rs,buffer); + char *rs; + union + { + float f; + unsigned char c[4]; + } + fl; + + /* if it is a float then it gets tricky */ + /* otherwise it is fairly simple */ + if (!IS_FLOAT (val->type)) + { + unsigned long v = floatFromVal (val); + + v >>= (offset * 8); + switch (size) + { + case 1: + tsprintf (buffer, "!immedbyte", (unsigned int) v & 0xff); + break; + case 2: + tsprintf (buffer, "!immedword", (unsigned int) v & 0xffff); + break; + default: + /* Hmm. Too big for now. */ + assert (0); + } + rs = Safe_calloc (1, strlen (buffer) + 1); + return strcpy (rs, buffer); } - /* PENDING: For now size must be 1 */ - assert(size == 1); + /* PENDING: For now size must be 1 */ + assert (size == 1); - /* it is type float */ - fl.f = (float) floatFromVal(val); + /* it is type float */ + fl.f = (float) floatFromVal (val); #ifdef _BIG_ENDIAN - tsprintf(buffer, "!immedbyte", fl.c[3-offset]); + tsprintf (buffer, "!immedbyte", fl.c[3 - offset]); #else - tsprintf(buffer, "!immedbyte", fl.c[offset]); + tsprintf (buffer, "!immedbyte", fl.c[offset]); #endif - rs = Safe_calloc(1,strlen(buffer)+1); - return strcpy (rs,buffer); + rs = Safe_calloc (1, strlen (buffer) + 1); + return strcpy (rs, buffer); } /*-----------------------------------------------------------------*/ /* aopLiteral - string from a literal value */ /*-----------------------------------------------------------------*/ -char *aopLiteral (value *val, int offset) +char * +aopLiteral (value * val, int offset) { - return aopLiteralLong(val, offset, 1); + return aopLiteralLong (val, offset, 1); } /*-----------------------------------------------------------------*/ /* emitRegularMap - emit code for maps with no special cases */ /*-----------------------------------------------------------------*/ -static void emitRegularMap (memmap * map, bool addPublics, bool arFlag) +static void +emitRegularMap (memmap * map, bool addPublics, bool arFlag) { - symbol *sym; - - if (addPublics) { - /* PENDING: special case here - should remove */ - if (!strcmp(map->sname, CODE_NAME)) - tfprintf(map->oFile, "\t!areacode\n", map->sname); - else if (!strcmp(map->sname, DATA_NAME)) - tfprintf(map->oFile, "\t!areadata\n", map->sname); - else if (!strcmp(map->sname, HOME_NAME)) - tfprintf(map->oFile, "\t!areahome\n", map->sname); - else - tfprintf(map->oFile, "\t!area\n", map->sname); - } + symbol *sym; - /* print the area name */ - for (sym = setFirstItem (map->syms); sym; - sym = setNextItem (map->syms)) { - - /* if extern then add it into the extern list */ - if (IS_EXTERN (sym->etype)) { - addSetHead (&externs, sym); - continue; - } - - /* if allocation required check is needed - then check if the symbol really requires - allocation only for local variables */ - if (arFlag && !IS_AGGREGATE(sym->type) && - !(sym->_isparm && !IS_REGPARM(sym->etype)) && - !sym->allocreq && sym->level) - continue ; - - /* if global variable & not static or extern - and addPublics allowed then add it to the public set */ - if ((sym->level == 0 || - (sym->_isparm && !IS_REGPARM(sym->etype))) && - addPublics && - !IS_STATIC (sym->etype) && - (sym->used || sym->fbody)) { - addSetHead (&publics, sym); - } - - /* if extern then do nothing or is a function - then do nothing */ - if (IS_FUNC (sym->type)) - continue; - - /* print extra debug info if required */ - if ((options.debug || sym->level == 0) && !options.nodebug) { - - cdbSymbol(sym,cdbFile,FALSE,FALSE); - - if (!sym->level) /* global */ - if (IS_STATIC(sym->etype)) - fprintf(map->oFile,"F%s$",moduleName); /* scope is file */ - else - fprintf(map->oFile,"G$"); /* scope is global */ + if (addPublics) + { + /* PENDING: special case here - should remove */ + if (!strcmp (map->sname, CODE_NAME)) + tfprintf (map->oFile, "\t!areacode\n", map->sname); + else if (!strcmp (map->sname, DATA_NAME)) + tfprintf (map->oFile, "\t!areadata\n", map->sname); + else if (!strcmp (map->sname, HOME_NAME)) + tfprintf (map->oFile, "\t!areahome\n", map->sname); else - /* symbol is local */ - fprintf(map->oFile,"L%s$",(sym->localof ? sym->localof->name : "-null-")); - fprintf(map->oFile,"%s$%d$%d",sym->name,sym->level,sym->block); - } - - /* if is has an absolute address then generate - an equate for this no need to allocate space */ - if (SPEC_ABSA (sym->etype)) { - if ((options.debug || sym->level == 0) && !options.nodebug) - fprintf (map->oFile," == 0x%04x\n",SPEC_ADDR (sym->etype)); - - fprintf (map->oFile, "%s\t=\t0x%04x\n", - sym->rname, - SPEC_ADDR (sym->etype)); - } - else { - /* allocate space */ + tfprintf (map->oFile, "\t!area\n", map->sname); + } + + /* print the area name */ + for (sym = setFirstItem (map->syms); sym; + sym = setNextItem (map->syms)) + { + + /* if extern then add it into the extern list */ + if (IS_EXTERN (sym->etype)) + { + addSetHead (&externs, sym); + continue; + } + + /* if allocation required check is needed + then check if the symbol really requires + allocation only for local variables */ + if (arFlag && !IS_AGGREGATE (sym->type) && + !(sym->_isparm && !IS_REGPARM (sym->etype)) && + !sym->allocreq && sym->level) + continue; + + /* if global variable & not static or extern + and addPublics allowed then add it to the public set */ + if ((sym->level == 0 || + (sym->_isparm && !IS_REGPARM (sym->etype))) && + addPublics && + !IS_STATIC (sym->etype) && + (sym->used || sym->fbody)) + { + addSetHead (&publics, sym); + } + + /* if extern then do nothing or is a function + then do nothing */ + if (IS_FUNC (sym->type)) + continue; + + /* print extra debug info if required */ if ((options.debug || sym->level == 0) && !options.nodebug) - fprintf(map->oFile,"==.\n"); - if (IS_STATIC(sym->etype)) - tfprintf(map->oFile, "!slabeldef\n", sym->rname); - else - tfprintf(map->oFile, "!labeldef\n", sym->rname); - tfprintf(map->oFile, "\t!ds\n", (unsigned int)getSize (sym->type) & 0xffff); - } + { - /* if it has an initial value then do it only if - it is a global variable */ - if (sym->ival && sym->level == 0) { - ast *ival = NULL; + cdbSymbol (sym, cdbFile, FALSE, FALSE); - if (IS_AGGREGATE (sym->type)) - ival = initAggregates (sym, sym->ival, NULL); + if (!sym->level) /* global */ + if (IS_STATIC (sym->etype)) + fprintf (map->oFile, "F%s$", moduleName); /* scope is file */ + else + fprintf (map->oFile, "G$"); /* scope is global */ + else + /* symbol is local */ + fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-")); + fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block); + } + + /* if is has an absolute address then generate + an equate for this no need to allocate space */ + if (SPEC_ABSA (sym->etype)) + { + if ((options.debug || sym->level == 0) && !options.nodebug) + fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype)); + + fprintf (map->oFile, "%s\t=\t0x%04x\n", + sym->rname, + SPEC_ADDR (sym->etype)); + } else - ival = newNode ('=', newAst_VALUE(symbolVal (sym)), - decorateType (resolveSymbols (list2expr (sym->ival)))); - codeOutFile = statsg->oFile; - allocInfo = 0; - eBBlockFromiCode (iCodeFromAst (ival)); - allocInfo = 1; - sym->ival = NULL; - } + { + /* allocate space */ + if ((options.debug || sym->level == 0) && !options.nodebug) + fprintf (map->oFile, "==.\n"); + if (IS_STATIC (sym->etype)) + tfprintf (map->oFile, "!slabeldef\n", sym->rname); + else + tfprintf (map->oFile, "!labeldef\n", sym->rname); + tfprintf (map->oFile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff); + } + + /* if it has an initial value then do it only if + it is a global variable */ + if (sym->ival && sym->level == 0) + { + ast *ival = NULL; + + if (IS_AGGREGATE (sym->type)) + ival = initAggregates (sym, sym->ival, NULL); + else + ival = newNode ('=', newAst_VALUE (symbolVal (sym)), + decorateType (resolveSymbols (list2expr (sym->ival)))); + codeOutFile = statsg->oFile; + allocInfo = 0; + eBBlockFromiCode (iCodeFromAst (ival)); + allocInfo = 1; + sym->ival = NULL; + } } } /*-----------------------------------------------------------------*/ /* initPointer - pointer initialization code massaging */ /*-----------------------------------------------------------------*/ -value *initPointer (initList *ilist) +value * +initPointer (initList * ilist) { - value *val; - ast *expr = list2expr(ilist); - - if (!expr) - goto wrong; - - /* try it the oldway first */ - if ((val = constExprValue(expr,FALSE))) - return val; - - /* no then we have to do these cludgy checks */ - /* pointers can be initialized with address of - a variable or address of an array element */ - if (IS_AST_OP(expr) && expr->opval.op == '&') { - /* address of symbol */ - if (IS_AST_SYM_VALUE(expr->left)) { - val = copyValue(AST_VALUE(expr->left)); - val->type = newLink(); - if (SPEC_SCLS(expr->left->etype) == S_CODE) { - DCL_TYPE(val->type) = CPOINTER ; - DCL_PTR_CONST(val->type) = port->mem.code_ro; - } - else - if (SPEC_SCLS(expr->left->etype) == S_XDATA) - DCL_TYPE(val->type) = FPOINTER; - else - if (SPEC_SCLS(expr->left->etype) == S_XSTACK ) - DCL_TYPE(val->type) = PPOINTER ; - else - if (SPEC_SCLS(expr->left->etype) == S_IDATA) - DCL_TYPE(val->type) = IPOINTER ; - else - if (SPEC_SCLS(expr->left->etype) == S_EEPROM) - DCL_TYPE(val->type) = EEPPOINTER ; - else - DCL_TYPE(val->type) = POINTER ; - val->type->next = expr->left->ftype; - val->etype = getSpec(val->type); - return val; - } - - /* if address of indexed array */ - if (IS_AST_OP(expr->left) && expr->left->opval.op == '[') - return valForArray(expr->left); - - /* if address of structure element then - case 1. a.b ; */ - if (IS_AST_OP(expr->left) && - expr->left->opval.op == '.' ) { - return valForStructElem(expr->left->left, - expr->left->right); - } - - /* case 2. (&a)->b ; - (&some_struct)->element */ - if (IS_AST_OP(expr->left) && - expr->left->opval.op == PTR_OP && - IS_ADDRESS_OF_OP(expr->left->left)) - return valForStructElem(expr->left->left->left, - expr->left->right); + value *val; + ast *expr = list2expr (ilist); + + if (!expr) + goto wrong; + + /* try it the oldway first */ + if ((val = constExprValue (expr, FALSE))) + return val; + + /* no then we have to do these cludgy checks */ + /* pointers can be initialized with address of + a variable or address of an array element */ + if (IS_AST_OP (expr) && expr->opval.op == '&') + { + /* address of symbol */ + if (IS_AST_SYM_VALUE (expr->left)) + { + val = copyValue (AST_VALUE (expr->left)); + val->type = newLink (); + if (SPEC_SCLS (expr->left->etype) == S_CODE) + { + DCL_TYPE (val->type) = CPOINTER; + DCL_PTR_CONST (val->type) = port->mem.code_ro; + } + else if (SPEC_SCLS (expr->left->etype) == S_XDATA) + DCL_TYPE (val->type) = FPOINTER; + else if (SPEC_SCLS (expr->left->etype) == S_XSTACK) + DCL_TYPE (val->type) = PPOINTER; + else if (SPEC_SCLS (expr->left->etype) == S_IDATA) + DCL_TYPE (val->type) = IPOINTER; + else if (SPEC_SCLS (expr->left->etype) == S_EEPROM) + DCL_TYPE (val->type) = EEPPOINTER; + else + DCL_TYPE (val->type) = POINTER; + val->type->next = expr->left->ftype; + val->etype = getSpec (val->type); + return val; + } + + /* if address of indexed array */ + if (IS_AST_OP (expr->left) && expr->left->opval.op == '[') + return valForArray (expr->left); + + /* if address of structure element then + case 1. a.b ; */ + if (IS_AST_OP (expr->left) && + expr->left->opval.op == '.') + { + return valForStructElem (expr->left->left, + expr->left->right); + } + + /* case 2. (&a)->b ; + (&some_struct)->element */ + if (IS_AST_OP (expr->left) && + expr->left->opval.op == PTR_OP && + IS_ADDRESS_OF_OP (expr->left->left)) + return valForStructElem (expr->left->left->left, + expr->left->right); } - /* case 3. (((char *) &a) +/- constant) */ - if (IS_AST_OP(expr) && - (expr->opval.op == '+' || expr->opval.op == '-') && - IS_AST_OP(expr->left) && expr->left->opval.op == CAST && - IS_AST_OP(expr->left->right) && - expr->left->right->opval.op == '&' && - IS_AST_LIT_VALUE(expr->right)) { - - return valForCastAggr(expr->left->right->left, - expr->left->left->opval.lnk, - expr->right,expr->opval.op); + /* case 3. (((char *) &a) +/- constant) */ + if (IS_AST_OP (expr) && + (expr->opval.op == '+' || expr->opval.op == '-') && + IS_AST_OP (expr->left) && expr->left->opval.op == CAST && + IS_AST_OP (expr->left->right) && + expr->left->right->opval.op == '&' && + IS_AST_LIT_VALUE (expr->right)) + { + + return valForCastAggr (expr->left->right->left, + expr->left->left->opval.lnk, + expr->right, expr->opval.op); } - wrong: - werror(E_INIT_WRONG); - return NULL; +wrong: + werror (E_INIT_WRONG); + return NULL; } /*-----------------------------------------------------------------*/ /* printChar - formats and prints a characater string with DB */ /*-----------------------------------------------------------------*/ -void printChar (FILE * ofile, char *s, int plen) +void +printChar (FILE * ofile, char *s, int plen) { - int i; - int len = strlen (s); - int pplen = 0; - char buf[100]; - char *p = buf; - - while (len && pplen < plen) { - i = 60; - while (i && *s && pplen < plen) { - if (*s < ' ' || *s == '\"') { - *p = '\0'; - if (p != buf) - tfprintf(ofile, "\t!ascii\n", buf); - tfprintf(ofile, "\t!db !constbyte\n", *s); - p = buf; - } - else { - *p = *s; - p++; - } - s++; - pplen++; - i--; - } - if (p != buf) { - *p = '\0'; - tfprintf(ofile, "\t!ascii\n", buf); - p = buf; - } - - if (len > 60) - len -= 60; - else - len = 0; + int i; + int len = strlen (s); + int pplen = 0; + char buf[100]; + char *p = buf; + + while (len && pplen < plen) + { + i = 60; + while (i && *s && pplen < plen) + { + if (*s < ' ' || *s == '\"') + { + *p = '\0'; + if (p != buf) + tfprintf (ofile, "\t!ascii\n", buf); + tfprintf (ofile, "\t!db !constbyte\n", *s); + p = buf; + } + else + { + *p = *s; + p++; + } + s++; + pplen++; + i--; + } + if (p != buf) + { + *p = '\0'; + tfprintf (ofile, "\t!ascii\n", buf); + p = buf; + } + + if (len > 60) + len -= 60; + else + len = 0; } - tfprintf(ofile, "\t!db !constbyte\n", 0); + tfprintf (ofile, "\t!db !constbyte\n", 0); } /*-----------------------------------------------------------------*/ /* return the generic pointer high byte for a given pointer type. */ /*-----------------------------------------------------------------*/ -int pointerTypeToGPByte(const int p_type) +int +pointerTypeToGPByte (const int p_type) { - switch (p_type) + switch (p_type) { - case IPOINTER: - case POINTER: - return 0; - case GPOINTER: - /* hack - if we get a generic pointer, we just assume - * it's an FPOINTER (i.e. in XDATA space). - */ - case FPOINTER: - return 1; - case CPOINTER: - return 2; - case PPOINTER: - return 3; - default: - fprintf(stderr, "*** internal error: unknown pointer type %d in GPByte.\n", - p_type); - break; + case IPOINTER: + case POINTER: + return 0; + case GPOINTER: + /* hack - if we get a generic pointer, we just assume + * it's an FPOINTER (i.e. in XDATA space). + */ + case FPOINTER: + return 1; + case CPOINTER: + return 2; + case PPOINTER: + return 3; + default: + fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n", + p_type); + break; } - return -1; + return -1; } /*-----------------------------------------------------------------*/ /* printPointerType - generates ival for pointer type */ /*-----------------------------------------------------------------*/ -void _printPointerType(FILE *oFile, const char *name) +void +_printPointerType (FILE * oFile, const char *name) { - if (IS_DS390_PORT) + if (IS_DS390_PORT) { - fprintf(oFile, "\t.byte %s,(%s >> 8),(%s >> 16)",name,name,name); + fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name); } - else + else { - fprintf(oFile, "\t.byte %s,(%s >> 8)",name,name); + fprintf (oFile, "\t.byte %s,(%s >> 8)", name, name); } } /*-----------------------------------------------------------------*/ /* printPointerType - generates ival for pointer type */ /*-----------------------------------------------------------------*/ -void printPointerType(FILE *oFile, const char *name) +void +printPointerType (FILE * oFile, const char *name) { - _printPointerType(oFile, name); - fprintf(oFile, "\n"); + _printPointerType (oFile, name); + fprintf (oFile, "\n"); } /*-----------------------------------------------------------------*/ /* printGPointerType - generates ival for generic pointer type */ /*-----------------------------------------------------------------*/ -void printGPointerType(FILE *oFile, const char *name, - const unsigned int type) +void +printGPointerType (FILE * oFile, const char *name, + const unsigned int type) { - _printPointerType(oFile,name); - fprintf(oFile, ",#0x%02x\n", pointerTypeToGPByte(type)); + _printPointerType (oFile, name); + fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type)); } /*-----------------------------------------------------------------*/ /* printIvalType - generates ival for int/char */ /*-----------------------------------------------------------------*/ -void printIvalType (sym_link * type, initList * ilist, FILE * oFile) +void +printIvalType (sym_link * type, initList * ilist, FILE * oFile) { - value *val; + value *val; - /* if initList is deep */ - if (ilist->type == INIT_DEEP) - ilist = ilist->init.deep; + /* if initList is deep */ + if (ilist->type == INIT_DEEP) + ilist = ilist->init.deep; - val = list2val (ilist); - switch (getSize (type)) { + val = list2val (ilist); + switch (getSize (type)) + { case 1: - if (!val) - tfprintf(oFile, "\t!db !constbyte\n", 0); - else - tfprintf(oFile, "\t!dbs\n", - aopLiteral (val, 0)); - break; + if (!val) + tfprintf (oFile, "\t!db !constbyte\n", 0); + else + tfprintf (oFile, "\t!dbs\n", + aopLiteral (val, 0)); + break; case 2: - if (port->use_dw_for_init) - tfprintf(oFile, "\t!dws\n", aopLiteralLong(val, 0, 2)); - else - fprintf(oFile, "\t.byte %s,%s\n", aopLiteral(val, 0),aopLiteral(val, 1)); - break; + if (port->use_dw_for_init) + tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2)); + else + fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1)); + break; case 4: - if (!val) { - tfprintf (oFile, "\t!dw !constword\n", 0); - tfprintf (oFile, "\t!dw !constword\n", 0); - } - else { - fprintf (oFile, "\t.byte %s,%s,%s,%s\n", - aopLiteral (val, 0), aopLiteral (val, 1), - aopLiteral (val, 2), aopLiteral (val, 3)); - } - break; + if (!val) + { + tfprintf (oFile, "\t!dw !constword\n", 0); + tfprintf (oFile, "\t!dw !constword\n", 0); + } + else + { + fprintf (oFile, "\t.byte %s,%s,%s,%s\n", + aopLiteral (val, 0), aopLiteral (val, 1), + aopLiteral (val, 2), aopLiteral (val, 3)); + } + break; } } /*-----------------------------------------------------------------*/ /* printIvalStruct - generates initial value for structures */ /*-----------------------------------------------------------------*/ -void printIvalStruct (symbol * sym,sym_link * type, - initList * ilist, FILE * oFile) +void +printIvalStruct (symbol * sym, sym_link * type, + initList * ilist, FILE * oFile) { - symbol *sflds; - initList *iloop; + symbol *sflds; + initList *iloop; - sflds = SPEC_STRUCT (type)->fields; - if (ilist->type != INIT_DEEP) { - werror (E_INIT_STRUCT, sym->name); - return; + sflds = SPEC_STRUCT (type)->fields; + if (ilist->type != INIT_DEEP) + { + werror (E_INIT_STRUCT, sym->name); + return; } - iloop = ilist->init.deep; + iloop = ilist->init.deep; - for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) - printIval (sflds, sflds->type, iloop, oFile); + for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) + printIval (sflds, sflds->type, iloop, oFile); - return; + return; } /*-----------------------------------------------------------------*/ /* printIvalChar - generates initital value for character array */ /*-----------------------------------------------------------------*/ -int printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s) +int +printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s) { - value *val; - int remain; + value *val; + int remain; - if (!s) { + if (!s) + { - val = list2val (ilist); - /* if the value is a character string */ - if (IS_ARRAY (val->type) && IS_CHAR (val->etype)) { - if (!DCL_ELEM (type)) - DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1; + val = list2val (ilist); + /* if the value is a character string */ + if (IS_ARRAY (val->type) && IS_CHAR (val->etype)) + { + if (!DCL_ELEM (type)) + DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1; - /* if size mismatch */ + /* if size mismatch */ /* if (DCL_ELEM (type) < ((int) strlen (SPEC_CVAL (val->etype).v_char) + 1)) */ /* werror (E_ARRAY_BOUND); */ - printChar (oFile, SPEC_CVAL (val->etype).v_char,DCL_ELEM(type)); + printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type)); - if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) -1))>0) - while (remain--) - tfprintf (oFile, "\t!db !constbyte\n", 0); + if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) + while (remain--) + tfprintf (oFile, "\t!db !constbyte\n", 0); - return 1; - } - else - return 0; + return 1; + } + else + return 0; } - else - printChar (oFile, s,strlen(s)+1); - return 1; + else + printChar (oFile, s, strlen (s) + 1); + return 1; } /*-----------------------------------------------------------------*/ /* printIvalArray - generates code for array initialization */ /*-----------------------------------------------------------------*/ -void printIvalArray (symbol * sym, sym_link * type, initList * ilist, - FILE * oFile) +void +printIvalArray (symbol * sym, sym_link * type, initList * ilist, + FILE * oFile) { - initList *iloop; - int lcnt = 0, size = 0; - - /* take care of the special case */ - /* array of characters can be init */ - /* by a string */ - if (IS_CHAR (type->next)) - if (printIvalChar (type, - (ilist->type == INIT_DEEP ? ilist->init.deep : ilist), - oFile, SPEC_CVAL (sym->etype).v_char)) + initList *iloop; + int lcnt = 0, size = 0; + + /* take care of the special case */ + /* array of characters can be init */ + /* by a string */ + if (IS_CHAR (type->next)) + if (printIvalChar (type, + (ilist->type == INIT_DEEP ? ilist->init.deep : ilist), + oFile, SPEC_CVAL (sym->etype).v_char)) return; - /* not the special case */ - if (ilist->type != INIT_DEEP) { - werror (E_INIT_STRUCT, sym->name); - return; + /* not the special case */ + if (ilist->type != INIT_DEEP) + { + werror (E_INIT_STRUCT, sym->name); + return; } - iloop = ilist->init.deep; - lcnt = DCL_ELEM (type); + iloop = ilist->init.deep; + lcnt = DCL_ELEM (type); - for (;;) { - size++; - printIval (sym, type->next, iloop, oFile); - iloop = (iloop ? iloop->next : NULL); + for (;;) + { + size++; + printIval (sym, type->next, iloop, oFile); + iloop = (iloop ? iloop->next : NULL); - /* if not array limits given & we */ - /* are out of initialisers then */ - if (!DCL_ELEM (type) && !iloop) - break; + /* if not array limits given & we */ + /* are out of initialisers then */ + if (!DCL_ELEM (type) && !iloop) + break; - /* no of elements given and we */ - /* have generated for all of them */ - if (!--lcnt) - break; + /* no of elements given and we */ + /* have generated for all of them */ + if (!--lcnt) + break; } - /* if we have not been given a size */ - if (!DCL_ELEM (type)) - DCL_ELEM (type) = size; + /* if we have not been given a size */ + if (!DCL_ELEM (type)) + DCL_ELEM (type) = size; - return; + return; } /*-----------------------------------------------------------------*/ /* printIvalFuncPtr - generate initial value for function pointers */ /*-----------------------------------------------------------------*/ -void printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile) +void +printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile) { - value *val; - int dLvl = 0; + value *val; + int dLvl = 0; - val = list2val (ilist); - /* check the types */ - if ((dLvl = checkType (val->type, type->next)) <= 0) { - tfprintf(oFile, "\t!dw !constword\n", 0); - return; + val = list2val (ilist); + /* check the types */ + if ((dLvl = checkType (val->type, type->next)) <= 0) + { + tfprintf (oFile, "\t!dw !constword\n", 0); + return; } - /* now generate the name */ - if (!val->sym) { - if (port->use_dw_for_init) - { - tfprintf(oFile, "\t!dws\n", val->name); - } - else - { - printPointerType(oFile, val->name); - } + /* now generate the name */ + if (!val->sym) + { + if (port->use_dw_for_init) + { + tfprintf (oFile, "\t!dws\n", val->name); + } + else + { + printPointerType (oFile, val->name); + } + } + else if (port->use_dw_for_init) + { + tfprintf (oFile, "\t!dws\n", val->sym->rname); } - else - if (port->use_dw_for_init) - { - tfprintf(oFile, "\t!dws\n", val->sym->rname); - } else - { - printPointerType(oFile, val->sym->rname); - } + { + printPointerType (oFile, val->sym->rname); + } - return; + return; } /*-----------------------------------------------------------------*/ /* printIvalCharPtr - generates initial values for character pointers */ /*-----------------------------------------------------------------*/ -int printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile) +int +printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile) { - int size = 0; - - /* PENDING: this is _very_ mcs51 specific, including a magic - number... - It's also endin specific. - */ - size = getSize (type); - - if (val->name && strlen(val->name)) { - if (size == 1) /* This appears to be Z80 specific?? */ - { - tfprintf(oFile, - "\t!dbs\n", val->name); - } - else if (size == FPTRSIZE) - { - if (port->use_dw_for_init) - { - tfprintf(oFile, "\t!dws\n", val->name); - } + int size = 0; + + /* PENDING: this is _very_ mcs51 specific, including a magic + number... + It's also endin specific. + */ + size = getSize (type); + + if (val->name && strlen (val->name)) + { + if (size == 1) /* This appears to be Z80 specific?? */ + { + tfprintf (oFile, + "\t!dbs\n", val->name); + } + else if (size == FPTRSIZE) + { + if (port->use_dw_for_init) + { + tfprintf (oFile, "\t!dws\n", val->name); + } + else + { + printPointerType (oFile, val->name); + } + } + else if (size == GPTRSIZE) + { + /* PENDING: 0x02 or 0x%02x, CDATA? */ + printGPointerType (oFile, val->name, + (IS_PTR (val->type) ? DCL_TYPE (val->type) : + PTR_TYPE (SPEC_OCLS (val->etype)))); + } else - { - printPointerType(oFile, val->name); - } - } - else if (size == GPTRSIZE) - { - /* PENDING: 0x02 or 0x%02x, CDATA? */ - printGPointerType(oFile, val->name, - (IS_PTR(val->type) ? DCL_TYPE(val->type) : - PTR_TYPE(SPEC_OCLS(val->etype)))); - } - else - { - fprintf(stderr, "*** internal error: unknown size in " - "printIvalCharPtr.\n"); - } + { + fprintf (stderr, "*** internal error: unknown size in " + "printIvalCharPtr.\n"); + } } - else { - /* What is this case? Are these pointers? */ - switch (size) { - case 1: - tfprintf(oFile, "\t!dbs\n", aopLiteral(val, 0)); - break; - case 2: - if (port->use_dw_for_init) - tfprintf(oFile, "\t!dws\n", aopLiteralLong(val, 0, size)); - else - tfprintf(oFile, "\t.byte %s,%s\n", - aopLiteral(val, 0),aopLiteral(val, 1)); - break; - case 3: - /* PENDING: 0x02 or 0x%02x, CDATA? */ - fprintf(oFile, "\t.byte %s,%s,#0x02\n", - aopLiteral (val, 0), aopLiteral (val, 1)); - break; - default: - assert(0); - } + else + { + /* What is this case? Are these pointers? */ + switch (size) + { + case 1: + tfprintf (oFile, "\t!dbs\n", aopLiteral (val, 0)); + break; + case 2: + if (port->use_dw_for_init) + tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, size)); + else + tfprintf (oFile, "\t.byte %s,%s\n", + aopLiteral (val, 0), aopLiteral (val, 1)); + break; + case 3: + /* PENDING: 0x02 or 0x%02x, CDATA? */ + fprintf (oFile, "\t.byte %s,%s,#0x02\n", + aopLiteral (val, 0), aopLiteral (val, 1)); + break; + default: + assert (0); + } } - if (val->sym && val->sym->isstrlit) - addSet (&statsg->syms, val->sym); + if (val->sym && val->sym->isstrlit) + addSet (&statsg->syms, val->sym); - return 1; + return 1; } /*-----------------------------------------------------------------*/ /* printIvalPtr - generates initial value for pointers */ /*-----------------------------------------------------------------*/ -void printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile) +void +printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile) { - value *val; - int size; + value *val; + int size; - /* if deep then */ - if (ilist->type == INIT_DEEP) - ilist = ilist->init.deep; + /* if deep then */ + if (ilist->type == INIT_DEEP) + ilist = ilist->init.deep; - /* function pointer */ - if (IS_FUNC (type->next)) { - printIvalFuncPtr (type, ilist, oFile); - return; + /* function pointer */ + if (IS_FUNC (type->next)) + { + printIvalFuncPtr (type, ilist, oFile); + return; } - if (!(val = initPointer (ilist))) - return ; + if (!(val = initPointer (ilist))) + return; - /* if character pointer */ - if (IS_CHAR (type->next)) - if (printIvalCharPtr (sym, type, val, oFile)) + /* if character pointer */ + if (IS_CHAR (type->next)) + if (printIvalCharPtr (sym, type, val, oFile)) return; - /* check the type */ - if (checkType (type, val->type) != 1) - werror (E_INIT_WRONG); + /* check the type */ + if (checkType (type, val->type) != 1) + werror (E_INIT_WRONG); - /* if val is literal */ - if (IS_LITERAL (val->etype)) { - switch (getSize (type)) { - case 1: - tfprintf(oFile, "\t!db !constbyte\n", (unsigned int)floatFromVal(val) & 0xff); - break; - case 2: - if (port->use_dw_for_init) - tfprintf(oFile, "\t!dws\n", aopLiteralLong(val, 0, 2)); - else - tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral(val, 0),aopLiteral(val, 1)); - break; - case 3: - fprintf (oFile, "\t.byte %s,%s,#0x02\n", - aopLiteral (val, 0), aopLiteral (val, 1)); - } - return; + /* if val is literal */ + if (IS_LITERAL (val->etype)) + { + switch (getSize (type)) + { + case 1: + tfprintf (oFile, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff); + break; + case 2: + if (port->use_dw_for_init) + tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2)); + else + tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1)); + break; + case 3: + fprintf (oFile, "\t.byte %s,%s,#0x02\n", + aopLiteral (val, 0), aopLiteral (val, 1)); + } + return; } - size = getSize (type); + size = getSize (type); - if (size == 1) /* Z80 specific?? */ + if (size == 1) /* Z80 specific?? */ { - tfprintf (oFile, "\t!dbs\n", val->name); + tfprintf (oFile, "\t!dbs\n", val->name); } - else if (size == FPTRSIZE) + else if (size == FPTRSIZE) { - tfprintf (oFile, "\t!dws\n", val->name); + tfprintf (oFile, "\t!dws\n", val->name); } - else if (size == GPTRSIZE) + else if (size == GPTRSIZE) { - printGPointerType(oFile, val->name, - (IS_PTR(val->type) ? DCL_TYPE(val->type) : - PTR_TYPE(SPEC_OCLS(val->etype)))); + printGPointerType (oFile, val->name, + (IS_PTR (val->type) ? DCL_TYPE (val->type) : + PTR_TYPE (SPEC_OCLS (val->etype)))); } - return; + return; } /*-----------------------------------------------------------------*/ /* printIval - generates code for initial value */ /*-----------------------------------------------------------------*/ -void printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile) +void +printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile) { - if (!ilist) - return; + if (!ilist) + return; - /* if structure then */ - if (IS_STRUCT (type)) { - printIvalStruct (sym, type, ilist, oFile); - return; + /* if structure then */ + if (IS_STRUCT (type)) + { + printIvalStruct (sym, type, ilist, oFile); + return; } - /* if this is a pointer */ - if (IS_PTR (type)) { - printIvalPtr (sym, type, ilist, oFile); - return; + /* if this is a pointer */ + if (IS_PTR (type)) + { + printIvalPtr (sym, type, ilist, oFile); + return; } - /* if this is an array */ - if (IS_ARRAY (type)) { - printIvalArray (sym, type, ilist, oFile); - return; + /* if this is an array */ + if (IS_ARRAY (type)) + { + printIvalArray (sym, type, ilist, oFile); + return; } - /* if type is SPECIFIER */ - if (IS_SPEC (type)) { - printIvalType (type, ilist, oFile); - return; + /* if type is SPECIFIER */ + if (IS_SPEC (type)) + { + printIvalType (type, ilist, oFile); + return; } } /*-----------------------------------------------------------------*/ /* emitStaticSeg - emitcode for the static segment */ /*-----------------------------------------------------------------*/ -void emitStaticSeg(memmap * map, FILE *out) +void +emitStaticSeg (memmap * map, FILE * out) { - symbol *sym; - - /* fprintf(map->oFile,"\t.area\t%s\n",map->sname); */ - if (!out) - out = code->oFile; - - /* for all variables in this segment do */ - for (sym = setFirstItem (map->syms); sym; - sym = setNextItem (map->syms)) { + symbol *sym; - /* if it is "extern" then do nothing */ - if (IS_EXTERN (sym->etype)) - continue; + /* fprintf(map->oFile,"\t.area\t%s\n",map->sname); */ + if (!out) + out = code->oFile; - /* if it is not static add it to the public - table */ - if (!IS_STATIC (sym->etype)) - addSetHead (&publics, sym); - - /* print extra debug info if required */ - if ((options.debug || sym->level == 0) && !options.nodebug) { + /* for all variables in this segment do */ + for (sym = setFirstItem (map->syms); sym; + sym = setNextItem (map->syms)) + { - cdbSymbol(sym,cdbFile,FALSE,FALSE); + /* if it is "extern" then do nothing */ + if (IS_EXTERN (sym->etype)) + continue; - if (!sym->level) { /* global */ - if (IS_STATIC(sym->etype)) - fprintf(out,"F%s$",moduleName); /* scope is file */ - else - fprintf(out,"G$"); /* scope is global */ - } - else - /* symbol is local */ - fprintf(out,"L%s$", - (sym->localof ? sym->localof->name : "-null-")); - fprintf(out,"%s$%d$%d",sym->name,sym->level,sym->block); - } - - /* if it has an absolute address */ - if (SPEC_ABSA (sym->etype)) { - if ((options.debug || sym->level == 0) && !options.nodebug) - fprintf(out," == 0x%04x\n", SPEC_ADDR (sym->etype)); + /* if it is not static add it to the public + table */ + if (!IS_STATIC (sym->etype)) + addSetHead (&publics, sym); - fprintf (out, "%s\t=\t0x%04x\n", - sym->rname, - SPEC_ADDR (sym->etype)); - } - else { + /* print extra debug info if required */ if ((options.debug || sym->level == 0) && !options.nodebug) - fprintf(out," == .\n"); - - /* if it has an initial value */ - if (sym->ival) { - fprintf (out, "%s:\n", sym->rname); - noAlloc++; - resolveIvalSym (sym->ival); - printIval (sym, sym->type, sym->ival, out); - noAlloc--; - } - else { - /* allocate space */ - fprintf (out, "%s:\n", sym->rname); - /* special case for character strings */ - if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) && - SPEC_CVAL (sym->etype).v_char) - printChar (out, - SPEC_CVAL (sym->etype).v_char, - strlen(SPEC_CVAL (sym->etype).v_char)+1); - else - tfprintf(out, "\t!ds\n", (unsigned int)getSize (sym->type)& 0xffff); - } - } + { + + cdbSymbol (sym, cdbFile, FALSE, FALSE); + + if (!sym->level) + { /* global */ + if (IS_STATIC (sym->etype)) + fprintf (out, "F%s$", moduleName); /* scope is file */ + else + fprintf (out, "G$"); /* scope is global */ + } + else + /* symbol is local */ + fprintf (out, "L%s$", + (sym->localof ? sym->localof->name : "-null-")); + fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block); + } + + /* if it has an absolute address */ + if (SPEC_ABSA (sym->etype)) + { + if ((options.debug || sym->level == 0) && !options.nodebug) + fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype)); + + fprintf (out, "%s\t=\t0x%04x\n", + sym->rname, + SPEC_ADDR (sym->etype)); + } + else + { + if ((options.debug || sym->level == 0) && !options.nodebug) + fprintf (out, " == .\n"); + + /* if it has an initial value */ + if (sym->ival) + { + fprintf (out, "%s:\n", sym->rname); + noAlloc++; + resolveIvalSym (sym->ival); + printIval (sym, sym->type, sym->ival, out); + noAlloc--; + } + else + { + /* allocate space */ + fprintf (out, "%s:\n", sym->rname); + /* special case for character strings */ + if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) && + SPEC_CVAL (sym->etype).v_char) + printChar (out, + SPEC_CVAL (sym->etype).v_char, + strlen (SPEC_CVAL (sym->etype).v_char) + 1); + else + tfprintf (out, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff); + } + } } } /*-----------------------------------------------------------------*/ /* emitMaps - emits the code for the data portion the code */ /*-----------------------------------------------------------------*/ -void emitMaps () +void +emitMaps () { - /* no special considerations for the following - data, idata & bit & xdata */ - emitRegularMap (data, TRUE, TRUE); - emitRegularMap (idata, TRUE,TRUE); - emitRegularMap (bit, TRUE,FALSE); - emitRegularMap (xdata, TRUE,TRUE); - emitRegularMap (sfr, FALSE,FALSE); - emitRegularMap (sfrbit, FALSE,FALSE); - emitRegularMap (home, TRUE,FALSE); - emitRegularMap (code, TRUE,FALSE); - - emitStaticSeg (statsg, code->oFile); + /* no special considerations for the following + data, idata & bit & xdata */ + emitRegularMap (data, TRUE, TRUE); + emitRegularMap (idata, TRUE, TRUE); + emitRegularMap (bit, TRUE, FALSE); + emitRegularMap (xdata, TRUE, TRUE); + emitRegularMap (sfr, FALSE, FALSE); + emitRegularMap (sfrbit, FALSE, FALSE); + emitRegularMap (home, TRUE, FALSE); + emitRegularMap (code, TRUE, FALSE); + + emitStaticSeg (statsg, code->oFile); } /*-----------------------------------------------------------------*/ /* flushStatics - flush all currently defined statics out to file */ /* and delete. Temporary function */ /*-----------------------------------------------------------------*/ -void flushStatics(void) +void +flushStatics (void) { - emitStaticSeg(statsg, codeOutFile); - statsg->syms = NULL; + emitStaticSeg (statsg, codeOutFile); + statsg->syms = NULL; } /*-----------------------------------------------------------------*/ /* createInterruptVect - creates the interrupt vector */ /*-----------------------------------------------------------------*/ -void createInterruptVect (FILE * vFile) +void +createInterruptVect (FILE * vFile) { - int i = 0; - mainf = newSymbol ("main", 0); - mainf->block = 0; - - /* only if the main function exists */ - if (!(mainf = findSymWithLevel (SymbolTab, mainf))) { - if (!options.cc_only) - werror(E_NO_MAIN); - return; + int i = 0; + mainf = newSymbol ("main", 0); + mainf->block = 0; + + /* only if the main function exists */ + if (!(mainf = findSymWithLevel (SymbolTab, mainf))) + { + if (!options.cc_only) + werror (E_NO_MAIN); + return; } - /* if the main is only a prototype ie. no body then do nothing */ - if (!mainf->fbody) { - /* if ! compile only then main function should be present */ - if (!options.cc_only) - werror(E_NO_MAIN); - return; + /* if the main is only a prototype ie. no body then do nothing */ + if (!mainf->fbody) + { + /* if ! compile only then main function should be present */ + if (!options.cc_only) + werror (E_NO_MAIN); + return; } - tfprintf(vFile, "\t!areacode\n", CODE_NAME); - fprintf (vFile, "__interrupt_vect:\n"); + tfprintf (vFile, "\t!areacode\n", CODE_NAME); + fprintf (vFile, "__interrupt_vect:\n"); - if (!port->genIVT || ! (port->genIVT(vFile, interrupts, maxInterrupts))) + if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts))) { - /* "generic" interrupt table header (if port doesn't specify one). - * - * Look suspiciously like 8051 code to me... - */ + /* "generic" interrupt table header (if port doesn't specify one). + + * Look suspiciously like 8051 code to me... + */ fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n"); /* now for the other interrupts */ - for (; i < maxInterrupts; i++) { - if (interrupts[i]) - fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname); - else - fprintf (vFile, "\treti\n\t.ds\t7\n"); - } + for (; i < maxInterrupts; i++) + { + if (interrupts[i]) + fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname); + else + fprintf (vFile, "\treti\n\t.ds\t7\n"); + } } } char *iComments1 = { - ";--------------------------------------------------------\n" - "; File Created by SDCC : FreeWare ANSI-C Compiler\n"}; + ";--------------------------------------------------------\n" + "; File Created by SDCC : FreeWare ANSI-C Compiler\n"}; char *iComments2 = { - ";--------------------------------------------------------\n"}; + ";--------------------------------------------------------\n"}; /*-----------------------------------------------------------------*/ /* initialComments - puts in some initial comments */ /*-----------------------------------------------------------------*/ -void initialComments (FILE * afile) +void +initialComments (FILE * afile) { - time_t t; - time(&t); - fprintf (afile, "%s", iComments1); - fprintf (afile, "; Version %s %s\n", VersionString,asctime(localtime(&t))); - fprintf (afile, "%s", iComments2); + time_t t; + time (&t); + fprintf (afile, "%s", iComments1); + fprintf (afile, "; Version %s %s\n", VersionString, asctime (localtime (&t))); + fprintf (afile, "%s", iComments2); } /*-----------------------------------------------------------------*/ /* printPublics - generates .global for publics */ /*-----------------------------------------------------------------*/ -void printPublics (FILE * afile) +void +printPublics (FILE * afile) { - symbol *sym; + symbol *sym; - fprintf (afile, "%s", iComments2); - fprintf (afile, "; Public variables in this module\n"); - fprintf (afile, "%s", iComments2); + fprintf (afile, "%s", iComments2); + fprintf (afile, "; Public variables in this module\n"); + fprintf (afile, "%s", iComments2); - for (sym = setFirstItem (publics); sym; - sym = setNextItem (publics)) - tfprintf(afile, "\t!global\n", sym->rname); + for (sym = setFirstItem (publics); sym; + sym = setNextItem (publics)) + tfprintf (afile, "\t!global\n", sym->rname); } /*-----------------------------------------------------------------*/ /* printExterns - generates .global for externs */ /*-----------------------------------------------------------------*/ -void printExterns (FILE * afile) +void +printExterns (FILE * afile) { - symbol *sym; + symbol *sym; - fprintf (afile, "%s", iComments2); - fprintf (afile, "; Externals used\n"); - fprintf (afile, "%s", iComments2); + fprintf (afile, "%s", iComments2); + fprintf (afile, "; Externals used\n"); + fprintf (afile, "%s", iComments2); - for (sym = setFirstItem (externs); sym; - sym = setNextItem (externs)) - tfprintf(afile, "\t!global\n", sym->rname); + for (sym = setFirstItem (externs); sym; + sym = setNextItem (externs)) + tfprintf (afile, "\t!global\n", sym->rname); } /*-----------------------------------------------------------------*/ /* emitOverlay - will emit code for the overlay stuff */ /*-----------------------------------------------------------------*/ -static void emitOverlay(FILE *afile) +static void +emitOverlay (FILE * afile) { - set *ovrset; - - if (!elementsInSet(ovrSetSets)) - tfprintf(afile,"\t!area\n", port->mem.overlay_name); - - /* for each of the sets in the overlay segment do */ - for (ovrset = setFirstItem(ovrSetSets); ovrset; - ovrset = setNextItem(ovrSetSets)) { + set *ovrset; - symbol *sym ; + if (!elementsInSet (ovrSetSets)) + tfprintf (afile, "\t!area\n", port->mem.overlay_name); - if (elementsInSet(ovrset)) { - /* this dummy area is used to fool the assembler - otherwise the assembler will append each of these - declarations into one chunk and will not overlay - sad but true */ - fprintf(afile,"\t.area _DUMMY\n"); - /* output the area informtion */ - fprintf(afile,"\t.area\t%s\n", port->mem.overlay_name); /* MOF */ - } - - for (sym = setFirstItem(ovrset); sym; - sym = setNextItem(ovrset)) { - - /* if extern then add it to the publics tabledo nothing */ - if (IS_EXTERN (sym->etype)) - continue; - - /* if allocation required check is needed - then check if the symbol really requires - allocation only for local variables */ - if (!IS_AGGREGATE(sym->type) && - !(sym->_isparm && !IS_REGPARM(sym->etype)) - && !sym->allocreq && sym->level) - continue ; - - /* if global variable & not static or extern - and addPublics allowed then add it to the public set */ - if ((sym->_isparm && !IS_REGPARM(sym->etype)) - && !IS_STATIC (sym->etype)) - addSetHead (&publics, sym); - - /* if extern then do nothing or is a function - then do nothing */ - if (IS_FUNC (sym->type)) - continue; - - /* print extra debug info if required */ - if ((options.debug || sym->level == 0) && !options.nodebug) { - - cdbSymbol(sym,cdbFile,FALSE,FALSE); - - if (!sym->level) { /* global */ - if (IS_STATIC(sym->etype)) - fprintf(afile,"F%s$",moduleName); /* scope is file */ - else - fprintf(afile,"G$"); /* scope is global */ - } - else - /* symbol is local */ - fprintf(afile,"L%s$", - (sym->localof ? sym->localof->name : "-null-")); - fprintf(afile,"%s$%d$%d",sym->name,sym->level,sym->block); - } - - /* if is has an absolute address then generate - an equate for this no need to allocate space */ - if (SPEC_ABSA (sym->etype)) { - - if ((options.debug || sym->level == 0) && !options.nodebug) - fprintf (afile," == 0x%04x\n",SPEC_ADDR (sym->etype)); - - fprintf (afile, "%s\t=\t0x%04x\n", - sym->rname, - SPEC_ADDR (sym->etype)); - } - else { - if ((options.debug || sym->level == 0) && !options.nodebug) - fprintf(afile,"==.\n"); - - /* allocate space */ - tfprintf(afile, "!labeldef\n", sym->rname); - tfprintf(afile, "\t!ds\n", (unsigned int)getSize (sym->type) & 0xffff); - } + /* for each of the sets in the overlay segment do */ + for (ovrset = setFirstItem (ovrSetSets); ovrset; + ovrset = setNextItem (ovrSetSets)) + { - } + symbol *sym; + + if (elementsInSet (ovrset)) + { + /* this dummy area is used to fool the assembler + otherwise the assembler will append each of these + declarations into one chunk and will not overlay + sad but true */ + fprintf (afile, "\t.area _DUMMY\n"); + /* output the area informtion */ + fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */ + } + + for (sym = setFirstItem (ovrset); sym; + sym = setNextItem (ovrset)) + { + + /* if extern then add it to the publics tabledo nothing */ + if (IS_EXTERN (sym->etype)) + continue; + + /* if allocation required check is needed + then check if the symbol really requires + allocation only for local variables */ + if (!IS_AGGREGATE (sym->type) && + !(sym->_isparm && !IS_REGPARM (sym->etype)) + && !sym->allocreq && sym->level) + continue; + + /* if global variable & not static or extern + and addPublics allowed then add it to the public set */ + if ((sym->_isparm && !IS_REGPARM (sym->etype)) + && !IS_STATIC (sym->etype)) + addSetHead (&publics, sym); + + /* if extern then do nothing or is a function + then do nothing */ + if (IS_FUNC (sym->type)) + continue; + + /* print extra debug info if required */ + if ((options.debug || sym->level == 0) && !options.nodebug) + { + + cdbSymbol (sym, cdbFile, FALSE, FALSE); + + if (!sym->level) + { /* global */ + if (IS_STATIC (sym->etype)) + fprintf (afile, "F%s$", moduleName); /* scope is file */ + else + fprintf (afile, "G$"); /* scope is global */ + } + else + /* symbol is local */ + fprintf (afile, "L%s$", + (sym->localof ? sym->localof->name : "-null-")); + fprintf (afile, "%s$%d$%d", sym->name, sym->level, sym->block); + } + + /* if is has an absolute address then generate + an equate for this no need to allocate space */ + if (SPEC_ABSA (sym->etype)) + { + + if ((options.debug || sym->level == 0) && !options.nodebug) + fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype)); + + fprintf (afile, "%s\t=\t0x%04x\n", + sym->rname, + SPEC_ADDR (sym->etype)); + } + else + { + if ((options.debug || sym->level == 0) && !options.nodebug) + fprintf (afile, "==.\n"); + + /* allocate space */ + tfprintf (afile, "!labeldef\n", sym->rname); + tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff); + } + + } } } /*-----------------------------------------------------------------*/ /* glue - the final glue that hold the whole thing together */ /*-----------------------------------------------------------------*/ -void glue () +void +glue () { - FILE *vFile; - FILE *asmFile; - FILE *ovrFile = tempfile(); - - addSetHead(&tmpfileSet,ovrFile); - /* print the global struct definitions */ - if (options.debug && !options.nodebug) - cdbStructBlock (0,cdbFile); - - vFile = tempfile(); - /* PENDING: this isnt the best place but it will do */ - if (port->general.glue_up_main) { - /* create the interrupt vector table */ - createInterruptVect (vFile); + FILE *vFile; + FILE *asmFile; + FILE *ovrFile = tempfile (); + + addSetHead (&tmpfileSet, ovrFile); + /* print the global struct definitions */ + if (options.debug && !options.nodebug) + cdbStructBlock (0, cdbFile); + + vFile = tempfile (); + /* PENDING: this isnt the best place but it will do */ + if (port->general.glue_up_main) + { + /* create the interrupt vector table */ + createInterruptVect (vFile); } - addSetHead(&tmpfileSet,vFile); + addSetHead (&tmpfileSet, vFile); - /* emit code for the all the variables declared */ - emitMaps (); - /* do the overlay segments */ - emitOverlay(ovrFile); + /* emit code for the all the variables declared */ + emitMaps (); + /* do the overlay segments */ + emitOverlay (ovrFile); - /* now put it all together into the assembler file */ - /* create the assembler file name */ + /* now put it all together into the assembler file */ + /* create the assembler file name */ - if (!options.c1mode) { - sprintf (buffer, srcFileName); - strcat (buffer, ".asm"); + if (!options.c1mode) + { + sprintf (buffer, srcFileName); + strcat (buffer, ".asm"); } - else { - strcpy(buffer, options.out_name); + else + { + strcpy (buffer, options.out_name); } - if (!(asmFile = fopen (buffer, "w"))) { - werror (E_FILE_OPEN_ERR, buffer); - exit (1); + if (!(asmFile = fopen (buffer, "w"))) + { + werror (E_FILE_OPEN_ERR, buffer); + exit (1); } - /* initial comments */ - initialComments (asmFile); + /* initial comments */ + initialComments (asmFile); - /* print module name */ - tfprintf(asmFile, "\t!module\n", moduleName); - tfprintf(asmFile, "\t!fileprelude\n"); + /* print module name */ + tfprintf (asmFile, "\t!module\n", moduleName); + tfprintf (asmFile, "\t!fileprelude\n"); - /* Let the port generate any global directives, etc. */ - if (port->genAssemblerPreamble) + /* Let the port generate any global directives, etc. */ + if (port->genAssemblerPreamble) { - port->genAssemblerPreamble(asmFile); + port->genAssemblerPreamble (asmFile); } - /* print the global variables in this module */ - printPublics (asmFile); - if (port->assembler.externGlobal) - printExterns (asmFile); - - /* copy the sfr segment */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; special function registers\n"); - fprintf (asmFile, "%s", iComments2); - copyFile (asmFile, sfr->oFile); - - /* copy the sbit segment */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; special function bits \n"); - fprintf (asmFile, "%s", iComments2); - copyFile (asmFile, sfrbit->oFile); - - /* copy the data segment */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; internal ram data\n"); - fprintf (asmFile, "%s", iComments2); - copyFile (asmFile, data->oFile); - - - /* create the overlay segments */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; overlayable items in internal ram \n"); - fprintf (asmFile, "%s", iComments2); - copyFile (asmFile, ovrFile); - - /* create the stack segment MOF */ - if (mainf && mainf->fbody) { + /* print the global variables in this module */ + printPublics (asmFile); + if (port->assembler.externGlobal) + printExterns (asmFile); + + /* copy the sfr segment */ fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; Stack segment in internal ram \n"); + fprintf (asmFile, "; special function registers\n"); fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n" - "__start__stack:\n\t.ds\t1\n\n"); - } + copyFile (asmFile, sfr->oFile); - /* create the idata segment */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; indirectly addressable internal ram data\n"); - fprintf (asmFile, "%s", iComments2); - copyFile (asmFile, idata->oFile); + /* copy the sbit segment */ + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; special function bits \n"); + fprintf (asmFile, "%s", iComments2); + copyFile (asmFile, sfrbit->oFile); - /* copy the bit segment */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; bit data\n"); - fprintf (asmFile, "%s", iComments2); - copyFile (asmFile, bit->oFile); + /* copy the data segment */ + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; internal ram data\n"); + fprintf (asmFile, "%s", iComments2); + copyFile (asmFile, data->oFile); - /* if external stack then reserve space of it */ - if (mainf && mainf->fbody && options.useXstack ) { + + /* create the overlay segments */ fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; external stack \n"); + fprintf (asmFile, "; overlayable items in internal ram \n"); fprintf (asmFile, "%s", iComments2); - fprintf (asmFile,"\t.area XSEG (XDATA)\n"); /* MOF */ - fprintf (asmFile,"\t.ds 256\n"); + copyFile (asmFile, ovrFile); + + /* create the stack segment MOF */ + if (mainf && mainf->fbody) + { + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; Stack segment in internal ram \n"); + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n" + "__start__stack:\n\t.ds\t1\n\n"); } + /* create the idata segment */ + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; indirectly addressable internal ram data\n"); + fprintf (asmFile, "%s", iComments2); + copyFile (asmFile, idata->oFile); + + /* copy the bit segment */ + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; bit data\n"); + fprintf (asmFile, "%s", iComments2); + copyFile (asmFile, bit->oFile); + + /* if external stack then reserve space of it */ + if (mainf && mainf->fbody && options.useXstack) + { + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; external stack \n"); + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "\t.area XSEG (XDATA)\n"); /* MOF */ + fprintf (asmFile, "\t.ds 256\n"); + } - /* copy xtern ram data */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; external ram data\n"); - fprintf (asmFile, "%s", iComments2); - copyFile (asmFile, xdata->oFile); - /* copy the interrupt vector table */ - if (mainf && mainf->fbody) { + /* copy xtern ram data */ fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; interrupt vector \n"); + fprintf (asmFile, "; external ram data\n"); fprintf (asmFile, "%s", iComments2); - copyFile (asmFile, vFile); + copyFile (asmFile, xdata->oFile); + + /* copy the interrupt vector table */ + if (mainf && mainf->fbody) + { + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; interrupt vector \n"); + fprintf (asmFile, "%s", iComments2); + copyFile (asmFile, vFile); } - /* copy global & static initialisations */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; global & static initialisations\n"); - fprintf (asmFile, "%s", iComments2); - - /* Everywhere we generate a reference to the static_name area, - * (which is currently only here), we immediately follow it with a - * definition of the post_static_name area. This guarantees that - * the post_static_name area will immediately follow the static_name - * area. - */ - tfprintf(asmFile, "\t!area\n", port->mem.static_name); /* MOF */ - tfprintf(asmFile, "\t!area\n", port->mem.post_static_name); - tfprintf(asmFile, "\t!area\n", port->mem.static_name); - - if (mainf && mainf->fbody) { - fprintf (asmFile,"__sdcc_gsinit_startup:\n"); - /* if external stack is specified then the - higher order byte of the xdatalocation is - going into P2 and the lower order going into - spx */ - if (options.useXstack) { - fprintf(asmFile,"\tmov\tP2,#0x%02x\n", - (((unsigned int)options.xdata_loc) >> 8) & 0xff); - fprintf(asmFile,"\tmov\t_spx,#0x%02x\n", - (unsigned int)options.xdata_loc & 0xff); - } - - /* initialise the stack pointer */ - /* if the user specified a value then use it */ - if (options.stack_loc) - fprintf(asmFile,"\tmov\tsp,#%d\n",options.stack_loc); - else - /* no: we have to compute it */ + /* copy global & static initialisations */ + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; global & static initialisations\n"); + fprintf (asmFile, "%s", iComments2); + + /* Everywhere we generate a reference to the static_name area, + * (which is currently only here), we immediately follow it with a + * definition of the post_static_name area. This guarantees that + * the post_static_name area will immediately follow the static_name + * area. + */ + tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */ + tfprintf (asmFile, "\t!area\n", port->mem.post_static_name); + tfprintf (asmFile, "\t!area\n", port->mem.static_name); + + if (mainf && mainf->fbody) + { + fprintf (asmFile, "__sdcc_gsinit_startup:\n"); + /* if external stack is specified then the + higher order byte of the xdatalocation is + going into P2 and the lower order going into + spx */ + if (options.useXstack) + { + fprintf (asmFile, "\tmov\tP2,#0x%02x\n", + (((unsigned int) options.xdata_loc) >> 8) & 0xff); + fprintf (asmFile, "\tmov\t_spx,#0x%02x\n", + (unsigned int) options.xdata_loc & 0xff); + } + + /* initialise the stack pointer */ + /* if the user specified a value then use it */ + if (options.stack_loc) + fprintf (asmFile, "\tmov\tsp,#%d\n", options.stack_loc); + else + /* no: we have to compute it */ if (!options.stackOnData && maxRegBank <= 3) - fprintf(asmFile,"\tmov\tsp,#%d\n",((maxRegBank + 1) * 8) -1); + fprintf (asmFile, "\tmov\tsp,#%d\n", ((maxRegBank + 1) * 8) - 1); else - fprintf(asmFile,"\tmov\tsp,#__start__stack\n"); /* MOF */ + fprintf (asmFile, "\tmov\tsp,#__start__stack\n"); /* MOF */ - fprintf (asmFile,"\tlcall\t__sdcc_external_startup\n"); - fprintf (asmFile,"\tmov\ta,dpl\n"); - fprintf (asmFile,"\tjz\t__sdcc_init_data\n"); - fprintf (asmFile,"\tljmp\t__sdcc_program_startup\n"); - fprintf (asmFile,"__sdcc_init_data:\n"); + fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n"); + fprintf (asmFile, "\tmov\ta,dpl\n"); + fprintf (asmFile, "\tjz\t__sdcc_init_data\n"); + fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n"); + fprintf (asmFile, "__sdcc_init_data:\n"); } - copyFile (asmFile, statsg->oFile); + copyFile (asmFile, statsg->oFile); - if (port->general.glue_up_main && mainf && mainf->fbody) + if (port->general.glue_up_main && mainf && mainf->fbody) { - /* This code is generated in the post-static area. - * This area is guaranteed to follow the static area - * by the ugly shucking and jiving about 20 lines ago. - */ - tfprintf(asmFile, "\t!area\n", port->mem.post_static_name); - fprintf (asmFile,"\tljmp\t__sdcc_program_startup\n"); + /* This code is generated in the post-static area. + * This area is guaranteed to follow the static area + * by the ugly shucking and jiving about 20 lines ago. + */ + tfprintf (asmFile, "\t!area\n", port->mem.post_static_name); + fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n"); } - fprintf (asmFile, - "%s" - "; Home\n" - "%s", iComments2, iComments2); - tfprintf(asmFile, "\t!areahome\n", HOME_NAME); - copyFile (asmFile, home->oFile); + fprintf (asmFile, + "%s" + "; Home\n" + "%s", iComments2, iComments2); + tfprintf (asmFile, "\t!areahome\n", HOME_NAME); + copyFile (asmFile, home->oFile); - /* copy over code */ - fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "; code\n"); - fprintf (asmFile, "%s", iComments2); - tfprintf(asmFile, "\t!areacode\n", CODE_NAME); - if (mainf && mainf->fbody) { + /* copy over code */ + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; code\n"); + fprintf (asmFile, "%s", iComments2); + tfprintf (asmFile, "\t!areacode\n", CODE_NAME); + if (mainf && mainf->fbody) + { - /* entry point @ start of CSEG */ - fprintf (asmFile,"__sdcc_program_startup:\n"); + /* entry point @ start of CSEG */ + fprintf (asmFile, "__sdcc_program_startup:\n"); - /* put in the call to main */ - fprintf(asmFile,"\tlcall\t_main\n"); - if (options.mainreturn) { + /* put in the call to main */ + fprintf (asmFile, "\tlcall\t_main\n"); + if (options.mainreturn) + { - fprintf(asmFile,";\treturn from main ; will return to caller\n"); - fprintf(asmFile,"\tret\n"); + fprintf (asmFile, ";\treturn from main ; will return to caller\n"); + fprintf (asmFile, "\tret\n"); - } else { + } + else + { - fprintf(asmFile,";\treturn from main will lock up\n"); - fprintf(asmFile,"\tsjmp .\n"); - } + fprintf (asmFile, ";\treturn from main will lock up\n"); + fprintf (asmFile, "\tsjmp .\n"); + } } - copyFile (asmFile, code->oFile); + copyFile (asmFile, code->oFile); - fclose (asmFile); - applyToSet(tmpfileSet,closeTmpFiles); - applyToSet(tmpfileNameSet, rmTmpFiles); + fclose (asmFile); + applyToSet (tmpfileSet, closeTmpFiles); + applyToSet (tmpfileNameSet, rmTmpFiles); } /** Creates a temporary file a'la tmpfile which avoids the bugs in cygwin wrt c:\tmp. Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile(). */ -FILE *tempfile(void) +FILE * +tempfile (void) { #if !defined(_MSC_VER) - const char *tmpdir = NULL; - if (getenv("TMP")) - tmpdir = getenv("TMP"); - else if (getenv("TEMP")) - tmpdir = getenv("TEMP"); - else if (getenv("TMPDIR")) - tmpdir = getenv("TMPDIR"); - if (tmpdir) { - char *name = tempnam(tmpdir, "sdcc"); - if (name) { - FILE *fp = fopen(name, "w+b"); - if (fp) - { - addSetHead(&tmpfileNameSet, name); - } - return fp; - } - return NULL; + const char *tmpdir = NULL; + if (getenv ("TMP")) + tmpdir = getenv ("TMP"); + else if (getenv ("TEMP")) + tmpdir = getenv ("TEMP"); + else if (getenv ("TMPDIR")) + tmpdir = getenv ("TMPDIR"); + if (tmpdir) + { + char *name = tempnam (tmpdir, "sdcc"); + if (name) + { + FILE *fp = fopen (name, "w+b"); + if (fp) + { + addSetHead (&tmpfileNameSet, name); + } + return fp; + } + return NULL; } #endif - return tmpfile(); + return tmpfile (); } -char *gc_strdup(const char *s) +char * +gc_strdup (const char *s) { - char *ret; - ret = Safe_calloc(1,strlen(s)+1); - strcpy(ret, s); - return ret; + char *ret; + ret = Safe_calloc (1, strlen (s) + 1); + strcpy (ret, s); + return ret; } diff --git a/src/SDCCglue.h b/src/SDCCglue.h index 65c83be9..3d9683e7 100644 --- a/src/SDCCglue.h +++ b/src/SDCCglue.h @@ -27,11 +27,11 @@ #ifndef SDCCGLUE_H #define SDCCGLUE_H 1 -void glue(); +void glue (); /* drdani Jan 30 2000 - This is needed in gen.c of z80 port */ + This is needed in gen.c of z80 port */ char *aopLiteral (value *, int); -void flushStatics(void); +void flushStatics (void); extern symbol *interrupts[]; extern set *publics; diff --git a/src/SDCChasht.c b/src/SDCChasht.c index 80c3864a..69d1f250 100644 --- a/src/SDCChasht.c +++ b/src/SDCChasht.c @@ -35,128 +35,141 @@ /*-----------------------------------------------------------------*/ /* newHashtItem - creates a new hashtable Item */ /*-----------------------------------------------------------------*/ -static hashtItem *_newHashtItem (int key, void *pkey, void *item) +static hashtItem * +_newHashtItem (int key, void *pkey, void *item) { - hashtItem *htip; + hashtItem *htip; - htip = Safe_calloc(1,sizeof(hashtItem)); + htip = Safe_calloc (1, sizeof (hashtItem)); - htip->key = key ; - htip->pkey = pkey; - htip->item = item; - htip->next = NULL ; - return htip; + htip->key = key; + htip->pkey = pkey; + htip->item = item; + htip->next = NULL; + return htip; } /*-----------------------------------------------------------------*/ /* newHashTable - allocates a new hashtable of size */ /*-----------------------------------------------------------------*/ -hTab *newHashTable (int size) +hTab * +newHashTable (int size) { - hTab *htab; + hTab *htab; - htab = Safe_calloc(1,sizeof(hTab)); + htab = Safe_calloc (1, sizeof (hTab)); - if (!(htab->table = calloc((size +1), sizeof(hashtItem *)))) { - fprintf(stderr,"out of virtual memory %s %d\n", - __FILE__,(size +1)* sizeof(hashtItem *)); - exit(1); + if (!(htab->table = calloc ((size + 1), sizeof (hashtItem *)))) + { + fprintf (stderr, "out of virtual memory %s %d\n", + __FILE__, (size + 1) * sizeof (hashtItem *)); + exit (1); } - htab->minKey = htab->size = size ; - return htab; + htab->minKey = htab->size = size; + return htab; } -void hTabAddItemLong(hTab **htab, int key, void *pkey, void *item) +void +hTabAddItemLong (hTab ** htab, int key, void *pkey, void *item) { - hashtItem *htip ; - hashtItem *last ; - - if (!(*htab) ) - *htab = newHashTable ( DEFAULT_HTAB_SIZE ); - - if (key > (*htab)->size ) { - int i; - (*htab)->table = Safe_realloc ((*htab)->table, - (key*2 + 2)*sizeof(hashtItem *)); - for ( i = (*htab)->size +1; i <= (key*2 + 1); i++ ) - (*htab)->table[i] = NULL ; - (*htab)->size = key*2 + 1; + hashtItem *htip; + hashtItem *last; + + if (!(*htab)) + *htab = newHashTable (DEFAULT_HTAB_SIZE); + + if (key > (*htab)->size) + { + int i; + (*htab)->table = Safe_realloc ((*htab)->table, + (key * 2 + 2) * sizeof (hashtItem *)); + for (i = (*htab)->size + 1; i <= (key * 2 + 1); i++) + (*htab)->table[i] = NULL; + (*htab)->size = key * 2 + 1; } - /* update the key */ - if ((*htab)->maxKey < key ) - (*htab)->maxKey = key ; - - if ((*htab)->minKey > key ) - (*htab)->minKey = key ; - - /* create the item */ - htip = _newHashtItem(key, pkey, item); - - /* if there is a clash then goto end of chain */ - if ((last = (*htab)->table[key])) { - while (last->next) - last = last->next ; - last->next = htip ; - } else - /* else just add it */ - (*htab)->table[key] = htip ; - (*htab)->nItems++ ; + /* update the key */ + if ((*htab)->maxKey < key) + (*htab)->maxKey = key; + + if ((*htab)->minKey > key) + (*htab)->minKey = key; + + /* create the item */ + htip = _newHashtItem (key, pkey, item); + + /* if there is a clash then goto end of chain */ + if ((last = (*htab)->table[key])) + { + while (last->next) + last = last->next; + last->next = htip; + } + else + /* else just add it */ + (*htab)->table[key] = htip; + (*htab)->nItems++; } /*-----------------------------------------------------------------*/ /* hTabAddItem - adds an item to the hash table */ /*-----------------------------------------------------------------*/ -void hTabAddItem (hTab **htab, int key, void *item ) +void +hTabAddItem (hTab ** htab, int key, void *item) { - hTabAddItemLong(htab, key, NULL, item); + hTabAddItemLong (htab, key, NULL, item); } /*-----------------------------------------------------------------*/ /* hTabDeleteItem - either delete an item */ /*-----------------------------------------------------------------*/ -void hTabDeleteItem (hTab **htab, int key , - const void *item, DELETE_ACTION action, - int (*compareFunc)(const void *, const void *)) +void +hTabDeleteItem (hTab ** htab, int key, + const void *item, DELETE_ACTION action, + int (*compareFunc) (const void *, const void *)) { - hashtItem *htip, **htipp ; + hashtItem *htip, **htipp; - if (!(*htab)) - return ; + if (!(*htab)) + return; - /* first check if anything exists in the slot */ - if (! (*htab)->table[key] ) - return ; + /* first check if anything exists in the slot */ + if (!(*htab)->table[key]) + return; - /* if delete chain */ - if ( action == DELETE_CHAIN ) - (*htab)->table[key] = NULL ; - else { + /* if delete chain */ + if (action == DELETE_CHAIN) + (*htab)->table[key] = NULL; + else + { - /* delete specific item */ - /* if a compare function is given then use the compare */ - /* function to find the item, else just compare the items */ + /* delete specific item */ + /* if a compare function is given then use the compare */ + /* function to find the item, else just compare the items */ - htipp = &((*htab)->table[key]); - htip = (*htab)->table[key]; - for (; htip; htip = htip->next) { + htipp = &((*htab)->table[key]); + htip = (*htab)->table[key]; + for (; htip; htip = htip->next) + { - if (compareFunc ? compareFunc(item,htip->item) : - (item == htip->item) ) { - *htipp=htip->next; - break; - } + if (compareFunc ? compareFunc (item, htip->item) : + (item == htip->item)) + { + *htipp = htip->next; + break; + } - htipp=&(htip->next); - } + htipp = &(htip->next); + } } - (*htab)->nItems-- ; + (*htab)->nItems--; - if (!(*htab)->nItems) { - *htab = NULL; + if (!(*htab)->nItems) + { + *htab = NULL; } } @@ -165,313 +178,350 @@ void hTabDeleteItem (hTab **htab, int key , /* leaks written by */ /* "BESSIERE Jerome" */ /*-----------------------------------------------------------------*/ -void hTabDeleteAll(hTab * p) +void +hTabDeleteAll (hTab * p) { - if (p && p->table) { - register int i; - register hashtItem *jc,*jn; - for (i=0;isize;i++) { - - if (!(jc = p->table[i])) continue; - jn = jc->next; - while(jc){ - free(jc); - if((jc=jn)) jn = jc->next; - } - p->table[i] = NULL ; - } - free(p->table); + if (p && p->table) + { + register int i; + register hashtItem *jc, *jn; + for (i = 0; i < p->size; i++) + { + + if (!(jc = p->table[i])) + continue; + jn = jc->next; + while (jc) + { + free (jc); + if ((jc = jn)) + jn = jc->next; + } + p->table[i] = NULL; + } + free (p->table); } } /*-----------------------------------------------------------------*/ /* hTabClearAll - clear all entries in the table (does not free) */ /*-----------------------------------------------------------------*/ -void hTabClearAll (hTab *htab) +void +hTabClearAll (hTab * htab) { - if (!htab || !htab->table) { - printf("null table\n"); - return ; + if (!htab || !htab->table) + { + printf ("null table\n"); + return; } - memset(htab->table, 0, htab->size*sizeof(hashtItem *)); + memset (htab->table, 0, htab->size * sizeof (hashtItem *)); - htab->minKey = htab->size; - htab->currKey = htab->nItems = htab->maxKey = 0; + htab->minKey = htab->size; + htab->currKey = htab->nItems = htab->maxKey = 0; } -static const hashtItem *_findItem(hTab *htab, int key, void *item, int (*compareFunc)(void *, void *)) +static const hashtItem * +_findItem (hTab * htab, int key, void *item, int (*compareFunc) (void *, void *)) { - hashtItem *htip; - - for (htip = htab->table[key] ; htip ; htip = htip->next ) { - /* if a compare function is given use it */ - if (compareFunc && compareFunc(item,htip->item)) - break; - else - if (item == htip->item) - break; + hashtItem *htip; + + for (htip = htab->table[key]; htip; htip = htip->next) + { + /* if a compare function is given use it */ + if (compareFunc && compareFunc (item, htip->item)) + break; + else if (item == htip->item) + break; } - return htip; + return htip; } -static const hashtItem *_findByKey(hTab *htab, int key, const void *pkey, int (*compare)(const void *, const void *)) +static const hashtItem * +_findByKey (hTab * htab, int key, const void *pkey, int (*compare) (const void *, const void *)) { - hashtItem *htip; + hashtItem *htip; - assert(compare); + assert (compare); - if (!htab) - return NULL; + if (!htab) + return NULL; - for (htip = htab->table[key] ; htip ; htip = htip->next) { - /* if a compare function is given use it */ - if (compare && compare(pkey, htip->pkey)) { - break; - } - else { - if (pkey == htip->pkey) { - break; - } - } + for (htip = htab->table[key]; htip; htip = htip->next) + { + /* if a compare function is given use it */ + if (compare && compare (pkey, htip->pkey)) + { + break; + } + else + { + if (pkey == htip->pkey) + { + break; + } + } } - return htip; + return htip; } -void *hTabFindByKey(hTab *h, int key, const void *pkey, int (*compare)(const void *, const void *)) +void * +hTabFindByKey (hTab * h, int key, const void *pkey, int (*compare) (const void *, const void *)) { - const hashtItem *item; + const hashtItem *item; - if ((item = _findByKey(h, key, pkey, compare))) - return item->item; - return NULL; + if ((item = _findByKey (h, key, pkey, compare))) + return item->item; + return NULL; } -int hTabDeleteByKey(hTab **h, int key, const void *pkey, int (*compare)(const void *, const void *)) +int +hTabDeleteByKey (hTab ** h, int key, const void *pkey, int (*compare) (const void *, const void *)) { - hashtItem *htip, **htipp ; - - if (!(*h)) - return 0; - - /* first check if anything exists in the slot */ - if (! (*h)->table[key] ) - return 0; - - /* delete specific item */ - /* if a compare function is given then use the compare */ - /* function to find the item, else just compare the items */ - - htipp = &((*h)->table[key]); - htip = (*h)->table[key]; - for (; htip; htip = htip->next) { - if ( - (compare && compare(pkey, htip->pkey)) || - pkey == htip->pkey) { - *htipp=htip->next; - break; - } - htipp=&(htip->next); + hashtItem *htip, **htipp; + + if (!(*h)) + return 0; + + /* first check if anything exists in the slot */ + if (!(*h)->table[key]) + return 0; + + /* delete specific item */ + /* if a compare function is given then use the compare */ + /* function to find the item, else just compare the items */ + + htipp = &((*h)->table[key]); + htip = (*h)->table[key]; + for (; htip; htip = htip->next) + { + if ( + (compare && compare (pkey, htip->pkey)) || + pkey == htip->pkey) + { + *htipp = htip->next; + break; + } + htipp = &(htip->next); } - (*h)->nItems-- ; + (*h)->nItems--; - if (!(*h)->nItems) { - *h = NULL; + if (!(*h)->nItems) + { + *h = NULL; } - return 1; + return 1; } /*-----------------------------------------------------------------*/ /* hTabIsInTable - will determine if an Item is in the hasht */ /*-----------------------------------------------------------------*/ -int hTabIsInTable (hTab *htab, int key, - void *item , int (*compareFunc)(void *,void *)) +int +hTabIsInTable (hTab * htab, int key, + void *item, int (*compareFunc) (void *, void *)) { - if (_findItem(htab, key, item, compareFunc)) - return 1; - return 0; + if (_findItem (htab, key, item, compareFunc)) + return 1; + return 0; } /*-----------------------------------------------------------------*/ /* hTabFirstItem - returns the first Item in the hTab */ /*-----------------------------------------------------------------*/ -void *hTabFirstItem (hTab *htab, int *k) +void * +hTabFirstItem (hTab * htab, int *k) { - int key ; - - if (!htab) - return NULL ; - - for ( key = htab->minKey ; key <= htab->maxKey ; key++ ) { - if (htab->table[key]) { - htab->currItem = htab->table[key]; - htab->currKey = key ; - *k = key ; - return htab->table[key]->item; - } + int key; + + if (!htab) + return NULL; + + for (key = htab->minKey; key <= htab->maxKey; key++) + { + if (htab->table[key]) + { + htab->currItem = htab->table[key]; + htab->currKey = key; + *k = key; + return htab->table[key]->item; + } } - return NULL ; + return NULL; } /*-----------------------------------------------------------------*/ /* hTabNextItem - returns the next item in the hTab */ /*-----------------------------------------------------------------*/ -void *hTabNextItem (hTab *htab, int *k) +void * +hTabNextItem (hTab * htab, int *k) { - int key ; + int key; - if (!htab) - return NULL; + if (!htab) + return NULL; - /* if this chain not ended then */ - if (htab->currItem->next) { - *k = htab->currItem->key ; - return (htab->currItem = htab->currItem->next)->item ; + /* if this chain not ended then */ + if (htab->currItem->next) + { + *k = htab->currItem->key; + return (htab->currItem = htab->currItem->next)->item; } - /* find the next chain which has something */ - for ( key = htab->currKey + 1; key <= htab->maxKey ; key++ ) { - if (htab->table[key]) { - htab->currItem = htab->table[key]; - *k = htab->currKey = key ; - return htab->table[key]->item; - } + /* find the next chain which has something */ + for (key = htab->currKey + 1; key <= htab->maxKey; key++) + { + if (htab->table[key]) + { + htab->currItem = htab->table[key]; + *k = htab->currKey = key; + return htab->table[key]->item; + } } - return NULL ; + return NULL; } /*-----------------------------------------------------------------*/ /* hTabFirstItemWK - returns the first Item in the hTab for a key */ /*-----------------------------------------------------------------*/ -void *hTabFirstItemWK (hTab *htab, int wk) +void * +hTabFirstItemWK (hTab * htab, int wk) { - if (!htab) - return NULL ; + if (!htab) + return NULL; - if (wk < htab->minKey || wk > htab->maxKey ) - return NULL; + if (wk < htab->minKey || wk > htab->maxKey) + return NULL; - htab->currItem = htab->table[wk] ; - htab->currKey = wk ; + htab->currItem = htab->table[wk]; + htab->currKey = wk; - return (htab->table[wk] ? htab->table[wk]->item : NULL); + return (htab->table[wk] ? htab->table[wk]->item : NULL); } /*-----------------------------------------------------------------*/ /* hTabNextItem - returns the next item in the hTab for a key */ /*-----------------------------------------------------------------*/ -void *hTabNextItemWK (hTab *htab ) +void * +hTabNextItemWK (hTab * htab) { - if (!htab) - return NULL; + if (!htab) + return NULL; - /* if this chain not ended then */ - if (htab->currItem->next) { - return (htab->currItem = htab->currItem->next)->item ; + /* if this chain not ended then */ + if (htab->currItem->next) + { + return (htab->currItem = htab->currItem->next)->item; } - return NULL ; + return NULL; } /*-----------------------------------------------------------------*/ /* hTabFromTable - hash Table from a hash table */ /*-----------------------------------------------------------------*/ -hTab *hTabFromTable (hTab *htab) +hTab * +hTabFromTable (hTab * htab) { - hTab *nhtab ; - hashtItem *htip; - int key ; + hTab *nhtab; + hashtItem *htip; + int key; - if (!htab) - return NULL ; + if (!htab) + return NULL; - nhtab = newHashTable(htab->size); + nhtab = newHashTable (htab->size); - for (key = htab->minKey; key <= htab->maxKey ; key++ ) { + for (key = htab->minKey; key <= htab->maxKey; key++) + { - for (htip = htab->table[key] ; htip ; htip = htip->next) - hTabAddItem (&nhtab, htip->key, htip->item); + for (htip = htab->table[key]; htip; htip = htip->next) + hTabAddItem (&nhtab, htip->key, htip->item); } - return nhtab ; + return nhtab; } /*-----------------------------------------------------------------*/ -/* isHtabsEqual - returns 1 if all items in htab1 is found in htab2*/ +/* isHtabsEqual - returns 1 if all items in htab1 is found in htab2 */ /*-----------------------------------------------------------------*/ -int isHtabsEqual (hTab *htab1, hTab *htab2, - int (*compareFunc)(void *,void *)) +int +isHtabsEqual (hTab * htab1, hTab * htab2, + int (*compareFunc) (void *, void *)) { - void *item; - int key; + void *item; + int key; - if ( htab1 == htab2 ) - return 1; + if (htab1 == htab2) + return 1; - if (htab1 == NULL || htab2 == NULL ) - return 0; + if (htab1 == NULL || htab2 == NULL) + return 0; - /* if they are different sizes then */ - if ( htab1->nItems != htab2->nItems) - return 0; + /* if they are different sizes then */ + if (htab1->nItems != htab2->nItems) + return 0; - /* now do an item by item check */ - for ( item = hTabFirstItem (htab1,&key) ;item; - item = hTabNextItem (htab1,&key)) - if (!hTabIsInTable (htab2, key, item, compareFunc)) + /* now do an item by item check */ + for (item = hTabFirstItem (htab1, &key); item; + item = hTabNextItem (htab1, &key)) + if (!hTabIsInTable (htab2, key, item, compareFunc)) return 0; - return 1; + return 1; } /*-----------------------------------------------------------------*/ /* hTabSearch - returns the first Item with the specified key */ /*-----------------------------------------------------------------*/ -hashtItem *hTabSearch (hTab *htab, int key ) +hashtItem * +hTabSearch (hTab * htab, int key) { - if (!htab) - return NULL ; + if (!htab) + return NULL; - if ((key < htab->minKey)||(key>htab->maxKey)) - return NULL ; + if ((key < htab->minKey) || (key > htab->maxKey)) + return NULL; - if (!htab->table[key]) - return NULL ; + if (!htab->table[key]) + return NULL; - return htab->table[key] ; + return htab->table[key]; } /*-----------------------------------------------------------------*/ /* hTabItemWithKey - returns the first item with the given key */ /*-----------------------------------------------------------------*/ -void *hTabItemWithKey (hTab *htab, int key ) +void * +hTabItemWithKey (hTab * htab, int key) { - hashtItem *htip; + hashtItem *htip; - if (!(htip = hTabSearch(htab,key))) - return NULL; + if (!(htip = hTabSearch (htab, key))) + return NULL; - return htip->item; + return htip->item; } /*-----------------------------------------------------------------*/ /*hTabAddItemIfNotP - adds an item with nothing found with key */ /*-----------------------------------------------------------------*/ -void hTabAddItemIfNotP (hTab **htab, int key, void *item) +void +hTabAddItemIfNotP (hTab ** htab, int key, void *item) { - if (!*htab) { - hTabAddItem (htab,key,item); - return; + if (!*htab) + { + hTabAddItem (htab, key, item); + return; } - if (hTabItemWithKey(*htab,key)) - return ; + if (hTabItemWithKey (*htab, key)) + return; - hTabAddItem(htab,key,item); + hTabAddItem (htab, key, item); } /** Simple implementation of a hash table which uses @@ -480,28 +530,32 @@ void hTabAddItemIfNotP (hTab **htab, int key, void *item) This is used for the assembler token table. The replace existing condition is used to implement inheritance. */ -static int _compare(const void *s1, const void *s2) +static int +_compare (const void *s1, const void *s2) { - return !strcmp(s1, s2); + return !strcmp (s1, s2); } -static int _hash(const char *sz) +static int +_hash (const char *sz) { - /* Dumb for now */ - return *sz; + /* Dumb for now */ + return *sz; } -void shash_add(hTab **h, const char *szKey, const char *szValue) +void +shash_add (hTab ** h, const char *szKey, const char *szValue) { - int key = _hash(szKey); - /* First, delete any that currently exist */ - hTabDeleteByKey(h, key, szKey, _compare); - /* Now add in ours */ - hTabAddItemLong(h, key, gc_strdup(szKey), gc_strdup(szValue)); + int key = _hash (szKey); + /* First, delete any that currently exist */ + hTabDeleteByKey (h, key, szKey, _compare); + /* Now add in ours */ + hTabAddItemLong (h, key, gc_strdup (szKey), gc_strdup (szValue)); } -const char *shash_find(hTab *h, const char *szKey) +const char * +shash_find (hTab * h, const char *szKey) { - int key = _hash(szKey); - return (char *)hTabFindByKey(h, key, szKey, _compare); + int key = _hash (szKey); + return (char *) hTabFindByKey (h, key, szKey, _compare); } diff --git a/src/SDCChasht.h b/src/SDCChasht.h index 94223688..4afcabec 100644 --- a/src/SDCChasht.h +++ b/src/SDCChasht.h @@ -30,40 +30,44 @@ /* hashtable item */ typedef struct hashtItem -{ + { int key; /* Pointer to the key that was hashed for key. Used for a hash table with unique keys. */ void *pkey; void *item; - struct hashtItem *next ; -} hashtItem ; + struct hashtItem *next; + } +hashtItem; /* hashtable */ typedef struct hTab -{ - int size ; /* max number of items */ - int minKey; /* minimum key value */ - int maxKey ; /* maximum key value */ - hashtItem **table ; /* the actual table */ - int currKey ; /* used for iteration */ - hashtItem *currItem ; /* current item within the list */ - int nItems ; -} hTab ; - -typedef enum { + { + int size; /* max number of items */ + int minKey; /* minimum key value */ + int maxKey; /* maximum key value */ + hashtItem **table; /* the actual table */ + int currKey; /* used for iteration */ + hashtItem *currItem; /* current item within the list */ + int nItems; + } +hTab; + +typedef enum + { DELETE_CHAIN = 1, - DELETE_ITEM -} DELETE_ACTION; + DELETE_ITEM + } +DELETE_ACTION; /*-----------------------------------------------------------------*/ -/* Forward definition for functions */ +/* Forward definition for functions */ /*-----------------------------------------------------------------*/ /* hashtable related functions */ -hTab *newHashTable (int); -void hTabAddItem (hTab **, int key, void *item); +hTab *newHashTable (int); +void hTabAddItem (hTab **, int key, void *item); /** Adds a new item to the hash table. @param h The hash table to add to @param key A hashed version of pkey @@ -71,7 +75,7 @@ void hTabAddItem (hTab **, int key, void *item); hash table after this function. @param item Value for this key. */ -void hTabAddItemLong(hTab **h, int key, void *pkey, void *item); +void hTabAddItemLong (hTab ** h, int key, void *pkey, void *item); /** Finds a item by exact key. Searches all items in the key 'key' for a key that according to 'compare' matches pkey. @@ -80,37 +84,37 @@ void hTabAddItemLong(hTab **h, int key, void *pkey, void *item); @param pkey The key to search for @param compare Returns 0 if pkey == this */ -void * hTabFindByKey(hTab *h, int key, const void *pkey, int (*compare)(const void *, const void *)); +void *hTabFindByKey (hTab * h, int key, const void *pkey, int (*compare) (const void *, const void *)); /** Deletes an item with the exact key 'pkey' @see hTabFindByKey */ -int hTabDeleteByKey(hTab **h, int key, const void *pkey, int (*compare)(const void *, const void *)); - -void hTabDeleteItem (hTab **, int key, - const void *item, DELETE_ACTION action, - int (*compareFunc)(const void *,const void *)); -int hTabIsInTable (hTab *, int , void * , - int (*compareFunc)(void *,void *)); -void *hTabFirstItem (hTab *, int *); -void *hTabNextItem (hTab *, int *); -hTab *hTabFromTable (hTab *); -int isHtabsEqual (hTab *,hTab *, int (*compareFunc)(void *,void *)); -hashtItem *hTabSearch (hTab *, int ); -void *hTabItemWithKey(hTab *,int ); -void hTabAddItemIfNotP(hTab **,int, void *); -void hTabDeleteAll(hTab *); -void *hTabFirstItemWK (hTab *htab, int wk); -void *hTabNextItemWK (hTab *htab ); -void hTabClearAll (hTab *htab); +int hTabDeleteByKey (hTab ** h, int key, const void *pkey, int (*compare) (const void *, const void *)); + +void hTabDeleteItem (hTab **, int key, + const void *item, DELETE_ACTION action, + int (*compareFunc) (const void *, const void *)); +int hTabIsInTable (hTab *, int, void *, + int (*compareFunc) (void *, void *)); +void *hTabFirstItem (hTab *, int *); +void *hTabNextItem (hTab *, int *); +hTab *hTabFromTable (hTab *); +int isHtabsEqual (hTab *, hTab *, int (*compareFunc) (void *, void *)); +hashtItem *hTabSearch (hTab *, int); +void *hTabItemWithKey (hTab *, int); +void hTabAddItemIfNotP (hTab **, int, void *); +void hTabDeleteAll (hTab *); +void *hTabFirstItemWK (hTab * htab, int wk); +void *hTabNextItemWK (hTab * htab); +void hTabClearAll (hTab * htab); /** Find the first item that either is 'item' or which according to 'compareFunc' is the same as item. @param compareFunc strcmp like compare function, may be null. */ -void *hTabFindItem(hTab *htab, int key, - void *item, int (*compareFunc)(void *,void *)); +void *hTabFindItem (hTab * htab, int key, + void *item, int (*compareFunc) (void *, void *)); -void shash_add(hTab **h, const char *szKey, const char *szValue); -const char *shash_find(hTab *h, const char *szKey); +void shash_add (hTab ** h, const char *szKey, const char *szValue); +const char *shash_find (hTab * h, const char *szKey); #endif diff --git a/src/SDCCicode.c b/src/SDCCicode.c index f82a6b71..0b74ff45 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -28,380 +28,397 @@ /*-----------------------------------------------------------------*/ /* global variables */ -set *iCodeChain = NULL ; +set *iCodeChain = NULL; int iTempNum = 0; int iTempLblNum = 0; -int operandKey = 0 ; +int operandKey = 0; int iCodeKey = 0; -char *filename ; -int lineno ; +char *filename; +int lineno; int block; int scopeLevel; int lvaluereq; -symbol *returnLabel ; /* function return label */ -symbol *entryLabel ; /* function entry label */ +symbol *returnLabel; /* function return label */ +symbol *entryLabel; /* function entry label */ /*-----------------------------------------------------------------*/ /* forward definition of some functions */ -operand *geniCodeDivision (operand *,operand *); -operand *geniCodeAssign (operand *,operand *,int); -operand *geniCodeArray (operand *,operand *); +operand *geniCodeDivision (operand *, operand *); +operand *geniCodeAssign (operand *, operand *, int); +operand *geniCodeArray (operand *, operand *); operand *geniCodeArray2Ptr (operand *); -operand *geniCodeRValue (operand *, bool ); +operand *geniCodeRValue (operand *, bool); operand *geniCodeDerefPtr (operand *); #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s) /* forward definition of print functions */ -PRINTFUNC(picGetValueAtAddr); -PRINTFUNC(picSetValueAtAddr); -PRINTFUNC(picAddrOf); -PRINTFUNC(picGeneric); -PRINTFUNC(picGenericOne); -PRINTFUNC(picCast); -PRINTFUNC(picAssign); -PRINTFUNC(picLabel); -PRINTFUNC(picGoto); -PRINTFUNC(picIfx); -PRINTFUNC(picJumpTable); -PRINTFUNC(picInline); -PRINTFUNC(picReceive); - -iCodeTable codeTable[] = { - { '!' , "not", picGenericOne , NULL }, - { '~' , "~" , picGenericOne , NULL }, - { RRC , "rrc", picGenericOne , NULL }, - { RLC , "rlc", picGenericOne , NULL }, - { GETHBIT ,"ghbit", picGenericOne , NULL }, - { UNARYMINUS , "-" , picGenericOne , NULL }, - { IPUSH , "push",picGenericOne , NULL }, - { IPOP , "pop", picGenericOne , NULL }, - { CALL , "call",picGenericOne , NULL }, - { PCALL , "pcall",picGenericOne , NULL }, - { FUNCTION , "proc", picGenericOne , NULL }, - { ENDFUNCTION ,"eproc", picGenericOne , NULL }, - { RETURN , "ret", picGenericOne , NULL }, - { '+' , "+" , picGeneric , NULL }, - { '-' , "-" , picGeneric , NULL }, - { '*' , "*" , picGeneric , NULL }, - { '/' , "/" , picGeneric , NULL }, - { '%' , "%" , picGeneric , NULL }, - { '>' , ">" , picGeneric , NULL }, - { '<' , "<" , picGeneric , NULL }, - { LE_OP , "<=" , picGeneric , NULL }, - { GE_OP , ">=" , picGeneric , NULL }, - { EQ_OP , "==" , picGeneric , NULL }, - { NE_OP , "!=" , picGeneric , NULL }, - { AND_OP , "&&" , picGeneric , NULL }, - { OR_OP , "||" , picGeneric , NULL }, - { '^' , "^" , picGeneric , NULL }, - { '|' , "|" , picGeneric , NULL }, - { BITWISEAND , "&" , picGeneric , NULL }, - { LEFT_OP , "<<" , picGeneric , NULL }, - { RIGHT_OP , ">>" , picGeneric , NULL }, - { GET_VALUE_AT_ADDRESS, "@" , picGetValueAtAddr, NULL }, - { ADDRESS_OF , "&" , picAddrOf , NULL }, - { CAST , "<>" , picCast , NULL }, - { '=' , ":=" , picAssign , NULL }, - { LABEL , "" , picLabel , NULL }, - { GOTO , "" , picGoto , NULL }, - { JUMPTABLE ,"jtab" , picJumpTable , NULL }, - { IFX , "if" , picIfx , NULL }, - { INLINEASM , "" , picInline , NULL }, - { RECEIVE , "recv", picReceive , NULL }, - { SEND , "send", picGenericOne , NULL } +PRINTFUNC (picGetValueAtAddr); +PRINTFUNC (picSetValueAtAddr); +PRINTFUNC (picAddrOf); +PRINTFUNC (picGeneric); +PRINTFUNC (picGenericOne); +PRINTFUNC (picCast); +PRINTFUNC (picAssign); +PRINTFUNC (picLabel); +PRINTFUNC (picGoto); +PRINTFUNC (picIfx); +PRINTFUNC (picJumpTable); +PRINTFUNC (picInline); +PRINTFUNC (picReceive); + +iCodeTable codeTable[] = +{ + {'!', "not", picGenericOne, NULL}, + {'~', "~", picGenericOne, NULL}, + {RRC, "rrc", picGenericOne, NULL}, + {RLC, "rlc", picGenericOne, NULL}, + {GETHBIT, "ghbit", picGenericOne, NULL}, + {UNARYMINUS, "-", picGenericOne, NULL}, + {IPUSH, "push", picGenericOne, NULL}, + {IPOP, "pop", picGenericOne, NULL}, + {CALL, "call", picGenericOne, NULL}, + {PCALL, "pcall", picGenericOne, NULL}, + {FUNCTION, "proc", picGenericOne, NULL}, + {ENDFUNCTION, "eproc", picGenericOne, NULL}, + {RETURN, "ret", picGenericOne, NULL}, + {'+', "+", picGeneric, NULL}, + {'-', "-", picGeneric, NULL}, + {'*', "*", picGeneric, NULL}, + {'/', "/", picGeneric, NULL}, + {'%', "%", picGeneric, NULL}, + {'>', ">", picGeneric, NULL}, + {'<', "<", picGeneric, NULL}, + {LE_OP, "<=", picGeneric, NULL}, + {GE_OP, ">=", picGeneric, NULL}, + {EQ_OP, "==", picGeneric, NULL}, + {NE_OP, "!=", picGeneric, NULL}, + {AND_OP, "&&", picGeneric, NULL}, + {OR_OP, "||", picGeneric, NULL}, + {'^', "^", picGeneric, NULL}, + {'|', "|", picGeneric, NULL}, + {BITWISEAND, "&", picGeneric, NULL}, + {LEFT_OP, "<<", picGeneric, NULL}, + {RIGHT_OP, ">>", picGeneric, NULL}, + {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL}, + {ADDRESS_OF, "&", picAddrOf, NULL}, + {CAST, "<>", picCast, NULL}, + {'=', ":=", picAssign, NULL}, + {LABEL, "", picLabel, NULL}, + {GOTO, "", picGoto, NULL}, + {JUMPTABLE, "jtab", picJumpTable, NULL}, + {IFX, "if", picIfx, NULL}, + {INLINEASM, "", picInline, NULL}, + {RECEIVE, "recv", picReceive, NULL}, + {SEND, "send", picGenericOne, NULL} }; /*-----------------------------------------------------------------*/ /* operandName - returns the name of the operand */ /*-----------------------------------------------------------------*/ -int printOperand (operand *op, FILE *file) +int +printOperand (operand * op, FILE * file) { - sym_link *opetype; - int pnl = 0; + sym_link *opetype; + int pnl = 0; - if (!op) - return 1; + if (!op) + return 1; - if (!file) { - file = stdout; - pnl = 1; + if (!file) + { + file = stdout; + pnl = 1; } - switch (op->type) { + switch (op->type) + { case VALUE: - opetype = getSpec (operandType(op)); - if (SPEC_NOUN(opetype) == V_FLOAT) - fprintf (file,"%g {", SPEC_CVAL(opetype).v_float); - else - fprintf (file,"0x%x {",(int) floatFromVal(op->operand.valOperand)); - printTypeChain(operandType(op),file); - fprintf(file,"}"); - break; + opetype = getSpec (operandType (op)); + if (SPEC_NOUN (opetype) == V_FLOAT) + fprintf (file, "%g {", SPEC_CVAL (opetype).v_float); + else + fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand)); + printTypeChain (operandType (op), file); + fprintf (file, "}"); + break; - case SYMBOL : + case SYMBOL: #define REGA 1 #ifdef REGA - fprintf (file,"%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d}",/*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" ,*/ - (OP_SYMBOL(op)->rname[0] ? OP_SYMBOL(op)->rname : OP_SYMBOL(op)->name), - op->key, - OP_LIVEFROM(op),OP_LIVETO(op), - OP_SYMBOL(op)->stack, - op->isaddr, OP_SYMBOL(op)->isreqv,OP_SYMBOL(op)->remat - ); - { - fprintf(file,"{"); printTypeChain(operandType(op),file); - if (SPIL_LOC(op) && IS_ITEMP(op)) - fprintf(file,"}{ sir@ %s",SPIL_LOC(op)->rname); - fprintf(file,"}"); - - } - - /* if assigned to registers */ - if (OP_SYMBOL(op)->nRegs) { - if (OP_SYMBOL(op)->isspilt) { - if (!OP_SYMBOL(op)->remat) - if (OP_SYMBOL(op)->usl.spillLoc) - fprintf(file,"[%s]",(OP_SYMBOL(op)->usl.spillLoc->rname[0] ? - OP_SYMBOL(op)->usl.spillLoc->rname : - OP_SYMBOL(op)->usl.spillLoc->name)); - else - fprintf(file,"[err]"); - else - fprintf(file,"[remat]"); - } - else { - int i; - fprintf(file,"["); - for(i=0;inRegs;i++) - fprintf(file,"%s ", port->getRegName(OP_SYMBOL(op)->regs[i])); - fprintf(file,"]"); + fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */ + (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name), + op->key, + OP_LIVEFROM (op), OP_LIVETO (op), + OP_SYMBOL (op)->stack, + op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat + ); + { + fprintf (file, "{"); + printTypeChain (operandType (op), file); + if (SPIL_LOC (op) && IS_ITEMP (op)) + fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname); + fprintf (file, "}"); + } - } + + /* if assigned to registers */ + if (OP_SYMBOL (op)->nRegs) + { + if (OP_SYMBOL (op)->isspilt) + { + if (!OP_SYMBOL (op)->remat) + if (OP_SYMBOL (op)->usl.spillLoc) + fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ? + OP_SYMBOL (op)->usl.spillLoc->rname : + OP_SYMBOL (op)->usl.spillLoc->name)); + else + fprintf (file, "[err]"); + else + fprintf (file, "[remat]"); + } + else + { + int i; + fprintf (file, "["); + for (i = 0; i < OP_SYMBOL (op)->nRegs; i++) + fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i])); + fprintf (file, "]"); + } + } #else - fprintf(file,"%s",(OP_SYMBOL(op)->rname[0] ? - OP_SYMBOL(op)->rname : OP_SYMBOL(op)->name)); - /* if assigned to registers */ - if (OP_SYMBOL(op)->nRegs && !OP_SYMBOL(op)->isspilt) { - int i; - fprintf(file,"["); - for(i=0;inRegs;i++) - fprintf(file,"%s ",(OP_SYMBOL(op)->regs[i] ? - OP_SYMBOL(op)->regs[i]->name : - "err")); - fprintf(file,"]"); - } + fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ? + OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name)); + /* if assigned to registers */ + if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt) + { + int i; + fprintf (file, "["); + for (i = 0; i < OP_SYMBOL (op)->nRegs; i++) + fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ? + OP_SYMBOL (op)->regs[i]->name : + "err")); + fprintf (file, "]"); + } #endif - break ; + break; case TYPE: - fprintf(file,"("); - printTypeChain(op->operand.typeOperand,file); - fprintf(file,")"); - break; + fprintf (file, "("); + printTypeChain (op->operand.typeOperand, file); + fprintf (file, ")"); + break; } - if (pnl) - fprintf(file,"\n"); - return 0; + if (pnl) + fprintf (file, "\n"); + return 0; } /*-----------------------------------------------------------------*/ /* print functions */ /*-----------------------------------------------------------------*/ -PRINTFUNC(picGetValueAtAddr) +PRINTFUNC (picGetValueAtAddr) { - fprintf(of,"\t"); - printOperand (IC_RESULT(ic),of); - fprintf (of," = "); - fprintf (of,"@["); - printOperand (IC_LEFT(ic), of); - fprintf (of,"]"); + fprintf (of, "\t"); + printOperand (IC_RESULT (ic), of); + fprintf (of, " = "); + fprintf (of, "@["); + printOperand (IC_LEFT (ic), of); + fprintf (of, "]"); - fprintf(of,"\n"); + fprintf (of, "\n"); } -PRINTFUNC(picSetValueAtAddr) +PRINTFUNC (picSetValueAtAddr) { - fprintf(of,"\t"); - fprintf(of,"*["); - printOperand(IC_LEFT(ic),of); - fprintf(of,"] = "); - printOperand(IC_RIGHT(ic),of); - fprintf (of,"\n"); + fprintf (of, "\t"); + fprintf (of, "*["); + printOperand (IC_LEFT (ic), of); + fprintf (of, "] = "); + printOperand (IC_RIGHT (ic), of); + fprintf (of, "\n"); } -PRINTFUNC(picAddrOf) +PRINTFUNC (picAddrOf) { - fprintf(of,"\t"); - printOperand(IC_RESULT(ic),of); - if (IS_ITEMP(IC_LEFT(ic))) - fprintf(of," = "); - else - fprintf(of," = &["); - printOperand(IC_LEFT(ic),of); - if (IC_RIGHT(ic)) { - if (IS_ITEMP(IC_LEFT(ic))) - fprintf(of," offsetAdd "); + fprintf (of, "\t"); + printOperand (IC_RESULT (ic), of); + if (IS_ITEMP (IC_LEFT (ic))) + fprintf (of, " = "); else - fprintf(of," , "); - printOperand(IC_RIGHT(ic),of); + fprintf (of, " = &["); + printOperand (IC_LEFT (ic), of); + if (IC_RIGHT (ic)) + { + if (IS_ITEMP (IC_LEFT (ic))) + fprintf (of, " offsetAdd "); + else + fprintf (of, " , "); + printOperand (IC_RIGHT (ic), of); } - if (IS_ITEMP(IC_LEFT(ic))) - fprintf (of,"\n"); - else - fprintf (of,"]\n"); + if (IS_ITEMP (IC_LEFT (ic))) + fprintf (of, "\n"); + else + fprintf (of, "]\n"); } -PRINTFUNC(picJumpTable) +PRINTFUNC (picJumpTable) { - symbol *sym; + symbol *sym; - fprintf(of,"\t"); - fprintf(of,"%s\t",s); - printOperand(IC_JTCOND(ic),of); - fprintf(of,"\n"); - for ( sym = setFirstItem(IC_JTLABELS(ic)); sym; - sym = setNextItem(IC_JTLABELS(ic))) - fprintf(of,"\t\t\t%s\n",sym->name); + fprintf (of, "\t"); + fprintf (of, "%s\t", s); + printOperand (IC_JTCOND (ic), of); + fprintf (of, "\n"); + for (sym = setFirstItem (IC_JTLABELS (ic)); sym; + sym = setNextItem (IC_JTLABELS (ic))) + fprintf (of, "\t\t\t%s\n", sym->name); } -PRINTFUNC(picGeneric) +PRINTFUNC (picGeneric) { - fprintf(of,"\t"); - printOperand(IC_RESULT(ic),of); - fprintf(of," = "); - printOperand(IC_LEFT(ic),of); - fprintf(of," %s ",s); - printOperand(IC_RIGHT(ic),of); - fprintf(of,"\n"); + fprintf (of, "\t"); + printOperand (IC_RESULT (ic), of); + fprintf (of, " = "); + printOperand (IC_LEFT (ic), of); + fprintf (of, " %s ", s); + printOperand (IC_RIGHT (ic), of); + fprintf (of, "\n"); } -PRINTFUNC(picGenericOne) +PRINTFUNC (picGenericOne) { - fprintf(of,"\t"); - if ( IC_RESULT(ic) ) { - printOperand(IC_RESULT(ic),of); - fprintf (of," = "); + fprintf (of, "\t"); + if (IC_RESULT (ic)) + { + printOperand (IC_RESULT (ic), of); + fprintf (of, " = "); } - if (IC_LEFT(ic)) { - fprintf (of,"%s ",s); - printOperand(IC_LEFT(ic),of); + if (IC_LEFT (ic)) + { + fprintf (of, "%s ", s); + printOperand (IC_LEFT (ic), of); } - if (! IC_RESULT(ic) && !IC_LEFT(ic)) - fprintf (of,s); + if (!IC_RESULT (ic) && !IC_LEFT (ic)) + fprintf (of, s); - fprintf(of,"\n"); + fprintf (of, "\n"); } -PRINTFUNC(picCast) +PRINTFUNC (picCast) { - fprintf(of,"\t"); - printOperand(IC_RESULT(ic),of); - fprintf (of," = "); - printOperand(IC_LEFT(ic),of); - printOperand(IC_RIGHT(ic),of); - fprintf(of,"\n"); + fprintf (of, "\t"); + printOperand (IC_RESULT (ic), of); + fprintf (of, " = "); + printOperand (IC_LEFT (ic), of); + printOperand (IC_RIGHT (ic), of); + fprintf (of, "\n"); } -PRINTFUNC(picAssign) +PRINTFUNC (picAssign) { - fprintf(of,"\t"); + fprintf (of, "\t"); - if (IC_RESULT(ic)->isaddr && IS_ITEMP(IC_RESULT(ic))) - fprintf(of,"*("); + if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic))) + fprintf (of, "*("); - printOperand(IC_RESULT(ic),of); + printOperand (IC_RESULT (ic), of); - if (IC_RESULT(ic)->isaddr && IS_ITEMP(IC_RESULT(ic))) - fprintf(of,")"); + if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic))) + fprintf (of, ")"); - fprintf(of," %s ", s); - printOperand (IC_RIGHT(ic),of); + fprintf (of, " %s ", s); + printOperand (IC_RIGHT (ic), of); - fprintf(of,"\n"); + fprintf (of, "\n"); } -PRINTFUNC(picLabel) +PRINTFUNC (picLabel) { - fprintf(of," %s($%d) :\n",IC_LABEL(ic)->name,IC_LABEL(ic)->key); + fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key); } -PRINTFUNC(picGoto) +PRINTFUNC (picGoto) { - fprintf(of,"\t"); - fprintf (of," goto %s($%d)\n", IC_LABEL(ic)->name,IC_LABEL(ic)->key); + fprintf (of, "\t"); + fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key); } -PRINTFUNC(picIfx) +PRINTFUNC (picIfx) { - fprintf(of,"\t"); - fprintf (of,"if "); - printOperand(IC_COND(ic),of); + fprintf (of, "\t"); + fprintf (of, "if "); + printOperand (IC_COND (ic), of); - if ( ! IC_TRUE(ic) ) - fprintf (of," == 0 goto %s($%d)\n",IC_FALSE(ic)->name,IC_FALSE(ic)->key); - else { - fprintf (of," != 0 goto %s($%d)\n",IC_TRUE(ic)->name,IC_TRUE(ic)->key); - if (IC_FALSE(ic)) - fprintf (of,"\tzzgoto %s\n",IC_FALSE(ic)->name); + if (!IC_TRUE (ic)) + fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key); + else + { + fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key); + if (IC_FALSE (ic)) + fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name); } } -PRINTFUNC(picInline) +PRINTFUNC (picInline) { - fprintf(of,"%s",IC_INLINE(ic)); + fprintf (of, "%s", IC_INLINE (ic)); } -PRINTFUNC(picReceive) +PRINTFUNC (picReceive) { - printOperand(IC_RESULT(ic),of); - fprintf(of," = %s ",s); - printOperand(IC_LEFT(ic),of); - fprintf(of,"\n"); + printOperand (IC_RESULT (ic), of); + fprintf (of, " = %s ", s); + printOperand (IC_LEFT (ic), of); + fprintf (of, "\n"); } /*-----------------------------------------------------------------*/ /* piCode - prints one iCode */ /*-----------------------------------------------------------------*/ -int piCode (void *item, FILE *of) +int +piCode (void *item, FILE * of) { - iCode *ic = item; - iCodeTable *icTab ; + iCode *ic = item; + iCodeTable *icTab; - if (!of) - of = stdout; + if (!of) + of = stdout; - icTab = getTableEntry(ic->op) ; - fprintf(stdout,"%s(%d:%d:%d:%d:%d)\t", - ic->filename,ic->lineno, - ic->seq,ic->key,ic->depth,ic->supportRtn); - icTab->iCodePrint(of,ic,icTab->printName); - return 1; + icTab = getTableEntry (ic->op); + fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t", + ic->filename, ic->lineno, + ic->seq, ic->key, ic->depth, ic->supportRtn); + icTab->iCodePrint (of, ic, icTab->printName); + return 1; } /*-----------------------------------------------------------------*/ /* printiCChain - prints intermediate code for humans */ /*-----------------------------------------------------------------*/ -void printiCChain (iCode *icChain, FILE *of) +void +printiCChain (iCode * icChain, FILE * of) { - iCode *loop ; - iCodeTable *icTab ; + iCode *loop; + iCodeTable *icTab; - if (!of) - of = stdout; - for ( loop = icChain ; loop ; loop = loop->next ) { - if ((icTab = getTableEntry (loop->op ))) { - fprintf(of,"%s(%d:%d:%d:%d:%d)\t", - loop->filename,loop->lineno, - loop->seq,loop->key,loop->depth,loop->supportRtn); + if (!of) + of = stdout; + for (loop = icChain; loop; loop = loop->next) + { + if ((icTab = getTableEntry (loop->op))) + { + fprintf (of, "%s(%d:%d:%d:%d:%d)\t", + loop->filename, loop->lineno, + loop->seq, loop->key, loop->depth, loop->supportRtn); - icTab->iCodePrint (of,loop,icTab->printName); - } + icTab->iCodePrint (of, loop, icTab->printName); + } } } @@ -409,134 +426,143 @@ void printiCChain (iCode *icChain, FILE *of) /*-----------------------------------------------------------------*/ /* newOperand - allocate, init & return a new iCode */ /*-----------------------------------------------------------------*/ -operand *newOperand () +operand * +newOperand () { - operand *op ; + operand *op; - op = Safe_calloc(1,sizeof(operand)); + op = Safe_calloc (1, sizeof (operand)); - op->key = 0 ; - return op; + op->key = 0; + return op; } /*-----------------------------------------------------------------*/ /* newiCode - create and return a new iCode entry initialised */ /*-----------------------------------------------------------------*/ -iCode *newiCode (int op, operand *left, operand *right) +iCode * +newiCode (int op, operand * left, operand * right) { - iCode *ic ; + iCode *ic; - ic = Safe_calloc(1,sizeof(iCode)); + ic = Safe_calloc (1, sizeof (iCode)); - ic->lineno = lineno ; - ic->filename= filename ; - ic->block = block; - ic->level = scopeLevel; - ic->op = op; - ic->key= iCodeKey++ ; - IC_LEFT(ic) = left; - IC_RIGHT(ic)= right; + ic->lineno = lineno; + ic->filename = filename; + ic->block = block; + ic->level = scopeLevel; + ic->op = op; + ic->key = iCodeKey++; + IC_LEFT (ic) = left; + IC_RIGHT (ic) = right; - return ic; + return ic; } /*-----------------------------------------------------------------*/ /* newiCode for conditional statements */ /*-----------------------------------------------------------------*/ -iCode *newiCodeCondition (operand *condition, - symbol *trueLabel, - symbol *falseLabel ) +iCode * +newiCodeCondition (operand * condition, + symbol * trueLabel, + symbol * falseLabel) { - iCode *ic ; + iCode *ic; - ic = newiCode(IFX,NULL,NULL); - IC_COND(ic) = condition ; - IC_TRUE(ic) = trueLabel ; - IC_FALSE(ic) = falseLabel; - return ic; + ic = newiCode (IFX, NULL, NULL); + IC_COND (ic) = condition; + IC_TRUE (ic) = trueLabel; + IC_FALSE (ic) = falseLabel; + return ic; } /*-----------------------------------------------------------------*/ /* newiCodeLabelGoto - unconditional goto statement| label stmnt */ /*-----------------------------------------------------------------*/ -iCode *newiCodeLabelGoto (int op, symbol *label) +iCode * +newiCodeLabelGoto (int op, symbol * label) { - iCode *ic ; + iCode *ic; - ic = newiCode(op,NULL,NULL); - ic->op = op ; - ic->argLabel.label = label ; - IC_LEFT(ic) = NULL ; - IC_RIGHT(ic) = NULL ; - IC_RESULT(ic) = NULL ; - return ic; + ic = newiCode (op, NULL, NULL); + ic->op = op; + ic->argLabel.label = label; + IC_LEFT (ic) = NULL; + IC_RIGHT (ic) = NULL; + IC_RESULT (ic) = NULL; + return ic; } /*-----------------------------------------------------------------*/ /* newiTemp - allocate & return a newItemp Variable */ /*-----------------------------------------------------------------*/ -symbol *newiTemp (char *s) +symbol * +newiTemp (char *s) { - symbol *itmp; + symbol *itmp; - if (s) - sprintf(buffer,"%s",s); - else - sprintf (buffer,"iTemp%d",iTempNum++); - itmp = newSymbol (buffer,1); - strcpy(itmp->rname,itmp->name); - itmp->isitmp = 1; + if (s) + sprintf (buffer, "%s", s); + else + sprintf (buffer, "iTemp%d", iTempNum++); + itmp = newSymbol (buffer, 1); + strcpy (itmp->rname, itmp->name); + itmp->isitmp = 1; - return itmp; + return itmp; } /*-----------------------------------------------------------------*/ /* newiTempLabel - creates a temp variable label */ /*-----------------------------------------------------------------*/ -symbol *newiTempLabel (char *s) +symbol * +newiTempLabel (char *s) { - symbol *itmplbl; + symbol *itmplbl; - /* check if this alredy exists */ - if (s && (itmplbl = findSym(LabelTab, NULL, s))) - return itmplbl ; + /* check if this alredy exists */ + if (s && (itmplbl = findSym (LabelTab, NULL, s))) + return itmplbl; - if (s) - itmplbl = newSymbol(s,1); - else { - sprintf(buffer,"iTempLbl%d",iTempLblNum++); - itmplbl = newSymbol(buffer,1); + if (s) + itmplbl = newSymbol (s, 1); + else + { + sprintf (buffer, "iTempLbl%d", iTempLblNum++); + itmplbl = newSymbol (buffer, 1); } - itmplbl->isitmp = 1; - itmplbl->islbl = 1; - itmplbl->key = labelKey++ ; - addSym (LabelTab, itmplbl, itmplbl->name,0,0); - return itmplbl ; + itmplbl->isitmp = 1; + itmplbl->islbl = 1; + itmplbl->key = labelKey++; + addSym (LabelTab, itmplbl, itmplbl->name, 0, 0); + return itmplbl; } /*-----------------------------------------------------------------*/ /* newiTempPreheaderLabel - creates a new preheader label */ /*-----------------------------------------------------------------*/ -symbol *newiTempPreheaderLabel() +symbol * +newiTempPreheaderLabel () { - symbol *itmplbl ; + symbol *itmplbl; - sprintf(buffer,"preHeaderLbl%d",iTempLblNum++); - itmplbl = newSymbol(buffer,1); + sprintf (buffer, "preHeaderLbl%d", iTempLblNum++); + itmplbl = newSymbol (buffer, 1); - itmplbl->isitmp = 1; - itmplbl->islbl = 1; - itmplbl->key = labelKey++ ; - addSym (LabelTab, itmplbl, itmplbl->name,0,0); - return itmplbl ; + itmplbl->isitmp = 1; + itmplbl->islbl = 1; + itmplbl->key = labelKey++; + addSym (LabelTab, itmplbl, itmplbl->name, 0, 0); + return itmplbl; } /*-----------------------------------------------------------------*/ /* initiCode - initialises some iCode related stuff */ /*-----------------------------------------------------------------*/ -void initiCode () +void +initiCode () { } @@ -544,731 +570,776 @@ void initiCode () /*-----------------------------------------------------------------*/ /* copyiCode - make a copy of the iCode given */ /*-----------------------------------------------------------------*/ -iCode *copyiCode (iCode *ic) +iCode * +copyiCode (iCode * ic) { - iCode *nic = newiCode(ic->op,NULL,NULL); + iCode *nic = newiCode (ic->op, NULL, NULL); - nic->lineno = ic->lineno ; - nic->filename= ic->filename ; - nic->block = ic->block; - nic->level = ic->level; + nic->lineno = ic->lineno; + nic->filename = ic->filename; + nic->block = ic->block; + nic->level = ic->level; - /* deal with the special cases first */ - switch (ic->op) { + /* deal with the special cases first */ + switch (ic->op) + { case IFX: - IC_COND(nic) = operandFromOperand(IC_COND(ic)); - IC_TRUE(nic) = IC_TRUE(ic); - IC_FALSE(nic)= IC_FALSE(ic); - break; + IC_COND (nic) = operandFromOperand (IC_COND (ic)); + IC_TRUE (nic) = IC_TRUE (ic); + IC_FALSE (nic) = IC_FALSE (ic); + break; case JUMPTABLE: - IC_JTCOND(nic) = operandFromOperand(IC_JTCOND(ic)); - IC_JTLABELS(nic) = IC_JTLABELS(ic); - break; + IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic)); + IC_JTLABELS (nic) = IC_JTLABELS (ic); + break; case CALL: case PCALL: - IC_RESULT(nic) = operandFromOperand(IC_RESULT(ic)); - IC_LEFT(nic) = operandFromOperand(IC_LEFT(ic)); - IC_ARGS(nic) = IC_ARGS(ic); - break; + IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic)); + IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic)); + IC_ARGS (nic) = IC_ARGS (ic); + break; case INLINEASM: - IC_INLINE(nic) = IC_INLINE(ic); - break; + IC_INLINE (nic) = IC_INLINE (ic); + break; default: - IC_RESULT(nic) = operandFromOperand(IC_RESULT(ic)); - IC_LEFT(nic) = operandFromOperand(IC_LEFT(ic)); - IC_RIGHT(nic)= operandFromOperand(IC_RIGHT(ic)); + IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic)); + IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic)); + IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic)); } - return nic; + return nic; } /*-----------------------------------------------------------------*/ /* getTableEntry - gets the table entry for the given operator */ /*-----------------------------------------------------------------*/ -iCodeTable *getTableEntry (int oper ) +iCodeTable * +getTableEntry (int oper) { - int i ; + int i; - for ( i = 0 ; i < (sizeof(codeTable)/sizeof(iCodeTable)); i++ ) - if (oper == codeTable[i].icode) - return &codeTable[i] ; + for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++) + if (oper == codeTable[i].icode) + return &codeTable[i]; - return NULL ; + return NULL; } /*-----------------------------------------------------------------*/ /* newiTempOperand - new intermediate temp operand */ /*-----------------------------------------------------------------*/ -operand *newiTempOperand (sym_link *type, char throwType) +operand * +newiTempOperand (sym_link * type, char throwType) { - symbol *itmp; - operand *op = newOperand(); - sym_link *etype; + symbol *itmp; + operand *op = newOperand (); + sym_link *etype; - op->type = SYMBOL ; - itmp = newiTemp(NULL); + op->type = SYMBOL; + itmp = newiTemp (NULL); - etype = getSpec(type); + etype = getSpec (type); - if (IS_LITERAL(etype) ) - throwType = 0 ; + if (IS_LITERAL (etype)) + throwType = 0; - /* copy the type information */ - if (type) - itmp->etype = getSpec (itmp->type = (throwType ? type : - copyLinkChain(type))); - if (IS_LITERAL(itmp->etype)) { - SPEC_SCLS(itmp->etype) = S_REGISTER ; - SPEC_OCLS(itmp->etype) = reg; + /* copy the type information */ + if (type) + itmp->etype = getSpec (itmp->type = (throwType ? type : + copyLinkChain (type))); + if (IS_LITERAL (itmp->etype)) + { + SPEC_SCLS (itmp->etype) = S_REGISTER; + SPEC_OCLS (itmp->etype) = reg; } - op->operand.symOperand = itmp; - op->key = itmp->key = ++operandKey ; - return op; + op->operand.symOperand = itmp; + op->key = itmp->key = ++operandKey; + return op; } /*-----------------------------------------------------------------*/ /* operandType - returns the type chain for an operand */ /*-----------------------------------------------------------------*/ -sym_link *operandType (operand *op) +sym_link * +operandType (operand * op) { - /* depending on type of operand */ - switch (op->type) { + /* depending on type of operand */ + switch (op->type) + { - case VALUE : - return op->operand.valOperand->type ; + case VALUE: + return op->operand.valOperand->type; case SYMBOL: - return op->operand.symOperand->type ; + return op->operand.symOperand->type; - case TYPE : - return op->operand.typeOperand ; + case TYPE: + return op->operand.typeOperand; default: - werror (E_INTERNAL_ERROR,__FILE__,__LINE__, - " operand type not known "); - assert (0) ; /* should never come here */ - /* Just to keep the compiler happy */ - return (sym_link *)0; + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + " operand type not known "); + assert (0); /* should never come here */ + /* Just to keep the compiler happy */ + return (sym_link *) 0; } } /*-----------------------------------------------------------------*/ /* isParamterToCall - will return 1 if op is a parameter to args */ /*-----------------------------------------------------------------*/ -int isParameterToCall (value *args, operand *op) +int +isParameterToCall (value * args, operand * op) { - value *tval = args ; + value *tval = args; - while (tval) { - if (tval->sym && - isSymbolEqual(op->operand.symOperand,tval->sym)) - return 1; - tval = tval->next ; + while (tval) + { + if (tval->sym && + isSymbolEqual (op->operand.symOperand, tval->sym)) + return 1; + tval = tval->next; } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* isOperandGlobal - return 1 if operand is a global variable */ /*-----------------------------------------------------------------*/ -int isOperandGlobal ( operand *op ) +int +isOperandGlobal (operand * op) { - if (!op) - return 0; + if (!op) + return 0; - if (IS_ITEMP(op)) - return 0; + if (IS_ITEMP (op)) + return 0; - if (op->type == SYMBOL && - (op->operand.symOperand->level == 0 || - IS_STATIC(op->operand.symOperand->etype) || - IS_EXTERN(op->operand.symOperand->etype)) + if (op->type == SYMBOL && + (op->operand.symOperand->level == 0 || + IS_STATIC (op->operand.symOperand->etype) || + IS_EXTERN (op->operand.symOperand->etype)) ) - return 1; + return 1; - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* isOperandVolatile - return 1 if the operand is volatile */ /*-----------------------------------------------------------------*/ -int isOperandVolatile ( operand *op , bool chkTemp) +int +isOperandVolatile (operand * op, bool chkTemp) { - sym_link *optype ; - sym_link *opetype ; + sym_link *optype; + sym_link *opetype; - if (IS_ITEMP(op) && !chkTemp) - return 0; + if (IS_ITEMP (op) && !chkTemp) + return 0; - opetype = getSpec(optype = operandType(op)); + opetype = getSpec (optype = operandType (op)); - if (IS_PTR(optype) && DCL_PTR_VOLATILE(optype)) - return 1; + if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype)) + return 1; - if (IS_VOLATILE(opetype)) - return 1; - return 0; + if (IS_VOLATILE (opetype)) + return 1; + return 0; } /*-----------------------------------------------------------------*/ /* isOperandLiteral - returns 1 if an operand contains a literal */ /*-----------------------------------------------------------------*/ -int isOperandLiteral ( operand *op ) +int +isOperandLiteral (operand * op) { - sym_link *opetype ; + sym_link *opetype; - if (!op) - return 0; + if (!op) + return 0; - opetype = getSpec (operandType(op)); + opetype = getSpec (operandType (op)); - if (IS_LITERAL(opetype)) - return 1; + if (IS_LITERAL (opetype)) + return 1; - return 0; + return 0; } /*-----------------------------------------------------------------*/ -/* isOperandInFarSpace - will return true if operand is in farSpace*/ +/* isOperandInFarSpace - will return true if operand is in farSpace */ /*-----------------------------------------------------------------*/ -bool isOperandInFarSpace (operand *op) +bool +isOperandInFarSpace (operand * op) { - sym_link *etype; + sym_link *etype; - if (!op) - return FALSE; + if (!op) + return FALSE; - if (!IS_SYMOP(op)) - return FALSE ; + if (!IS_SYMOP (op)) + return FALSE; - if (!IS_TRUE_SYMOP(op)) { - if (SPIL_LOC(op)) - etype = SPIL_LOC(op)->etype; - else - return FALSE; + if (!IS_TRUE_SYMOP (op)) + { + if (SPIL_LOC (op)) + etype = SPIL_LOC (op)->etype; + else + return FALSE; } - else + else { - etype = getSpec(operandType(op)); + etype = getSpec (operandType (op)); } - return (IN_FARSPACE(SPEC_OCLS(etype)) ? TRUE : FALSE); + return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE); } /*-----------------------------------------------------------------*/ /* isOperandOnStack - will return true if operand is on stack */ /*-----------------------------------------------------------------*/ -bool isOperandOnStack(operand *op) +bool +isOperandOnStack (operand * op) { - sym_link *etype; + sym_link *etype; - if (!op) - return FALSE; + if (!op) + return FALSE; - if (!IS_SYMOP(op)) - return FALSE ; + if (!IS_SYMOP (op)) + return FALSE; - etype = getSpec(operandType(op)); + etype = getSpec (operandType (op)); - return ((IN_STACK(etype)) ? TRUE : FALSE); + return ((IN_STACK (etype)) ? TRUE : FALSE); } /*-----------------------------------------------------------------*/ /* operandLitValue - literal value of an operand */ /*-----------------------------------------------------------------*/ -double operandLitValue ( operand *op ) +double +operandLitValue (operand * op) { - assert(isOperandLiteral(op)); + assert (isOperandLiteral (op)); - return floatFromVal(op->operand.valOperand); + return floatFromVal (op->operand.valOperand); } /*-----------------------------------------------------------------*/ /* operandOperation - perforoms operations on operands */ /*-----------------------------------------------------------------*/ -operand *operandOperation (operand *left,operand *right, - int op, sym_link *type) -{ - operand *retval = (operand *)0; - - assert(isOperandLiteral(left)); - if (right) - assert(isOperandLiteral(right)); - - switch (op) { - case '+' : - retval = operandFromValue (valCastLiteral(type, - operandLitValue(left) + - operandLitValue(right))); - break ; - case '-' : - retval = operandFromValue(valCastLiteral(type, - operandLitValue(left) - - operandLitValue(right))); - break; +operand * +operandOperation (operand * left, operand * right, + int op, sym_link * type) +{ + operand *retval = (operand *) 0; + + assert (isOperandLiteral (left)); + if (right) + assert (isOperandLiteral (right)); + + switch (op) + { + case '+': + retval = operandFromValue (valCastLiteral (type, + operandLitValue (left) + + operandLitValue (right))); + break; + case '-': + retval = operandFromValue (valCastLiteral (type, + operandLitValue (left) - + operandLitValue (right))); + break; case '*': - retval = operandFromValue(valCastLiteral(type, - operandLitValue(left) * - operandLitValue(right))); - break; + retval = operandFromValue (valCastLiteral (type, + operandLitValue (left) * + operandLitValue (right))); + break; case '/': - if ((unsigned long) operandLitValue(right) == 0){ - werror(E_DIVIDE_BY_ZERO); - retval = right; + if ((unsigned long) operandLitValue (right) == 0) + { + werror (E_DIVIDE_BY_ZERO); + retval = right; - } - else - retval = operandFromValue (valCastLiteral(type, - operandLitValue(left) / - operandLitValue(right))); - break; + } + else + retval = operandFromValue (valCastLiteral (type, + operandLitValue (left) / + operandLitValue (right))); + break; case '%': - if ((unsigned long) operandLitValue(right) == 0){ - werror(E_DIVIDE_BY_ZERO); - retval = right; - } - else - retval = operandFromLit ((unsigned long) operandLitValue(left) % - (unsigned long) operandLitValue(right)); - break; - case LEFT_OP : - retval = operandFromLit ((unsigned long) operandLitValue(left) << - (unsigned long) operandLitValue(right)); - break; - case RIGHT_OP : - retval = operandFromLit ((unsigned long) operandLitValue(left) >> - (unsigned long) operandLitValue(right)); - break; - case EQ_OP : - retval = operandFromLit (operandLitValue(left) == - operandLitValue(right)); - break; - case '<' : - retval = operandFromLit (operandLitValue(left) < - operandLitValue(right)); - break; - case LE_OP : - retval = operandFromLit (operandLitValue(left) <= - operandLitValue(right)); - break; - case NE_OP : - retval = operandFromLit (operandLitValue(left) != - operandLitValue(right)); - break; - case '>' : - retval = operandFromLit (operandLitValue(left) > - operandLitValue(right)); - break; - case GE_OP : - retval = operandFromLit (operandLitValue(left) >= - operandLitValue(right)); - break; - case BITWISEAND : - retval = operandFromLit ((unsigned long) operandLitValue(left) & - (unsigned long) operandLitValue(right)); - break; - case '|' : - retval = operandFromLit ((unsigned long) operandLitValue(left) | - (unsigned long) operandLitValue(right)); - break; - case '^' : - retval = operandFromLit ((unsigned long) operandLitValue(left) ^ - (unsigned long) operandLitValue(right)); - break; + if ((unsigned long) operandLitValue (right) == 0) + { + werror (E_DIVIDE_BY_ZERO); + retval = right; + } + else + retval = operandFromLit ((unsigned long) operandLitValue (left) % + (unsigned long) operandLitValue (right)); + break; + case LEFT_OP: + retval = operandFromLit ((unsigned long) operandLitValue (left) << + (unsigned long) operandLitValue (right)); + break; + case RIGHT_OP: + retval = operandFromLit ((unsigned long) operandLitValue (left) >> + (unsigned long) operandLitValue (right)); + break; + case EQ_OP: + retval = operandFromLit (operandLitValue (left) == + operandLitValue (right)); + break; + case '<': + retval = operandFromLit (operandLitValue (left) < + operandLitValue (right)); + break; + case LE_OP: + retval = operandFromLit (operandLitValue (left) <= + operandLitValue (right)); + break; + case NE_OP: + retval = operandFromLit (operandLitValue (left) != + operandLitValue (right)); + break; + case '>': + retval = operandFromLit (operandLitValue (left) > + operandLitValue (right)); + break; + case GE_OP: + retval = operandFromLit (operandLitValue (left) >= + operandLitValue (right)); + break; + case BITWISEAND: + retval = operandFromLit ((unsigned long) operandLitValue (left) & + (unsigned long) operandLitValue (right)); + break; + case '|': + retval = operandFromLit ((unsigned long) operandLitValue (left) | + (unsigned long) operandLitValue (right)); + break; + case '^': + retval = operandFromLit ((unsigned long) operandLitValue (left) ^ + (unsigned long) operandLitValue (right)); + break; case AND_OP: - retval = operandFromLit (operandLitValue(left) && - operandLitValue(right)); - break; + retval = operandFromLit (operandLitValue (left) && + operandLitValue (right)); + break; case OR_OP: - retval = operandFromLit (operandLitValue(left) || - operandLitValue(right)); - break; + retval = operandFromLit (operandLitValue (left) || + operandLitValue (right)); + break; case RRC: - { - long i = operandLitValue(left); + { + long i = operandLitValue (left); - retval = operandFromLit ((i >> (getSize(operandType(left))*8 - 1)) | - (i << 1)); - } - break; + retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) | + (i << 1)); + } + break; case RLC: - { - long i = operandLitValue(left); + { + long i = operandLitValue (left); - retval = operandFromLit ((i << (getSize(operandType(left))*8 - 1)) | - (i >> 1)); - } - break; + retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) | + (i >> 1)); + } + break; case UNARYMINUS: - retval = operandFromLit(-1 * operandLitValue(left)); - break; + retval = operandFromLit (-1 * operandLitValue (left)); + break; case '~': - retval = operandFromLit(~ ((long) operandLitValue(left))); - break; + retval = operandFromLit (~((long) operandLitValue (left))); + break; case '!': - retval = operandFromLit(! operandLitValue(left)); - break; + retval = operandFromLit (!operandLitValue (left)); + break; - default : - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - " operandOperation invalid operator "); - assert (0); + default: + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + " operandOperation invalid operator "); + assert (0); } - return retval; + return retval; } /*-----------------------------------------------------------------*/ /* isOperandEqual - compares two operand & return 1 if they r = */ /*-----------------------------------------------------------------*/ -int isOperandEqual (operand *left, operand *right) +int +isOperandEqual (operand * left, operand * right) { - /* if the pointers are equal then they are equal */ - if ( left == right ) - return 1; + /* if the pointers are equal then they are equal */ + if (left == right) + return 1; - /* if either of them null then false */ - if ( !left || !right) - return 0; + /* if either of them null then false */ + if (!left || !right) + return 0; - if (left->type != right->type) - return 0; + if (left->type != right->type) + return 0; - if (IS_SYMOP(left) && IS_SYMOP(right)) - return left->key == right->key ; - - /* if types are the same */ - switch (left->type) { - case SYMBOL : - return isSymbolEqual(left->operand.symOperand, - right->operand.symOperand); - case VALUE : - return (floatFromVal(left->operand.valOperand) == - floatFromVal(right->operand.valOperand)); - case TYPE : - if (checkType(left->operand.typeOperand, - right->operand.typeOperand) == 1) - return 1; + if (IS_SYMOP (left) && IS_SYMOP (right)) + return left->key == right->key; + + /* if types are the same */ + switch (left->type) + { + case SYMBOL: + return isSymbolEqual (left->operand.symOperand, + right->operand.symOperand); + case VALUE: + return (floatFromVal (left->operand.valOperand) == + floatFromVal (right->operand.valOperand)); + case TYPE: + if (checkType (left->operand.typeOperand, + right->operand.typeOperand) == 1) + return 1; } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* isiCodeEqual - comapres two iCodes are returns true if yes */ /*-----------------------------------------------------------------*/ -int isiCodeEqual (iCode *left, iCode *right) +int +isiCodeEqual (iCode * left, iCode * right) { - /* if the same pointer */ - if (left == right) - return 1; + /* if the same pointer */ + if (left == right) + return 1; - /* if either of them null */ - if (!left || !right) - return 0; + /* if either of them null */ + if (!left || !right) + return 0; - /* if operand are the same */ - if ( left->op == right->op ) { + /* if operand are the same */ + if (left->op == right->op) + { - /* compare all the elements depending on type */ - if (left->op != IFX ) { - if (!isOperandEqual(IC_LEFT(left),IC_LEFT(right))) - return 0; - if (!isOperandEqual(IC_RIGHT(left),IC_RIGHT(right))) - return 0; + /* compare all the elements depending on type */ + if (left->op != IFX) + { + if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right))) + return 0; + if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right))) + return 0; - } else { - if (!isOperandEqual(IC_COND(left),IC_COND(right))) - return 0; - if (!isSymbolEqual (IC_TRUE(left),IC_TRUE(right))) - return 0; - if (!isSymbolEqual(IC_FALSE(left),IC_FALSE(right))) - return 0; - } - return 1; + } + else + { + if (!isOperandEqual (IC_COND (left), IC_COND (right))) + return 0; + if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right))) + return 0; + if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right))) + return 0; + } + return 1; } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* newiTempFromOp - create a temp Operand with same attributes */ /*-----------------------------------------------------------------*/ -operand *newiTempFromOp (operand *op) +operand * +newiTempFromOp (operand * op) { - operand *nop; + operand *nop; - if (!op) - return NULL; + if (!op) + return NULL; - if (!IS_ITEMP(op)) - return op; + if (!IS_ITEMP (op)) + return op; - nop = newiTempOperand(operandType(op),TRUE); - nop->isaddr = op->isaddr ; - nop->isvolatile = op->isvolatile ; - nop->isGlobal = op->isGlobal ; - nop->isLiteral= op->isLiteral ; - nop->noSpilLoc= op->noSpilLoc; - nop->usesDefs = op->usesDefs; - nop->isParm = op->isParm; - nop->parmBytes = op->parmBytes; - return nop; + nop = newiTempOperand (operandType (op), TRUE); + nop->isaddr = op->isaddr; + nop->isvolatile = op->isvolatile; + nop->isGlobal = op->isGlobal; + nop->isLiteral = op->isLiteral; + nop->noSpilLoc = op->noSpilLoc; + nop->usesDefs = op->usesDefs; + nop->isParm = op->isParm; + nop->parmBytes = op->parmBytes; + return nop; } /*-----------------------------------------------------------------*/ /* operand from operand - creates an operand holder for the type */ /*-----------------------------------------------------------------*/ -operand *operandFromOperand (operand *op) +operand * +operandFromOperand (operand * op) { - operand *nop ; + operand *nop; - if (!op) - return NULL; - nop = newOperand(); - nop->type = op->type; - nop->isaddr = op->isaddr ; - nop->key = op->key ; - nop->isvolatile = op->isvolatile ; - nop->isGlobal = op->isGlobal ; - nop->isLiteral= op->isLiteral ; - nop->noSpilLoc= op->noSpilLoc; - nop->usesDefs = op->usesDefs; - nop->isParm = op->isParm; - nop->parmBytes = op->parmBytes; - - switch (nop->type) { - case SYMBOL : - nop->operand.symOperand = op->operand.symOperand ; - break; - case VALUE : - nop->operand.valOperand = op->operand.valOperand; - break; - case TYPE : - nop->operand.typeOperand = op->operand.typeOperand ; - break ; - } - - return nop; + if (!op) + return NULL; + nop = newOperand (); + nop->type = op->type; + nop->isaddr = op->isaddr; + nop->key = op->key; + nop->isvolatile = op->isvolatile; + nop->isGlobal = op->isGlobal; + nop->isLiteral = op->isLiteral; + nop->noSpilLoc = op->noSpilLoc; + nop->usesDefs = op->usesDefs; + nop->isParm = op->isParm; + nop->parmBytes = op->parmBytes; + + switch (nop->type) + { + case SYMBOL: + nop->operand.symOperand = op->operand.symOperand; + break; + case VALUE: + nop->operand.valOperand = op->operand.valOperand; + break; + case TYPE: + nop->operand.typeOperand = op->operand.typeOperand; + break; + } + + return nop; } /*-----------------------------------------------------------------*/ /* opFromOpWithDU - makes a copy of the operand and DU chains */ /*-----------------------------------------------------------------*/ -operand *opFromOpWithDU (operand *op, bitVect *defs, bitVect *uses) +operand * +opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses) { - operand *nop = operandFromOperand(op); + operand *nop = operandFromOperand (op); - if (nop->type == SYMBOL) { - OP_SYMBOL(nop)->defs = bitVectCopy(defs); - OP_SYMBOL(nop)->uses = bitVectCopy(uses); + if (nop->type == SYMBOL) + { + OP_SYMBOL (nop)->defs = bitVectCopy (defs); + OP_SYMBOL (nop)->uses = bitVectCopy (uses); } - return nop; + return nop; } /*-----------------------------------------------------------------*/ /* operandFromSymbol - creates an operand from a symbol */ /*-----------------------------------------------------------------*/ -operand *operandFromSymbol (symbol *sym) -{ - operand *op ; - iCode *ic ; - int ok =1 ; - /* if the symbol's type is a literal */ - /* then it is an enumerator type */ - if (IS_LITERAL(sym->etype) && SPEC_ENUM(sym->etype)) - return operandFromValue (valFromType(sym->etype)); - - if (!sym->key) - sym->key = ++operandKey ; - - /* if this an implicit variable, means struct/union */ - /* member so just return it */ - if (sym->implicit || IS_FUNC(sym->type)) { - op = newOperand(); - op->type = SYMBOL ; - op->operand.symOperand = sym; - op->key = sym->key ; - op->isvolatile = isOperandVolatile(op,TRUE); - op->isGlobal = isOperandGlobal(op); - op->parmBytes = sym->argStack; - return op; +operand * +operandFromSymbol (symbol * sym) +{ + operand *op; + iCode *ic; + int ok = 1; + /* if the symbol's type is a literal */ + /* then it is an enumerator type */ + if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype)) + return operandFromValue (valFromType (sym->etype)); + + if (!sym->key) + sym->key = ++operandKey; + + /* if this an implicit variable, means struct/union */ + /* member so just return it */ + if (sym->implicit || IS_FUNC (sym->type)) + { + op = newOperand (); + op->type = SYMBOL; + op->operand.symOperand = sym; + op->key = sym->key; + op->isvolatile = isOperandVolatile (op, TRUE); + op->isGlobal = isOperandGlobal (op); + op->parmBytes = sym->argStack; + return op; } - /* under the following conditions create a - register equivalent for a local symbol */ - if (sym->level && sym->etype && SPEC_OCLS(sym->etype) && - (IN_FARSPACE(SPEC_OCLS(sym->etype)) && (!IS_DS390_PORT)) && - options.stackAuto == 0) - ok =0; - - if (!IS_AGGREGATE(sym->type) && /* not an aggregate */ - !IS_FUNC(sym->type) && /* not a function */ - !sym->_isparm && /* not a parameter */ - sym->level && /* is a local variable */ - !sym->addrtaken && /* whose address has not been taken */ - !sym->reqv && /* does not already have a register euivalence */ - !IS_VOLATILE(sym->etype) && /* not declared as volatile */ - !IS_STATIC(sym->etype) && /* and not declared static */ - !sym->islbl && /* not a label */ - ok && /* farspace check */ - !IS_BITVAR(sym->etype) /* not a bit variable */ - ) { - - /* we will use it after all optimizations - and before liveRange calculation */ - sym->reqv = newiTempOperand(sym->type,0); - sym->reqv->key = sym->key ; - OP_SYMBOL(sym->reqv)->key = sym->key; - OP_SYMBOL(sym->reqv)->isreqv = 1; - OP_SYMBOL(sym->reqv)->islocal = 1; - SPIL_LOC(sym->reqv) = sym; - } - - if (!IS_AGGREGATE(sym->type)) { - op = newOperand(); - op->type = SYMBOL; - op->operand.symOperand = sym; - op->isaddr = 1; - op->key = sym->key; - op->isvolatile = isOperandVolatile(op,TRUE); - op->isGlobal = isOperandGlobal(op); - op->isPtr = IS_PTR(operandType(op)); - op->isParm = sym->_isparm ; - return op; + /* under the following conditions create a + register equivalent for a local symbol */ + if (sym->level && sym->etype && SPEC_OCLS (sym->etype) && + (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!IS_DS390_PORT)) && + options.stackAuto == 0) + ok = 0; + + if (!IS_AGGREGATE (sym->type) && /* not an aggregate */ + !IS_FUNC (sym->type) && /* not a function */ + !sym->_isparm && /* not a parameter */ + sym->level && /* is a local variable */ + !sym->addrtaken && /* whose address has not been taken */ + !sym->reqv && /* does not already have a register euivalence */ + !IS_VOLATILE (sym->etype) && /* not declared as volatile */ + !IS_STATIC (sym->etype) && /* and not declared static */ + !sym->islbl && /* not a label */ + ok && /* farspace check */ + !IS_BITVAR (sym->etype) /* not a bit variable */ + ) + { + + /* we will use it after all optimizations + and before liveRange calculation */ + sym->reqv = newiTempOperand (sym->type, 0); + sym->reqv->key = sym->key; + OP_SYMBOL (sym->reqv)->key = sym->key; + OP_SYMBOL (sym->reqv)->isreqv = 1; + OP_SYMBOL (sym->reqv)->islocal = 1; + SPIL_LOC (sym->reqv) = sym; } - /* create :- */ - /* itemp = &[_symbol] */ + if (!IS_AGGREGATE (sym->type)) + { + op = newOperand (); + op->type = SYMBOL; + op->operand.symOperand = sym; + op->isaddr = 1; + op->key = sym->key; + op->isvolatile = isOperandVolatile (op, TRUE); + op->isGlobal = isOperandGlobal (op); + op->isPtr = IS_PTR (operandType (op)); + op->isParm = sym->_isparm; + return op; + } + + /* create :- */ + /* itemp = &[_symbol] */ - ic = newiCode(ADDRESS_OF,newOperand(),NULL); - IC_LEFT(ic)->type = SYMBOL ; - IC_LEFT(ic)->operand.symOperand = sym ; - IC_LEFT(ic)->key = sym->key; - (IC_LEFT(ic))->isvolatile = isOperandVolatile(IC_LEFT(ic),TRUE); - (IC_LEFT(ic))->isGlobal = isOperandGlobal(IC_LEFT(ic)); - IC_LEFT(ic)->isPtr = IS_PTR(operandType(IC_LEFT(ic))); + ic = newiCode (ADDRESS_OF, newOperand (), NULL); + IC_LEFT (ic)->type = SYMBOL; + IC_LEFT (ic)->operand.symOperand = sym; + IC_LEFT (ic)->key = sym->key; + (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE); + (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic)); + IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic))); - /* create result */ - IC_RESULT(ic) = newiTempOperand(sym->type,0); - if (IS_ARRAY(sym->type)) { - IC_RESULT(ic) = geniCodeArray2Ptr (IC_RESULT(ic)); - IC_RESULT(ic)->isaddr = 0; - } else - IC_RESULT(ic)->isaddr = (!IS_AGGREGATE(sym->type)); + /* create result */ + IC_RESULT (ic) = newiTempOperand (sym->type, 0); + if (IS_ARRAY (sym->type)) + { + IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic)); + IC_RESULT (ic)->isaddr = 0; + } + else + IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type)); - IC_RESULT(ic)->operand.symOperand->args = sym->args; + IC_RESULT (ic)->operand.symOperand->args = sym->args; - ADDTOCHAIN(ic); + ADDTOCHAIN (ic); - return IC_RESULT(ic) ; + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* operandFromValue - creates an operand from value */ /*-----------------------------------------------------------------*/ -operand *operandFromValue (value *val) +operand * +operandFromValue (value * val) { - operand *op ; + operand *op; - /* if this is a symbol then do the symbol thing */ - if (val->sym) - return operandFromSymbol (val->sym); + /* if this is a symbol then do the symbol thing */ + if (val->sym) + return operandFromSymbol (val->sym); - /* this is not a symbol */ - op = newOperand(); - op->type = VALUE ; - op->operand.valOperand = val ; - op->isLiteral = isOperandLiteral(op); - return op; + /* this is not a symbol */ + op = newOperand (); + op->type = VALUE; + op->operand.valOperand = val; + op->isLiteral = isOperandLiteral (op); + return op; } /*-----------------------------------------------------------------*/ /* operandFromLink - operand from typeChain */ /*-----------------------------------------------------------------*/ -operand *operandFromLink (sym_link *type) +operand * +operandFromLink (sym_link * type) { - operand *op ; + operand *op; - /* operand from sym_link */ - if ( ! type ) - return NULL ; + /* operand from sym_link */ + if (!type) + return NULL; - op = newOperand(); - op->type = TYPE ; - op->operand.typeOperand = copyLinkChain(type); - return op; + op = newOperand (); + op->type = TYPE; + op->operand.typeOperand = copyLinkChain (type); + return op; } /*-----------------------------------------------------------------*/ /* operandFromLit - makes an operand from a literal value */ /*-----------------------------------------------------------------*/ -operand *operandFromLit ( float i) +operand * +operandFromLit (float i) { - return operandFromValue (valueFromLit (i)); + return operandFromValue (valueFromLit (i)); } /*-----------------------------------------------------------------*/ /* operandFromAst - creates an operand from an ast */ /*-----------------------------------------------------------------*/ -operand *operandFromAst ( ast *tree ) +operand * +operandFromAst (ast * tree) { - if (! tree ) - return NULL ; + if (!tree) + return NULL; - /* depending on type do */ - switch (tree->type ) { - case EX_OP : - return ast2iCode (tree) ; - break ; + /* depending on type do */ + switch (tree->type) + { + case EX_OP: + return ast2iCode (tree); + break; - case EX_VALUE : - return operandFromValue(tree->opval.val) ; - break ; + case EX_VALUE: + return operandFromValue (tree->opval.val); + break; - case EX_LINK : - return operandFromLink (tree->opval.lnk) ; + case EX_LINK: + return operandFromLink (tree->opval.lnk); } - assert(0); - /* Just to keep the comiler happy */ - return (operand *)0; + assert (0); + /* Just to keep the comiler happy */ + return (operand *) 0; } /*-----------------------------------------------------------------*/ /* setOperandType - sets the operand's type to the given type */ /*-----------------------------------------------------------------*/ -void setOperandType (operand *op, sym_link *type) +void +setOperandType (operand * op, sym_link * type) { - /* depending on the type of operand */ - switch (op->type) { + /* depending on the type of operand */ + switch (op->type) + { - case VALUE : - op->operand.valOperand->etype = - getSpec( op->operand.valOperand->type = - copyLinkChain (type )) ; - return ; + case VALUE: + op->operand.valOperand->etype = + getSpec (op->operand.valOperand->type = + copyLinkChain (type)); + return; - case SYMBOL : - if (op->operand.symOperand->isitmp ) - op->operand.symOperand->etype = - getSpec( op->operand.symOperand->type = - copyLinkChain (type )) ; - else - werror (E_INTERNAL_ERROR,__FILE__,__LINE__, - "attempt to modify type of source"); - return; + case SYMBOL: + if (op->operand.symOperand->isitmp) + op->operand.symOperand->etype = + getSpec (op->operand.symOperand->type = + copyLinkChain (type)); + else + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "attempt to modify type of source"); + return; case TYPE: - op->operand.typeOperand = copyLinkChain (type); - return ; + op->operand.typeOperand = copyLinkChain (type); + return; } } @@ -1276,137 +1347,139 @@ void setOperandType (operand *op, sym_link *type) /*-----------------------------------------------------------------*/ /* perform "usual unary conversions" */ /*-----------------------------------------------------------------*/ -operand *usualUnaryConversions(operand *op) +operand * +usualUnaryConversions (operand * op) { - if (IS_INTEGRAL(operandType(op))) + if (IS_INTEGRAL (operandType (op))) { - if (getSize(operandType(op)) < INTSIZE) - { - /* Widen to int. */ - return geniCodeCast(INTTYPE,op,TRUE); - } + if (getSize (operandType (op)) < INTSIZE) + { + /* Widen to int. */ + return geniCodeCast (INTTYPE, op, TRUE); + } } - return op; + return op; } /*-----------------------------------------------------------------*/ /* perform "usual binary conversions" */ /*-----------------------------------------------------------------*/ -sym_link * usualBinaryConversions(operand **op1, operand **op2) +sym_link * +usualBinaryConversions (operand ** op1, operand ** op2) { - if (!options.ANSIint) + if (!options.ANSIint) { /* "Classic" SDCC behavior. */ sym_link *ctype; - sym_link *rtype = operandType(*op2); - sym_link *ltype = operandType(*op1); + sym_link *rtype = operandType (*op2); + sym_link *ltype = operandType (*op1); - ctype = computeType(ltype,rtype); - *op1 = geniCodeCast(ctype,*op1,TRUE); - *op2= geniCodeCast(ctype,*op2,TRUE); + ctype = computeType (ltype, rtype); + *op1 = geniCodeCast (ctype, *op1, TRUE); + *op2 = geniCodeCast (ctype, *op2, TRUE); return ctype; } - *op1 = usualUnaryConversions(*op1); - *op2 = usualUnaryConversions(*op2); + *op1 = usualUnaryConversions (*op1); + *op2 = usualUnaryConversions (*op2); - /* Try to make the two operands of the same type, following - * the "usual binary conversions" promotion rules. - * - * NB: floating point types are not yet properly handled; we - * follow the "classic" behavior. - */ + /* Try to make the two operands of the same type, following + * the "usual binary conversions" promotion rules. + * + * NB: floating point types are not yet properly handled; we + * follow the "classic" behavior. + */ - if (IS_FLOAT(operandType(*op1)) || IS_FLOAT(operandType(*op2))) + if (IS_FLOAT (operandType (*op1)) || IS_FLOAT (operandType (*op2))) { - return newFloatLink(); + return newFloatLink (); } - if (!IS_INTEGRAL(operandType(*op1)) || !IS_INTEGRAL(operandType(*op2))) + if (!IS_INTEGRAL (operandType (*op1)) || !IS_INTEGRAL (operandType (*op2))) { - /* if either is not an integer type, we're done. */ - return copyLinkChain(operandType(*op1)); /* Punt! we should never get here. */ + /* if either is not an integer type, we're done. */ + return copyLinkChain (operandType (*op1)); /* Punt! we should never get here. */ } - /* If either is an unsigned long, make sure both are. */ - if (SPEC_USIGN(operandType(*op1)) && IS_LONG(operandType(*op1))) + /* If either is an unsigned long, make sure both are. */ + if (SPEC_USIGN (operandType (*op1)) && IS_LONG (operandType (*op1))) { - if (!SPEC_USIGN(operandType(*op2)) || !IS_LONG(operandType(*op2))) - { - *op2 = geniCodeCast(ULONGTYPE,*op2,TRUE); - } - return copyLinkChain(operandType(*op1)); + if (!SPEC_USIGN (operandType (*op2)) || !IS_LONG (operandType (*op2))) + { + *op2 = geniCodeCast (ULONGTYPE, *op2, TRUE); + } + return copyLinkChain (operandType (*op1)); } - if (SPEC_USIGN(operandType(*op2)) && IS_LONG(operandType(*op2))) + if (SPEC_USIGN (operandType (*op2)) && IS_LONG (operandType (*op2))) { - if (!SPEC_USIGN(operandType(*op1)) || !IS_LONG(operandType(*op1))) - { - *op1 = geniCodeCast(ULONGTYPE,*op1,TRUE); - } - return copyLinkChain(operandType(*op2)); - } - - /* Next, if one is long and the other is int (signed or un), - * cast both to long. - * - * Note that because in our environment a long can hold all - * the values of an unsigned int, the "long/unsigned int" pair - * in the ANSI conversion table is unnecessary; this test - * handles that case implicitly. - */ - if (IS_LONG(operandType(*op1))) + if (!SPEC_USIGN (operandType (*op1)) || !IS_LONG (operandType (*op1))) + { + *op1 = geniCodeCast (ULONGTYPE, *op1, TRUE); + } + return copyLinkChain (operandType (*op2)); + } + + /* Next, if one is long and the other is int (signed or un), + * cast both to long. + * + * Note that because in our environment a long can hold all + * the values of an unsigned int, the "long/unsigned int" pair + * in the ANSI conversion table is unnecessary; this test + * handles that case implicitly. + */ + if (IS_LONG (operandType (*op1))) { - /* NB: because of the unary conversions, op2 cannot - * be smaller than int. Therefore, if it is not - * long, it is a regular int. - */ - if (!IS_LONG(operandType(*op2))) - { - *op2 = geniCodeCast(LONGTYPE,*op2,TRUE); - } - return copyLinkChain(operandType(*op1)); + /* NB: because of the unary conversions, op2 cannot + * be smaller than int. Therefore, if it is not + * long, it is a regular int. + */ + if (!IS_LONG (operandType (*op2))) + { + *op2 = geniCodeCast (LONGTYPE, *op2, TRUE); + } + return copyLinkChain (operandType (*op1)); } - if (IS_LONG(operandType(*op2))) + if (IS_LONG (operandType (*op2))) { - /* NB: because of the unary conversions, op2 cannot - * be smaller than int. Therefore, if it is not - * long, it is a regular int. - */ - if (!IS_LONG(operandType(*op1))) - { - *op1 = geniCodeCast(LONGTYPE,*op1,TRUE); - } - return copyLinkChain(operandType(*op2)); + /* NB: because of the unary conversions, op2 cannot + * be smaller than int. Therefore, if it is not + * long, it is a regular int. + */ + if (!IS_LONG (operandType (*op1))) + { + *op1 = geniCodeCast (LONGTYPE, *op1, TRUE); + } + return copyLinkChain (operandType (*op2)); } - /* All right, neither is long; they must both be integers. - * - * Only remaining issue is signed vs. unsigned; if one is unsigned - * and the other isn't, convert both to unsigned. - */ - if (SPEC_USIGN(operandType(*op1))) + /* All right, neither is long; they must both be integers. + + * Only remaining issue is signed vs. unsigned; if one is unsigned + * and the other isn't, convert both to unsigned. + */ + if (SPEC_USIGN (operandType (*op1))) { - if (!SPEC_USIGN(operandType(*op2))) - { - *op2 = geniCodeCast(UINTTYPE,*op2,TRUE); - } - return copyLinkChain(operandType(*op1)); + if (!SPEC_USIGN (operandType (*op2))) + { + *op2 = geniCodeCast (UINTTYPE, *op2, TRUE); + } + return copyLinkChain (operandType (*op1)); } - if (SPEC_USIGN(operandType(*op2))) + if (SPEC_USIGN (operandType (*op2))) { - if (!SPEC_USIGN(operandType(*op1))) - { - *op1 = geniCodeCast(UINTTYPE,*op1,TRUE); - } - return copyLinkChain(operandType(*op2)); + if (!SPEC_USIGN (operandType (*op1))) + { + *op1 = geniCodeCast (UINTTYPE, *op1, TRUE); + } + return copyLinkChain (operandType (*op2)); } - /* Done! */ - return copyLinkChain(operandType(*op1)); + /* Done! */ + return copyLinkChain (operandType (*op1)); } @@ -1414,788 +1487,835 @@ sym_link * usualBinaryConversions(operand **op1, operand **op2) /* geniCodeValueAtAddress - generate intermeditate code for value */ /* at address */ /*-----------------------------------------------------------------*/ -operand *geniCodeRValue (operand *op, bool force) +operand * +geniCodeRValue (operand * op, bool force) { - iCode *ic ; - sym_link *type = operandType(op); - sym_link *etype= getSpec(type); + iCode *ic; + sym_link *type = operandType (op); + sym_link *etype = getSpec (type); - /* if this is an array & already */ - /* an address then return this */ - if (IS_AGGREGATE(type) || - (IS_PTR(type) && !force && !op->isaddr)) - return operandFromOperand(op); + /* if this is an array & already */ + /* an address then return this */ + if (IS_AGGREGATE (type) || + (IS_PTR (type) && !force && !op->isaddr)) + return operandFromOperand (op); - /* if this is not an address then must be */ - /* rvalue already so return this one */ - if (!op->isaddr) - return op ; + /* if this is not an address then must be */ + /* rvalue already so return this one */ + if (!op->isaddr) + return op; - /* if this is not a temp symbol then */ - if (!IS_ITEMP(op) && - !force && - !IN_FARSPACE(SPEC_OCLS(etype))) { - op = operandFromOperand(op); - op->isaddr = 0; - return op; + /* if this is not a temp symbol then */ + if (!IS_ITEMP (op) && + !force && + !IN_FARSPACE (SPEC_OCLS (etype))) + { + op = operandFromOperand (op); + op->isaddr = 0; + return op; } - if (IS_SPEC(type) && - IS_TRUE_SYMOP(op) && - (!IN_FARSPACE(SPEC_OCLS(etype)) || IS_DS390_PORT)) { - op = operandFromOperand(op); - op->isaddr = 0; - return op; + if (IS_SPEC (type) && + IS_TRUE_SYMOP (op) && + (!IN_FARSPACE (SPEC_OCLS (etype)) || IS_DS390_PORT)) + { + op = operandFromOperand (op); + op->isaddr = 0; + return op; } - ic = newiCode(GET_VALUE_AT_ADDRESS,op,NULL); - if (IS_PTR(type) && op->isaddr && force) - type = type->next; + ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL); + if (IS_PTR (type) && op->isaddr && force) + type = type->next; - type = copyLinkChain(type); + type = copyLinkChain (type); - IC_RESULT(ic) = newiTempOperand (type,1); - IC_RESULT(ic)->isaddr = 0; + IC_RESULT (ic) = newiTempOperand (type, 1); + IC_RESULT (ic)->isaddr = 0; /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */ - /* if the right is a symbol */ - if (op->type == SYMBOL) - IC_RESULT(ic)->operand.symOperand->args = - op->operand.symOperand->args ; - ADDTOCHAIN(ic); + /* if the right is a symbol */ + if (op->type == SYMBOL) + IC_RESULT (ic)->operand.symOperand->args = + op->operand.symOperand->args; + ADDTOCHAIN (ic); - return IC_RESULT(ic) ; + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeCast - changes the value from one type to another */ /*-----------------------------------------------------------------*/ -operand *geniCodeCast (sym_link *type, operand *op, bool implicit) +operand * +geniCodeCast (sym_link * type, operand * op, bool implicit) { - iCode *ic ; - sym_link *optype ; - sym_link *opetype = getSpec(optype = operandType(op)); - sym_link *restype ; + iCode *ic; + sym_link *optype; + sym_link *opetype = getSpec (optype = operandType (op)); + sym_link *restype; - /* one of them has size zero then error */ - if (IS_VOID(optype)) { - werror(E_CAST_ZERO); - return op; + /* one of them has size zero then error */ + if (IS_VOID (optype)) + { + werror (E_CAST_ZERO); + return op; } - /* if the operand is already the desired type then do nothing */ - if ( checkType (type,optype) == 1) - return op; + /* if the operand is already the desired type then do nothing */ + if (checkType (type, optype) == 1) + return op; - /* if this is a literal then just change the type & return */ - if (IS_LITERAL(opetype) && op->type == VALUE && !IS_PTR(type) && !IS_PTR(optype)) - return operandFromValue(valCastLiteral(type, - operandLitValue(op))); + /* if this is a literal then just change the type & return */ + if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype)) + return operandFromValue (valCastLiteral (type, + operandLitValue (op))); + + /* if casting to some pointer type && + the destination is not a generic pointer + then give a warning : (only for implicit casts) */ + if (IS_PTR (optype) && implicit && + (DCL_TYPE (optype) != DCL_TYPE (type)) && + !IS_GENPTR (type)) + { + werror (E_INCOMPAT_CAST); + werror (E_CONTINUE, "from type '"); + printTypeChain (optype, stderr); + fprintf (stderr, "' to type '"); + printTypeChain (type, stderr); + fprintf (stderr, "'\n"); + } + + /* if they are the same size create an assignment */ + if (getSize (type) == getSize (optype) && + !IS_BITFIELD (type) && + !IS_FLOAT (type) && + !IS_FLOAT (optype) && + ((IS_SPEC (type) && IS_SPEC (optype)) || + (!IS_SPEC (type) && !IS_SPEC (optype)))) + { - /* if casting to some pointer type && - the destination is not a generic pointer - then give a warning : (only for implicit casts)*/ - if (IS_PTR(optype) && implicit && - (DCL_TYPE(optype) != DCL_TYPE(type)) && - !IS_GENPTR(type)) { - werror(E_INCOMPAT_CAST); - werror(E_CONTINUE,"from type '"); - printTypeChain(optype,stderr);fprintf(stderr,"' to type '"); - printTypeChain(type,stderr);fprintf(stderr,"'\n"); + ic = newiCode ('=', NULL, op); + IC_RESULT (ic) = newiTempOperand (type, 0); + SPIL_LOC (IC_RESULT (ic)) = + (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL); + IC_RESULT (ic)->isaddr = 0; } + else + { + ic = newiCode (CAST, operandFromLink (type), + geniCodeRValue (op, FALSE)); - /* if they are the same size create an assignment */ - if (getSize(type) == getSize(optype) && - !IS_BITFIELD(type) && - !IS_FLOAT(type) && - !IS_FLOAT(optype) && - ((IS_SPEC(type) && IS_SPEC(optype)) || - (!IS_SPEC(type) && !IS_SPEC(optype)))) { - - ic = newiCode('=',NULL,op); - IC_RESULT(ic) = newiTempOperand(type,0); - SPIL_LOC(IC_RESULT(ic)) = - (IS_TRUE_SYMOP(op) ? OP_SYMBOL(op) : NULL); - IC_RESULT(ic)->isaddr = 0; - } else { - ic = newiCode(CAST,operandFromLink(type), - geniCodeRValue(op,FALSE)); - - IC_RESULT(ic)= newiTempOperand(type,0); + IC_RESULT (ic) = newiTempOperand (type, 0); } - /* preserve the storage class & output class */ - /* of the original variable */ - restype = getSpec(operandType(IC_RESULT(ic))); - SPEC_SCLS(restype) = SPEC_SCLS(opetype); - SPEC_OCLS(restype) = SPEC_OCLS(opetype); + /* preserve the storage class & output class */ + /* of the original variable */ + restype = getSpec (operandType (IC_RESULT (ic))); + SPEC_SCLS (restype) = SPEC_SCLS (opetype); + SPEC_OCLS (restype) = SPEC_OCLS (opetype); - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeLabel - will create a Label */ /*-----------------------------------------------------------------*/ -void geniCodeLabel (symbol *label) +void +geniCodeLabel (symbol * label) { - iCode *ic; + iCode *ic; - ic = newiCodeLabelGoto(LABEL,label); - ADDTOCHAIN(ic); + ic = newiCodeLabelGoto (LABEL, label); + ADDTOCHAIN (ic); } /*-----------------------------------------------------------------*/ /* geniCodeGoto - will create a Goto */ /*-----------------------------------------------------------------*/ -void geniCodeGoto (symbol *label) +void +geniCodeGoto (symbol * label) { - iCode *ic; + iCode *ic; - ic = newiCodeLabelGoto(GOTO,label); - ADDTOCHAIN(ic); + ic = newiCodeLabelGoto (GOTO, label); + ADDTOCHAIN (ic); } /*-----------------------------------------------------------------*/ /* geniCodeMultiply - gen intermediate code for multiplication */ /*-----------------------------------------------------------------*/ -operand *geniCodeMultiply (operand *left, operand *right,bool ptrSizeCalculation) -{ - iCode *ic ; - int p2 = 0; - int saveOption; - sym_link *resType ; - LRTYPE ; - - /* if they are both literal then we know the result */ - if (IS_LITERAL(letype) && IS_LITERAL(retype)) - return operandFromValue (valMult(left->operand.valOperand, - right->operand.valOperand)); - - - //Force 1 byte * 1 byte = 2 bytes result if we are computing ptr size - if ((ptrSizeCalculation)&&(1==getSize(rtype))&& - (1==getSize(ltype))) { - saveOption = options.ANSIint; - options.ANSIint = 0; - resType = usualBinaryConversions(&left, &right); - ltype = operandType(left); - rtype = operandType(right); - SPEC_SHORT(getSpec(resType)) = 0; - options.ANSIint = saveOption; - } - else - resType = usualBinaryConversions(&left, &right); - - /* if the right is a literal & power of 2 */ - /* then make it a left shift */ - /*If we are computing ptr size then normal multiplication*/ - /*code generated for 1 byte * 1 byte literal = 2 bytes result is more efficient in most cases*/ - /*than 2 bytes result = 2 bytes << literal if port as 1 byte muldiv*/ - if (IS_LITERAL(retype) && !IS_FLOAT(letype) && - !((ptrSizeCalculation)&&(getSize(resType)!=getSize(ltype))&&(1==port->muldiv.native_below))&& - (p2 = powof2 ((unsigned long)floatFromVal(right->operand.valOperand)))) +operand * +geniCodeMultiply (operand * left, operand * right, bool ptrSizeCalculation) +{ + iCode *ic; + int p2 = 0; + int saveOption; + sym_link *resType; + LRTYPE; + + /* if they are both literal then we know the result */ + if (IS_LITERAL (letype) && IS_LITERAL (retype)) + return operandFromValue (valMult (left->operand.valOperand, + right->operand.valOperand)); + + + //Force 1 byte * 1 byte = 2 bytes result if we are computing ptr size + if ((ptrSizeCalculation) && (1 == getSize (rtype)) && + (1 == getSize (ltype))) + { + saveOption = options.ANSIint; + options.ANSIint = 0; + resType = usualBinaryConversions (&left, &right); + ltype = operandType (left); + rtype = operandType (right); + SPEC_SHORT (getSpec (resType)) = 0; + options.ANSIint = saveOption; + } + else + resType = usualBinaryConversions (&left, &right); + + /* if the right is a literal & power of 2 */ + /* then make it a left shift */ + /*If we are computing ptr size then normal multiplication */ + /*code generated for 1 byte * 1 byte literal = 2 bytes result is more efficient in most cases */ + /*than 2 bytes result = 2 bytes << literal if port as 1 byte muldiv */ + if (IS_LITERAL (retype) && !IS_FLOAT (letype) && + !((ptrSizeCalculation) && (getSize (resType) != getSize (ltype)) && (1 == port->muldiv.native_below)) && + (p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand)))) + { + if ((ptrSizeCalculation) && (getSize (resType) != getSize (ltype))) { - if((ptrSizeCalculation)&&(getSize(resType)!=getSize(ltype))){ - /* LEFT_OP need same size for left and result, */ - left = geniCodeCast(resType,left,TRUE); - ltype = operandType(left); - } - ic = newiCode(LEFT_OP, left,operandFromLit(p2)); /* left shift */ + /* LEFT_OP need same size for left and result, */ + left = geniCodeCast (resType, left, TRUE); + ltype = operandType (left); } - else { - ic = newiCode('*',left,right); /* normal multiplication */ - /* if the size left or right > 1 then support routine */ - if (getSize(ltype) > 1 || getSize(rtype) > 1) - ic->supportRtn = 1; + ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */ + } + else + { + ic = newiCode ('*', left, right); /* normal multiplication */ + /* if the size left or right > 1 then support routine */ + if (getSize (ltype) > 1 || getSize (rtype) > 1) + ic->supportRtn = 1; } - IC_RESULT(ic) = newiTempOperand(resType,1); + IC_RESULT (ic) = newiTempOperand (resType, 1); - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeDivision - gen intermediate code for division */ /*-----------------------------------------------------------------*/ -operand *geniCodeDivision (operand *left, operand *right) -{ - iCode *ic ; - int p2 = 0; - sym_link *resType; - sym_link *rtype = operandType(right); - sym_link *retype= getSpec(rtype); - sym_link *ltype = operandType(left); - sym_link *letype= getSpec(ltype); - - resType = usualBinaryConversions(&left, &right); - - /* if the right is a literal & power of 2 */ - /* then make it a right shift */ - if (IS_LITERAL(retype) && - !IS_FLOAT(letype) && - (p2 = powof2 ((unsigned long) - floatFromVal(right->operand.valOperand)))) - ic = newiCode(RIGHT_OP, left,operandFromLit(p2)); /* right shift */ - else { - ic = newiCode('/',left,right); /* normal division */ - /* if the size left or right > 1 then support routine */ - if (getSize(ltype) > 1 || getSize(rtype) > 1) - ic->supportRtn = 1; +operand * +geniCodeDivision (operand * left, operand * right) +{ + iCode *ic; + int p2 = 0; + sym_link *resType; + sym_link *rtype = operandType (right); + sym_link *retype = getSpec (rtype); + sym_link *ltype = operandType (left); + sym_link *letype = getSpec (ltype); + + resType = usualBinaryConversions (&left, &right); + + /* if the right is a literal & power of 2 */ + /* then make it a right shift */ + if (IS_LITERAL (retype) && + !IS_FLOAT (letype) && + (p2 = powof2 ((unsigned long) + floatFromVal (right->operand.valOperand)))) + ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */ + else + { + ic = newiCode ('/', left, right); /* normal division */ + /* if the size left or right > 1 then support routine */ + if (getSize (ltype) > 1 || getSize (rtype) > 1) + ic->supportRtn = 1; } - IC_RESULT(ic) = newiTempOperand(resType,0); + IC_RESULT (ic) = newiTempOperand (resType, 0); - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeModulus - gen intermediate code for modulus */ /*-----------------------------------------------------------------*/ -operand *geniCodeModulus (operand *left, operand *right) +operand * +geniCodeModulus (operand * left, operand * right) { - iCode *ic ; - sym_link *resType; - LRTYPE ; + iCode *ic; + sym_link *resType; + LRTYPE; - /* if they are both literal then we know the result */ - if (IS_LITERAL(letype) && IS_LITERAL(retype)) - return operandFromValue (valMod(left->operand.valOperand, - right->operand.valOperand)); + /* if they are both literal then we know the result */ + if (IS_LITERAL (letype) && IS_LITERAL (retype)) + return operandFromValue (valMod (left->operand.valOperand, + right->operand.valOperand)); - resType = usualBinaryConversions(&left, &right); + resType = usualBinaryConversions (&left, &right); - /* now they are the same size */ - ic = newiCode('%',left,right); + /* now they are the same size */ + ic = newiCode ('%', left, right); - /* if the size left or right > 1 then support routine */ - if (getSize(ltype) > 1 || getSize(rtype) > 1) - ic->supportRtn = 1; - IC_RESULT(ic) = newiTempOperand(resType,0); + /* if the size left or right > 1 then support routine */ + if (getSize (ltype) > 1 || getSize (rtype) > 1) + ic->supportRtn = 1; + IC_RESULT (ic) = newiTempOperand (resType, 0); - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodePtrPtrSubtract - subtracts pointer from pointer */ /*-----------------------------------------------------------------*/ -operand *geniCodePtrPtrSubtract (operand *left, operand *right) +operand * +geniCodePtrPtrSubtract (operand * left, operand * right) { - iCode *ic ; - operand *result; - LRTYPE ; + iCode *ic; + operand *result; + LRTYPE; - /* if they are both literals then */ - if (IS_LITERAL(letype) && IS_LITERAL(retype)) { - result = operandFromValue (valMinus(left->operand.valOperand, - right->operand.valOperand)); - goto subtractExit; + /* if they are both literals then */ + if (IS_LITERAL (letype) && IS_LITERAL (retype)) + { + result = operandFromValue (valMinus (left->operand.valOperand, + right->operand.valOperand)); + goto subtractExit; } - ic = newiCode('-',left,right); + ic = newiCode ('-', left, right); - IC_RESULT(ic) = result = newiTempOperand(newIntLink(),1); - ADDTOCHAIN(ic); + IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1); + ADDTOCHAIN (ic); - subtractExit: - return geniCodeDivision (result, - operandFromLit(getSize(ltype->next))); +subtractExit: + return geniCodeDivision (result, + operandFromLit (getSize (ltype->next))); } /*-----------------------------------------------------------------*/ /* geniCodeSubtract - generates code for subtraction */ /*-----------------------------------------------------------------*/ -operand *geniCodeSubtract (operand *left, operand *right) +operand * +geniCodeSubtract (operand * left, operand * right) { - iCode *ic ; - int isarray= 0; - sym_link *resType; - LRTYPE ; + iCode *ic; + int isarray = 0; + sym_link *resType; + LRTYPE; - /* if they both pointers then */ - if ((IS_PTR(ltype) || IS_ARRAY(ltype)) && - (IS_PTR(rtype) || IS_ARRAY(rtype))) - return geniCodePtrPtrSubtract (left,right); + /* if they both pointers then */ + if ((IS_PTR (ltype) || IS_ARRAY (ltype)) && + (IS_PTR (rtype) || IS_ARRAY (rtype))) + return geniCodePtrPtrSubtract (left, right); - /* if they are both literal then we know the result */ - if (IS_LITERAL(letype) && IS_LITERAL(retype) - && left->isLiteral && right->isLiteral) - return operandFromValue (valMinus(left->operand.valOperand, - right->operand.valOperand)); + /* if they are both literal then we know the result */ + if (IS_LITERAL (letype) && IS_LITERAL (retype) + && left->isLiteral && right->isLiteral) + return operandFromValue (valMinus (left->operand.valOperand, + right->operand.valOperand)); - /* if left is an array or pointer */ - if ( IS_PTR(ltype) || IS_ARRAY(ltype) ) { - isarray = left->isaddr ; - right = geniCodeMultiply (right, - operandFromLit(getSize(ltype->next)),TRUE); - resType = copyLinkChain(IS_ARRAY(ltype) ? ltype->next : ltype); + /* if left is an array or pointer */ + if (IS_PTR (ltype) || IS_ARRAY (ltype)) + { + isarray = left->isaddr; + right = geniCodeMultiply (right, + operandFromLit (getSize (ltype->next)), TRUE); + resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype); } - else { /* make them the same size */ - resType = usualBinaryConversions(&left, &right); + else + { /* make them the same size */ + resType = usualBinaryConversions (&left, &right); } - ic = newiCode('-',left,right); + ic = newiCode ('-', left, right); - IC_RESULT(ic)= newiTempOperand(resType,1); - IC_RESULT(ic)->isaddr = (isarray ? 1 : 0); + IC_RESULT (ic) = newiTempOperand (resType, 1); + IC_RESULT (ic)->isaddr = (isarray ? 1 : 0); - /* if left or right is a float */ - if (IS_FLOAT(ltype) || IS_FLOAT(rtype)) - ic->supportRtn = 1; + /* if left or right is a float */ + if (IS_FLOAT (ltype) || IS_FLOAT (rtype)) + ic->supportRtn = 1; - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeAdd - generates iCode for addition */ /*-----------------------------------------------------------------*/ -operand *geniCodeAdd (operand *left, operand *right ) +operand * +geniCodeAdd (operand * left, operand * right) { - iCode *ic ; - sym_link *resType ; - operand *size ; - int isarray = 0; - LRTYPE ; + iCode *ic; + sym_link *resType; + operand *size; + int isarray = 0; + LRTYPE; - /* if left is an array then array access */ - if (IS_ARRAY(ltype)) - return geniCodeArray (left,right); + /* if left is an array then array access */ + if (IS_ARRAY (ltype)) + return geniCodeArray (left, right); - /* if the right side is LITERAL zero */ - /* return the left side */ - if (IS_LITERAL(retype) && right->isLiteral && !floatFromVal(valFromType(retype))) - return left; + /* if the right side is LITERAL zero */ + /* return the left side */ + if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype))) + return left; - /* if left is literal zero return right */ - if (IS_LITERAL(letype) && left->isLiteral && !floatFromVal(valFromType(letype))) - return right ; + /* if left is literal zero return right */ + if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype))) + return right; + + /* if left is an array or pointer then size */ + if (IS_PTR (ltype)) + { - /* if left is an array or pointer then size */ - if (IS_PTR(ltype)) { - - isarray = left->isaddr; - size = - operandFromLit(getSize(ltype->next)); + isarray = left->isaddr; + size = + operandFromLit (getSize (ltype->next)); - right = geniCodeMultiply (right ,size,(getSize(ltype)!= 1)); + right = geniCodeMultiply (right, size, (getSize (ltype) != 1)); - resType = copyLinkChain(ltype); + resType = copyLinkChain (ltype); } - else { /* make them the same size */ - resType = usualBinaryConversions(&left, &right); + else + { /* make them the same size */ + resType = usualBinaryConversions (&left, &right); } - /* if they are both literals then we know */ - if (IS_LITERAL(letype) && IS_LITERAL(retype) - && left->isLiteral && right->isLiteral) - return operandFromValue (valPlus(valFromType(letype), - valFromType(retype))); + /* if they are both literals then we know */ + if (IS_LITERAL (letype) && IS_LITERAL (retype) + && left->isLiteral && right->isLiteral) + return operandFromValue (valPlus (valFromType (letype), + valFromType (retype))); - ic = newiCode('+',left,right); + ic = newiCode ('+', left, right); - IC_RESULT(ic) = newiTempOperand(resType,1); - IC_RESULT(ic)->isaddr = ( isarray ? 1 : 0); + IC_RESULT (ic) = newiTempOperand (resType, 1); + IC_RESULT (ic)->isaddr = (isarray ? 1 : 0); - /* if left or right is a float then support - routine */ - if (IS_FLOAT(ltype) || IS_FLOAT(rtype)) - ic->supportRtn = 1; + /* if left or right is a float then support + routine */ + if (IS_FLOAT (ltype) || IS_FLOAT (rtype)) + ic->supportRtn = 1; - ADDTOCHAIN(ic); + ADDTOCHAIN (ic); - return IC_RESULT(ic) ; + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* aggrToPtr - changes an aggregate to pointer to an aggregate */ /*-----------------------------------------------------------------*/ -sym_link *aggrToPtr ( sym_link *type, bool force) +sym_link * +aggrToPtr (sym_link * type, bool force) { - sym_link *etype ; - sym_link *ptype ; + sym_link *etype; + sym_link *ptype; - if (IS_PTR(type) && !force) - return type; + if (IS_PTR (type) && !force) + return type; - etype = getSpec(type); - ptype = newLink(); + etype = getSpec (type); + ptype = newLink (); - ptype->next = type; - /* if the output class is generic */ - if ((DCL_TYPE(ptype) = PTR_TYPE(SPEC_OCLS(etype))) == CPOINTER) - DCL_PTR_CONST(ptype) = port->mem.code_ro; + ptype->next = type; + /* if the output class is generic */ + if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER) + DCL_PTR_CONST (ptype) = port->mem.code_ro; - /* if the variable was declared a constant */ - /* then the pointer points to a constant */ - if (IS_CONSTANT(etype) ) - DCL_PTR_CONST(ptype) = 1; + /* if the variable was declared a constant */ + /* then the pointer points to a constant */ + if (IS_CONSTANT (etype)) + DCL_PTR_CONST (ptype) = 1; - /* the variable was volatile then pointer to volatile */ - if (IS_VOLATILE(etype)) - DCL_PTR_VOLATILE(ptype) = 1; - return ptype; + /* the variable was volatile then pointer to volatile */ + if (IS_VOLATILE (etype)) + DCL_PTR_VOLATILE (ptype) = 1; + return ptype; } /*-----------------------------------------------------------------*/ /* geniCodeArray2Ptr - array to pointer */ /*-----------------------------------------------------------------*/ -operand *geniCodeArray2Ptr (operand *op) +operand * +geniCodeArray2Ptr (operand * op) { - sym_link *optype = operandType(op); - sym_link *opetype = getSpec(optype); + sym_link *optype = operandType (op); + sym_link *opetype = getSpec (optype); - /* set the pointer depending on the storage class */ - if ((DCL_TYPE(optype) = PTR_TYPE(SPEC_OCLS(opetype))) == CPOINTER) - DCL_PTR_CONST(optype) = port->mem.code_ro; + /* set the pointer depending on the storage class */ + if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER) + DCL_PTR_CONST (optype) = port->mem.code_ro; - /* if the variable was declared a constant */ - /* then the pointer points to a constant */ - if (IS_CONSTANT(opetype) ) - DCL_PTR_CONST(optype) = 1; + /* if the variable was declared a constant */ + /* then the pointer points to a constant */ + if (IS_CONSTANT (opetype)) + DCL_PTR_CONST (optype) = 1; - /* the variable was volatile then pointer to volatile */ - if (IS_VOLATILE(opetype)) - DCL_PTR_VOLATILE(optype) = 1; - op->isaddr = 0; - return op; + /* the variable was volatile then pointer to volatile */ + if (IS_VOLATILE (opetype)) + DCL_PTR_VOLATILE (optype) = 1; + op->isaddr = 0; + return op; } /*-----------------------------------------------------------------*/ /* geniCodeArray - array access */ /*-----------------------------------------------------------------*/ -operand *geniCodeArray (operand *left,operand *right) +operand * +geniCodeArray (operand * left, operand * right) { - iCode *ic; - sym_link *ltype = operandType(left); + iCode *ic; + sym_link *ltype = operandType (left); - if (IS_PTR(ltype)) { - if (IS_PTR(ltype->next) && left->isaddr) - { - left = geniCodeRValue(left,FALSE); - } - return geniCodeDerefPtr(geniCodeAdd(left,right)); + if (IS_PTR (ltype)) + { + if (IS_PTR (ltype->next) && left->isaddr) + { + left = geniCodeRValue (left, FALSE); + } + return geniCodeDerefPtr (geniCodeAdd (left, right)); } - /* array access */ - right = geniCodeMultiply(right, - operandFromLit(getSize(ltype->next)),TRUE); + /* array access */ + right = geniCodeMultiply (right, + operandFromLit (getSize (ltype->next)), TRUE); - /* we can check for limits here */ - if (isOperandLiteral(right) && - IS_ARRAY(ltype) && - DCL_ELEM(ltype) && - (operandLitValue(right)/getSize(ltype->next)) >= DCL_ELEM(ltype)) { - werror(E_ARRAY_BOUND); - right = operandFromLit(0); + /* we can check for limits here */ + if (isOperandLiteral (right) && + IS_ARRAY (ltype) && + DCL_ELEM (ltype) && + (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype)) + { + werror (E_ARRAY_BOUND); + right = operandFromLit (0); } - ic = newiCode('+',left,right); + ic = newiCode ('+', left, right); - IC_RESULT(ic) = newiTempOperand(((IS_PTR(ltype) && - !IS_AGGREGATE(ltype->next) && - !IS_PTR(ltype->next)) - ? ltype : ltype->next),0); + IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) && + !IS_AGGREGATE (ltype->next) && + !IS_PTR (ltype->next)) + ? ltype : ltype->next), 0); - IC_RESULT(ic)->isaddr = (!IS_AGGREGATE(ltype->next)); - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next)); + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeStruct - generates intermediate code for structres */ /*-----------------------------------------------------------------*/ -operand *geniCodeStruct (operand *left, operand *right, bool islval) +operand * +geniCodeStruct (operand * left, operand * right, bool islval) { - iCode *ic ; - sym_link *type = operandType(left); - sym_link *etype = getSpec(type); - sym_link *retype ; - symbol *element = getStructElement(SPEC_STRUCT(etype), - right->operand.symOperand); + iCode *ic; + sym_link *type = operandType (left); + sym_link *etype = getSpec (type); + sym_link *retype; + symbol *element = getStructElement (SPEC_STRUCT (etype), + right->operand.symOperand); - /* add the offset */ - ic = newiCode('+',left,operandFromLit(element->offset)); + /* add the offset */ + ic = newiCode ('+', left, operandFromLit (element->offset)); - IC_RESULT(ic) = newiTempOperand(element->type,0); + IC_RESULT (ic) = newiTempOperand (element->type, 0); - /* preserve the storage & output class of the struct */ - /* as well as the volatile attribute */ - retype = getSpec(operandType(IC_RESULT(ic))); - SPEC_SCLS(retype) = SPEC_SCLS(etype); - SPEC_OCLS(retype) = SPEC_OCLS(etype); - SPEC_VOLATILE(retype) |= SPEC_VOLATILE(etype); + /* preserve the storage & output class of the struct */ + /* as well as the volatile attribute */ + retype = getSpec (operandType (IC_RESULT (ic))); + SPEC_SCLS (retype) = SPEC_SCLS (etype); + SPEC_OCLS (retype) = SPEC_OCLS (etype); + SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype); - if (IS_PTR(element->type)) - setOperandType(IC_RESULT(ic),aggrToPtr(operandType(IC_RESULT(ic)),TRUE)); + if (IS_PTR (element->type)) + setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE)); - IC_RESULT(ic)->isaddr = (!IS_AGGREGATE(element->type)); + IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type)); - ADDTOCHAIN(ic); - return (islval ? IC_RESULT(ic) : geniCodeRValue(IC_RESULT(ic),TRUE)); + ADDTOCHAIN (ic); + return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE)); } /*-----------------------------------------------------------------*/ /* geniCodePostInc - generate int code for Post increment */ /*-----------------------------------------------------------------*/ -operand *geniCodePostInc (operand *op) -{ - iCode *ic ; - operand *rOp ; - sym_link *optype = operandType(op); - operand *result ; - operand *rv = (IS_ITEMP(op) ? - geniCodeRValue(op,(IS_PTR(optype) ? TRUE : FALSE)) : - op); - sym_link *rvtype = operandType(rv); - int size = 0; - - /* if this is not an address we have trouble */ - if ( ! op->isaddr ) { - werror (E_LVALUE_REQUIRED,"++"); - return op ; +operand * +geniCodePostInc (operand * op) +{ + iCode *ic; + operand *rOp; + sym_link *optype = operandType (op); + operand *result; + operand *rv = (IS_ITEMP (op) ? + geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) : + op); + sym_link *rvtype = operandType (rv); + int size = 0; + + /* if this is not an address we have trouble */ + if (!op->isaddr) + { + werror (E_LVALUE_REQUIRED, "++"); + return op; } - rOp = newiTempOperand(rvtype,0); - rOp->noSpilLoc = 1; + rOp = newiTempOperand (rvtype, 0); + rOp->noSpilLoc = 1; - if (IS_ITEMP(rv)) - rv->noSpilLoc = 1; + if (IS_ITEMP (rv)) + rv->noSpilLoc = 1; - geniCodeAssign(rOp,rv,0); - - size = (IS_PTR(rvtype) ? getSize(rvtype->next) : 1); - if (IS_FLOAT(rvtype)) - ic = newiCode('+',rv,operandFromValue(constFloatVal("1.0"))); - else - ic = newiCode('+',rv,operandFromLit(size)); + geniCodeAssign (rOp, rv, 0); - IC_RESULT(ic) = result =newiTempOperand(rvtype,0); - ADDTOCHAIN(ic); + size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1); + if (IS_FLOAT (rvtype)) + ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0"))); + else + ic = newiCode ('+', rv, operandFromLit (size)); - geniCodeAssign(op,result,0); + IC_RESULT (ic) = result = newiTempOperand (rvtype, 0); + ADDTOCHAIN (ic); - return rOp; + geniCodeAssign (op, result, 0); + + return rOp; } /*-----------------------------------------------------------------*/ /* geniCodePreInc - generate code for preIncrement */ /*-----------------------------------------------------------------*/ -operand *geniCodePreInc (operand *op) +operand * +geniCodePreInc (operand * op) { - iCode *ic ; - sym_link *optype = operandType(op); - operand *rop = (IS_ITEMP(op) ? - geniCodeRValue (op,(IS_PTR(optype) ? TRUE : FALSE)) : - op); - sym_link *roptype = operandType(rop); - operand *result; - int size = 0; + iCode *ic; + sym_link *optype = operandType (op); + operand *rop = (IS_ITEMP (op) ? + geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) : + op); + sym_link *roptype = operandType (rop); + operand *result; + int size = 0; - if ( ! op->isaddr ) { - werror(E_LVALUE_REQUIRED,"++"); - return op ; + if (!op->isaddr) + { + werror (E_LVALUE_REQUIRED, "++"); + return op; } - size = (IS_PTR(roptype) ? getSize(roptype->next) : 1); - if (IS_FLOAT(roptype)) - ic = newiCode('+',rop,operandFromValue(constFloatVal("1.0"))); - else - ic = newiCode('+',rop,operandFromLit(size)); - IC_RESULT(ic) = result = newiTempOperand(roptype,0) ; - ADDTOCHAIN(ic); + size = (IS_PTR (roptype) ? getSize (roptype->next) : 1); + if (IS_FLOAT (roptype)) + ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0"))); + else + ic = newiCode ('+', rop, operandFromLit (size)); + IC_RESULT (ic) = result = newiTempOperand (roptype, 0); + ADDTOCHAIN (ic); - return geniCodeAssign(op,result,0) ; + return geniCodeAssign (op, result, 0); } /*-----------------------------------------------------------------*/ /* geniCodePostDec - generates code for Post decrement */ /*-----------------------------------------------------------------*/ -operand *geniCodePostDec (operand *op) -{ - iCode *ic ; - operand *rOp ; - sym_link *optype = operandType(op); - operand *result ; - operand *rv = (IS_ITEMP(op) ? - geniCodeRValue(op,(IS_PTR(optype) ? TRUE : FALSE)) : - op); - sym_link *rvtype = operandType(rv); - int size = 0; - - /* if this is not an address we have trouble */ - if ( ! op->isaddr ) { - werror (E_LVALUE_REQUIRED,"++"); - return op ; +operand * +geniCodePostDec (operand * op) +{ + iCode *ic; + operand *rOp; + sym_link *optype = operandType (op); + operand *result; + operand *rv = (IS_ITEMP (op) ? + geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) : + op); + sym_link *rvtype = operandType (rv); + int size = 0; + + /* if this is not an address we have trouble */ + if (!op->isaddr) + { + werror (E_LVALUE_REQUIRED, "++"); + return op; } - rOp = newiTempOperand(rvtype,0); - rOp->noSpilLoc = 1; + rOp = newiTempOperand (rvtype, 0); + rOp->noSpilLoc = 1; - if (IS_ITEMP(rv)) - rv->noSpilLoc = 1; + if (IS_ITEMP (rv)) + rv->noSpilLoc = 1; - geniCodeAssign(rOp,rv,0); - - size = (IS_PTR(rvtype) ? getSize(rvtype->next) : 1); - if (IS_FLOAT(rvtype)) - ic = newiCode('-',rv,operandFromValue(constFloatVal("1.0"))); - else - ic = newiCode('-',rv,operandFromLit(size)); + geniCodeAssign (rOp, rv, 0); - IC_RESULT(ic) = result =newiTempOperand(rvtype,0); - ADDTOCHAIN(ic); + size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1); + if (IS_FLOAT (rvtype)) + ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0"))); + else + ic = newiCode ('-', rv, operandFromLit (size)); + + IC_RESULT (ic) = result = newiTempOperand (rvtype, 0); + ADDTOCHAIN (ic); - geniCodeAssign(op,result,0); + geniCodeAssign (op, result, 0); - return rOp; + return rOp; } /*-----------------------------------------------------------------*/ /* geniCodePreDec - generate code for pre decrement */ /*-----------------------------------------------------------------*/ -operand *geniCodePreDec (operand *op) +operand * +geniCodePreDec (operand * op) { - iCode *ic ; - sym_link *optype = operandType(op); - operand *rop = (IS_ITEMP(op) ? - geniCodeRValue (op,(IS_PTR(optype) ? TRUE : FALSE)) : - op); - sym_link *roptype = operandType(rop); - operand *result; - int size = 0; + iCode *ic; + sym_link *optype = operandType (op); + operand *rop = (IS_ITEMP (op) ? + geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) : + op); + sym_link *roptype = operandType (rop); + operand *result; + int size = 0; - if ( ! op->isaddr ) { - werror(E_LVALUE_REQUIRED,"++"); - return op ; + if (!op->isaddr) + { + werror (E_LVALUE_REQUIRED, "++"); + return op; } - size = (IS_PTR(roptype) ? getSize(roptype->next) : 1); - if (IS_FLOAT(roptype)) - ic = newiCode('-',rop,operandFromValue(constFloatVal("1.0"))); - else - ic = newiCode('-',rop,operandFromLit(size)); - IC_RESULT(ic) = result = newiTempOperand(roptype,0) ; - ADDTOCHAIN(ic); + size = (IS_PTR (roptype) ? getSize (roptype->next) : 1); + if (IS_FLOAT (roptype)) + ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0"))); + else + ic = newiCode ('-', rop, operandFromLit (size)); + IC_RESULT (ic) = result = newiTempOperand (roptype, 0); + ADDTOCHAIN (ic); - return geniCodeAssign(op,result,0) ; + return geniCodeAssign (op, result, 0); } /*-----------------------------------------------------------------*/ /* geniCodeBitwise - gen int code for bitWise operators */ /*-----------------------------------------------------------------*/ -operand *geniCodeBitwise (operand *left, operand *right, - int oper, sym_link *resType) +operand * +geniCodeBitwise (operand * left, operand * right, + int oper, sym_link * resType) { - iCode *ic; + iCode *ic; - left = geniCodeCast(resType,left,TRUE); - right= geniCodeCast(resType,right,TRUE); + left = geniCodeCast (resType, left, TRUE); + right = geniCodeCast (resType, right, TRUE); - ic = newiCode(oper,left,right); - IC_RESULT(ic) = newiTempOperand(resType,0); + ic = newiCode (oper, left, right); + IC_RESULT (ic) = newiTempOperand (resType, 0); - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeAddressOf - gens icode for '&' address of operator */ /*-----------------------------------------------------------------*/ -operand *geniCodeAddressOf (operand *op) +operand * +geniCodeAddressOf (operand * op) { - iCode *ic; - sym_link *p ; - sym_link *optype = operandType(op); - sym_link *opetype= getSpec(optype); + iCode *ic; + sym_link *p; + sym_link *optype = operandType (op); + sym_link *opetype = getSpec (optype); - /* lvalue check already done in decorateType */ - /* this must be a lvalue */ + /* lvalue check already done in decorateType */ + /* this must be a lvalue */ /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */ /* werror (E_LVALUE_REQUIRED,"&"); */ /* return op; */ /* } */ - p = newLink(); - p->class = DECLARATOR ; + p = newLink (); + p->class = DECLARATOR; - /* set the pointer depending on the storage class */ - if ((DCL_TYPE(p) = PTR_TYPE(SPEC_OCLS(opetype))) == CPOINTER) - DCL_PTR_CONST(p) = port->mem.code_ro; + /* set the pointer depending on the storage class */ + if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER) + DCL_PTR_CONST (p) = port->mem.code_ro; - /* make sure we preserve the const & volatile */ - if (IS_CONSTANT(opetype)) - DCL_PTR_CONST(p) = 1; + /* make sure we preserve the const & volatile */ + if (IS_CONSTANT (opetype)) + DCL_PTR_CONST (p) = 1; - if (IS_VOLATILE(opetype)) - DCL_PTR_VOLATILE(p) = 1; + if (IS_VOLATILE (opetype)) + DCL_PTR_VOLATILE (p) = 1; - p->next = copyLinkChain(optype); + p->next = copyLinkChain (optype); - /* if already a temp */ - if (IS_ITEMP(op)) { - setOperandType (op,p); - op->isaddr= 0; - return op; + /* if already a temp */ + if (IS_ITEMP (op)) + { + setOperandType (op, p); + op->isaddr = 0; + return op; } - /* other wise make this of the type coming in */ - ic = newiCode(ADDRESS_OF,op,NULL); - IC_RESULT(ic) = newiTempOperand(p,1); - IC_RESULT(ic)->isaddr = 0; - ADDTOCHAIN(ic); - return IC_RESULT(ic); + /* other wise make this of the type coming in */ + ic = newiCode (ADDRESS_OF, op, NULL); + IC_RESULT (ic) = newiTempOperand (p, 1); + IC_RESULT (ic)->isaddr = 0; + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* setOClass - sets the output class depending on the pointer type */ /*-----------------------------------------------------------------*/ -void setOClass (sym_link *ptr, sym_link *spec) +void +setOClass (sym_link * ptr, sym_link * spec) { - switch (DCL_TYPE(ptr)) { + switch (DCL_TYPE (ptr)) + { case POINTER: - SPEC_OCLS(spec) = data ; - break ; + SPEC_OCLS (spec) = data; + break; case GPOINTER: - SPEC_OCLS(spec) = generic; - break; + SPEC_OCLS (spec) = generic; + break; case FPOINTER: - SPEC_OCLS(spec) = xdata ; - break ; + SPEC_OCLS (spec) = xdata; + break; case CPOINTER: - SPEC_OCLS(spec) = code ; - break ; + SPEC_OCLS (spec) = code; + break; case IPOINTER: - SPEC_OCLS(spec) = idata; - break; + SPEC_OCLS (spec) = idata; + break; case PPOINTER: - SPEC_OCLS(spec) = xstack; - break; + SPEC_OCLS (spec) = xstack; + break; case EEPPOINTER: - SPEC_OCLS(spec) = eeprom; - break; + SPEC_OCLS (spec) = eeprom; + break; default: - break; + break; } } @@ -2203,117 +2323,123 @@ void setOClass (sym_link *ptr, sym_link *spec) /*-----------------------------------------------------------------*/ /* geniCodeDerefPtr - dereference pointer with '*' */ /*-----------------------------------------------------------------*/ -operand *geniCodeDerefPtr (operand *op) +operand * +geniCodeDerefPtr (operand * op) { - sym_link *rtype , *retype ; - sym_link *optype = operandType(op); + sym_link *rtype, *retype; + sym_link *optype = operandType (op); - /* if this is a pointer then generate the rvalue */ - if (IS_PTR(optype)) { - if (IS_TRUE_SYMOP(op)) { - op->isaddr = 1; - op = geniCodeRValue(op,TRUE); - } - else - op = geniCodeRValue(op,TRUE); + /* if this is a pointer then generate the rvalue */ + if (IS_PTR (optype)) + { + if (IS_TRUE_SYMOP (op)) + { + op->isaddr = 1; + op = geniCodeRValue (op, TRUE); + } + else + op = geniCodeRValue (op, TRUE); } - /* now get rid of the pointer part */ - if (lvaluereq && IS_ITEMP(op) ) + /* now get rid of the pointer part */ + if (lvaluereq && IS_ITEMP (op)) { - retype = getSpec(rtype = copyLinkChain(optype)) ; + retype = getSpec (rtype = copyLinkChain (optype)); } - else + else { - retype = getSpec(rtype = copyLinkChain(optype->next)) ; + retype = getSpec (rtype = copyLinkChain (optype->next)); } - /* if this is a pointer then outputclass needs 2b updated */ - if (IS_PTR(optype)) - setOClass(optype,retype); + /* if this is a pointer then outputclass needs 2b updated */ + if (IS_PTR (optype)) + setOClass (optype, retype); - op->isGptr = IS_GENPTR(optype); + op->isGptr = IS_GENPTR (optype); - /* if the pointer was declared as a constant */ - /* then we cannot allow assignment to the derefed */ - if (IS_PTR_CONST(optype)) - SPEC_CONST(retype) = 1; + /* if the pointer was declared as a constant */ + /* then we cannot allow assignment to the derefed */ + if (IS_PTR_CONST (optype)) + SPEC_CONST (retype) = 1; - op->isaddr = (IS_PTR(rtype) || - IS_STRUCT(rtype) || - IS_INT(rtype) || - IS_CHAR(rtype) || - IS_FLOAT(rtype) ); + op->isaddr = (IS_PTR (rtype) || + IS_STRUCT (rtype) || + IS_INT (rtype) || + IS_CHAR (rtype) || + IS_FLOAT (rtype)); - if (!lvaluereq) - op = geniCodeRValue(op,TRUE); + if (!lvaluereq) + op = geniCodeRValue (op, TRUE); - setOperandType(op,rtype); + setOperandType (op, rtype); - return op; + return op; } /*-----------------------------------------------------------------*/ /* geniCodeUnaryMinus - does a unary minus of the operand */ /*-----------------------------------------------------------------*/ -operand *geniCodeUnaryMinus (operand *op) +operand * +geniCodeUnaryMinus (operand * op) { - iCode *ic ; - sym_link *optype = operandType(op); + iCode *ic; + sym_link *optype = operandType (op); - if (IS_LITERAL(optype)) - return operandFromLit(- floatFromVal(op->operand.valOperand)); + if (IS_LITERAL (optype)) + return operandFromLit (-floatFromVal (op->operand.valOperand)); - ic = newiCode(UNARYMINUS,op,NULL); - IC_RESULT(ic) = newiTempOperand(optype,0); - ADDTOCHAIN(ic); - return IC_RESULT(ic); + ic = newiCode (UNARYMINUS, op, NULL); + IC_RESULT (ic) = newiTempOperand (optype, 0); + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeLeftShift - gen i code for left shift */ /*-----------------------------------------------------------------*/ -operand *geniCodeLeftShift (operand *left, operand *right) +operand * +geniCodeLeftShift (operand * left, operand * right) { - iCode *ic; + iCode *ic; - /* Note that we don't use the usual binary conversions for the - * shift operations, in accordance with our ANSI friends. - */ - if (options.ANSIint) + /* Note that we don't use the usual binary conversions for the + * shift operations, in accordance with our ANSI friends. + */ + if (options.ANSIint) { - right = usualUnaryConversions(right); - left = usualUnaryConversions(left); + right = usualUnaryConversions (right); + left = usualUnaryConversions (left); } - ic = newiCode(LEFT_OP,left,right); - IC_RESULT(ic) = newiTempOperand(operandType(left),0); - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + ic = newiCode (LEFT_OP, left, right); + IC_RESULT (ic) = newiTempOperand (operandType (left), 0); + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeRightShift - gen i code for right shift */ /*-----------------------------------------------------------------*/ -operand *geniCodeRightShift (operand *left, operand *right) +operand * +geniCodeRightShift (operand * left, operand * right) { - iCode *ic; + iCode *ic; - /* Note that we don't use the usual binary conversions for the - * shift operations, in accordance with our ANSI friends. - */ - if (options.ANSIint) + /* Note that we don't use the usual binary conversions for the + * shift operations, in accordance with our ANSI friends. + */ + if (options.ANSIint) { - right = usualUnaryConversions(right); - left = usualUnaryConversions(left); + right = usualUnaryConversions (right); + left = usualUnaryConversions (left); } - ic = newiCode(RIGHT_OP,left,right); - IC_RESULT(ic) = newiTempOperand(operandType(left),0); - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + ic = newiCode (RIGHT_OP, left, right); + IC_RESULT (ic) = newiTempOperand (operandType (left), 0); + ADDTOCHAIN (ic); + return IC_RESULT (ic); } #if defined(__BORLANDC__) || defined(_MSC_VER) @@ -2325,247 +2451,266 @@ operand *geniCodeRightShift (operand *left, operand *right) /*-----------------------------------------------------------------*/ /* geniCodeLogic- logic code */ /*-----------------------------------------------------------------*/ -operand *geniCodeLogic (operand *left, operand *right, int op ) +operand * +geniCodeLogic (operand * left, operand * right, int op) { - iCode *ic ; - sym_link *ctype; - sym_link *rtype = operandType(right); - sym_link *ltype = operandType(left); + iCode *ic; + sym_link *ctype; + sym_link *rtype = operandType (right); + sym_link *ltype = operandType (left); - /* left is integral type and right is literal then - check if the literal value is within bounds */ - if (IS_INTEGRAL(ltype) && IS_LITERAL(rtype)) { - int nbits = bitsForType(ltype); - long v = operandLitValue(right); + /* left is integral type and right is literal then + check if the literal value is within bounds */ + if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype)) + { + int nbits = bitsForType (ltype); + long v = operandLitValue (right); - if (v > ((LONG_LONG) 1 << nbits) && v > 0) - werror(W_CONST_RANGE," compare operation "); + if (v > ((LONG_LONG) 1 << nbits) && v > 0) + werror (W_CONST_RANGE, " compare operation "); } - ctype = usualBinaryConversions(&left, &right); + ctype = usualBinaryConversions (&left, &right); - ic = newiCode(op,left,right); - IC_RESULT(ic) = newiTempOperand (newCharLink(),1); + ic = newiCode (op, left, right); + IC_RESULT (ic) = newiTempOperand (newCharLink (), 1); - /* if comparing anything greater than one byte - and not a '==' || '!=' || '&&' || '||' (these - will be inlined */ - if (getSize(ctype) > 1 && - op != EQ_OP && - op != NE_OP && - op != AND_OP && - op != OR_OP ) - ic->supportRtn = 1; + /* if comparing anything greater than one byte + and not a '==' || '!=' || '&&' || '||' (these + will be inlined */ + if (getSize (ctype) > 1 && + op != EQ_OP && + op != NE_OP && + op != AND_OP && + op != OR_OP) + ic->supportRtn = 1; - ADDTOCHAIN(ic); - return IC_RESULT(ic); + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeUnary - for a a generic unary operation */ /*-----------------------------------------------------------------*/ -operand *geniCodeUnary (operand *op, int oper ) +operand * +geniCodeUnary (operand * op, int oper) { - iCode *ic = newiCode (oper,op,NULL); + iCode *ic = newiCode (oper, op, NULL); - IC_RESULT(ic)= newiTempOperand(operandType(op),0); - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + IC_RESULT (ic) = newiTempOperand (operandType (op), 0); + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeConditional - geniCode for '?' ':' operation */ /*-----------------------------------------------------------------*/ -operand *geniCodeConditional (ast *tree) +operand * +geniCodeConditional (ast * tree) { - iCode *ic ; - symbol *falseLabel = newiTempLabel(NULL); - symbol *exitLabel = newiTempLabel(NULL); - operand *cond = ast2iCode(tree->left); - operand *true, *false , *result; + iCode *ic; + symbol *falseLabel = newiTempLabel (NULL); + symbol *exitLabel = newiTempLabel (NULL); + operand *cond = ast2iCode (tree->left); + operand *true, *false, *result; - ic = newiCodeCondition(geniCodeRValue(cond,FALSE), - NULL,falseLabel); - ADDTOCHAIN(ic); + ic = newiCodeCondition (geniCodeRValue (cond, FALSE), + NULL, falseLabel); + ADDTOCHAIN (ic); - true = ast2iCode(tree->right->left); + true = ast2iCode (tree->right->left); - /* move the value to a new Operand */ - result = newiTempOperand(operandType(true),0); - geniCodeAssign(result,geniCodeRValue(true,FALSE),0); + /* move the value to a new Operand */ + result = newiTempOperand (operandType (true), 0); + geniCodeAssign (result, geniCodeRValue (true, FALSE), 0); - /* generate an unconditional goto */ - geniCodeGoto(exitLabel); + /* generate an unconditional goto */ + geniCodeGoto (exitLabel); - /* now for the right side */ - geniCodeLabel(falseLabel); + /* now for the right side */ + geniCodeLabel (falseLabel); - false = ast2iCode(tree->right->right); - geniCodeAssign(result,geniCodeRValue(false,FALSE),0); + false = ast2iCode (tree->right->right); + geniCodeAssign (result, geniCodeRValue (false, FALSE), 0); - /* create the exit label */ - geniCodeLabel(exitLabel); + /* create the exit label */ + geniCodeLabel (exitLabel); - return result ; + return result; } /*-----------------------------------------------------------------*/ /* geniCodeAssign - generate code for assignment */ /*-----------------------------------------------------------------*/ -operand *geniCodeAssign (operand *left, operand *right, int nosupdate) +operand * +geniCodeAssign (operand * left, operand * right, int nosupdate) { - iCode *ic ; - sym_link *ltype = operandType(left); - sym_link *rtype = operandType(right); + iCode *ic; + sym_link *ltype = operandType (left); + sym_link *rtype = operandType (right); - if (!left->isaddr && !IS_ITEMP(left)) { - werror(E_LVALUE_REQUIRED,"assignment"); - return left; + if (!left->isaddr && !IS_ITEMP (left)) + { + werror (E_LVALUE_REQUIRED, "assignment"); + return left; } - /* left is integral type and right is literal then - check if the literal value is within bounds */ - if (IS_INTEGRAL(ltype) && right->type == VALUE && IS_LITERAL(rtype)) { - int nbits = bitsForType(ltype); - long v = operandLitValue(right); - - if (v > ((LONG_LONG)1 << nbits) && v > 0) - werror(W_CONST_RANGE," = operation"); - } - - /* if the left & right type don't exactly match */ - /* if pointer set then make sure the check is - done with the type & not the pointer */ - /* then cast rights type to left */ - - /* first check the type for pointer assignement */ - if (left->isaddr && IS_PTR(ltype) && IS_ITEMP(left) && - checkType(ltype,rtype)<0) { - if (checkType(ltype->next,rtype) < 0) - right = geniCodeCast(ltype->next,right,TRUE); - } else - if (checkType(ltype,rtype) < 0 ) - right = geniCodeCast(ltype,right,TRUE); - - /* if left is a true symbol & ! volatile - create an assignment to temporary for - the right & then assign this temporary - to the symbol this is SSA . isn't it simple - and folks have published mountains of paper on it */ - if (IS_TRUE_SYMOP(left) && - !isOperandVolatile(left,FALSE) && - isOperandGlobal(left)) { - symbol *sym = NULL; - - if (IS_TRUE_SYMOP(right)) - sym = OP_SYMBOL(right); - ic = newiCode('=',NULL,right); - IC_RESULT(ic) = right = newiTempOperand(ltype,0); - SPIL_LOC(right) = sym ; - ADDTOCHAIN(ic); - } - - ic = newiCode('=',NULL,right); - IC_RESULT(ic) = left; - ADDTOCHAIN(ic); - - /* if left isgptr flag is set then support - routine will be required */ - if (left->isGptr) - ic->supportRtn = 1; - - ic->nosupdate = nosupdate; - return left; + /* left is integral type and right is literal then + check if the literal value is within bounds */ + if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype)) + { + int nbits = bitsForType (ltype); + long v = operandLitValue (right); + + if (v > ((LONG_LONG) 1 << nbits) && v > 0) + werror (W_CONST_RANGE, " = operation"); + } + + /* if the left & right type don't exactly match */ + /* if pointer set then make sure the check is + done with the type & not the pointer */ + /* then cast rights type to left */ + + /* first check the type for pointer assignement */ + if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) && + checkType (ltype, rtype) < 0) + { + if (checkType (ltype->next, rtype) < 0) + right = geniCodeCast (ltype->next, right, TRUE); + } + else if (checkType (ltype, rtype) < 0) + right = geniCodeCast (ltype, right, TRUE); + + /* if left is a true symbol & ! volatile + create an assignment to temporary for + the right & then assign this temporary + to the symbol this is SSA . isn't it simple + and folks have published mountains of paper on it */ + if (IS_TRUE_SYMOP (left) && + !isOperandVolatile (left, FALSE) && + isOperandGlobal (left)) + { + symbol *sym = NULL; + + if (IS_TRUE_SYMOP (right)) + sym = OP_SYMBOL (right); + ic = newiCode ('=', NULL, right); + IC_RESULT (ic) = right = newiTempOperand (ltype, 0); + SPIL_LOC (right) = sym; + ADDTOCHAIN (ic); + } + + ic = newiCode ('=', NULL, right); + IC_RESULT (ic) = left; + ADDTOCHAIN (ic); + + /* if left isgptr flag is set then support + routine will be required */ + if (left->isGptr) + ic->supportRtn = 1; + + ic->nosupdate = nosupdate; + return left; } /*-----------------------------------------------------------------*/ /* geniCodeSEParms - generate code for side effecting fcalls */ /*-----------------------------------------------------------------*/ -static void geniCodeSEParms (ast *parms) +static void +geniCodeSEParms (ast * parms) { - if (!parms) - return ; + if (!parms) + return; - if (parms->type == EX_OP && parms->opval.op == PARAM) { - geniCodeSEParms (parms->left) ; - geniCodeSEParms (parms->right); - return ; + if (parms->type == EX_OP && parms->opval.op == PARAM) + { + geniCodeSEParms (parms->left); + geniCodeSEParms (parms->right); + return; } - /* hack don't like this but too lazy to think of - something better */ - if (IS_ADDRESS_OF_OP(parms)) - parms->left->lvalue = 1; + /* hack don't like this but too lazy to think of + something better */ + if (IS_ADDRESS_OF_OP (parms)) + parms->left->lvalue = 1; - if (IS_CAST_OP(parms) && - IS_PTR(parms->ftype) && - IS_ADDRESS_OF_OP(parms->right)) - parms->right->left->lvalue = 1; + if (IS_CAST_OP (parms) && + IS_PTR (parms->ftype) && + IS_ADDRESS_OF_OP (parms->right)) + parms->right->left->lvalue = 1; - parms->opval.oprnd = - geniCodeRValue(ast2iCode (parms),FALSE); + parms->opval.oprnd = + geniCodeRValue (ast2iCode (parms), FALSE); - parms->type = EX_OPERAND ; + parms->type = EX_OPERAND; } /*-----------------------------------------------------------------*/ /* geniCodeParms - generates parameters */ /*-----------------------------------------------------------------*/ -static void geniCodeParms ( ast *parms , int *stack, sym_link *fetype, symbol *func) +static void +geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func) { - iCode *ic ; - operand *pval ; + iCode *ic; + operand *pval; - if ( ! parms ) - return ; + if (!parms) + return; - /* if this is a param node then do the left & right */ - if (parms->type == EX_OP && parms->opval.op == PARAM) { - geniCodeParms (parms->left, stack,fetype,func) ; - geniCodeParms (parms->right, stack,fetype,func); - return ; + /* if this is a param node then do the left & right */ + if (parms->type == EX_OP && parms->opval.op == PARAM) + { + geniCodeParms (parms->left, stack, fetype, func); + geniCodeParms (parms->right, stack, fetype, func); + return; } - /* get the parameter value */ - if (parms->type == EX_OPERAND) - pval = parms->opval.oprnd ; - else { - /* maybe this else should go away ?? */ - /* hack don't like this but too lazy to think of - something better */ - if (IS_ADDRESS_OF_OP(parms)) - parms->left->lvalue = 1; + /* get the parameter value */ + if (parms->type == EX_OPERAND) + pval = parms->opval.oprnd; + else + { + /* maybe this else should go away ?? */ + /* hack don't like this but too lazy to think of + something better */ + if (IS_ADDRESS_OF_OP (parms)) + parms->left->lvalue = 1; - if (IS_CAST_OP(parms) && - IS_PTR(parms->ftype) && - IS_ADDRESS_OF_OP(parms->right)) - parms->right->left->lvalue = 1; + if (IS_CAST_OP (parms) && + IS_PTR (parms->ftype) && + IS_ADDRESS_OF_OP (parms->right)) + parms->right->left->lvalue = 1; - pval = geniCodeRValue(ast2iCode (parms),FALSE); + pval = geniCodeRValue (ast2iCode (parms), FALSE); } - /* if register parm then make it a send */ - if (((parms->argSym && IS_REGPARM(parms->argSym->etype)) || - IS_REGPARM(parms->etype)) && !func->hasVargs ) { - ic = newiCode(SEND,pval,NULL); - ADDTOCHAIN(ic); - } else { - /* now decide whether to push or assign */ - if (!(options.stackAuto || IS_RENT(fetype))) { + /* if register parm then make it a send */ + if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) || + IS_REGPARM (parms->etype)) && !func->hasVargs) + { + ic = newiCode (SEND, pval, NULL); + ADDTOCHAIN (ic); + } + else + { + /* now decide whether to push or assign */ + if (!(options.stackAuto || IS_RENT (fetype))) + { - /* assign */ - operand *top = operandFromSymbol(parms->argSym); - geniCodeAssign(top,pval,1); - } - else { - sym_link *p = operandType(pval); - /* push */ - ic = newiCode(IPUSH,pval,NULL); - ic->parmPush = 1; - /* update the stack adjustment */ - *stack += getSize(IS_AGGREGATE(p)? aggrToPtr(p,FALSE):p); - ADDTOCHAIN(ic); - } + /* assign */ + operand *top = operandFromSymbol (parms->argSym); + geniCodeAssign (top, pval, 1); + } + else + { + sym_link *p = operandType (pval); + /* push */ + ic = newiCode (IPUSH, pval, NULL); + ic->parmPush = 1; + /* update the stack adjustment */ + *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p); + ADDTOCHAIN (ic); + } } } @@ -2573,716 +2718,758 @@ static void geniCodeParms ( ast *parms , int *stack, sym_link *fetype, symbol *f /*-----------------------------------------------------------------*/ /* geniCodeCall - generates temp code for calling */ /*-----------------------------------------------------------------*/ -operand *geniCodeCall (operand *left, ast *parms) +operand * +geniCodeCall (operand * left, ast * parms) { - iCode *ic ; - operand *result ; - sym_link *type, *etype; - int stack = 0 ; + iCode *ic; + operand *result; + sym_link *type, *etype; + int stack = 0; - /* take care of parameters with side-effecting - function calls in them, this is required to take care - of overlaying function parameters */ - geniCodeSEParms ( parms ); + /* take care of parameters with side-effecting + function calls in them, this is required to take care + of overlaying function parameters */ + geniCodeSEParms (parms); - /* first the parameters */ - geniCodeParms ( parms , &stack , getSpec(operandType(left)), OP_SYMBOL(left)); + /* first the parameters */ + geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left)); - /* now call : if symbol then pcall */ - if (IS_ITEMP(left)) - ic = newiCode(PCALL,left,NULL); - else - ic = newiCode(CALL,left,NULL); + /* now call : if symbol then pcall */ + if (IS_ITEMP (left)) + ic = newiCode (PCALL, left, NULL); + else + ic = newiCode (CALL, left, NULL); - IC_ARGS(ic) = left->operand.symOperand->args ; - type = copyLinkChain(operandType(left)->next); - etype = getSpec(type); - SPEC_EXTR(etype) = 0; - IC_RESULT(ic) = result = newiTempOperand(type,1); + IC_ARGS (ic) = left->operand.symOperand->args; + type = copyLinkChain (operandType (left)->next); + etype = getSpec (type); + SPEC_EXTR (etype) = 0; + IC_RESULT (ic) = result = newiTempOperand (type, 1); - ADDTOCHAIN(ic); + ADDTOCHAIN (ic); - /* stack adjustment after call */ - left->parmBytes = stack; + /* stack adjustment after call */ + left->parmBytes = stack; - return result; + return result; } /*-----------------------------------------------------------------*/ /* geniCodeReceive - generate intermediate code for "receive" */ /*-----------------------------------------------------------------*/ -static void geniCodeReceive (value *args) +static void +geniCodeReceive (value * args) { - /* for all arguments that are passed in registers */ - while (args) { - - if (IS_REGPARM(args->etype)) { - operand *opr = operandFromValue(args); - operand *opl ; - symbol *sym = OP_SYMBOL(opr); - iCode *ic ; + /* for all arguments that are passed in registers */ + while (args) + { - /* we will use it after all optimizations - and before liveRange calculation */ - if (!sym->addrtaken && !IS_VOLATILE(sym->etype)) { - - if (IN_FARSPACE(SPEC_OCLS(sym->etype)) && - options.stackAuto == 0 && - !IS_DS390_PORT) { - } else { - opl = newiTempOperand(args->type,0); - sym->reqv = opl ; - sym->reqv->key = sym->key ; - OP_SYMBOL(sym->reqv)->key = sym->key; - OP_SYMBOL(sym->reqv)->isreqv = 1; - OP_SYMBOL(sym->reqv)->islocal= 0; - SPIL_LOC(sym->reqv) = sym; - } - } + if (IS_REGPARM (args->etype)) + { + operand *opr = operandFromValue (args); + operand *opl; + symbol *sym = OP_SYMBOL (opr); + iCode *ic; + + /* we will use it after all optimizations + and before liveRange calculation */ + if (!sym->addrtaken && !IS_VOLATILE (sym->etype)) + { + + if (IN_FARSPACE (SPEC_OCLS (sym->etype)) && + options.stackAuto == 0 && + !IS_DS390_PORT) + { + } + else + { + opl = newiTempOperand (args->type, 0); + sym->reqv = opl; + sym->reqv->key = sym->key; + OP_SYMBOL (sym->reqv)->key = sym->key; + OP_SYMBOL (sym->reqv)->isreqv = 1; + OP_SYMBOL (sym->reqv)->islocal = 0; + SPIL_LOC (sym->reqv) = sym; + } + } - ic = newiCode(RECEIVE,NULL,NULL); - currFunc->recvSize = getSize(sym->etype); - IC_RESULT(ic) = opr; - ADDTOCHAIN(ic); - } + ic = newiCode (RECEIVE, NULL, NULL); + currFunc->recvSize = getSize (sym->etype); + IC_RESULT (ic) = opr; + ADDTOCHAIN (ic); + } - args = args->next; + args = args->next; } } /*-----------------------------------------------------------------*/ /* geniCodeFunctionBody - create the function body */ /*-----------------------------------------------------------------*/ -void geniCodeFunctionBody (ast *tree) -{ - iCode *ic ; - operand *func ; - sym_link *fetype ; - int savelineno ; - - /* reset the auto generation */ - /* numbers */ - iTempNum = 0 ; - iTempLblNum = 0; - operandKey = 0 ; - iCodeKey = 0 ; - func = ast2iCode(tree->left); - fetype = getSpec(operandType(func)); - - savelineno = lineno; - lineno = OP_SYMBOL(func)->lineDef; - /* create an entry label */ - geniCodeLabel(entryLabel); - lineno = savelineno; - - /* create a proc icode */ - ic = newiCode(FUNCTION,func,NULL); - /* if the function has parmas then */ - /* save the parameters information */ - ic->argLabel.args = tree->values.args ; - ic->lineno = OP_SYMBOL(func)->lineDef; - - ADDTOCHAIN(ic); - - /* for all parameters that are passed - on registers add a "receive" */ - geniCodeReceive( tree->values.args ); - - /* generate code for the body */ - ast2iCode(tree->right); +void +geniCodeFunctionBody (ast * tree) +{ + iCode *ic; + operand *func; + sym_link *fetype; + int savelineno; + + /* reset the auto generation */ + /* numbers */ + iTempNum = 0; + iTempLblNum = 0; + operandKey = 0; + iCodeKey = 0; + func = ast2iCode (tree->left); + fetype = getSpec (operandType (func)); + + savelineno = lineno; + lineno = OP_SYMBOL (func)->lineDef; + /* create an entry label */ + geniCodeLabel (entryLabel); + lineno = savelineno; + + /* create a proc icode */ + ic = newiCode (FUNCTION, func, NULL); + /* if the function has parmas then */ + /* save the parameters information */ + ic->argLabel.args = tree->values.args; + ic->lineno = OP_SYMBOL (func)->lineDef; + + ADDTOCHAIN (ic); + + /* for all parameters that are passed + on registers add a "receive" */ + geniCodeReceive (tree->values.args); + + /* generate code for the body */ + ast2iCode (tree->right); - /* create a label for return */ - geniCodeLabel(returnLabel); + /* create a label for return */ + geniCodeLabel (returnLabel); - /* now generate the end proc */ - ic = newiCode(ENDFUNCTION,func,NULL); - ADDTOCHAIN(ic); - return ; + /* now generate the end proc */ + ic = newiCode (ENDFUNCTION, func, NULL); + ADDTOCHAIN (ic); + return; } /*-----------------------------------------------------------------*/ /* geniCodeReturn - gen icode for 'return' statement */ /*-----------------------------------------------------------------*/ -void geniCodeReturn (operand *op) +void +geniCodeReturn (operand * op) { - iCode *ic; + iCode *ic; - /* if the operand is present force an rvalue */ - if (op) - op = geniCodeRValue(op,FALSE); + /* if the operand is present force an rvalue */ + if (op) + op = geniCodeRValue (op, FALSE); - ic = newiCode(RETURN,op,NULL); - ADDTOCHAIN(ic); + ic = newiCode (RETURN, op, NULL); + ADDTOCHAIN (ic); } /*-----------------------------------------------------------------*/ /* geniCodeIfx - generates code for extended if statement */ /*-----------------------------------------------------------------*/ -void geniCodeIfx (ast *tree) +void +geniCodeIfx (ast * tree) { - iCode *ic; - operand *condition = ast2iCode(tree->left); - sym_link *cetype; + iCode *ic; + operand *condition = ast2iCode (tree->left); + sym_link *cetype; - /* if condition is null then exit */ - if (!condition) - goto exit ; - else - condition = geniCodeRValue(condition,FALSE); + /* if condition is null then exit */ + if (!condition) + goto exit; + else + condition = geniCodeRValue (condition, FALSE); - cetype = getSpec(operandType(condition)); - /* if the condition is a literal */ - if (IS_LITERAL(cetype)) { - if (floatFromVal(condition->operand.valOperand)) { - if (tree->trueLabel) - geniCodeGoto(tree->trueLabel); - else - assert(1); - } - else { - if (tree->falseLabel) - geniCodeGoto (tree->falseLabel); + cetype = getSpec (operandType (condition)); + /* if the condition is a literal */ + if (IS_LITERAL (cetype)) + { + if (floatFromVal (condition->operand.valOperand)) + { + if (tree->trueLabel) + geniCodeGoto (tree->trueLabel); + else + assert (1); + } else - assert(1); - } - goto exit; + { + if (tree->falseLabel) + geniCodeGoto (tree->falseLabel); + else + assert (1); + } + goto exit; } - if ( tree->trueLabel ) { - ic = newiCodeCondition(condition, - tree->trueLabel, - NULL ); - ADDTOCHAIN(ic); + if (tree->trueLabel) + { + ic = newiCodeCondition (condition, + tree->trueLabel, + NULL); + ADDTOCHAIN (ic); - if ( tree->falseLabel) - geniCodeGoto(tree->falseLabel); + if (tree->falseLabel) + geniCodeGoto (tree->falseLabel); } - else { - ic = newiCodeCondition (condition, - NULL, - tree->falseLabel); - ADDTOCHAIN(ic); + else + { + ic = newiCodeCondition (condition, + NULL, + tree->falseLabel); + ADDTOCHAIN (ic); } - exit: - ast2iCode(tree->right); +exit: + ast2iCode (tree->right); } /*-----------------------------------------------------------------*/ /* geniCodeJumpTable - tries to create a jump table for switch */ /*-----------------------------------------------------------------*/ -int geniCodeJumpTable (operand *cond, value *caseVals, ast *tree) +int +geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) { - int min = 0 ,max = 0, t, cnt = 0; - value *vch; - iCode *ic; - operand *boundary; - symbol *falseLabel; - set *labels = NULL ; + int min = 0, max = 0, t, cnt = 0; + value *vch; + iCode *ic; + operand *boundary; + symbol *falseLabel; + set *labels = NULL; - if (!tree || !caseVals) - return 0; + if (!tree || !caseVals) + return 0; - /* the criteria for creating a jump table is */ - /* all integer numbers between the maximum & minimum must */ - /* be present , the maximum value should not exceed 255 */ - min = max = (int)floatFromVal(vch = caseVals); - sprintf(buffer,"_case_%d_%d", - tree->values.switchVals.swNum, - min); - addSet(&labels,newiTempLabel(buffer)); - - /* if there is only one case value then no need */ - if (!(vch = vch->next )) - return 0; + /* the criteria for creating a jump table is */ + /* all integer numbers between the maximum & minimum must */ + /* be present , the maximum value should not exceed 255 */ + min = max = (int) floatFromVal (vch = caseVals); + sprintf (buffer, "_case_%d_%d", + tree->values.switchVals.swNum, + min); + addSet (&labels, newiTempLabel (buffer)); + + /* if there is only one case value then no need */ + if (!(vch = vch->next)) + return 0; - while (vch) { - if (((t = (int)floatFromVal(vch)) - max) != 1) - return 0; - sprintf(buffer,"_case_%d_%d", - tree->values.switchVals.swNum, - t); - addSet(&labels,newiTempLabel(buffer)); - max = t; - cnt++ ; - vch = vch->next ; - } - - /* if the number of case statements <= 2 then */ - /* it is not economical to create the jump table */ - /* since two compares are needed for boundary conditions */ - if ((! optimize.noJTabBoundary && cnt <= 2) || max > (255/3)) - return 0; + while (vch) + { + if (((t = (int) floatFromVal (vch)) - max) != 1) + return 0; + sprintf (buffer, "_case_%d_%d", + tree->values.switchVals.swNum, + t); + addSet (&labels, newiTempLabel (buffer)); + max = t; + cnt++; + vch = vch->next; + } + + /* if the number of case statements <= 2 then */ + /* it is not economical to create the jump table */ + /* since two compares are needed for boundary conditions */ + if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3)) + return 0; - if ( tree->values.switchVals.swDefault ) - sprintf (buffer,"_default_%d",tree->values.switchVals.swNum); - else - sprintf (buffer,"_swBrk_%d",tree->values.switchVals.swNum ); - - falseLabel = newiTempLabel (buffer); - - /* so we can create a jumptable */ - /* first we rule out the boundary conditions */ - /* if only optimization says so */ - if ( ! optimize.noJTabBoundary ) { - sym_link *cetype = getSpec(operandType(cond)); - /* no need to check the lower bound if - the condition is unsigned & minimum value is zero */ - if (!( min == 0 && SPEC_USIGN(cetype))) { - boundary = geniCodeLogic (cond,operandFromLit(min),'<'); - ic = newiCodeCondition (boundary,falseLabel,NULL); - ADDTOCHAIN(ic); - } - - /* now for upper bounds */ - boundary = geniCodeLogic(cond,operandFromLit(max),'>'); - ic = newiCodeCondition (boundary,falseLabel,NULL); - ADDTOCHAIN(ic); - } - - /* if the min is not zero then we no make it zero */ - if (min) { - cond = geniCodeSubtract(cond,operandFromLit(min)); - setOperandType(cond, UCHARTYPE); - } - - /* now create the jumptable */ - ic = newiCode(JUMPTABLE,NULL,NULL); - IC_JTCOND(ic) = cond; - IC_JTLABELS(ic) = labels; - ADDTOCHAIN(ic); - return 1; + if (tree->values.switchVals.swDefault) + sprintf (buffer, "_default_%d", tree->values.switchVals.swNum); + else + sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum); + + falseLabel = newiTempLabel (buffer); + + /* so we can create a jumptable */ + /* first we rule out the boundary conditions */ + /* if only optimization says so */ + if (!optimize.noJTabBoundary) + { + sym_link *cetype = getSpec (operandType (cond)); + /* no need to check the lower bound if + the condition is unsigned & minimum value is zero */ + if (!(min == 0 && SPEC_USIGN (cetype))) + { + boundary = geniCodeLogic (cond, operandFromLit (min), '<'); + ic = newiCodeCondition (boundary, falseLabel, NULL); + ADDTOCHAIN (ic); + } + + /* now for upper bounds */ + boundary = geniCodeLogic (cond, operandFromLit (max), '>'); + ic = newiCodeCondition (boundary, falseLabel, NULL); + ADDTOCHAIN (ic); + } + + /* if the min is not zero then we no make it zero */ + if (min) + { + cond = geniCodeSubtract (cond, operandFromLit (min)); + setOperandType (cond, UCHARTYPE); + } + + /* now create the jumptable */ + ic = newiCode (JUMPTABLE, NULL, NULL); + IC_JTCOND (ic) = cond; + IC_JTLABELS (ic) = labels; + ADDTOCHAIN (ic); + return 1; } /*-----------------------------------------------------------------*/ /* geniCodeSwitch - changes a switch to a if statement */ /*-----------------------------------------------------------------*/ -void geniCodeSwitch (ast *tree) +void +geniCodeSwitch (ast * tree) { - iCode *ic ; - operand *cond = geniCodeRValue(ast2iCode (tree->left),FALSE); - value *caseVals = tree->values.switchVals.swVals ; - symbol *trueLabel , *falseLabel; + iCode *ic; + operand *cond = geniCodeRValue (ast2iCode (tree->left), FALSE); + value *caseVals = tree->values.switchVals.swVals; + symbol *trueLabel, *falseLabel; - /* if we can make this a jump table */ - if ( geniCodeJumpTable (cond,caseVals,tree) ) - goto jumpTable ; /* no need for the comparison */ + /* if we can make this a jump table */ + if (geniCodeJumpTable (cond, caseVals, tree)) + goto jumpTable; /* no need for the comparison */ - /* for the cases defined do */ - while (caseVals) { + /* for the cases defined do */ + while (caseVals) + { - operand *compare = geniCodeLogic (cond, - operandFromValue(caseVals), - EQ_OP); + operand *compare = geniCodeLogic (cond, + operandFromValue (caseVals), + EQ_OP); - sprintf(buffer,"_case_%d_%d", - tree->values.switchVals.swNum, - (int) floatFromVal(caseVals)); - trueLabel = newiTempLabel(buffer); + sprintf (buffer, "_case_%d_%d", + tree->values.switchVals.swNum, + (int) floatFromVal (caseVals)); + trueLabel = newiTempLabel (buffer); - ic = newiCodeCondition(compare,trueLabel,NULL); - ADDTOCHAIN(ic); - caseVals = caseVals->next; + ic = newiCodeCondition (compare, trueLabel, NULL); + ADDTOCHAIN (ic); + caseVals = caseVals->next; } - /* if default is present then goto break else break */ - if ( tree->values.switchVals.swDefault ) - sprintf (buffer,"_default_%d",tree->values.switchVals.swNum); - else - sprintf (buffer,"_swBrk_%d",tree->values.switchVals.swNum ); + /* if default is present then goto break else break */ + if (tree->values.switchVals.swDefault) + sprintf (buffer, "_default_%d", tree->values.switchVals.swNum); + else + sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum); - falseLabel = newiTempLabel (buffer); - geniCodeGoto(falseLabel); + falseLabel = newiTempLabel (buffer); + geniCodeGoto (falseLabel); - jumpTable: - ast2iCode(tree->right); +jumpTable: + ast2iCode (tree->right); } /*-----------------------------------------------------------------*/ /* geniCodeInline - intermediate code for inline assembler */ /*-----------------------------------------------------------------*/ -static void geniCodeInline (ast *tree) +static void +geniCodeInline (ast * tree) { - iCode *ic; + iCode *ic; - ic = newiCode(INLINEASM,NULL,NULL); - IC_INLINE(ic) = tree->values.inlineasm; - ADDTOCHAIN(ic); + ic = newiCode (INLINEASM, NULL, NULL); + IC_INLINE (ic) = tree->values.inlineasm; + ADDTOCHAIN (ic); } /*-----------------------------------------------------------------*/ /* ast2iCode - creates an icodeList from an ast */ /*-----------------------------------------------------------------*/ -operand *ast2iCode (ast *tree) +operand * +ast2iCode (ast * tree) { - operand *left = NULL; - operand *right= NULL; + operand *left = NULL; + operand *right = NULL; - if (!tree) - return NULL ; + if (!tree) + return NULL; - /* set the global variables for filename & line number */ - if ( tree->filename ) - filename = tree->filename ; - if ( tree->lineno) - lineno = tree->lineno ; - if (tree->block) - block = tree->block ; - if (tree->level) - scopeLevel = tree->level; + /* set the global variables for filename & line number */ + if (tree->filename) + filename = tree->filename; + if (tree->lineno) + lineno = tree->lineno; + if (tree->block) + block = tree->block; + if (tree->level) + scopeLevel = tree->level; + + if (tree->type == EX_VALUE) + return operandFromValue (tree->opval.val); + + if (tree->type == EX_LINK) + return operandFromLink (tree->opval.lnk); + + /* if we find a nullop */ + if (tree->type == EX_OP && + (tree->opval.op == NULLOP || + tree->opval.op == BLOCK)) + { + ast2iCode (tree->left); + ast2iCode (tree->right); + return NULL; + } + + /* special cases for not evaluating */ + if (tree->opval.op != ':' && + tree->opval.op != '?' && + tree->opval.op != CALL && + tree->opval.op != IFX && + tree->opval.op != LABEL && + tree->opval.op != GOTO && + tree->opval.op != SWITCH && + tree->opval.op != FUNCTION && + tree->opval.op != INLINEASM) + { - if (tree->type == EX_VALUE ) - return operandFromValue(tree->opval.val); + if (IS_ASSIGN_OP (tree->opval.op) || + IS_DEREF_OP (tree) || + (tree->opval.op == '&' && !tree->right) || + tree->opval.op == PTR_OP) + { + lvaluereq++; + if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) || + (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left))) + { + int olvr = lvaluereq; + lvaluereq = 0; + left = operandFromAst (tree->left); + lvaluereq = olvr - 1; + } + else + { + left = operandFromAst (tree->left); + lvaluereq--; + } + if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left)) + left = geniCodeRValue (left, TRUE); + } + else + { + left = operandFromAst (tree->left); + } + if (tree->opval.op == INC_OP || + tree->opval.op == DEC_OP) + { + lvaluereq++; + right = operandFromAst (tree->right); + lvaluereq--; + } + else + { + right = operandFromAst (tree->right); + } + } - if (tree->type == EX_LINK ) - return operandFromLink (tree->opval.lnk); + /* now depending on the type of operand */ + /* this will be a biggy */ + switch (tree->opval.op) + { - /* if we find a nullop */ - if (tree->type == EX_OP && - ( tree->opval.op == NULLOP || - tree->opval.op == BLOCK )) { - ast2iCode (tree->left); - ast2iCode (tree->right); - return NULL ; - } - - /* special cases for not evaluating */ - if ( tree->opval.op != ':' && - tree->opval.op != '?' && - tree->opval.op != CALL && - tree->opval.op != IFX && - tree->opval.op != LABEL && - tree->opval.op != GOTO && - tree->opval.op != SWITCH && - tree->opval.op != FUNCTION && - tree->opval.op != INLINEASM ) { - - if (IS_ASSIGN_OP(tree->opval.op) || - IS_DEREF_OP(tree) || - (tree->opval.op == '&' && !tree->right) || - tree->opval.op == PTR_OP) { - lvaluereq++; - if ((IS_ARRAY_OP(tree->left) && IS_ARRAY_OP(tree->left->left)) || - (IS_DEREF_OP(tree) && IS_ARRAY_OP(tree->left))) + case '[': /* array operation */ { - int olvr = lvaluereq ; - lvaluereq = 0; - left = operandFromAst(tree->left); - lvaluereq = olvr - 1; - } else { - left = operandFromAst(tree->left); - lvaluereq--; + sym_link *ltype = operandType (left); + left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE); + right = geniCodeRValue (right, TRUE); } - if (IS_DEREF_OP(tree) && IS_DEREF_OP(tree->left)) - left = geniCodeRValue(left,TRUE); - } else { - left = operandFromAst(tree->left); - } - if (tree->opval.op == INC_OP || - tree->opval.op == DEC_OP) { - lvaluereq++; - right= operandFromAst(tree->right); - lvaluereq--; - } else { - right= operandFromAst(tree->right); - } - } - - /* now depending on the type of operand */ - /* this will be a biggy */ - switch (tree->opval.op) { - - case '[' : /* array operation */ - { - sym_link *ltype = operandType(left); - left= geniCodeRValue (left,IS_PTR(ltype->next) ? TRUE : FALSE); - right=geniCodeRValue (right,TRUE); - } - - return geniCodeArray (left,right); - - case '.' : /* structure dereference */ - if (IS_PTR(operandType(left))) - left = geniCodeRValue(left,TRUE); - else - left = geniCodeRValue(left,FALSE); - return geniCodeStruct (left,right,tree->lvalue); + return geniCodeArray (left, right); - case PTR_OP: /* structure pointer dereference */ - { - sym_link *pType; - pType = operandType(left); - left = geniCodeRValue(left,TRUE); + case '.': /* structure dereference */ + if (IS_PTR (operandType (left))) + left = geniCodeRValue (left, TRUE); + else + left = geniCodeRValue (left, FALSE); - setOClass (pType,getSpec(operandType(left))); - } + return geniCodeStruct (left, right, tree->lvalue); - return geniCodeStruct (left, right,tree->lvalue); + case PTR_OP: /* structure pointer dereference */ + { + sym_link *pType; + pType = operandType (left); + left = geniCodeRValue (left, TRUE); - case INC_OP: /* increment operator */ - if ( left ) - return geniCodePostInc (left); - else - return geniCodePreInc (right); + setOClass (pType, getSpec (operandType (left))); + } - case DEC_OP: /* decrement operator */ - if ( left ) - return geniCodePostDec (left); - else - return geniCodePreDec (right); + return geniCodeStruct (left, right, tree->lvalue); - case '&' : /* bitwise and or address of operator */ - if ( right ) { /* this is a bitwise operator */ - left= geniCodeRValue(left,FALSE); - right= geniCodeRValue(right,FALSE); - return geniCodeBitwise (left,right,BITWISEAND,tree->ftype); - } else - return geniCodeAddressOf (left); + case INC_OP: /* increment operator */ + if (left) + return geniCodePostInc (left); + else + return geniCodePreInc (right); - case '|': /* bitwise or & xor */ + case DEC_OP: /* decrement operator */ + if (left) + return geniCodePostDec (left); + else + return geniCodePreDec (right); + + case '&': /* bitwise and or address of operator */ + if (right) + { /* this is a bitwise operator */ + left = geniCodeRValue (left, FALSE); + right = geniCodeRValue (right, FALSE); + return geniCodeBitwise (left, right, BITWISEAND, tree->ftype); + } + else + return geniCodeAddressOf (left); + + case '|': /* bitwise or & xor */ case '^': - return geniCodeBitwise (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE), - tree->opval.op, - tree->ftype); + return geniCodeBitwise (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE), + tree->opval.op, + tree->ftype); case '/': - return geniCodeDivision (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE)); + return geniCodeDivision (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE)); - case '%' : - return geniCodeModulus (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE)); + case '%': + return geniCodeModulus (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE)); case '*': - if ( right ) - return geniCodeMultiply (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE),FALSE); - else - return geniCodeDerefPtr (geniCodeRValue(left,FALSE)); + if (right) + return geniCodeMultiply (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE), FALSE); + else + return geniCodeDerefPtr (geniCodeRValue (left, FALSE)); - case '-' : - if ( right ) - return geniCodeSubtract (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE)); - else - return geniCodeUnaryMinus (geniCodeRValue(left,FALSE)); + case '-': + if (right) + return geniCodeSubtract (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE)); + else + return geniCodeUnaryMinus (geniCodeRValue (left, FALSE)); - case '+' : - if ( right ) - return geniCodeAdd (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE)); - else - return geniCodeRValue(left,FALSE) ; /* unary '+' has no meaning */ + case '+': + if (right) + return geniCodeAdd (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE)); + else + return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */ case LEFT_OP: - return geniCodeLeftShift (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE)); + return geniCodeLeftShift (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE)); case RIGHT_OP: - return geniCodeRightShift (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE)); + return geniCodeRightShift (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE)); case CAST: - return geniCodeCast (operandType(left), - geniCodeRValue(right,FALSE),FALSE); + return geniCodeCast (operandType (left), + geniCodeRValue (right, FALSE), FALSE); - case '~' : - case '!' : + case '~': + case '!': case RRC: case RLC: - return geniCodeUnary (geniCodeRValue(left,FALSE),tree->opval.op); + return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op); case GETHBIT: - { - operand *op = geniCodeUnary (geniCodeRValue(left,FALSE),tree->opval.op); - setOperandType(op, UCHARTYPE); - return op; - } - case '>' : - case '<' : + { + operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op); + setOperandType (op, UCHARTYPE); + return op; + } + case '>': + case '<': case LE_OP: case GE_OP: case EQ_OP: case NE_OP: case AND_OP: case OR_OP: - return geniCodeLogic (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE), - tree->opval.op); - case '?' : - return geniCodeConditional (tree); + return geniCodeLogic (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE), + tree->opval.op); + case '?': + return geniCodeConditional (tree); case SIZEOF: - return operandFromLit(getSize(tree->right->ftype)); - - case '=' : - { - sym_link *rtype = operandType(right); - sym_link *ltype = operandType(left); - if (IS_PTR(rtype) && IS_ITEMP(right) - && right->isaddr && checkType(rtype->next,ltype)==1) - right = geniCodeRValue(right,TRUE); - else - right = geniCodeRValue(right,FALSE); + return operandFromLit (getSize (tree->right->ftype)); + + case '=': + { + sym_link *rtype = operandType (right); + sym_link *ltype = operandType (left); + if (IS_PTR (rtype) && IS_ITEMP (right) + && right->isaddr && checkType (rtype->next, ltype) == 1) + right = geniCodeRValue (right, TRUE); + else + right = geniCodeRValue (right, FALSE); - geniCodeAssign (left,right,0); - return right ; - } + geniCodeAssign (left, right, 0); + return right; + } case MUL_ASSIGN: - return - geniCodeAssign(left, - geniCodeMultiply(geniCodeRValue (operandFromOperand(left), - FALSE), - geniCodeRValue(right,FALSE),FALSE),0); + return + geniCodeAssign (left, + geniCodeMultiply (geniCodeRValue (operandFromOperand (left), + FALSE), + geniCodeRValue (right, FALSE), FALSE), 0); case DIV_ASSIGN: - return - geniCodeAssign(left, - geniCodeDivision(geniCodeRValue(operandFromOperand(left), - FALSE), - geniCodeRValue(right,FALSE)),0); + return + geniCodeAssign (left, + geniCodeDivision (geniCodeRValue (operandFromOperand (left), + FALSE), + geniCodeRValue (right, FALSE)), 0); case MOD_ASSIGN: - return - geniCodeAssign(left, - geniCodeModulus(geniCodeRValue(operandFromOperand(left), - FALSE), - geniCodeRValue(right,FALSE)),0); + return + geniCodeAssign (left, + geniCodeModulus (geniCodeRValue (operandFromOperand (left), + FALSE), + geniCodeRValue (right, FALSE)), 0); case ADD_ASSIGN: - { - sym_link *rtype = operandType(right); - sym_link *ltype = operandType(left); - if (IS_PTR(rtype) && IS_ITEMP(right) - && right->isaddr && checkType(rtype->next,ltype)==1) - right = geniCodeRValue(right,TRUE); - else - right = geniCodeRValue(right,FALSE); + { + sym_link *rtype = operandType (right); + sym_link *ltype = operandType (left); + if (IS_PTR (rtype) && IS_ITEMP (right) + && right->isaddr && checkType (rtype->next, ltype) == 1) + right = geniCodeRValue (right, TRUE); + else + right = geniCodeRValue (right, FALSE); - return geniCodeAssign(left, - geniCodeAdd (geniCodeRValue(operandFromOperand(left), - FALSE), - right),0); - } - case SUB_ASSIGN: - { - sym_link *rtype = operandType(right); - sym_link *ltype = operandType(left); - if (IS_PTR(rtype) && IS_ITEMP(right) - && right->isaddr && checkType(rtype->next,ltype)==1) { - right = geniCodeRValue(right,TRUE); + return geniCodeAssign (left, + geniCodeAdd (geniCodeRValue (operandFromOperand (left), + FALSE), + right), 0); } - else { - right = geniCodeRValue(right,FALSE); + case SUB_ASSIGN: + { + sym_link *rtype = operandType (right); + sym_link *ltype = operandType (left); + if (IS_PTR (rtype) && IS_ITEMP (right) + && right->isaddr && checkType (rtype->next, ltype) == 1) + { + right = geniCodeRValue (right, TRUE); + } + else + { + right = geniCodeRValue (right, FALSE); + } + return + geniCodeAssign (left, + geniCodeSubtract (geniCodeRValue (operandFromOperand (left), + FALSE), + right), 0); } - return - geniCodeAssign (left, - geniCodeSubtract(geniCodeRValue(operandFromOperand(left), - FALSE), - right),0); - } case LEFT_ASSIGN: - return - geniCodeAssign (left, - geniCodeLeftShift(geniCodeRValue(operandFromOperand(left) - ,FALSE), - geniCodeRValue(right,FALSE)),0); + return + geniCodeAssign (left, + geniCodeLeftShift (geniCodeRValue (operandFromOperand (left) + ,FALSE), + geniCodeRValue (right, FALSE)), 0); case RIGHT_ASSIGN: - return - geniCodeAssign(left, - geniCodeRightShift(geniCodeRValue(operandFromOperand(left) - ,FALSE), - geniCodeRValue(right,FALSE)),0); + return + geniCodeAssign (left, + geniCodeRightShift (geniCodeRValue (operandFromOperand (left) + ,FALSE), + geniCodeRValue (right, FALSE)), 0); case AND_ASSIGN: return - geniCodeAssign (left, - geniCodeBitwise(geniCodeRValue(operandFromOperand(left), - FALSE), - geniCodeRValue(right,FALSE), - BITWISEAND, - operandType(left)),0); + geniCodeAssign (left, + geniCodeBitwise (geniCodeRValue (operandFromOperand (left), + FALSE), + geniCodeRValue (right, FALSE), + BITWISEAND, + operandType (left)), 0); case XOR_ASSIGN: return - geniCodeAssign (left, - geniCodeBitwise (geniCodeRValue(operandFromOperand(left), - FALSE), - geniCodeRValue(right,FALSE), - '^', - operandType(left)),0); + geniCodeAssign (left, + geniCodeBitwise (geniCodeRValue (operandFromOperand (left), + FALSE), + geniCodeRValue (right, FALSE), + '^', + operandType (left)), 0); case OR_ASSIGN: return - geniCodeAssign (left, - geniCodeBitwise (geniCodeRValue(operandFromOperand(left) - ,FALSE), - geniCodeRValue(right,FALSE), - '|', - operandType(left)),0); - case ',' : - return geniCodeRValue(right,FALSE); + geniCodeAssign (left, + geniCodeBitwise (geniCodeRValue (operandFromOperand (left) + ,FALSE), + geniCodeRValue (right, FALSE), + '|', + operandType (left)), 0); + case ',': + return geniCodeRValue (right, FALSE); case CALL: - return geniCodeCall (ast2iCode(tree->left), - tree->right); + return geniCodeCall (ast2iCode (tree->left), + tree->right); case LABEL: - geniCodeLabel(ast2iCode(tree->left)->operand.symOperand); - return ast2iCode (tree->right); + geniCodeLabel (ast2iCode (tree->left)->operand.symOperand); + return ast2iCode (tree->right); case GOTO: - geniCodeGoto (ast2iCode(tree->left)->operand.symOperand); - return ast2iCode (tree->right); + geniCodeGoto (ast2iCode (tree->left)->operand.symOperand); + return ast2iCode (tree->right); case FUNCTION: - geniCodeFunctionBody ( tree ); - return NULL ; + geniCodeFunctionBody (tree); + return NULL; case RETURN: - geniCodeReturn (right); - return NULL ; + geniCodeReturn (right); + return NULL; case IFX: - geniCodeIfx (tree); - return NULL ; + geniCodeIfx (tree); + return NULL; case SWITCH: - geniCodeSwitch (tree); - return NULL; + geniCodeSwitch (tree); + return NULL; case INLINEASM: - geniCodeInline (tree); - return NULL ; + geniCodeInline (tree); + return NULL; } - return NULL; + return NULL; } /*-----------------------------------------------------------------*/ /* reverseICChain - gets from the list and creates a linkedlist */ /*-----------------------------------------------------------------*/ -iCode *reverseiCChain () +iCode * +reverseiCChain () { - iCode *loop = NULL ; - iCode *prev = NULL ; + iCode *loop = NULL; + iCode *prev = NULL; - while ((loop = getSet(&iCodeChain))) { - loop->next = prev ; - if ( prev ) - prev->prev = loop; - prev = loop ; + while ((loop = getSet (&iCodeChain))) + { + loop->next = prev; + if (prev) + prev->prev = loop; + prev = loop; } - return prev; + return prev; } /*-----------------------------------------------------------------*/ /* iCodeFromAst - given an ast will convert it to iCode */ /*-----------------------------------------------------------------*/ -iCode *iCodeFromAst ( ast *tree ) +iCode * +iCodeFromAst (ast * tree) { - returnLabel = newiTempLabel("_return"); - entryLabel = newiTempLabel("_entry") ; - ast2iCode (tree); - return reverseiCChain (); + returnLabel = newiTempLabel ("_return"); + entryLabel = newiTempLabel ("_entry"); + ast2iCode (tree); + return reverseiCChain (); } - diff --git a/src/SDCCicode.h b/src/SDCCicode.h index c22e63d1..ca414246 100644 --- a/src/SDCCicode.h +++ b/src/SDCCicode.h @@ -27,22 +27,26 @@ #ifndef SDCCICODE_H #define SDCCICODE_H 1 -extern symbol *returnLabel ; -extern symbol *entryLabel ; -extern int iCodeKey ; -extern int operandKey ; - -enum { - CONDITIONAL = 0 , - EXPRESSION , - STATEMENT , - LEAF }; - -typedef enum { - SYMBOL =1, - VALUE , - TYPE -} OPTYPE; +extern symbol *returnLabel; +extern symbol *entryLabel; +extern int iCodeKey; +extern int operandKey; + +enum + { + CONDITIONAL = 0, + EXPRESSION, + STATEMENT, + LEAF + }; + +typedef enum + { + SYMBOL = 1, + VALUE, + TYPE + } +OPTYPE; #define IS_SYMOP(op) (op && op->type == SYMBOL) #define ADDTOCHAIN(x) addSetHead(&iCodeChain,x) @@ -70,30 +74,34 @@ typedef enum { #define OP_ISLIVE_FCALL(op) (IS_ITEMP(op) && OP_SYMBOL(op)->isLiveFcall) /* typedef for operand */ -typedef struct operand { - OPTYPE type; /* type of operand */ - unsigned int isaddr : 1; /* is an address */ - unsigned int isvolatile: 1; /* is a volatile operand */ - unsigned int isGlobal :1 ; /* is a global operand */ - unsigned int isPtr :1 ; /* is assigned a pointer */ - unsigned int isGptr :1 ; /* is a generic pointer */ - unsigned int isParm :1 ; /* is a parameter */ - unsigned int isLiteral:1 ; /* operand is literal */ - unsigned int noSpilLoc:1 ; /* cannot be assigned a spil location */ - - unsigned key ; - int parmBytes; - union { - struct symbol *symOperand ; /* operand is of type symbol */ - struct value *valOperand ; /* operand is of type value */ - struct sym_link *typeOperand; /* operand is of type typechain */ - } operand ; - - bitVect *usesDefs; /* which definitions are used by this */ - struct asmop *aop ; /* asm op for this operand */ -} operand ; - -/* definition for intermediate code */ +typedef struct operand + { + OPTYPE type; /* type of operand */ + unsigned int isaddr:1; /* is an address */ + unsigned int isvolatile:1; /* is a volatile operand */ + unsigned int isGlobal:1; /* is a global operand */ + unsigned int isPtr:1; /* is assigned a pointer */ + unsigned int isGptr:1; /* is a generic pointer */ + unsigned int isParm:1; /* is a parameter */ + unsigned int isLiteral:1; /* operand is literal */ + unsigned int noSpilLoc:1; /* cannot be assigned a spil location */ + + unsigned key; + int parmBytes; + union + { + struct symbol *symOperand; /* operand is of type symbol */ + struct value *valOperand; /* operand is of type value */ + struct sym_link *typeOperand; /* operand is of type typechain */ + } + operand; + + bitVect *usesDefs; /* which definitions are used by this */ + struct asmop *aop; /* asm op for this operand */ + } +operand; + +/* definition for intermediate code */ #define IC_RESULT(x) (x)->ulrrcnd.lrr.result #define IC_LEFT(x) (x)->ulrrcnd.lrr.left #define IC_RIGHT(x) (x)->ulrrcnd.lrr.right @@ -106,68 +114,80 @@ typedef struct operand { #define IC_JTLABELS(x) (x)->ulrrcnd.jmpTab.labels #define IC_INLINE(x) (x)->inlineAsm -typedef struct iCode -{ - unsigned int op ; /* operation defined */ - int key ; /* running key for this iCode */ - int seq ; /* sequence number within routine */ - short depth ; /* loop depth of this iCode */ - short level ; /* scope level */ - short block ; /* sequential block number */ - unsigned nosupdate:1; /* don't update spillocation with this */ - unsigned generated:1; /* code generated for this one */ - unsigned parmPush :1; /* parameter push Vs spill push */ - unsigned supportRtn:1; /* will cause a call to a support routine */ - unsigned regsSaved:1 ; /* registers have been saved */ - unsigned bankSaved:1 ; /* register bank has been saved */ - - struct iCode *next ; /* next in chain */ - struct iCode *prev ; /* previous in chain */ - set *movedFrom; /* if this iCode gets moved to another block */ - bitVect *rlive ; /* ranges that are live at this point */ - int defKey ; /* key for the operand being defined */ - bitVect *uses ; /* vector of key of used symbols */ - bitVect *rUsed ; /* registers used by this instruction */ - bitVect *rMask ; /* registers in use during this instruction */ - union { - struct { - operand *left ; /* left if any */ - operand *right ; /* right if any */ - operand *result ; /* result of this op */ - } lrr ; - - struct { - operand *condition ; /* if this is a conditional */ - symbol *trueLabel ; /* true for conditional */ - symbol *falseLabel; /* false for conditional */ - } cnd; - - struct { - operand *condition ; /* condition for the jump */ - set *labels ; /* ordered set of labels */ - } jmpTab ; - - } ulrrcnd; - - union { - symbol *label ; /* for a goto statement */ - value *args ; - } argLabel ; - - char *inlineAsm ; /* pointer to inline assembler code */ - - int lineno ; /* file & lineno for debug information */ - char *filename ; -} iCode ; +typedef struct iCode + { + unsigned int op; /* operation defined */ + int key; /* running key for this iCode */ + int seq; /* sequence number within routine */ + short depth; /* loop depth of this iCode */ + short level; /* scope level */ + short block; /* sequential block number */ + unsigned nosupdate:1; /* don't update spillocation with this */ + unsigned generated:1; /* code generated for this one */ + unsigned parmPush:1; /* parameter push Vs spill push */ + unsigned supportRtn:1; /* will cause a call to a support routine */ + unsigned regsSaved:1; /* registers have been saved */ + unsigned bankSaved:1; /* register bank has been saved */ + + struct iCode *next; /* next in chain */ + struct iCode *prev; /* previous in chain */ + set *movedFrom; /* if this iCode gets moved to another block */ + bitVect *rlive; /* ranges that are live at this point */ + int defKey; /* key for the operand being defined */ + bitVect *uses; /* vector of key of used symbols */ + bitVect *rUsed; /* registers used by this instruction */ + bitVect *rMask; /* registers in use during this instruction */ + union + { + struct + { + operand *left; /* left if any */ + operand *right; /* right if any */ + operand *result; /* result of this op */ + } + lrr; + + struct + { + operand *condition; /* if this is a conditional */ + symbol *trueLabel; /* true for conditional */ + symbol *falseLabel; /* false for conditional */ + } + cnd; + + struct + { + operand *condition; /* condition for the jump */ + set *labels; /* ordered set of labels */ + } + jmpTab; + + } + ulrrcnd; + + union + { + symbol *label; /* for a goto statement */ + value *args; + } + argLabel; + + char *inlineAsm; /* pointer to inline assembler code */ + + int lineno; /* file & lineno for debug information */ + char *filename; + } +iCode; /* various functions associated to iCode */ -typedef struct icodeFuncTable -{ - int icode ; - char *printName ; - void (*iCodePrint)(FILE *,iCode *,char *) ; - iCode * (*iCodeCopy)(iCode *) ; -} iCodeTable ; +typedef struct icodeFuncTable + { + int icode; + char *printName; + void (*iCodePrint) (FILE *, iCode *, char *); + iCode *(*iCodeCopy) (iCode *); + } +iCodeTable; /* useful macros */ #define SKIP_IC2(x) (x->op == GOTO || \ @@ -185,7 +205,7 @@ typedef struct icodeFuncTable x->op == JUMPTABLE || \ x->op == RECEIVE || \ SKIP_IC1(x)|| \ - x->op == SEND ) + x->op == SEND ) #define IS_CONDITIONAL(x) (x->op == EQ_OP || \ x->op == '<' || \ @@ -244,41 +264,41 @@ typedef struct icodeFuncTable /*-----------------------------------------------------------------*/ /* forward references for functions */ /*-----------------------------------------------------------------*/ -iCode *reverseiCChain ( ); -bool isOperandOnStack (operand *); -int isOperandVolatile (operand *,bool); -int isOperandGlobal (operand *); -void printiCChain ( iCode * , FILE *); -operand *ast2iCode ( ast *); -operand *geniCodeCast ( sym_link *, operand *,bool); +iCode *reverseiCChain (); +bool isOperandOnStack (operand *); +int isOperandVolatile (operand *, bool); +int isOperandGlobal (operand *); +void printiCChain (iCode *, FILE *); +operand *ast2iCode (ast *); +operand *geniCodeCast (sym_link *, operand *, bool); operand *geniCodePtrPtrSubtract (operand *, operand *); -void initiCode (); -iCode *iCodeFromAst ( ast * ); -int isiCodeEqual ( iCode *,iCode *) ; -int isOperandEqual ( operand *, operand *); -iCodeTable *getTableEntry (int ); -int isOperandLiteral (operand *); -operand *operandOperation (operand *,operand *,int,sym_link *); -double operandLitValue ( operand * ); +void initiCode (); +iCode *iCodeFromAst (ast *); +int isiCodeEqual (iCode *, iCode *); +int isOperandEqual (operand *, operand *); +iCodeTable *getTableEntry (int); +int isOperandLiteral (operand *); +operand *operandOperation (operand *, operand *, int, sym_link *); +double operandLitValue (operand *); operand *operandFromLit (float); -operand *operandFromOperand(operand *); -int isParameterToCall (value *,operand *); -iCode *newiCodeLabelGoto (int , symbol *); -symbol *newiTemp(char *); -symbol *newiTempLabel (char *); -symbol *newiTempPreheaderLabel (); -iCode *newiCode (int, operand *, operand *); -sym_link *operandType(operand *); +operand *operandFromOperand (operand *); +int isParameterToCall (value *, operand *); +iCode *newiCodeLabelGoto (int, symbol *); +symbol *newiTemp (char *); +symbol *newiTempLabel (char *); +symbol *newiTempPreheaderLabel (); +iCode *newiCode (int, operand *, operand *); +sym_link *operandType (operand *); operand *operandFromValue (value *); -operand *operandFromSymbol(symbol *); -sym_link *aggrToPtr ( sym_link *, bool); -int piCode (void *, FILE * ); -int printOperand (operand *,FILE *); -void setOperandType (operand *, sym_link *); -bool isOperandInFarSpace (operand *); -operand *opFromOpWithDU (operand *,bitVect *,bitVect *); -iCode *copyiCode (iCode *); -operand *newiTempFromOp( operand *); +operand *operandFromSymbol (symbol *); +sym_link *aggrToPtr (sym_link *, bool); +int piCode (void *, FILE *); +int printOperand (operand *, FILE *); +void setOperandType (operand *, sym_link *); +bool isOperandInFarSpace (operand *); +operand *opFromOpWithDU (operand *, bitVect *, bitVect *); +iCode *copyiCode (iCode *); +operand *newiTempFromOp (operand *); /*-----------------------------------------------------------------*/ /* declaration of exported variables */ /*-----------------------------------------------------------------*/ diff --git a/src/SDCClabel.c b/src/SDCClabel.c index d579fe9a..5c26ce67 100644 --- a/src/SDCClabel.c +++ b/src/SDCClabel.c @@ -24,409 +24,442 @@ #include "common.h" -hTab *labelRef = NULL ; -hTab *labelDef = NULL ; +hTab *labelRef = NULL; +hTab *labelDef = NULL; /*-----------------------------------------------------------------*/ /* buildLabelRefTable - creates an hashTable of label referneces */ /*-----------------------------------------------------------------*/ -void buildLabelRefTable (iCode *ic) +void +buildLabelRefTable (iCode * ic) { - iCode *lic; - - setToNull ((void **)&labelRef); - setToNull ((void **)&labelDef); - labelRef = newHashTable(labelKey + 1); - labelDef = newHashTable(labelKey + 1); - - for (lic = ic ; lic ; lic = lic->next ) { - if ( lic->op == GOTO ) - hTabAddItem (&labelRef, (IC_LABEL(lic))->key, lic); - - if ( lic->op == JUMPTABLE ) { - symbol *lbl ; - for (lbl = setFirstItem(IC_JTLABELS(lic)); lbl; - lbl = setNextItem(IC_JTLABELS(lic))) { - hTabAddItem(&labelRef,lbl->key,lic); + iCode *lic; + + setToNull ((void **) &labelRef); + setToNull ((void **) &labelDef); + labelRef = newHashTable (labelKey + 1); + labelDef = newHashTable (labelKey + 1); + + for (lic = ic; lic; lic = lic->next) + { + if (lic->op == GOTO) + hTabAddItem (&labelRef, (IC_LABEL (lic))->key, lic); + + if (lic->op == JUMPTABLE) + { + symbol *lbl; + for (lbl = setFirstItem (IC_JTLABELS (lic)); lbl; + lbl = setNextItem (IC_JTLABELS (lic))) + { + hTabAddItem (&labelRef, lbl->key, lic); } } - - if (lic->op == IFX ) { - if (IC_TRUE(lic)) - hTabAddItem(&labelRef,(IC_TRUE(lic))->key, lic); - else - hTabAddItem(&labelRef,(IC_FALSE(lic))->key, lic); + + if (lic->op == IFX) + { + if (IC_TRUE (lic)) + hTabAddItem (&labelRef, (IC_TRUE (lic))->key, lic); + else + hTabAddItem (&labelRef, (IC_FALSE (lic))->key, lic); } - if ( lic->op == LABEL ) - hTabAddItem (&labelDef,(IC_LABEL(lic))->key, lic); - + if (lic->op == LABEL) + hTabAddItem (&labelDef, (IC_LABEL (lic))->key, lic); + } } /*-----------------------------------------------------------------*/ /* labelGotoNext - kills gotos to next statement */ /*-----------------------------------------------------------------*/ -int labelGotoNext (iCode *ic) +int +labelGotoNext (iCode * ic) { - iCode *loop; - int change = 0 ; - - for ( loop = ic ; loop ; loop = loop->next) { - - if (loop->op == GOTO && /* if this is a goto */ - loop->next && /* and we have a next one */ - loop->next->op == LABEL && /* next one is a label */ - loop->next->argLabel.label->key == loop->argLabel.label->key) /* same label */ - { - loop->prev->next = loop->next ; /* get this out of the chain */ - loop->next->prev = loop->prev ; - hTabDeleteItem (&labelRef,(IC_LABEL(loop))->key, loop, DELETE_ITEM, NULL); - change++ ; - } + iCode *loop; + int change = 0; + + for (loop = ic; loop; loop = loop->next) + { + + if (loop->op == GOTO && /* if this is a goto */ + loop->next && /* and we have a next one */ + loop->next->op == LABEL && /* next one is a label */ + loop->next->argLabel.label->key == loop->argLabel.label->key) /* same label */ + { + loop->prev->next = loop->next; /* get this out of the chain */ + loop->next->prev = loop->prev; + hTabDeleteItem (&labelRef, (IC_LABEL (loop))->key, loop, DELETE_ITEM, NULL); + change++; + } } - return change ; + return change; } /*-----------------------------------------------------------------*/ /* labelIfx - special case Ifx elimination */ /*-----------------------------------------------------------------*/ -int labelIfx ( iCode *ic) +int +labelIfx (iCode * ic) { - iCode *loop ; - int change = 0; - - - for ( loop = ic ; loop ; loop = loop->next ) { - /* if condition goto label */ - /* goto label */ - /* i.e. the flow is going to the same location - regardless of the condition in this case the - condition can be eliminated with a WARNING ofcource */ - if ( loop->op == IFX && - loop->next && - loop->next->op == GOTO ) { - if (IC_TRUE(loop) && - IC_TRUE(loop)->key == IC_LABEL(loop->next)->key) { - - /* get rid of this if */ - werror(W_CONTROL_FLOW,loop->filename,loop->lineno); - loop->prev->next = loop->next; - loop->next->prev = loop->prev; - hTabDeleteItem(&labelRef, - (IC_TRUE(loop))->key, - loop, DELETE_ITEM,NULL); - change++ ; - continue ; + iCode *loop; + int change = 0; + + + for (loop = ic; loop; loop = loop->next) + { + /* if condition goto label */ + /* goto label */ + /* i.e. the flow is going to the same location + regardless of the condition in this case the + condition can be eliminated with a WARNING ofcource */ + if (loop->op == IFX && + loop->next && + loop->next->op == GOTO) + { + if (IC_TRUE (loop) && + IC_TRUE (loop)->key == IC_LABEL (loop->next)->key) + { + + /* get rid of this if */ + werror (W_CONTROL_FLOW, loop->filename, loop->lineno); + loop->prev->next = loop->next; + loop->next->prev = loop->prev; + hTabDeleteItem (&labelRef, + (IC_TRUE (loop))->key, + loop, DELETE_ITEM, NULL); + change++; + continue; } - else { - if (IC_FALSE(loop) && - IC_FALSE(loop)->key == IC_LABEL(loop->next)->key){ - /* get rid of this if */ - werror(W_CONTROL_FLOW,loop->filename,loop->lineno); - loop->prev->next = loop->next; - loop->next->prev = loop->prev; - hTabDeleteItem(&labelRef, - (IC_FALSE(loop))->key, - loop, DELETE_ITEM,NULL); - change++; - continue ; - } + else + { + if (IC_FALSE (loop) && + IC_FALSE (loop)->key == IC_LABEL (loop->next)->key) + { + /* get rid of this if */ + werror (W_CONTROL_FLOW, loop->filename, loop->lineno); + loop->prev->next = loop->next; + loop->next->prev = loop->prev; + hTabDeleteItem (&labelRef, + (IC_FALSE (loop))->key, + loop, DELETE_ITEM, NULL); + change++; + continue; + } } } - /* same as above but with a twist */ - /* if condition goto label */ - /* label: */ - if (loop->op == IFX && - loop->next && - loop->next->op == LABEL && - ((IC_TRUE(loop) && IC_TRUE(loop)->key == IC_LABEL(loop->next)->key) || - (IC_FALSE(loop) && IC_FALSE(loop)->key == IC_LABEL(loop->next)->key))) { - - werror(W_CONTROL_FLOW,loop->filename,loop->lineno); - loop->prev->next = loop->next; - loop->next->prev = loop->prev; - hTabDeleteItem(&labelRef, - IC_LABEL(loop->next)->key, - loop, DELETE_ITEM,NULL); - change++; - continue ; + /* same as above but with a twist */ + /* if condition goto label */ + /* label: */ + if (loop->op == IFX && + loop->next && + loop->next->op == LABEL && + ((IC_TRUE (loop) && IC_TRUE (loop)->key == IC_LABEL (loop->next)->key) || + (IC_FALSE (loop) && IC_FALSE (loop)->key == IC_LABEL (loop->next)->key))) + { + + werror (W_CONTROL_FLOW, loop->filename, loop->lineno); + loop->prev->next = loop->next; + loop->next->prev = loop->prev; + hTabDeleteItem (&labelRef, + IC_LABEL (loop->next)->key, + loop, DELETE_ITEM, NULL); + change++; + continue; } - - /* we will eliminate certain special case situations*/ - /* of the conditional statement :- */ - /* if cond != 0 goto _trueLabel */ - /* goto _falseLabel */ - /* _trueLabel : */ - /* ... */ - /* in these cases , if this is the only reference */ - /* to the _trueLabel, we can change it to :- */ - /* if cond == 0 goto _falseLabel */ - /* ... */ - /* similarly if we have a situation like :- */ - /* if cond == 0 goto _falseLabel */ - /* goto _someLabel */ - /* _falseLabel : */ - /* we can change this to */ - /* if cond != 0 goto _someLabel */ - /* ... */ - if (loop->op == IFX && - loop->next && - loop->next->op == GOTO && - loop->next->next && - loop->next->next->op == LABEL ) { - - - /* now check that the last label is the */ - /* same as the _trueLabel of this */ - if (IC_TRUE(loop)) - if ( (IC_TRUE(loop))->key != (IC_LABEL(loop->next->next))->key ) - continue ; - else ; - else - if ( (IC_FALSE(loop))->key != (IC_LABEL(loop->next->next))->key ) - continue; - - /* now make sure that this is the only */ - /* referenece to the _trueLabel */ - if ( IC_TRUE(loop) && hTabItemWithKey(labelRef,(IC_TRUE(loop))->key) ) { - - /* we just change the falseLabel */ - /* to the next goto statement */ - /* unreferenced label will take */ - /* care of removing the label */ - /* delete reference to the true label */ - - hTabDeleteItem(&labelRef, (IC_TRUE(loop))->key, loop, DELETE_ITEM,NULL); - IC_TRUE(loop) = NULL ; - IC_FALSE(loop) = IC_LABEL(loop->next); - /* add reference to the LABEL */ - hTabAddItem (&labelRef,(IC_FALSE(loop))->key,loop); - /* next remove the goto */ - hTabDeleteItem(&labelRef, - (IC_LABEL(loop->next))->key,loop->next,DELETE_ITEM,NULL); - loop->next = loop->next->next ; - loop->next->prev = loop ; - change++; - continue ; + + /* we will eliminate certain special case situations */ + /* of the conditional statement :- */ + /* if cond != 0 goto _trueLabel */ + /* goto _falseLabel */ + /* _trueLabel : */ + /* ... */ + /* in these cases , if this is the only reference */ + /* to the _trueLabel, we can change it to :- */ + /* if cond == 0 goto _falseLabel */ + /* ... */ + /* similarly if we have a situation like :- */ + /* if cond == 0 goto _falseLabel */ + /* goto _someLabel */ + /* _falseLabel : */ + /* we can change this to */ + /* if cond != 0 goto _someLabel */ + /* ... */ + if (loop->op == IFX && + loop->next && + loop->next->op == GOTO && + loop->next->next && + loop->next->next->op == LABEL) + { + + + /* now check that the last label is the */ + /* same as the _trueLabel of this */ + if (IC_TRUE (loop)) + if ((IC_TRUE (loop))->key != (IC_LABEL (loop->next->next))->key) + continue; + else; + else if ((IC_FALSE (loop))->key != (IC_LABEL (loop->next->next))->key) + continue; + + /* now make sure that this is the only */ + /* referenece to the _trueLabel */ + if (IC_TRUE (loop) && hTabItemWithKey (labelRef, (IC_TRUE (loop))->key)) + { + + /* we just change the falseLabel */ + /* to the next goto statement */ + /* unreferenced label will take */ + /* care of removing the label */ + /* delete reference to the true label */ + + hTabDeleteItem (&labelRef, (IC_TRUE (loop))->key, loop, DELETE_ITEM, NULL); + IC_TRUE (loop) = NULL; + IC_FALSE (loop) = IC_LABEL (loop->next); + /* add reference to the LABEL */ + hTabAddItem (&labelRef, (IC_FALSE (loop))->key, loop); + /* next remove the goto */ + hTabDeleteItem (&labelRef, + (IC_LABEL (loop->next))->key, loop->next, DELETE_ITEM, NULL); + loop->next = loop->next->next; + loop->next->prev = loop; + change++; + continue; + } + + /* now do the same with the false labels */ + if (IC_FALSE (loop) && + hTabItemWithKey (labelRef, (IC_FALSE (loop))->key)) + { + + hTabDeleteItem (&labelRef, (IC_FALSE (loop))->key, loop, DELETE_ITEM, NULL); + IC_FALSE (loop) = NULL; + IC_TRUE (loop) = IC_LABEL (loop->next); + hTabAddItem (&labelRef, (IC_TRUE (loop))->key, loop); + hTabDeleteItem (&labelRef, (IC_LABEL (loop->next))->key, loop->next, DELETE_ITEM, NULL); + loop->next = loop->next->next; + loop->next->prev = loop; + change++; + continue; } - - /* now do the same with the false labels */ - if (IC_FALSE(loop) && - hTabItemWithKey(labelRef,(IC_FALSE(loop))->key)) { - - hTabDeleteItem(&labelRef, (IC_FALSE(loop))->key, loop, DELETE_ITEM,NULL); - IC_FALSE(loop) = NULL ; - IC_TRUE(loop) = IC_LABEL(loop->next); - hTabAddItem (&labelRef,(IC_TRUE(loop))->key,loop); - hTabDeleteItem(&labelRef,(IC_LABEL(loop->next))->key,loop->next,DELETE_ITEM,NULL); - loop->next = loop->next->next ; - loop->next->prev = loop ; - change++; - continue ; - } } } - return change ; + return change; } /*-----------------------------------------------------------------*/ /* labelGotoGoto - target of a goto is a goto */ /*-----------------------------------------------------------------*/ -int labelGotoGoto (iCode *ic) +int +labelGotoGoto (iCode * ic) { - iCode *loop; - int change = 0 ; - - for ( loop = ic ; loop ; loop = loop->next ) { - iCode *stat ; - symbol *sLabel = NULL; - stat = NULL ; - switch (loop->op) { - case GOTO: /* for a goto statement */ - stat = hTabItemWithKey(labelDef,(sLabel = IC_LABEL(loop))->key) ; - break ; - case IFX : /* for a conditional jump */ - if (IC_TRUE(loop)) - stat = hTabItemWithKey(labelDef,(sLabel = IC_TRUE(loop))->key); - else - stat = hTabItemWithKey (labelDef,(sLabel = IC_FALSE(loop))->key); + iCode *loop; + int change = 0; + + for (loop = ic; loop; loop = loop->next) + { + iCode *stat; + symbol *sLabel = NULL; + stat = NULL; + switch (loop->op) + { + case GOTO: /* for a goto statement */ + stat = hTabItemWithKey (labelDef, (sLabel = IC_LABEL (loop))->key); + break; + case IFX: /* for a conditional jump */ + if (IC_TRUE (loop)) + stat = hTabItemWithKey (labelDef, (sLabel = IC_TRUE (loop))->key); + else + stat = hTabItemWithKey (labelDef, (sLabel = IC_FALSE (loop))->key); } - - /* if we have a target statement then check if the next */ - /* one is a goto: this means target of goto is a goto */ - if ( stat && stat->next && - ( stat->next->op == GOTO || - stat->next->op == LABEL) && - stat->next != loop ) { - - symbol *repLabel = stat->next->argLabel.label ; /* replace with label */ - - /* if they are the same then continue */ - if (repLabel->key == sLabel->key) - continue ; - - /* replacement depends on the statement type */ - switch (loop->op) { - - case GOTO: /* for a goto statement */ - - hTabDeleteItem (&labelRef, (IC_LABEL(loop))->key, loop,DELETE_ITEM,NULL); - loop->argLabel.label = repLabel ; - hTabAddItem (&labelRef, repLabel->key, loop); - break ; - - case IFX : /* for a conditional jump */ - if (IC_TRUE(loop)) { - - hTabDeleteItem (&labelRef, (IC_TRUE(loop))->key, loop,DELETE_ITEM,NULL); - IC_TRUE(loop) = repLabel ; - } - else { - - hTabDeleteItem (&labelRef, (IC_FALSE(loop))->key, loop,DELETE_ITEM,NULL); - IC_FALSE(loop) = repLabel; + + /* if we have a target statement then check if the next */ + /* one is a goto: this means target of goto is a goto */ + if (stat && stat->next && + (stat->next->op == GOTO || + stat->next->op == LABEL) && + stat->next != loop) + { + + symbol *repLabel = stat->next->argLabel.label; /* replace with label */ + + /* if they are the same then continue */ + if (repLabel->key == sLabel->key) + continue; + + /* replacement depends on the statement type */ + switch (loop->op) + { + + case GOTO: /* for a goto statement */ + + hTabDeleteItem (&labelRef, (IC_LABEL (loop))->key, loop, DELETE_ITEM, NULL); + loop->argLabel.label = repLabel; + hTabAddItem (&labelRef, repLabel->key, loop); + break; + + case IFX: /* for a conditional jump */ + if (IC_TRUE (loop)) + { + + hTabDeleteItem (&labelRef, (IC_TRUE (loop))->key, loop, DELETE_ITEM, NULL); + IC_TRUE (loop) = repLabel; } - hTabAddItem (&labelRef, repLabel->key, loop); - + else + { + + hTabDeleteItem (&labelRef, (IC_FALSE (loop))->key, loop, DELETE_ITEM, NULL); + IC_FALSE (loop) = repLabel; + } + hTabAddItem (&labelRef, repLabel->key, loop); + } - change++ ; + change++; } } - - return change ; + + return change; } /*-----------------------------------------------------------------*/ /* labelUnrefLabel - remove unreferneced labels */ /*-----------------------------------------------------------------*/ -int labelUnrefLabel (iCode *ic) +int +labelUnrefLabel (iCode * ic) { - iCode *loop; - int change = 0 ; - - for ( loop = ic ; loop ; loop = loop->next) { - - /* if this is a label */ - if (loop->op == LABEL) { - set *refs ; - - refs = NULL ; - if ( ( (IC_LABEL(loop))->key == returnLabel->key ) || - ( (IC_LABEL(loop))->key == entryLabel->key ) ) - continue ; - - if (hTabItemWithKey(labelRef,(IC_LABEL(loop))->key) ) - continue ; - - /* else eliminitate this one */ - loop->prev->next = loop->next ; /* get this out of the chain */ - loop->next->prev = loop->prev ; - change ++ ; + iCode *loop; + int change = 0; + + for (loop = ic; loop; loop = loop->next) + { + + /* if this is a label */ + if (loop->op == LABEL) + { + set *refs; + + refs = NULL; + if (((IC_LABEL (loop))->key == returnLabel->key) || + ((IC_LABEL (loop))->key == entryLabel->key)) + continue; + + if (hTabItemWithKey (labelRef, (IC_LABEL (loop))->key)) + continue; + + /* else eliminitate this one */ + loop->prev->next = loop->next; /* get this out of the chain */ + loop->next->prev = loop->prev; + change++; } } - return change ; + return change; } /*-----------------------------------------------------------------*/ /* labelUnreach - remove unreachable code */ /*-----------------------------------------------------------------*/ -int labelUnreach (iCode *ic) +int +labelUnreach (iCode * ic) { - iCode *loop; - iCode *tic; - int change = 0 ; - - /* if we hit a return statement or a goto statement */ - /* remove all statements till we hit the next label */ - for (loop = ic ; loop ; loop = loop->next) { - iCode *loop2 ; - - /* found a goto || return && the next */ - /* statement is not a label */ - if (loop->op == GOTO || loop->op == RETURN ) { - - if (loop->next && - (loop->next->op == LABEL || - loop->next->op == ENDFUNCTION )) - continue ; - - /* loop till we find a label */ - loop2 = loop->next ; - while (loop2 && loop2->op != LABEL) - loop2 = loop2->next; - - /* throw away those in between */ - for (tic = loop->next ; tic && tic != loop2 ; tic=tic->next) { - /* remove label references if any */ - switch (tic->op) { - case GOTO : - hTabDeleteItem (&labelRef,IC_LABEL(tic)->key,tic,DELETE_ITEM,NULL); - break; - case IFX : - if (IC_TRUE(tic)) - hTabDeleteItem (&labelRef,IC_TRUE(tic)->key,tic,DELETE_ITEM,NULL); - else - hTabDeleteItem (&labelRef,IC_FALSE(tic)->key,tic,DELETE_ITEM,NULL); - break; - - } + iCode *loop; + iCode *tic; + int change = 0; + + /* if we hit a return statement or a goto statement */ + /* remove all statements till we hit the next label */ + for (loop = ic; loop; loop = loop->next) + { + iCode *loop2; + + /* found a goto || return && the next */ + /* statement is not a label */ + if (loop->op == GOTO || loop->op == RETURN) + { + + if (loop->next && + (loop->next->op == LABEL || + loop->next->op == ENDFUNCTION)) + continue; + + /* loop till we find a label */ + loop2 = loop->next; + while (loop2 && loop2->op != LABEL) + loop2 = loop2->next; + + /* throw away those in between */ + for (tic = loop->next; tic && tic != loop2; tic = tic->next) + { + /* remove label references if any */ + switch (tic->op) + { + case GOTO: + hTabDeleteItem (&labelRef, IC_LABEL (tic)->key, tic, DELETE_ITEM, NULL); + break; + case IFX: + if (IC_TRUE (tic)) + hTabDeleteItem (&labelRef, IC_TRUE (tic)->key, tic, DELETE_ITEM, NULL); + else + hTabDeleteItem (&labelRef, IC_FALSE (tic)->key, tic, DELETE_ITEM, NULL); + break; + + } } - /* now set up the pointers */ - loop->next = loop2; - if (loop2) - loop2->prev = loop ; - change++; + /* now set up the pointers */ + loop->next = loop2; + if (loop2) + loop2->prev = loop; + change++; } } - return change ; + return change; } /*-----------------------------------------------------------------*/ /* iCodeLabelOptimize - some obvious & general optimizations */ /*-----------------------------------------------------------------*/ -iCode *iCodeLabelOptimize (iCode *ic) -{ - if (!optimize.label1 && - !optimize.label2 && - !optimize.label3 && - !optimize.label4 ) - return ic; - - /* build labelreferences */ - buildLabelRefTable (ic); - - /* the following transformations need to ne done */ - /* repeatedly till a fixed point is reached */ - while (1) { - int change ; - change = 0 ; - - /* first eliminate any goto statement */ - /* that goes to the next statement */ - if (optimize.label1) - change += labelGotoNext (ic); - - if ( optimize.label2 ) - change += labelIfx (ic); - - /* target of a goto is a goto then rename this goto */ - if (optimize.label3 ) - change += labelGotoGoto (ic); - - /* remove unreference labels */ - if (optimize.label4) - change += labelUnrefLabel (ic); - - /* remove unreachable code */ - change += labelUnreach (ic); - - if (!change) /* fixed point reached */ - break; - } - +iCode * +iCodeLabelOptimize (iCode * ic) +{ + if (!optimize.label1 && + !optimize.label2 && + !optimize.label3 && + !optimize.label4) return ic; + + /* build labelreferences */ + buildLabelRefTable (ic); + + /* the following transformations need to ne done */ + /* repeatedly till a fixed point is reached */ + while (1) + { + int change; + change = 0; + + /* first eliminate any goto statement */ + /* that goes to the next statement */ + if (optimize.label1) + change += labelGotoNext (ic); + + if (optimize.label2) + change += labelIfx (ic); + + /* target of a goto is a goto then rename this goto */ + if (optimize.label3) + change += labelGotoGoto (ic); + + /* remove unreference labels */ + if (optimize.label4) + change += labelUnrefLabel (ic); + + /* remove unreachable code */ + change += labelUnreach (ic); + + if (!change) /* fixed point reached */ + break; + } + + return ic; } diff --git a/src/SDCClabel.h b/src/SDCClabel.h index 3ece83d6..76adb951 100644 --- a/src/SDCClabel.h +++ b/src/SDCClabel.h @@ -28,11 +28,11 @@ #ifndef SDCCLABEL_H #define SDCCLABEL_H -extern hTab *labelRef ; -extern hTab *labelDef ; +extern hTab *labelRef; +extern hTab *labelDef; extern int labelKey; -iCode *iCodeLabelOptimize (iCode *); +iCode *iCodeLabelOptimize (iCode *); #endif diff --git a/src/SDCCloop.c b/src/SDCCloop.c index db1188cc..453cba1f 100644 --- a/src/SDCCloop.c +++ b/src/SDCCloop.c @@ -26,1095 +26,1161 @@ #include "common.h" #include "newalloc.h" -DEFSETFUNC(isDefAlive); +DEFSETFUNC (isDefAlive); -STACK_DCL(regionStack,eBBlock *, MAX_NEST_LEVEL * 10); +STACK_DCL (regionStack, eBBlock *, MAX_NEST_LEVEL * 10); /*-----------------------------------------------------------------*/ /* newInduction - creates a new induction variable */ /*-----------------------------------------------------------------*/ -induction *newInduction (operand *sym, unsigned int op, - long constVal, iCode *ic, operand *asym) +induction * +newInduction (operand * sym, unsigned int op, + long constVal, iCode * ic, operand * asym) { - induction *ip; + induction *ip; - ip = Safe_calloc(1,sizeof(induction)); + ip = Safe_calloc (1, sizeof (induction)); - ip->sym = sym; - ip->asym= asym; - ip->op = op; - ip->cval = constVal; - ip->ic = ic; + ip->sym = sym; + ip->asym = asym; + ip->op = op; + ip->cval = constVal; + ip->ic = ic; - return ip; + return ip; } /*-----------------------------------------------------------------*/ /* newRegion - allocate & returns a loop structure */ /*-----------------------------------------------------------------*/ -region *newRegion () +region * +newRegion () { - region *lp ; + region *lp; - lp = Safe_calloc(1,sizeof(region)); + lp = Safe_calloc (1, sizeof (region)); - return lp; + return lp; } /*-----------------------------------------------------------------*/ /* pinduction - prints induction */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(pinduction) +DEFSETFUNC (pinduction) { - induction *ip = item; - iCodeTable *icTab; - - fprintf(stdout,"\t"); - printOperand(ip->sym,stdout); - icTab = getTableEntry(ip->ic->op); - icTab->iCodePrint(stdout,ip->ic,icTab->printName); - fprintf(stdout," %04d\n",(int)ip->cval); - return 0; + induction *ip = item; + iCodeTable *icTab; + + fprintf (stdout, "\t"); + printOperand (ip->sym, stdout); + icTab = getTableEntry (ip->ic->op); + icTab->iCodePrint (stdout, ip->ic, icTab->printName); + fprintf (stdout, " %04d\n", (int) ip->cval); + return 0; } /*-----------------------------------------------------------------*/ /* pregion - prints loop information */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(pregion) +DEFSETFUNC (pregion) { - region *lp = item; - - printf("================\n"); - printf(" loop with entry -- > "); printEntryLabel(lp->entry,ap); - printf("\n"); - printf(" loop body --> "); applyToSet(lp->regBlocks,printEntryLabel); - printf("\n"); - printf(" loop exits --> "); applyToSet(lp->exits,printEntryLabel); - printf("\n"); - return 0; + region *lp = item; + + printf ("================\n"); + printf (" loop with entry -- > "); + printEntryLabel (lp->entry, ap); + printf ("\n"); + printf (" loop body --> "); + applyToSet (lp->regBlocks, printEntryLabel); + printf ("\n"); + printf (" loop exits --> "); + applyToSet (lp->exits, printEntryLabel); + printf ("\n"); + return 0; } /*-----------------------------------------------------------------*/ /* backEdges - returns a list of back edges */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(backEdges) +DEFSETFUNC (backEdges) { - edge *ep = item; - V_ARG(set **,bEdges); - - /* if this is a back edge ; to determine this we check */ - /* to see if the 'to' is in the dominator list of the */ - /* 'from' if yes then this is a back edge */ - if (bitVectBitValue (ep->from->domVect,ep->to->bbnum)) { - addSetHead (bEdges,ep); - return 1; + edge *ep = item; + V_ARG (set **, bEdges); + + /* if this is a back edge ; to determine this we check */ + /* to see if the 'to' is in the dominator list of the */ + /* 'from' if yes then this is a back edge */ + if (bitVectBitValue (ep->from->domVect, ep->to->bbnum)) + { + addSetHead (bEdges, ep); + return 1; } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* intersectLoopSucc - returns intersection of loop Successors */ /*-----------------------------------------------------------------*/ -static bitVect *intersectLoopSucc ( set *lexits, eBBlock **ebbs) +static bitVect * +intersectLoopSucc (set * lexits, eBBlock ** ebbs) { - bitVect *succVect = NULL; - eBBlock *exit = setFirstItem(lexits); + bitVect *succVect = NULL; + eBBlock *exit = setFirstItem (lexits); - if (!exit) - return NULL; + if (!exit) + return NULL; - succVect = bitVectCopy(exit->succVect); + succVect = bitVectCopy (exit->succVect); - for (exit = setNextItem(lexits); exit ; - exit = setNextItem(lexits)) { - succVect = bitVectIntersect(succVect, - exit->succVect); + for (exit = setNextItem (lexits); exit; + exit = setNextItem (lexits)) + { + succVect = bitVectIntersect (succVect, + exit->succVect); } - return succVect ; + return succVect; } /*-----------------------------------------------------------------*/ /* loopInsert will insert a block into the loop set */ /*-----------------------------------------------------------------*/ -static void loopInsert (set **regionSet, eBBlock *block) +static void +loopInsert (set ** regionSet, eBBlock * block) { - if (!isinSet (*regionSet,block)) { - addSetHead (regionSet,block); - STACK_PUSH(regionStack,block); + if (!isinSet (*regionSet, block)) + { + addSetHead (regionSet, block); + STACK_PUSH (regionStack, block); } } /*-----------------------------------------------------------------*/ /* insertIntoLoop - insert item into loop */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(insertIntoLoop) +DEFSETFUNC (insertIntoLoop) { - eBBlock *ebp = item ; - V_ARG(set **,regionSet); + eBBlock *ebp = item; + V_ARG (set **, regionSet); - loopInsert (regionSet,ebp); - return 0; + loopInsert (regionSet, ebp); + return 0; } /*-----------------------------------------------------------------*/ /* isNotInBlocks - will return 1 if not is blocks */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(isNotInBlocks) +DEFSETFUNC (isNotInBlocks) { - eBBlock *ebp = item; - V_ARG(set *,blocks); + eBBlock *ebp = item; + V_ARG (set *, blocks); - if (! isinSet (blocks,ebp)) - return 1; + if (!isinSet (blocks, ebp)) + return 1; - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* hasIncomingDefs - has definitions coming into the loop. i.e. */ /* check to see if the preheaders outDefs has any definitions */ /*-----------------------------------------------------------------*/ -int hasIncomingDefs (region *lreg, operand *op) +int +hasIncomingDefs (region * lreg, operand * op) { - eBBlock *preHdr = lreg->entry->preHeader; + eBBlock *preHdr = lreg->entry->preHeader; - if (preHdr && bitVectBitsInCommon(preHdr->outDefs,OP_DEFS(op))) - return 1; - return 0; + if (preHdr && bitVectBitsInCommon (preHdr->outDefs, OP_DEFS (op))) + return 1; + return 0; } /*-----------------------------------------------------------------*/ /* findLoopEndSeq - will return the sequence number of the last */ /* iCode with the maximum dfNumber in the region */ /*-----------------------------------------------------------------*/ -int findLoopEndSeq (region *lreg) +int +findLoopEndSeq (region * lreg) { - eBBlock *block; - eBBlock *lblock; - - for (block = lblock =setFirstItem(lreg->regBlocks); block; - block = setNextItem(lreg->regBlocks)) { - if (block != lblock && block->lSeq > lblock->lSeq) - lblock = block; + eBBlock *block; + eBBlock *lblock; + + for (block = lblock = setFirstItem (lreg->regBlocks); block; + block = setNextItem (lreg->regBlocks)) + { + if (block != lblock && block->lSeq > lblock->lSeq) + lblock = block; } - return lblock->lSeq; + return lblock->lSeq; } /*-----------------------------------------------------------------*/ /* addToExitsMarkDepth - will add the the exitSet all blocks that */ /* have exits, will also update the depth field in the blocks */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(addToExitsMarkDepth) +DEFSETFUNC (addToExitsMarkDepth) { - eBBlock *ebp = item ; - V_ARG(set *,loopBlocks); - V_ARG(set **,exits); - V_ARG(int, depth); - V_ARG(region *,lr); - - /* mark the loop depth of this block */ - if (!ebp->depth) - ebp->depth = depth; - - /* put the loop region info in the block */ - /* NOTE: here we will update only the inner most loop - that it is a part of */ - if (!ebp->partOfLoop) - ebp->partOfLoop = lr; - - /* if any of the successors go out of the loop then */ - /* we add this one to the exits */ - if ( applyToSet(ebp->succList,isNotInBlocks,loopBlocks)) { - addSetHead (exits,ebp); - return 1; + eBBlock *ebp = item; + V_ARG (set *, loopBlocks); + V_ARG (set **, exits); + V_ARG (int, depth); + V_ARG (region *, lr); + + /* mark the loop depth of this block */ + if (!ebp->depth) + ebp->depth = depth; + + /* put the loop region info in the block */ + /* NOTE: here we will update only the inner most loop + that it is a part of */ + if (!ebp->partOfLoop) + ebp->partOfLoop = lr; + + /* if any of the successors go out of the loop then */ + /* we add this one to the exits */ + if (applyToSet (ebp->succList, isNotInBlocks, loopBlocks)) + { + addSetHead (exits, ebp); + return 1; } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* createLoop - will create a set of region */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(createLoop) +DEFSETFUNC (createLoop) { - edge *ep = item; - V_ARG(set **,allRegion); - region *aloop = newRegion(); - eBBlock *block; - - /* make sure regionStack is empty */ - while (!STACK_EMPTY(regionStack)) - STACK_POP(regionStack); - - /* add the entryBlock */ - addSet (&aloop->regBlocks,ep->to); - loopInsert (&aloop->regBlocks,ep->from); - - while (!STACK_EMPTY(regionStack)) { - block = STACK_POP(regionStack); - /* if block != entry */ - if (block != ep->to) - applyToSet(block->predList,insertIntoLoop,&aloop->regBlocks); + edge *ep = item; + V_ARG (set **, allRegion); + region *aloop = newRegion (); + eBBlock *block; + + /* make sure regionStack is empty */ + while (!STACK_EMPTY (regionStack)) + STACK_POP (regionStack); + + /* add the entryBlock */ + addSet (&aloop->regBlocks, ep->to); + loopInsert (&aloop->regBlocks, ep->from); + + while (!STACK_EMPTY (regionStack)) + { + block = STACK_POP (regionStack); + /* if block != entry */ + if (block != ep->to) + applyToSet (block->predList, insertIntoLoop, &aloop->regBlocks); } - aloop->entry = ep->to ; + aloop->entry = ep->to; - /* now add it to the set */ - addSetHead (allRegion,aloop); - return 0; + /* now add it to the set */ + addSetHead (allRegion, aloop); + return 0; } /*-----------------------------------------------------------------*/ /* dominatedBy - will return 1 if item is dominated by block */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(dominatedBy) +DEFSETFUNC (dominatedBy) { - eBBlock *ebp = item; - V_ARG(eBBlock *,block); + eBBlock *ebp = item; + V_ARG (eBBlock *, block); - return bitVectBitValue (ebp->domVect,block->bbnum); + return bitVectBitValue (ebp->domVect, block->bbnum); } /*-----------------------------------------------------------------*/ /* addDefInExprs - adds an expression into the inexpressions */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(addDefInExprs) +DEFSETFUNC (addDefInExprs) { - eBBlock *ebp = item; - V_ARG(cseDef *,cdp); - V_ARG(eBBlock **,ebbs); - V_ARG(int,count); + eBBlock *ebp = item; + V_ARG (cseDef *, cdp); + V_ARG (eBBlock **, ebbs); + V_ARG (int, count); - addSetHead(&ebp->inExprs,cdp); - cseBBlock (ebp,0,ebbs,count); - return 0; + addSetHead (&ebp->inExprs, cdp); + cseBBlock (ebp, 0, ebbs, count); + return 0; } /*-----------------------------------------------------------------*/ -/* assignmentsToSym - for a set of blocks determine # time assigned*/ +/* assignmentsToSym - for a set of blocks determine # time assigned */ /*-----------------------------------------------------------------*/ - int assignmentsToSym (set *sset, operand *sym) +int +assignmentsToSym (set * sset, operand * sym) { - eBBlock *ebp ; - int assigns = 0; - set *blocks = setFromSet(sset); + eBBlock *ebp; + int assigns = 0; + set *blocks = setFromSet (sset); - for (ebp = setFirstItem(blocks) ; ebp ; - ebp = setNextItem(blocks)) { + for (ebp = setFirstItem (blocks); ebp; + ebp = setNextItem (blocks)) + { - /* get all the definitions for this symbol - in this block */ - bitVect *defs = bitVectIntersect(ebp->ldefs,OP_DEFS(sym)); - assigns += bitVectnBitsOn(defs); - setToNull((void **)&defs); + /* get all the definitions for this symbol + in this block */ + bitVect *defs = bitVectIntersect (ebp->ldefs, OP_DEFS (sym)); + assigns += bitVectnBitsOn (defs); + setToNull ((void **) &defs); } - return assigns; + return assigns; } /*-----------------------------------------------------------------*/ /* isOperandInvariant - determines if an operand is an invariant */ /*-----------------------------------------------------------------*/ -int isOperandInvariant (operand *op, region *theLoop, set *lInvars) +int +isOperandInvariant (operand * op, region * theLoop, set * lInvars) { - int opin = 0 ; - /* operand is an invariant if it is a */ - /* a. constants . */ - /* b. that have defintions reaching loop entry */ - /* c. that are already defined as invariant */ - /* d. has no assignments in the loop */ - if (op) { - if (IS_OP_LITERAL(op)) - opin = 1 ; + int opin = 0; + /* operand is an invariant if it is a */ + /* a. constants . */ + /* b. that have defintions reaching loop entry */ + /* c. that are already defined as invariant */ + /* d. has no assignments in the loop */ + if (op) + { + if (IS_OP_LITERAL (op)) + opin = 1; + else if (IS_SYMOP (op) && + OP_SYMBOL (op)->addrtaken) + opin = 0; + else if (ifDefSymIs (theLoop->entry->inExprs, op)) + opin = 1; + else if (ifDefSymIs (lInvars, op)) + opin = 1; + else if (IS_SYMOP (op) && + !IS_OP_GLOBAL (op) && + !IS_OP_VOLATILE (op) && + assignmentsToSym (theLoop->regBlocks, op) == 0) + opin = 1; + } else - if (IS_SYMOP(op) && - OP_SYMBOL(op)->addrtaken) - opin = 0 ; - else - if (ifDefSymIs(theLoop->entry->inExprs,op)) - opin = 1 ; - else - if (ifDefSymIs(lInvars,op)) - opin = 1 ; - else - if (IS_SYMOP(op) && - ! IS_OP_GLOBAL(op) && - ! IS_OP_VOLATILE(op) && - assignmentsToSym (theLoop->regBlocks,op) == 0 ) - opin = 1 ; - } else opin++ ; - - return opin ; + opin++; + + return opin; } /*-----------------------------------------------------------------*/ /* pointerAssigned - will return 1 if pointer set found */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(pointerAssigned) +DEFSETFUNC (pointerAssigned) { - eBBlock *ebp = item; - V_ARG(operand *,op); + eBBlock *ebp = item; + V_ARG (operand *, op); - return ebp->hasFcall || bitVectBitValue(ebp->ptrsSet,op->key); + return ebp->hasFcall || bitVectBitValue (ebp->ptrsSet, op->key); } /*-----------------------------------------------------------------*/ /* hasNonPtrUse - returns true if operand has non pointer usage */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(hasNonPtrUse) +DEFSETFUNC (hasNonPtrUse) { - eBBlock *ebp = item; - V_ARG(operand *,op); - iCode *ic = usedInRemaining(op,ebp->sch); + eBBlock *ebp = item; + V_ARG (operand *, op); + iCode *ic = usedInRemaining (op, ebp->sch); - if (ic && !POINTER_SET(ic) && !POINTER_GET(ic)) - return 1; + if (ic && !POINTER_SET (ic) && !POINTER_GET (ic)) + return 1; - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* loopInvariants - takes loop invariants out of region */ /*-----------------------------------------------------------------*/ - int loopInvariants( region *theLoop , eBBlock **ebbs, int count) +int +loopInvariants (region * theLoop, eBBlock ** ebbs, int count) { - eBBlock *lBlock ; - set *lInvars = NULL ; + eBBlock *lBlock; + set *lInvars = NULL; - int change = 0 ; + int change = 0; - /* if the preHeader does not exist then do nothing */ - /* or no exits then do nothing ( have to think about this situation */ - if (theLoop->entry->preHeader == NULL || - theLoop->exits == NULL ) - return 0; - - /* we will do the elimination for those blocks */ - /* in the loop that dominates all exits from the loop */ - for (lBlock = setFirstItem(theLoop->regBlocks); lBlock; - lBlock = setNextItem(theLoop->regBlocks)) { - - iCode *ic; - int domsAllExits ; - int i ; - - /* mark the dominates all exits flag */ - domsAllExits = ( applyToSet (theLoop->exits,dominatedBy,lBlock) == - elementsInSet (theLoop->exits)); - - - /* now we go thru the instructions of this block and */ - /* collect those instructions with invariant operands*/ - for ( ic = lBlock->sch ; ic ; ic = ic->next ) { - - int lin , rin ; - cseDef *ivar ; - - if (SKIP_IC(ic) || POINTER_SET(ic) || ic->op == IFX) - continue ; - - /* if result is volatile then skip */ - if (IC_RESULT(ic) && - ( isOperandVolatile(IC_RESULT(ic),TRUE) || - IS_OP_PARM(IC_RESULT(ic)))) - continue ; - - lin = rin = 0 ; - - /* special case */ - /* if address of then it is an invariant */ - if (ic->op == ADDRESS_OF && - IS_SYMOP(IC_LEFT(ic)) && - IS_AGGREGATE(operandType(IC_LEFT(ic)))) - lin++; - else - /* check if left operand is an invariant */ - if ( (lin = isOperandInvariant (IC_LEFT(ic),theLoop,lInvars))) - /* if this is a pointer get then make sure - that the pointer set does not exist in - any of the blocks */ - if (POINTER_GET(ic) && - ( applyToSet (theLoop->regBlocks,pointerAssigned,IC_LEFT(ic)) )) - lin = 0; - - /* do the same for right */ - rin = isOperandInvariant (IC_RIGHT(ic),theLoop, lInvars); - - /* if this is a POINTER_GET then special case, make sure all - usages within the loop are POINTER_GET any other usage - would mean that this is not an invariant , since the pointer - could then be passed as a parameter */ - if (POINTER_GET(ic) && - applyToSet(theLoop->regBlocks,hasNonPtrUse,IC_LEFT(ic))) - continue ; - - /* if both the left & right are invariants : then check that*/ - /* this definition exists in the out definition of all the */ - /* blocks, this will ensure that this is not assigned any */ - /* other value in the loop , and not used in this block */ - /* prior to this definition which means only this definition*/ - /* is used in this loop */ - if (lin && rin && IC_RESULT(ic)) { - eBBlock *sBlock ; - set *lSet = setFromSet(theLoop->regBlocks); - - /* if this block does not dominate all exists */ - /* make sure this defintion is not used anywhere else */ - if (!domsAllExits) { - - if (isOperandGlobal(IC_RESULT(ic))) - continue; - /* for successors for all exits */ - for ( sBlock = setFirstItem(theLoop->exits); sBlock; - sBlock = setNextItem(theLoop->exits)) { - - for(i=0; i < count; ebbs[i++]->visited = 0); - lBlock->visited = 1; - if ( applyToSet (sBlock->succList,isDefAlive,ic)) - break ; - } - - /* we have found usage */ - if (sBlock ) - continue ; - } + /* if the preHeader does not exist then do nothing */ + /* or no exits then do nothing ( have to think about this situation */ + if (theLoop->entry->preHeader == NULL || + theLoop->exits == NULL) + return 0; - /* now make sure this is the only definition */ - for (sBlock = setFirstItem(lSet); sBlock ; - sBlock = setNextItem (lSet)) { - /* if this is the block make sure the definition */ - /* reaches the end of the block */ - if (sBlock == lBlock ) { - if (! ifDiCodeIs (sBlock->outExprs,ic)) - break; - } - else - if (bitVectBitsInCommon (sBlock->defSet,OP_DEFS(IC_RESULT(ic)))) - break; - } + /* we will do the elimination for those blocks */ + /* in the loop that dominates all exits from the loop */ + for (lBlock = setFirstItem (theLoop->regBlocks); lBlock; + lBlock = setNextItem (theLoop->regBlocks)) + { - if (sBlock) - continue ; /* another definition present in the block */ - - /* now check if it exists in the in of this block */ - /* if not then it was killed before this instruction */ - if (! bitVectBitValue (lBlock->inDefs,ic->key)) - continue ; - - /* now we know it is a true invariant */ - /* remove it from the insts chain & put */ - /* in the invariant set */ - OP_SYMBOL(IC_RESULT(ic))->isinvariant = 1; - remiCodeFromeBBlock (lBlock,ic); - - /* maintain the data flow */ - /* this means removing from definition from the */ - /* defset of this block and adding it to the */ - /* inexpressions of all blocks within the loop */ - bitVectUnSetBit (lBlock->defSet,ic->key); - bitVectUnSetBit (lBlock->ldefs,ic->key); - ivar = newCseDef(IC_RESULT(ic),ic); - applyToSet (theLoop->regBlocks, addDefInExprs, ivar,ebbs,count); - addSet(&lInvars,ivar); - } - } - } /* for all loop blocks */ - - /* if we have some invariants then */ - if (lInvars) { - eBBlock *preHdr= theLoop->entry->preHeader ; - iCode *icFirst = NULL , *icLast = NULL ; - cseDef *cdp; - - /* create an iCode chain from it */ - for (cdp = setFirstItem(lInvars); cdp ; cdp = setNextItem(lInvars)) { - - /* maintain data flow .. add it to the */ - /* ldefs defSet & outExprs of the preheader */ - preHdr->defSet = bitVectSetBit (preHdr->defSet,cdp->diCode->key); - preHdr->ldefs = bitVectSetBit (preHdr->ldefs,cdp->diCode->key); - cdp->diCode->lineno = preHdr->ech->lineno; - addSetHead (&preHdr->outExprs,cdp); - - - if (!icFirst) - icFirst = cdp->diCode; - if (icLast) { - icLast->next = cdp->diCode; - cdp->diCode->prev = icLast; - icLast = cdp->diCode ; - } else - icLast = cdp->diCode; - change++ ; - } - - /* add the instruction chain to the end of the - preheader for this loop, preheaders will always - have atleast a label */ - preHdr->ech->next = icFirst ; - icFirst->prev = preHdr->ech ; - preHdr->ech = icLast; - icLast->next = NULL; + iCode *ic; + int domsAllExits; + int i; + + /* mark the dominates all exits flag */ + domsAllExits = (applyToSet (theLoop->exits, dominatedBy, lBlock) == + elementsInSet (theLoop->exits)); + + + /* now we go thru the instructions of this block and */ + /* collect those instructions with invariant operands */ + for (ic = lBlock->sch; ic; ic = ic->next) + { + + int lin, rin; + cseDef *ivar; + + if (SKIP_IC (ic) || POINTER_SET (ic) || ic->op == IFX) + continue; + + /* if result is volatile then skip */ + if (IC_RESULT (ic) && + (isOperandVolatile (IC_RESULT (ic), TRUE) || + IS_OP_PARM (IC_RESULT (ic)))) + continue; + + lin = rin = 0; + + /* special case */ + /* if address of then it is an invariant */ + if (ic->op == ADDRESS_OF && + IS_SYMOP (IC_LEFT (ic)) && + IS_AGGREGATE (operandType (IC_LEFT (ic)))) + lin++; + else + /* check if left operand is an invariant */ + if ((lin = isOperandInvariant (IC_LEFT (ic), theLoop, lInvars))) + /* if this is a pointer get then make sure + that the pointer set does not exist in + any of the blocks */ + if (POINTER_GET (ic) && + (applyToSet (theLoop->regBlocks, pointerAssigned, IC_LEFT (ic)))) + lin = 0; + + /* do the same for right */ + rin = isOperandInvariant (IC_RIGHT (ic), theLoop, lInvars); + + /* if this is a POINTER_GET then special case, make sure all + usages within the loop are POINTER_GET any other usage + would mean that this is not an invariant , since the pointer + could then be passed as a parameter */ + if (POINTER_GET (ic) && + applyToSet (theLoop->regBlocks, hasNonPtrUse, IC_LEFT (ic))) + continue; + + /* if both the left & right are invariants : then check that */ + /* this definition exists in the out definition of all the */ + /* blocks, this will ensure that this is not assigned any */ + /* other value in the loop , and not used in this block */ + /* prior to this definition which means only this definition */ + /* is used in this loop */ + if (lin && rin && IC_RESULT (ic)) + { + eBBlock *sBlock; + set *lSet = setFromSet (theLoop->regBlocks); + + /* if this block does not dominate all exists */ + /* make sure this defintion is not used anywhere else */ + if (!domsAllExits) + { + + if (isOperandGlobal (IC_RESULT (ic))) + continue; + /* for successors for all exits */ + for (sBlock = setFirstItem (theLoop->exits); sBlock; + sBlock = setNextItem (theLoop->exits)) + { + + for (i = 0; i < count; ebbs[i++]->visited = 0); + lBlock->visited = 1; + if (applyToSet (sBlock->succList, isDefAlive, ic)) + break; + } + + /* we have found usage */ + if (sBlock) + continue; + } + + /* now make sure this is the only definition */ + for (sBlock = setFirstItem (lSet); sBlock; + sBlock = setNextItem (lSet)) + { + /* if this is the block make sure the definition */ + /* reaches the end of the block */ + if (sBlock == lBlock) + { + if (!ifDiCodeIs (sBlock->outExprs, ic)) + break; + } + else if (bitVectBitsInCommon (sBlock->defSet, OP_DEFS (IC_RESULT (ic)))) + break; + } + + if (sBlock) + continue; /* another definition present in the block */ + + /* now check if it exists in the in of this block */ + /* if not then it was killed before this instruction */ + if (!bitVectBitValue (lBlock->inDefs, ic->key)) + continue; + + /* now we know it is a true invariant */ + /* remove it from the insts chain & put */ + /* in the invariant set */ + OP_SYMBOL (IC_RESULT (ic))->isinvariant = 1; + remiCodeFromeBBlock (lBlock, ic); + + /* maintain the data flow */ + /* this means removing from definition from the */ + /* defset of this block and adding it to the */ + /* inexpressions of all blocks within the loop */ + bitVectUnSetBit (lBlock->defSet, ic->key); + bitVectUnSetBit (lBlock->ldefs, ic->key); + ivar = newCseDef (IC_RESULT (ic), ic); + applyToSet (theLoop->regBlocks, addDefInExprs, ivar, ebbs, count); + addSet (&lInvars, ivar); + } + } + } /* for all loop blocks */ + + /* if we have some invariants then */ + if (lInvars) + { + eBBlock *preHdr = theLoop->entry->preHeader; + iCode *icFirst = NULL, *icLast = NULL; + cseDef *cdp; + + /* create an iCode chain from it */ + for (cdp = setFirstItem (lInvars); cdp; cdp = setNextItem (lInvars)) + { + + /* maintain data flow .. add it to the */ + /* ldefs defSet & outExprs of the preheader */ + preHdr->defSet = bitVectSetBit (preHdr->defSet, cdp->diCode->key); + preHdr->ldefs = bitVectSetBit (preHdr->ldefs, cdp->diCode->key); + cdp->diCode->lineno = preHdr->ech->lineno; + addSetHead (&preHdr->outExprs, cdp); + + + if (!icFirst) + icFirst = cdp->diCode; + if (icLast) + { + icLast->next = cdp->diCode; + cdp->diCode->prev = icLast; + icLast = cdp->diCode; + } + else + icLast = cdp->diCode; + change++; + } + + /* add the instruction chain to the end of the + preheader for this loop, preheaders will always + have atleast a label */ + preHdr->ech->next = icFirst; + icFirst->prev = preHdr->ech; + preHdr->ech = icLast; + icLast->next = NULL; } - return change ; + return change; } /*-----------------------------------------------------------------*/ -/* addressTaken - returns true if the symbol is found in the addrof*/ +/* addressTaken - returns true if the symbol is found in the addrof */ /*-----------------------------------------------------------------*/ -int addressTaken (set *sset ,operand *sym) +int +addressTaken (set * sset, operand * sym) { - set *loop; - eBBlock *ebp ; - set *loop2; - - for (loop = sset; loop ; loop = loop->next) { - ebp = loop->item; - loop2 = ebp->addrOf ; - while (loop2) { - if (isOperandEqual((operand *)loop2->item,sym)) - return 1; - loop2 = loop2->next; - } + set *loop; + eBBlock *ebp; + set *loop2; + + for (loop = sset; loop; loop = loop->next) + { + ebp = loop->item; + loop2 = ebp->addrOf; + while (loop2) + { + if (isOperandEqual ((operand *) loop2->item, sym)) + return 1; + loop2 = loop2->next; + } } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* findInduction :- returns 1 & the item if the induction is found */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(findInduction) +DEFSETFUNC (findInduction) { - induction *ip = item; - V_ARG(operand *,sym); - V_ARG(induction **,ipp); - - if (isOperandEqual(ip->sym,sym)) { - *ipp = ip; - return 1; + induction *ip = item; + V_ARG (operand *, sym); + V_ARG (induction **, ipp); + + if (isOperandEqual (ip->sym, sym)) + { + *ipp = ip; + return 1; } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* findDefInRegion - finds the definition within the region */ /*-----------------------------------------------------------------*/ -iCode *findDefInRegion (set *regBlocks, operand *defOp, eBBlock **owner) +iCode * +findDefInRegion (set * regBlocks, operand * defOp, eBBlock ** owner) { - eBBlock *lBlock ; - - /* for all blocks in the region */ - for (lBlock = setFirstItem(regBlocks); lBlock ; - lBlock = setNextItem(regBlocks)) { - - /* if a definition for this exists */ - if (bitVectBitsInCommon(lBlock->defSet,OP_DEFS(defOp))) { - iCode *ic; - - /* go thru the instruction chain to find it */ - for (ic = lBlock->sch ; ic ; ic = ic->next ) - if (bitVectBitValue (OP_DEFS(defOp),ic->key)) { - if (owner) - *owner = lBlock ; - return ic; - } - } + eBBlock *lBlock; + + /* for all blocks in the region */ + for (lBlock = setFirstItem (regBlocks); lBlock; + lBlock = setNextItem (regBlocks)) + { + + /* if a definition for this exists */ + if (bitVectBitsInCommon (lBlock->defSet, OP_DEFS (defOp))) + { + iCode *ic; + + /* go thru the instruction chain to find it */ + for (ic = lBlock->sch; ic; ic = ic->next) + if (bitVectBitValue (OP_DEFS (defOp), ic->key)) + { + if (owner) + *owner = lBlock; + return ic; + } + } } - return NULL ; + return NULL; } /*-----------------------------------------------------------------*/ /* basicInduction - finds the basic induction variables in a loop */ /*-----------------------------------------------------------------*/ -set *basicInduction (region *loopReg , eBBlock **ebbs, int count) +set * +basicInduction (region * loopReg, eBBlock ** ebbs, int count) { - eBBlock *lBlock ; - set *indVars = NULL ; - - /* i.e. all assignments of the form a := a +/- const*/ - /* for all blocks within the loop do */ - for ( lBlock = setFirstItem(loopReg->regBlocks); lBlock ; - lBlock = setNextItem(loopReg->regBlocks)) { - - iCode *ic, *dic ; - - /* for all instructions in the blocks do */ - for ( ic = lBlock->sch ; ic ; ic = ic->next ) { - - operand *aSym ; - unsigned long litValue ; - induction *ip; - iCode *indIc; - eBBlock *owner = NULL; - int nexits; - - /* look for assignments of the form */ - /* symbolVar := iTempNN */ - if ( ic->op != '=') - continue ; - - if (!IS_TRUE_SYMOP(IC_RESULT(ic)) && - !OP_SYMBOL(IC_RESULT(ic))->isreqv) - continue ; - - if (isOperandGlobal(IC_RESULT(ic))) - continue ; - - if (!IS_ITEMP(IC_RIGHT(ic))) - continue ; - - /* if it has multiple assignments within the loop then skip */ - if (assignmentsToSym (loopReg->regBlocks,IC_RESULT(ic)) > 1 ) - continue ; - - /* if the address of this was taken inside the loop then continue */ - if (addressTaken (loopReg->regBlocks,IC_RESULT(ic))) - continue ; - - /* find the definition for the result in the block */ - if (! (dic = findDefInRegion (setFromSet(loopReg->regBlocks), - IC_RIGHT(ic),&owner))) - continue ; - - /* if not +/- continue */ - if (dic->op != '+' && dic->op != '-') - continue ; - - /* make sure definition is of the form a +/- c */ - if (!IS_OP_LITERAL(IC_LEFT(dic)) && !IS_OP_LITERAL(IC_RIGHT(dic))) - continue ; - - aSym = (IS_OP_LITERAL(IC_RIGHT(dic)) ? - (litValue = operandLitValue(IC_RIGHT(dic)),IC_LEFT(dic)) : - (litValue = operandLitValue(IC_LEFT(dic)),IC_RIGHT(dic))); - - if (!isOperandEqual(IC_RESULT(ic),aSym) && - !isOperandEqual(IC_RIGHT(ic),aSym)) { - iCode *ddic ; - /* find the definition for this and check */ - if (!(ddic = findDefInRegion (setFromSet(loopReg->regBlocks), - aSym,&owner))) - continue ; - - if (ddic->op != '=') - continue ; - - if (!isOperandEqual(IC_RESULT(ddic),aSym) || - !isOperandEqual(IC_RIGHT(ddic),IC_RESULT(ic))) - continue ; - } - - /* if the right hand side has more than one usage then - don't make it an induction (will have to think some more) */ - if (bitVectnBitsOn(OP_USES(IC_RIGHT(ic))) > 1) - continue; - - /* if the definition is volatile then it cannot be - an induction object */ - if (isOperandVolatile(IC_RIGHT(ic),FALSE) || - isOperandVolatile(IC_RESULT(ic),FALSE)) - continue; - - /* whew !! that was a lot of work to find the definition */ - /* create an induction object */ - indIc = newiCode('=',NULL,IC_RESULT(ic)); - indIc->lineno = ic->lineno; - IC_RESULT(indIc) = operandFromOperand(IC_RIGHT(ic)); - IC_RESULT(indIc)->isaddr = 0; - OP_SYMBOL(IC_RESULT(indIc))->isind = 1; - ip = newInduction (IC_RIGHT(ic),dic->op,litValue,indIc,NULL); - - /* replace the inducted variable by the iTemp */ - replaceSymBySym (loopReg->regBlocks,IC_RESULT(ic),IC_RIGHT(ic)); - - /* if it has only one exit then remove it from here - and put it in the exit block */ - nexits = elementsInSet (loopReg->exits); - if (nexits == 1) { - eBBlock *exit = setFirstItem(loopReg->exits); - - /* if it is the same block then there is no - need to move it about */ - if ( exit != lBlock) { - iCode *saveic = ic->prev; - /* remove it */ - remiCodeFromeBBlock(lBlock,ic); - /* clear the definition */ - bitVectUnSetBit(lBlock->defSet,ic->key); - /* add it to the exit */ - addiCodeToeBBlock(exit,ic,NULL); - /* set the definition bit */ - exit->defSet = bitVectSetBit(exit->defSet,ic->key); - ic = saveic ; - } - } - - /* if the number of exits is greater than one then - we use another trick ; we will create an intersection - of succesors of the exits, then take those that are not - part of the loop and have dfNumber greater loop entry - and insert a new definition in them */ - if ( nexits > 1) { - - bitVect *loopSuccs = intersectLoopSucc (loopReg->exits,ebbs); - - /* loopSuccs now contains intersection - of all the loops successors */ - if (loopSuccs) { - int i; - for (i = 0 ; i < loopSuccs->size; i++) { - if (bitVectBitValue(loopSuccs,i)) { - - eBBlock *eblock = ebbs[i]; - - /* if the successor does not belong to the loop - and will be executed after the loop : then - add a definition to the block */ - if ( !isinSet(loopReg->regBlocks,eblock) && - eblock->dfnum > loopReg->entry->dfnum) { - /* create the definition */ - iCode *newic = newiCode('=',NULL, - operandFromOperand(IC_RIGHT(ic))); - IC_RESULT(newic) = operandFromOperand(IC_RESULT(ic)); - OP_DEFS(IC_RESULT(newic)) = - bitVectSetBit(OP_DEFS(IC_RESULT(newic)),newic->key); - OP_USES(IC_RIGHT(newic)) = - bitVectSetBit(OP_USES(IC_RIGHT(newic)),newic->key); - /* and add it */ - if (eblock->sch && eblock->sch->op == LABEL) - addiCodeToeBBlock(eblock,newic,eblock->sch->next); - else - addiCodeToeBBlock(eblock,newic,eblock->sch); - /* set the definition bit */ - eblock->defSet = bitVectSetBit(eblock->defSet,ic->key); - } - } - } - } - } - - addSet (&indVars,ip); - } - - } /* end of all blocks for basic induction variables */ - - return indVars; + eBBlock *lBlock; + set *indVars = NULL; + + /* i.e. all assignments of the form a := a +/- const */ + /* for all blocks within the loop do */ + for (lBlock = setFirstItem (loopReg->regBlocks); lBlock; + lBlock = setNextItem (loopReg->regBlocks)) + { + + iCode *ic, *dic; + + /* for all instructions in the blocks do */ + for (ic = lBlock->sch; ic; ic = ic->next) + { + + operand *aSym; + unsigned long litValue; + induction *ip; + iCode *indIc; + eBBlock *owner = NULL; + int nexits; + + /* look for assignments of the form */ + /* symbolVar := iTempNN */ + if (ic->op != '=') + continue; + + if (!IS_TRUE_SYMOP (IC_RESULT (ic)) && + !OP_SYMBOL (IC_RESULT (ic))->isreqv) + continue; + + if (isOperandGlobal (IC_RESULT (ic))) + continue; + + if (!IS_ITEMP (IC_RIGHT (ic))) + continue; + + /* if it has multiple assignments within the loop then skip */ + if (assignmentsToSym (loopReg->regBlocks, IC_RESULT (ic)) > 1) + continue; + + /* if the address of this was taken inside the loop then continue */ + if (addressTaken (loopReg->regBlocks, IC_RESULT (ic))) + continue; + + /* find the definition for the result in the block */ + if (!(dic = findDefInRegion (setFromSet (loopReg->regBlocks), + IC_RIGHT (ic), &owner))) + continue; + + /* if not +/- continue */ + if (dic->op != '+' && dic->op != '-') + continue; + + /* make sure definition is of the form a +/- c */ + if (!IS_OP_LITERAL (IC_LEFT (dic)) && !IS_OP_LITERAL (IC_RIGHT (dic))) + continue; + + aSym = (IS_OP_LITERAL (IC_RIGHT (dic)) ? + (litValue = operandLitValue (IC_RIGHT (dic)), IC_LEFT (dic)) : + (litValue = operandLitValue (IC_LEFT (dic)), IC_RIGHT (dic))); + + if (!isOperandEqual (IC_RESULT (ic), aSym) && + !isOperandEqual (IC_RIGHT (ic), aSym)) + { + iCode *ddic; + /* find the definition for this and check */ + if (!(ddic = findDefInRegion (setFromSet (loopReg->regBlocks), + aSym, &owner))) + continue; + + if (ddic->op != '=') + continue; + + if (!isOperandEqual (IC_RESULT (ddic), aSym) || + !isOperandEqual (IC_RIGHT (ddic), IC_RESULT (ic))) + continue; + } + + /* if the right hand side has more than one usage then + don't make it an induction (will have to think some more) */ + if (bitVectnBitsOn (OP_USES (IC_RIGHT (ic))) > 1) + continue; + + /* if the definition is volatile then it cannot be + an induction object */ + if (isOperandVolatile (IC_RIGHT (ic), FALSE) || + isOperandVolatile (IC_RESULT (ic), FALSE)) + continue; + + /* whew !! that was a lot of work to find the definition */ + /* create an induction object */ + indIc = newiCode ('=', NULL, IC_RESULT (ic)); + indIc->lineno = ic->lineno; + IC_RESULT (indIc) = operandFromOperand (IC_RIGHT (ic)); + IC_RESULT (indIc)->isaddr = 0; + OP_SYMBOL (IC_RESULT (indIc))->isind = 1; + ip = newInduction (IC_RIGHT (ic), dic->op, litValue, indIc, NULL); + + /* replace the inducted variable by the iTemp */ + replaceSymBySym (loopReg->regBlocks, IC_RESULT (ic), IC_RIGHT (ic)); + + /* if it has only one exit then remove it from here + and put it in the exit block */ + nexits = elementsInSet (loopReg->exits); + if (nexits == 1) + { + eBBlock *exit = setFirstItem (loopReg->exits); + + /* if it is the same block then there is no + need to move it about */ + if (exit != lBlock) + { + iCode *saveic = ic->prev; + /* remove it */ + remiCodeFromeBBlock (lBlock, ic); + /* clear the definition */ + bitVectUnSetBit (lBlock->defSet, ic->key); + /* add it to the exit */ + addiCodeToeBBlock (exit, ic, NULL); + /* set the definition bit */ + exit->defSet = bitVectSetBit (exit->defSet, ic->key); + ic = saveic; + } + } + + /* if the number of exits is greater than one then + we use another trick ; we will create an intersection + of succesors of the exits, then take those that are not + part of the loop and have dfNumber greater loop entry + and insert a new definition in them */ + if (nexits > 1) + { + + bitVect *loopSuccs = intersectLoopSucc (loopReg->exits, ebbs); + + /* loopSuccs now contains intersection + of all the loops successors */ + if (loopSuccs) + { + int i; + for (i = 0; i < loopSuccs->size; i++) + { + if (bitVectBitValue (loopSuccs, i)) + { + + eBBlock *eblock = ebbs[i]; + + /* if the successor does not belong to the loop + and will be executed after the loop : then + add a definition to the block */ + if (!isinSet (loopReg->regBlocks, eblock) && + eblock->dfnum > loopReg->entry->dfnum) + { + /* create the definition */ + iCode *newic = newiCode ('=', NULL, + operandFromOperand (IC_RIGHT (ic))); + IC_RESULT (newic) = operandFromOperand (IC_RESULT (ic)); + OP_DEFS (IC_RESULT (newic)) = + bitVectSetBit (OP_DEFS (IC_RESULT (newic)), newic->key); + OP_USES (IC_RIGHT (newic)) = + bitVectSetBit (OP_USES (IC_RIGHT (newic)), newic->key); + /* and add it */ + if (eblock->sch && eblock->sch->op == LABEL) + addiCodeToeBBlock (eblock, newic, eblock->sch->next); + else + addiCodeToeBBlock (eblock, newic, eblock->sch); + /* set the definition bit */ + eblock->defSet = bitVectSetBit (eblock->defSet, ic->key); + } + } + } + } + } + + addSet (&indVars, ip); + } + + } /* end of all blocks for basic induction variables */ + + return indVars; } /*-----------------------------------------------------------------*/ /* loopInduction - remove induction variables from a loop */ /*-----------------------------------------------------------------*/ - int loopInduction( region *loopReg, eBBlock **ebbs, int count) +int +loopInduction (region * loopReg, eBBlock ** ebbs, int count) { - int change = 0 ; - eBBlock *lBlock, *lastBlock = NULL; - set *indVars = NULL ; - set *basicInd=NULL ; + int change = 0; + eBBlock *lBlock, *lastBlock = NULL; + set *indVars = NULL; + set *basicInd = NULL; - if (loopReg->entry->preHeader == NULL) - return 0; + if (loopReg->entry->preHeader == NULL) + return 0; - /* we first determine the basic Induction variables */ - basicInd = setFromSet(indVars = basicInduction(loopReg, ebbs,count)); + /* we first determine the basic Induction variables */ + basicInd = setFromSet (indVars = basicInduction (loopReg, ebbs, count)); - /* find other induction variables : by other we mean definitions of */ - /* the form x := y (* | / ) .. we will move this one to */ - /* beginning of the loop and reduce strength i.e. replace with +/- */ - /* these expensive expressions: OH! and y must be induction too */ - for ( lBlock = setFirstItem(loopReg->regBlocks), lastBlock = lBlock; - lBlock && indVars; - lBlock = setNextItem(loopReg->regBlocks)) { + /* find other induction variables : by other we mean definitions of */ + /* the form x := y (* | / ) .. we will move this one to */ + /* beginning of the loop and reduce strength i.e. replace with +/- */ + /* these expensive expressions: OH! and y must be induction too */ + for (lBlock = setFirstItem (loopReg->regBlocks), lastBlock = lBlock; + lBlock && indVars; + lBlock = setNextItem (loopReg->regBlocks)) + { - iCode *ic, *indIc; - induction *ip; + iCode *ic, *indIc; + induction *ip; - /* last block is the one with the highest block - number */ - if (lastBlock->bbnum < lBlock->bbnum ) - lastBlock = lBlock; - - for ( ic = lBlock->sch ; ic ; ic = ic->next ) { - operand *aSym ; - unsigned long litVal ; - int lr = 0; - - /* consider only * & / */ - if (ic->op != '*' && ic->op != '/') - continue ; - - /* if the result has more definitions then */ - if (assignmentsToSym(loopReg->regBlocks,IC_RESULT(ic)) > 1) - continue ; - - /* check if the operands are what we want */ - /* i.e. one of them an symbol the other a literal */ - if (! ( (IS_SYMOP(IC_LEFT(ic)) && IS_OP_LITERAL(IC_RIGHT(ic))) || - (IS_OP_LITERAL(IC_LEFT(ic)) && IS_SYMOP(IC_RIGHT(ic))) )) - continue ; - - aSym = (IS_SYMOP(IC_LEFT(ic)) ? - (lr = 1, litVal = operandLitValue(IC_RIGHT(ic)), IC_LEFT(ic) ) : - (litVal= operandLitValue(IC_LEFT(ic)), IC_RIGHT(ic) ) ) ; - - ip = NULL ; - /* check if this is an induction variable */ - if (! applyToSetFTrue (basicInd,findInduction,aSym,&ip)) - continue ; - - /* ask port for size not worth if native instruction - exist for multiply & divide */ - if (getSize(operandType(IC_LEFT(ic))) <= port->muldiv.native_below || - getSize(operandType(IC_RIGHT(ic))) <= port->muldiv.native_below) - continue; - - /* if this is a division then the remainder should be zero - for it to be inducted */ - if (ic->op == '/' && (ip->cval % litVal)) - continue ; - - /* create the iCode to be placed in the loop header */ - /* and create the induction object */ - - /* create an instruction */ - /* this will be put on the loop header */ - indIc = newiCode(ic->op, - operandFromOperand(aSym), - operandFromLit(litVal)); - indIc->lineno = ic->lineno; - IC_RESULT(indIc) = operandFromOperand(IC_RESULT(ic)); - OP_SYMBOL(IC_RESULT(indIc))->isind = 1; - - /* keep track of the inductions */ - litVal = (ic->op == '*' ? (litVal * ip->cval) : - (ip->cval / litVal)); - - addSet (&indVars, - newInduction (IC_RESULT(ic),ip->op,litVal,indIc,NULL)); - - /* now change this instruction */ - ic->op = ip->op; - if (lr) { - IC_LEFT(ic) = operandFromOperand(IC_RESULT(ic)); - IC_RIGHT(ic) = operandFromLit(litVal); - } else { - IC_RIGHT(ic) = operandFromOperand(IC_RESULT(ic)); - IC_LEFT(ic) = operandFromLit(litVal); - } - - /* we need somemore initialisation code */ - /* we subtract the litVal from itself if increment */ - if ( ic->op == '+' ) { - indIc = newiCode('-', - operandFromOperand(IC_RESULT(ic)), - operandFromLit(litVal)); - indIc->lineno = ic->lineno; - IC_RESULT(indIc) = operandFromOperand(IC_RESULT(ic)); - - addSet (&indVars, - newInduction (IC_RESULT(ic),ip->op,litVal,indIc,NULL)); - } - } + /* last block is the one with the highest block + number */ + if (lastBlock->bbnum < lBlock->bbnum) + lastBlock = lBlock; + + for (ic = lBlock->sch; ic; ic = ic->next) + { + operand *aSym; + unsigned long litVal; + int lr = 0; + + /* consider only * & / */ + if (ic->op != '*' && ic->op != '/') + continue; + + /* if the result has more definitions then */ + if (assignmentsToSym (loopReg->regBlocks, IC_RESULT (ic)) > 1) + continue; + + /* check if the operands are what we want */ + /* i.e. one of them an symbol the other a literal */ + if (!((IS_SYMOP (IC_LEFT (ic)) && IS_OP_LITERAL (IC_RIGHT (ic))) || + (IS_OP_LITERAL (IC_LEFT (ic)) && IS_SYMOP (IC_RIGHT (ic))))) + continue; + + aSym = (IS_SYMOP (IC_LEFT (ic)) ? + (lr = 1, litVal = operandLitValue (IC_RIGHT (ic)), IC_LEFT (ic)) : + (litVal = operandLitValue (IC_LEFT (ic)), IC_RIGHT (ic))); + + ip = NULL; + /* check if this is an induction variable */ + if (!applyToSetFTrue (basicInd, findInduction, aSym, &ip)) + continue; + + /* ask port for size not worth if native instruction + exist for multiply & divide */ + if (getSize (operandType (IC_LEFT (ic))) <= port->muldiv.native_below || + getSize (operandType (IC_RIGHT (ic))) <= port->muldiv.native_below) + continue; + + /* if this is a division then the remainder should be zero + for it to be inducted */ + if (ic->op == '/' && (ip->cval % litVal)) + continue; + + /* create the iCode to be placed in the loop header */ + /* and create the induction object */ + + /* create an instruction */ + /* this will be put on the loop header */ + indIc = newiCode (ic->op, + operandFromOperand (aSym), + operandFromLit (litVal)); + indIc->lineno = ic->lineno; + IC_RESULT (indIc) = operandFromOperand (IC_RESULT (ic)); + OP_SYMBOL (IC_RESULT (indIc))->isind = 1; + + /* keep track of the inductions */ + litVal = (ic->op == '*' ? (litVal * ip->cval) : + (ip->cval / litVal)); + + addSet (&indVars, + newInduction (IC_RESULT (ic), ip->op, litVal, indIc, NULL)); + + /* now change this instruction */ + ic->op = ip->op; + if (lr) + { + IC_LEFT (ic) = operandFromOperand (IC_RESULT (ic)); + IC_RIGHT (ic) = operandFromLit (litVal); + } + else + { + IC_RIGHT (ic) = operandFromOperand (IC_RESULT (ic)); + IC_LEFT (ic) = operandFromLit (litVal); + } + + /* we need somemore initialisation code */ + /* we subtract the litVal from itself if increment */ + if (ic->op == '+') + { + indIc = newiCode ('-', + operandFromOperand (IC_RESULT (ic)), + operandFromLit (litVal)); + indIc->lineno = ic->lineno; + IC_RESULT (indIc) = operandFromOperand (IC_RESULT (ic)); + + addSet (&indVars, + newInduction (IC_RESULT (ic), ip->op, litVal, indIc, NULL)); + } + } } - /* if we have some induction variables then */ - if ( indVars ) { - eBBlock *preHdr = loopReg->entry->preHeader ; - iCode *icFirst = NULL , *icLast = NULL ; - induction *ip; - bitVect *indVect = NULL; - - /* create an iCode chain from it */ - for (ip = setFirstItem(indVars); - ip ; - ip = setNextItem(indVars)) { - - indVect = bitVectSetBit(indVect,ip->ic->key); - ip->ic->lineno = preHdr->ech->lineno; - if (!icFirst) - icFirst = ip->ic; - if (icLast) { - icLast->next = ip->ic; - ip->ic->prev = icLast; - icLast = ip->ic ; - } else - icLast = ip->ic; - change++ ; - } - - /* add the instruction chain to the end of the */ - /* preheader for this loop */ - preHdr->ech->next = icFirst ; - icFirst->prev = preHdr->ech ; - preHdr->ech = icLast; - icLast->next = NULL; - - /* add the induction variable vector to the last - block in the loop */ - lastBlock->isLastInLoop = 1; - lastBlock->linds = indVect; + /* if we have some induction variables then */ + if (indVars) + { + eBBlock *preHdr = loopReg->entry->preHeader; + iCode *icFirst = NULL, *icLast = NULL; + induction *ip; + bitVect *indVect = NULL; + + /* create an iCode chain from it */ + for (ip = setFirstItem (indVars); + ip; + ip = setNextItem (indVars)) + { + + indVect = bitVectSetBit (indVect, ip->ic->key); + ip->ic->lineno = preHdr->ech->lineno; + if (!icFirst) + icFirst = ip->ic; + if (icLast) + { + icLast->next = ip->ic; + ip->ic->prev = icLast; + icLast = ip->ic; + } + else + icLast = ip->ic; + change++; + } + + /* add the instruction chain to the end of the */ + /* preheader for this loop */ + preHdr->ech->next = icFirst; + icFirst->prev = preHdr->ech; + preHdr->ech = icLast; + icLast->next = NULL; + + /* add the induction variable vector to the last + block in the loop */ + lastBlock->isLastInLoop = 1; + lastBlock->linds = indVect; } - setToNull ((void **)&indVars); - return change ; + setToNull ((void **) &indVars); + return change; } /*-----------------------------------------------------------------*/ /* mergeRegions - will merge region with same entry point */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(mergeRegions) +DEFSETFUNC (mergeRegions) { - region *theLoop = item; - V_ARG(set*,allRegion) ; - region *lp ; + region *theLoop = item; + V_ARG (set *, allRegion); + region *lp; - /* if this has already been merged then do nothing */ - if (theLoop->merged) - return 0; + /* if this has already been merged then do nothing */ + if (theLoop->merged) + return 0; - /* go thru all the region and check if any of them have the */ - /* entryPoint as the Loop */ - for (lp = setFirstItem(allRegion); lp ; lp = setNextItem(allRegion)) { + /* go thru all the region and check if any of them have the */ + /* entryPoint as the Loop */ + for (lp = setFirstItem (allRegion); lp; lp = setNextItem (allRegion)) + { - if (lp == theLoop) - continue ; + if (lp == theLoop) + continue; - if (lp->entry == theLoop->entry) { - theLoop->regBlocks = unionSets (theLoop->regBlocks, - lp->regBlocks,THROW_BOTH); - lp->merged = 1; - } + if (lp->entry == theLoop->entry) + { + theLoop->regBlocks = unionSets (theLoop->regBlocks, + lp->regBlocks, THROW_BOTH); + lp->merged = 1; + } } - return 1; + return 1; } /*-----------------------------------------------------------------*/ /* ifMerged - return 1 if the merge flag is 1 */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(ifMerged) +DEFSETFUNC (ifMerged) { - region *lp = item; + region *lp = item; - return lp->merged ; + return lp->merged; } /*-----------------------------------------------------------------*/ /* mergeInnerLoops - will merge into body when entry is present */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(mergeInnerLoops) +DEFSETFUNC (mergeInnerLoops) { - region *theLoop = item; - V_ARG(set *,allRegion); - V_ARG(int *,maxDepth); - region *lp; - - /* check if the entry point is present in the body of any */ - /* loop then put the body of this loop into the outer loop*/ - for (lp = setFirstItem(allRegion); lp ; lp = setNextItem(allRegion)) { - - if ( lp == theLoop ) - continue ; - - if (isinSet(lp->regBlocks, theLoop->entry)) { - lp->containsLoops += theLoop->containsLoops + 1 ; - if ( lp->containsLoops > (*maxDepth)) - *maxDepth = lp->containsLoops; - - lp->regBlocks = unionSets (lp->regBlocks, - theLoop->regBlocks,THROW_DEST); - } + region *theLoop = item; + V_ARG (set *, allRegion); + V_ARG (int *, maxDepth); + region *lp; + + /* check if the entry point is present in the body of any */ + /* loop then put the body of this loop into the outer loop */ + for (lp = setFirstItem (allRegion); lp; lp = setNextItem (allRegion)) + { + + if (lp == theLoop) + continue; + + if (isinSet (lp->regBlocks, theLoop->entry)) + { + lp->containsLoops += theLoop->containsLoops + 1; + if (lp->containsLoops > (*maxDepth)) + *maxDepth = lp->containsLoops; + + lp->regBlocks = unionSets (lp->regBlocks, + theLoop->regBlocks, THROW_DEST); + } } - return 1; + return 1; } /*-----------------------------------------------------------------*/ /* createLoopRegions - will detect and create a set of natural loops */ /*-----------------------------------------------------------------*/ -hTab *createLoopRegions (eBBlock **ebbs , int count ) +hTab * +createLoopRegions (eBBlock ** ebbs, int count) { - set *allRegion = NULL; /* set of all loops */ - hTab *orderedLoops = NULL ; - set *bEdges = NULL; - int maxDepth = 0; - region *lp; - - /* get all the back edges in the graph */ - if (! applyToSet(graphEdges,backEdges,&bEdges)) - return 0 ; /* found no loops */ - - /* for each of these back edges get the blocks that */ - /* constitute the loops */ - applyToSet(bEdges,createLoop,&allRegion); - - /* now we will create regions from these loops */ - /* loops with the same entry points are considered to be the */ - /* same loop & they are merged. If the entry point of a loop */ - /* is found in the body of another loop then , all the blocks*/ - /* in that loop are added to the loops containing the header */ - applyToSet(allRegion, mergeRegions , allRegion); - - /* delete those already merged */ - deleteItemIf (&allRegion, ifMerged); - - applyToSet(allRegion, mergeInnerLoops, allRegion, &maxDepth); - maxDepth++; - /* now create all the exits .. also */ - /* create an ordered set of loops */ - /* i.e. we process loops in the inner to outer order */ - for (lp = setFirstItem(allRegion) ; lp ; lp = setNextItem(allRegion)) { - applyToSet (lp->regBlocks,addToExitsMarkDepth, - lp->regBlocks,&lp->exits, - (maxDepth - lp->containsLoops),lp); - - hTabAddItem (&orderedLoops,lp->containsLoops,lp); + set *allRegion = NULL; /* set of all loops */ + hTab *orderedLoops = NULL; + set *bEdges = NULL; + int maxDepth = 0; + region *lp; + + /* get all the back edges in the graph */ + if (!applyToSet (graphEdges, backEdges, &bEdges)) + return 0; /* found no loops */ + + /* for each of these back edges get the blocks that */ + /* constitute the loops */ + applyToSet (bEdges, createLoop, &allRegion); + + /* now we will create regions from these loops */ + /* loops with the same entry points are considered to be the */ + /* same loop & they are merged. If the entry point of a loop */ + /* is found in the body of another loop then , all the blocks */ + /* in that loop are added to the loops containing the header */ + applyToSet (allRegion, mergeRegions, allRegion); + + /* delete those already merged */ + deleteItemIf (&allRegion, ifMerged); + + applyToSet (allRegion, mergeInnerLoops, allRegion, &maxDepth); + maxDepth++; + /* now create all the exits .. also */ + /* create an ordered set of loops */ + /* i.e. we process loops in the inner to outer order */ + for (lp = setFirstItem (allRegion); lp; lp = setNextItem (allRegion)) + { + applyToSet (lp->regBlocks, addToExitsMarkDepth, + lp->regBlocks, &lp->exits, + (maxDepth - lp->containsLoops), lp); + + hTabAddItem (&orderedLoops, lp->containsLoops, lp); } - return orderedLoops ; + return orderedLoops; } /*-----------------------------------------------------------------*/ /* loopOptimizations - identify region & remove invariants & ind */ /*-----------------------------------------------------------------*/ -int loopOptimizations (hTab *orderedLoops, eBBlock **ebbs, int count) +int +loopOptimizations (hTab * orderedLoops, eBBlock ** ebbs, int count) { - region *lp ; - int change = 0 ; - int k; + region *lp; + int change = 0; + int k; - /* if no loop optimizations requested */ - if (! optimize.loopInvariant && - ! optimize.loopInduction ) - return 0; + /* if no loop optimizations requested */ + if (!optimize.loopInvariant && + !optimize.loopInduction) + return 0; - /* now we process the loops inner to outer order */ - /* this is essential to maintain data flow information */ - /* the other choice is an ugly iteration for the depth */ - /* of the loops would hate that */ - for ( lp = hTabFirstItem(orderedLoops,&k); lp ; - lp = hTabNextItem(orderedLoops,&k)) { + /* now we process the loops inner to outer order */ + /* this is essential to maintain data flow information */ + /* the other choice is an ugly iteration for the depth */ + /* of the loops would hate that */ + for (lp = hTabFirstItem (orderedLoops, &k); lp; + lp = hTabNextItem (orderedLoops, &k)) + { - if (optimize.loopInvariant) - change += loopInvariants(lp, ebbs, count); + if (optimize.loopInvariant) + change += loopInvariants (lp, ebbs, count); - if (optimize.loopInduction) - change += loopInduction(lp, ebbs, count); + if (optimize.loopInduction) + change += loopInduction (lp, ebbs, count); } - return change; + return change; } diff --git a/src/SDCCloop.h b/src/SDCCloop.h index dc43c91c..1027b4a1 100644 --- a/src/SDCCloop.h +++ b/src/SDCCloop.h @@ -28,33 +28,37 @@ #ifndef SDCCLOOP_H #define SDCCLOOP_H 1 -typedef struct region { - - unsigned int merged:1; - eBBlock *entry ; /* entry Block */ - int containsLoops; /* contains other loops */ - set *regBlocks ; /* set of all blocks */ - set *exits ; /* set of exits */ -} region ; - -typedef struct induction { - - operand *sym ; +typedef struct region + { + + unsigned int merged:1; + eBBlock *entry; /* entry Block */ + int containsLoops; /* contains other loops */ + set *regBlocks; /* set of all blocks */ + set *exits; /* set of exits */ + } +region; + +typedef struct induction + { + + operand *sym; operand *asym; - unsigned int op ; - long cval ; + unsigned int op; + long cval; iCode *ic; -} induction ; + } +induction; -DEFSETFUNC(backEdges); -DEFSETFUNC(pregion); -DEFSETFUNC(pinduction); +DEFSETFUNC (backEdges); +DEFSETFUNC (pregion); +DEFSETFUNC (pinduction); int loopOptimizations (hTab *, eBBlock **, int); -int addressTaken (set *,operand *); -hTab *createLoopRegions (eBBlock **, int ); +int addressTaken (set *, operand *); +hTab *createLoopRegions (eBBlock **, int); iCode *findDefInRegion (set *, operand *, eBBlock **); int hasIncomingDefs (region *, operand *); -int findLoopEndSeq(region *); +int findLoopEndSeq (region *); #endif diff --git a/src/SDCClrange.c b/src/SDCClrange.c index daca5285..c3922ce0 100644 --- a/src/SDCClrange.c +++ b/src/SDCClrange.c @@ -26,242 +26,259 @@ #include "common.h" #include "limits.h" -int iCodeSeq = 0 ; +int iCodeSeq = 0; hTab *liveRanges = NULL; hTab *iCodehTab = NULL; /*-----------------------------------------------------------------*/ /* sequenceiCode - creates a sequence number for the iCode & add */ /*-----------------------------------------------------------------*/ -void sequenceiCode (eBBlock **ebbs, int count) +void +sequenceiCode (eBBlock ** ebbs, int count) { - int i; - - for (i = 0 ; i < count ; i++ ) { - - iCode *ic; - ebbs[i]->fSeq = iCodeSeq + 1; - for ( ic = ebbs[i]->sch ; ic ; ic= ic->next) { - ic->seq = ++iCodeSeq; - ic->depth = ebbs[i]->depth; - hTabAddItem(&iCodehTab,ic->key,ic); + int i; + + for (i = 0; i < count; i++) + { + + iCode *ic; + ebbs[i]->fSeq = iCodeSeq + 1; + for (ic = ebbs[i]->sch; ic; ic = ic->next) + { + ic->seq = ++iCodeSeq; + ic->depth = ebbs[i]->depth; + hTabAddItem (&iCodehTab, ic->key, ic); } - ebbs[i]->lSeq = iCodeSeq ; + ebbs[i]->lSeq = iCodeSeq; } } /*-----------------------------------------------------------------*/ /* markVisited - will set the visited flag for the given Block */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(markVisited) +DEFSETFUNC (markVisited) { - eBBlock *ebp = item; - - if (ebp->visited) - return 0; - ebp->visited = 1; - applyToSet(ebp->succList,markVisited); + eBBlock *ebp = item; + + if (ebp->visited) return 0; + ebp->visited = 1; + applyToSet (ebp->succList, markVisited); + return 0; } /*-----------------------------------------------------------------*/ /* isOpAlive - checks to see if the usage in this block is the */ /* uses the same definitions as this one */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(isOpAlive) +DEFSETFUNC (isOpAlive) { - eBBlock *ebp = item; - V_ARG(operand *,op); - V_ARG(eBBlock *,orig); - V_ARG(iCode *,ic); - - if (ebp->visited) - return 0; + eBBlock *ebp = item; + V_ARG (operand *, op); + V_ARG (eBBlock *, orig); + V_ARG (iCode *, ic); - ebp->visited = 1; - - /* if we have reached the originating block */ - /* or this block has some definiton for it */ - /* then check if it is used between start & */ - /* this point */ - if ( ebp == orig || - bitVectBitsInCommon(OP_DEFS(op),ebp->defSet)) - if (usedBetweenPoints (op,ebp->sch,ic)) - return 1; - else { - applyToSet(ebp->succList,markVisited); - return 0; - } - else - /* choosing this more expensive one since - killDeadCode will take away some definitions - but there is not way right now to take away - the usage information for the corresponding - usages, this will lead to longer live ranges */ - if (usedInRemaining(op,ebp->sch)) - return 1; + if (ebp->visited) + return 0; + ebp->visited = 1; - return (applyToSet(ebp->succList,isOpAlive,op,orig,ic)); + /* if we have reached the originating block */ + /* or this block has some definiton for it */ + /* then check if it is used between start & */ + /* this point */ + if (ebp == orig || + bitVectBitsInCommon (OP_DEFS (op), ebp->defSet)) + if (usedBetweenPoints (op, ebp->sch, ic)) + return 1; + else + { + applyToSet (ebp->succList, markVisited); + return 0; + } + else + /* choosing this more expensive one since + killDeadCode will take away some definitions + but there is not way right now to take away + the usage information for the corresponding + usages, this will lead to longer live ranges */ + if (usedInRemaining (op, ebp->sch)) + return 1; + + + return (applyToSet (ebp->succList, isOpAlive, op, orig, ic)); } /*-----------------------------------------------------------------*/ /* isLastUse - return TRUE if no usage of this operand after this */ /*-----------------------------------------------------------------*/ -int isLastUse (operand *op, eBBlock *ebp, iCode *ic, - eBBlock **ebbs, int count) +int +isLastUse (operand * op, eBBlock * ebp, iCode * ic, + eBBlock ** ebbs, int count) { - int i; + int i; - /* if this is used in the remaining */ - if (usedInRemaining(op,ic)) - return 0; - - /* if not then check any of the successor blocks use it */ - for (i = 0 ; i < count ; ebbs[i++]->visited = 0); - if (applyToSet(ebp->succList,isOpAlive,op,ebp,ic)) - return 0; + /* if this is used in the remaining */ + if (usedInRemaining (op, ic)) + return 0; - /* this is the last use */ - return 1; + /* if not then check any of the successor blocks use it */ + for (i = 0; i < count; ebbs[i++]->visited = 0); + if (applyToSet (ebp->succList, isOpAlive, op, ebp, ic)) + return 0; + + /* this is the last use */ + return 1; } /*-----------------------------------------------------------------*/ /* unionDefsUsed - unions the defsUsed in a block */ /*-----------------------------------------------------------------*/ -DEFSETFUNC(unionDefsUsed) +DEFSETFUNC (unionDefsUsed) { - eBBlock *ebp = item; - V_ARG(bitVect **,bvp); + eBBlock *ebp = item; + V_ARG (bitVect **, bvp); - if (ebp->visited) - return 0; + if (ebp->visited) + return 0; - ebp->visited = 1; + ebp->visited = 1; - *bvp = bitVectUnion(*bvp, ebp->usesDefs); - applyToSet(ebp->succList,unionDefsUsed,bvp); - return 0; + *bvp = bitVectUnion (*bvp, ebp->usesDefs); + applyToSet (ebp->succList, unionDefsUsed, bvp); + return 0; } /*-----------------------------------------------------------------*/ /* setFromRange - sets the from range of a given operand */ /*-----------------------------------------------------------------*/ -void setFromRange (operand *op, int from) +void +setFromRange (operand * op, int from) { - /* only for compiler defined temporaries */ - if (!IS_ITEMP(op)) - return ; + /* only for compiler defined temporaries */ + if (!IS_ITEMP (op)) + return; - hTabAddItemIfNotP (&liveRanges,op->key,OP_SYMBOL(op)); + hTabAddItemIfNotP (&liveRanges, op->key, OP_SYMBOL (op)); - if (op->isaddr) - OP_SYMBOL(op)->isptr = 1; + if (op->isaddr) + OP_SYMBOL (op)->isptr = 1; - if (!OP_LIVEFROM(op) || - OP_LIVEFROM(op) > from) - OP_LIVEFROM(op) = from; + if (!OP_LIVEFROM (op) || + OP_LIVEFROM (op) > from) + OP_LIVEFROM (op) = from; } /*-----------------------------------------------------------------*/ /* setToRange - set the range to for an operand */ /*-----------------------------------------------------------------*/ -void setToRange (operand *op,int to, bool check) -{ - /* only for compiler defined temps */ - if (!IS_ITEMP(op)) - return ; - - OP_SYMBOL(op)->key = op->key; - hTabAddItemIfNotP (&liveRanges,op->key,OP_SYMBOL(op)); - - if (op->isaddr) - OP_SYMBOL(op)->isptr = 1; - - if (check) - if (!OP_LIVETO(op)) - OP_LIVETO(op) = to; - else ; - else - OP_LIVETO(op) = to; +void +setToRange (operand * op, int to, bool check) +{ + /* only for compiler defined temps */ + if (!IS_ITEMP (op)) + return; + + OP_SYMBOL (op)->key = op->key; + hTabAddItemIfNotP (&liveRanges, op->key, OP_SYMBOL (op)); + + if (op->isaddr) + OP_SYMBOL (op)->isptr = 1; + + if (check) + if (!OP_LIVETO (op)) + OP_LIVETO (op) = to; + else; + else + OP_LIVETO (op) = to; } /*-----------------------------------------------------------------*/ /* firstDeOf - finds the first definition in seq for op */ /*-----------------------------------------------------------------*/ -static iCode *firstDefOf (operand *op) +static iCode * +firstDefOf (operand * op) { - int i; - iCode *ric=NULL,*lic=NULL; - int fSeq = INT_MAX; + int i; + iCode *ric = NULL, *lic = NULL; + int fSeq = INT_MAX; - if (!OP_DEFS(op)) - return NULL; + if (!OP_DEFS (op)) + return NULL; - for (i=0; i < OP_DEFS(op)->size ;i++) { - if (bitVectBitValue(OP_DEFS(op),i) && - (lic = hTabItemWithKey(iCodehTab,i)) && - lic->seq < fSeq) { + for (i = 0; i < OP_DEFS (op)->size; i++) + { + if (bitVectBitValue (OP_DEFS (op), i) && + (lic = hTabItemWithKey (iCodehTab, i)) && + lic->seq < fSeq) + { - fSeq = lic->seq ; - ric = lic; + fSeq = lic->seq; + ric = lic; } } - return ric; + return ric; } /*-----------------------------------------------------------------*/ /* useDefLoopCheck - check for uses before init inside loops */ /*-----------------------------------------------------------------*/ -static void useDefLoopCheck(operand *op,iCode *ic) +static void +useDefLoopCheck (operand * op, iCode * ic) { - /* this is for situations like the following - int a,b; - - while (...) { - a = ... ; - ... - _some_usage_of_b_; - ... - b = ... ; - } - in this case the definition of 'b' will flow to the usages - but register allocator cannot handle these situations.so - will mark as spilt */ - - int i =0, fdSeq ; - int er=0; - iCode *tic ; - - /* get the first definition */ - if (!(tic = firstDefOf(op))) - return ; - - fdSeq = tic->seq; - /* now go thru the usages & make sure they follow - the first definition */ - for (i=0; i <= OP_USES(op)->size;i++ ) { - if (bitVectBitValue(OP_USES(op),i) && - (tic = hTabItemWithKey(iCodehTab,i)) && - tic->seq < fdSeq){ - er = 1; - break; + /* this is for situations like the following + int a,b; + + while (...) { + a = ... ; + ... + _some_usage_of_b_; + ... + b = ... ; + } + in this case the definition of 'b' will flow to the usages + but register allocator cannot handle these situations.so + will mark as spilt */ + + int i = 0, fdSeq; + int er = 0; + iCode *tic; + + /* get the first definition */ + if (!(tic = firstDefOf (op))) + return; + + fdSeq = tic->seq; + /* now go thru the usages & make sure they follow + the first definition */ + for (i = 0; i <= OP_USES (op)->size; i++) + { + if (bitVectBitValue (OP_USES (op), i) && + (tic = hTabItemWithKey (iCodehTab, i)) && + tic->seq < fdSeq) + { + er = 1; + break; } } - /* found a usage without definition */ - if (er) { - if (OP_SYMBOL(op)->isreqv && SPIL_LOC(op) ) { - - werror(W_LOCAL_NOINIT, - SPIL_LOC(op)->name, - ic->filename,ic->lineno); - } else { - - werror(W_LOCAL_NOINIT, - OP_SYMBOL(op)->name, - ic->filename,ic->lineno); + /* found a usage without definition */ + if (er) + { + if (OP_SYMBOL (op)->isreqv && SPIL_LOC (op)) + { + + werror (W_LOCAL_NOINIT, + SPIL_LOC (op)->name, + ic->filename, ic->lineno); + } + else + { + + werror (W_LOCAL_NOINIT, + OP_SYMBOL (op)->name, + ic->filename, ic->lineno); } - OP_SYMBOL(op)->isspilt = 1; + OP_SYMBOL (op)->isspilt = 1; } } @@ -269,283 +286,318 @@ static void useDefLoopCheck(operand *op,iCode *ic) /*-----------------------------------------------------------------*/ /* operandLUse - check and set the last use for a given operand */ /*-----------------------------------------------------------------*/ -operand *operandLUse (operand *op, eBBlock **ebbs, - int count, iCode *ic, eBBlock *ebp) -{ - setFromRange(op,ic->seq); - if (ic->depth) - OP_SYMBOL(op)->used += (((unsigned int)1 << ic->depth) + 1); - else - OP_SYMBOL(op)->used += 1; - - if (isLastUse(op,ebp,ic->next,ebbs,count) || - (OP_LIVETO(op) && OP_LIVETO(op) < ic->seq)) { - int torange = ic->seq; - /* if this is the last use then if this block belongs - to a loop & some definition comes into the loop - then extend the live range to the end of the loop */ - if (ebp->partOfLoop && - hasIncomingDefs(ebp->partOfLoop,op)) { - torange = findLoopEndSeq(ebp->partOfLoop); +operand * +operandLUse (operand * op, eBBlock ** ebbs, + int count, iCode * ic, eBBlock * ebp) +{ + setFromRange (op, ic->seq); + if (ic->depth) + OP_SYMBOL (op)->used += (((unsigned int) 1 << ic->depth) + 1); + else + OP_SYMBOL (op)->used += 1; + + if (isLastUse (op, ebp, ic->next, ebbs, count) || + (OP_LIVETO (op) && OP_LIVETO (op) < ic->seq)) + { + int torange = ic->seq; + /* if this is the last use then if this block belongs + to a loop & some definition comes into the loop + then extend the live range to the end of the loop */ + if (ebp->partOfLoop && + hasIncomingDefs (ebp->partOfLoop, op)) + { + torange = findLoopEndSeq (ebp->partOfLoop); } - op = operandFromOperand(op); - setToRange(op,torange,FALSE); - } - ic->uses = bitVectSetBit(ic->uses,op->key); - - if (!OP_SYMBOL(op)->udChked) + op = operandFromOperand (op); + setToRange (op, torange, FALSE); + } + ic->uses = bitVectSetBit (ic->uses, op->key); + + if (!OP_SYMBOL (op)->udChked) { - sym_link *type = operandType(op); - sym_link *etype = getSpec(type); - - OP_SYMBOL(op)->udChked = 1; - /* good place to check if unintialised */ - if ((IS_TRUE_SYMOP(op) || OP_SYMBOL(op)->isreqv) && - OP_SYMBOL(op)->islocal && - !IS_AGGREGATE(type) && - !IS_FUNC(type) && - ic->op != ADDRESS_OF && - !IS_STATIC(etype) ) { - - if (bitVectIsZero(op->usesDefs)) { - OP_SYMBOL(op)->isspilt = 1; - - if (OP_SYMBOL(op)->isreqv && - !OP_SYMBOL(op)->_isparm && SPIL_LOC(op) ) { - - werror(W_LOCAL_NOINIT, - SPIL_LOC(op)->name, - ic->filename,ic->lineno); - } else { - - werror(W_LOCAL_NOINIT, - OP_SYMBOL(op)->name, - ic->filename,ic->lineno); + sym_link *type = operandType (op); + sym_link *etype = getSpec (type); + + OP_SYMBOL (op)->udChked = 1; + /* good place to check if unintialised */ + if ((IS_TRUE_SYMOP (op) || OP_SYMBOL (op)->isreqv) && + OP_SYMBOL (op)->islocal && + !IS_AGGREGATE (type) && + !IS_FUNC (type) && + ic->op != ADDRESS_OF && + !IS_STATIC (etype)) + { + + if (bitVectIsZero (op->usesDefs)) + { + OP_SYMBOL (op)->isspilt = 1; + + if (OP_SYMBOL (op)->isreqv && + !OP_SYMBOL (op)->_isparm && SPIL_LOC (op)) + { + + werror (W_LOCAL_NOINIT, + SPIL_LOC (op)->name, + ic->filename, ic->lineno); + } + else + { + + werror (W_LOCAL_NOINIT, + OP_SYMBOL (op)->name, + ic->filename, ic->lineno); } - } else { - if (ebp->depth && op->usesDefs && - !OP_SYMBOL(op)->_isparm) { - /* check non-inits inside loops */ - useDefLoopCheck(op,ic); + } + else + { + if (ebp->depth && op->usesDefs && + !OP_SYMBOL (op)->_isparm) + { + /* check non-inits inside loops */ + useDefLoopCheck (op, ic); } } - } + } } - return op; + return op; } /*-----------------------------------------------------------------*/ /* killAllAlive - mark all the definitions living with this seq */ /*-----------------------------------------------------------------*/ -void killAllAlive (int seq) +void +killAllAlive (int seq) { - symbol *sym; - int k; + symbol *sym; + int k; - for (sym = hTabFirstItem(liveRanges,&k); sym; - sym = hTabNextItem(liveRanges,&k)) - if (!sym->liveTo || (sym->liveTo < sym->liveFrom)) - sym->liveTo = seq; + for (sym = hTabFirstItem (liveRanges, &k); sym; + sym = hTabNextItem (liveRanges, &k)) + if (!sym->liveTo || (sym->liveTo < sym->liveFrom)) + sym->liveTo = seq; } /*-----------------------------------------------------------------*/ /* defUsedAfterLoop - all definitions & usages before sequence num */ /*-----------------------------------------------------------------*/ -bool defUsedAfterLoop (operand *op, int seq) +bool +defUsedAfterLoop (operand * op, int seq) { - int i; - iCode *ic; - - /* check for the usages first */ - if (OP_SYMBOL(op)->uses && !bitVectIsZero(OP_SYMBOL(op)->uses)) { - for (i = 0 ; i < OP_SYMBOL(op)->uses->size ; i++ ) { - - if (bitVectBitValue( OP_SYMBOL(op)->uses,i) && /* usage found */ - (ic = hTabItemWithKey(iCodehTab,i)) && /* "" */ - ic->seq > seq ) /* & is after the seq */ - return TRUE ; + int i; + iCode *ic; + + /* check for the usages first */ + if (OP_SYMBOL (op)->uses && !bitVectIsZero (OP_SYMBOL (op)->uses)) + { + for (i = 0; i < OP_SYMBOL (op)->uses->size; i++) + { + + if (bitVectBitValue (OP_SYMBOL (op)->uses, i) && /* usage found */ + (ic = hTabItemWithKey (iCodehTab, i)) && /* "" */ + ic->seq > seq) /* & is after the seq */ + return TRUE; } } - return FALSE; + return FALSE; } /*-----------------------------------------------------------------*/ /* markLiveRanges - for each operand mark the liveFrom & liveTo */ /*-----------------------------------------------------------------*/ -void markLiveRanges (eBBlock *ebp, eBBlock **ebbs, int count) +void +markLiveRanges (eBBlock * ebp, eBBlock ** ebbs, int count) { - iCode *ic; - bitVect *defsUsed = NULL; - bitVect *defsNotUsed = NULL; - int i; - /* for all the instructions */ - for (ic = ebp->sch ; ic ; ic = ic->next ) { - - if (ic->op == CALL || ic->op == PCALL) { - setFromRange(IC_RESULT(ic),ic->seq); - /* if the result has no usage then - mark this as the end of its life too - and take it away from the defs for the block*/ - if (bitVectIsZero(OP_SYMBOL(IC_RESULT(ic))->uses)) { - setToRange(IC_RESULT(ic),ic->seq,FALSE); - bitVectUnSetBit(ebp->defSet,ic->key); + iCode *ic; + bitVect *defsUsed = NULL; + bitVect *defsNotUsed = NULL; + int i; + /* for all the instructions */ + for (ic = ebp->sch; ic; ic = ic->next) + { + + if (ic->op == CALL || ic->op == PCALL) + { + setFromRange (IC_RESULT (ic), ic->seq); + /* if the result has no usage then + mark this as the end of its life too + and take it away from the defs for the block */ + if (bitVectIsZero (OP_SYMBOL (IC_RESULT (ic))->uses)) + { + setToRange (IC_RESULT (ic), ic->seq, FALSE); + bitVectUnSetBit (ebp->defSet, ic->key); } } - if (SKIP_IC2(ic)) - continue ; + if (SKIP_IC2 (ic)) + continue; + + /* take care of the special icodes first */ + if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic))) + { + operandLUse (IC_JTCOND (ic), ebbs, count, ic, ebp); + continue; + } - /* take care of the special icodes first */ - if (ic->op == JUMPTABLE && IS_SYMOP(IC_JTCOND(ic))) { - operandLUse (IC_JTCOND(ic),ebbs,count,ic,ebp); - continue; + if (ic->op == IFX && IS_SYMOP (IC_COND (ic))) + { + operandLUse (IC_COND (ic), ebbs, count, ic, ebp); + continue; } - - if (ic->op == IFX && IS_SYMOP(IC_COND(ic))) { - operandLUse (IC_COND(ic),ebbs,count,ic,ebp); - continue ; - } - - if (IS_SYMOP(IC_LEFT(ic))) - operandLUse (IC_LEFT(ic),ebbs,count,ic,ebp); - - if (IS_SYMOP(IC_RIGHT(ic))) - operandLUse (IC_RIGHT(ic),ebbs,count,ic,ebp); - - if (POINTER_SET(ic)) - operandLUse(IC_RESULT(ic),ebbs,count,ic,ebp); - else - if (IC_RESULT(ic)) - ic->defKey = IC_RESULT(ic)->key ; + + if (IS_SYMOP (IC_LEFT (ic))) + operandLUse (IC_LEFT (ic), ebbs, count, ic, ebp); + + if (IS_SYMOP (IC_RIGHT (ic))) + operandLUse (IC_RIGHT (ic), ebbs, count, ic, ebp); + + if (POINTER_SET (ic)) + operandLUse (IC_RESULT (ic), ebbs, count, ic, ebp); + else if (IC_RESULT (ic)) + ic->defKey = IC_RESULT (ic)->key; } - /* for all the definitions in the block */ - /* compute and set the live from */ - if ( ebp->ldefs && ! bitVectIsZero(ebp->ldefs)) { - for ( i = 0 ; i < ebp->ldefs->size ; i++ ) { - iCode *dic; - - if (bitVectBitValue(ebp->ldefs,i) && - (dic = hTabItemWithKey(iCodehTab,i))) { - - /* if the definition has a from & it is greater */ - /* than the defininng iCode->seq then change it */ - setFromRange(IC_RESULT(dic),dic->seq); - } - } + /* for all the definitions in the block */ + /* compute and set the live from */ + if (ebp->ldefs && !bitVectIsZero (ebp->ldefs)) + { + for (i = 0; i < ebp->ldefs->size; i++) + { + iCode *dic; + + if (bitVectBitValue (ebp->ldefs, i) && + (dic = hTabItemWithKey (iCodehTab, i))) + { + + /* if the definition has a from & it is greater */ + /* than the defininng iCode->seq then change it */ + setFromRange (IC_RESULT (dic), dic->seq); + } + } } - /* special case for lastBlock in a loop: here we - mark the end of all the induction variables for the - loop */ - if (ebp->isLastInLoop && !bitVectIsZero(ebp->linds)) { - for ( i = 0 ; i <= ebp->linds->size ; i++ ) { - iCode *dic; - - if (bitVectBitValue(ebp->linds,i) && - (dic = hTabItemWithKey(iCodehTab,i))) { - - /* if this is a register equvalent make sure - it is not defined or used anywhere after the loop */ - if (OP_SYMBOL(IC_RESULT(dic))->isreqv && - defUsedAfterLoop(IC_RESULT(dic), ebp->lSeq)) - continue; - - setToRange(IC_RESULT(dic),( ebp->lSeq ),FALSE); + /* special case for lastBlock in a loop: here we + mark the end of all the induction variables for the + loop */ + if (ebp->isLastInLoop && !bitVectIsZero (ebp->linds)) + { + for (i = 0; i <= ebp->linds->size; i++) + { + iCode *dic; + + if (bitVectBitValue (ebp->linds, i) && + (dic = hTabItemWithKey (iCodehTab, i))) + { + + /* if this is a register equvalent make sure + it is not defined or used anywhere after the loop */ + if (OP_SYMBOL (IC_RESULT (dic))->isreqv && + defUsedAfterLoop (IC_RESULT (dic), ebp->lSeq)) + continue; + + setToRange (IC_RESULT (dic), (ebp->lSeq), FALSE); } - } + } } - /* for defnitions coming into the block if they */ - /* not used by itself & any of its successors */ - /* they are dead */ - /* first union the definitions used in all successors - and itself */ - for (i = 0; i < count ; ebbs[i++]->visited = 0); - applyToSet(ebp->succList,unionDefsUsed,&defsUsed); - defsUsed = bitVectUnion(defsUsed,ebp->usesDefs); - - /* now subract the result of these unions from */ - /* the incoming definitions this will give the */ - /* definitions that are never used in the future */ - defsNotUsed = bitVectCplAnd(bitVectCopy(ebp->inDefs), - defsUsed); - - /* mark the end of the defintions */ - if ( !bitVectIsZero(defsNotUsed) && ebp->sch ) { - for ( i = 0 ; i < defsNotUsed->size; i++ ) { - iCode *dic; - - if (bitVectBitValue(defsNotUsed,i) && - (dic = hTabItemWithKey(iCodehTab,i))) { - - setToRange(IC_RESULT(dic),( ebp->fSeq - 1),TRUE); + /* for defnitions coming into the block if they */ + /* not used by itself & any of its successors */ + /* they are dead */ + /* first union the definitions used in all successors + and itself */ + for (i = 0; i < count; ebbs[i++]->visited = 0); + applyToSet (ebp->succList, unionDefsUsed, &defsUsed); + defsUsed = bitVectUnion (defsUsed, ebp->usesDefs); + + /* now subract the result of these unions from */ + /* the incoming definitions this will give the */ + /* definitions that are never used in the future */ + defsNotUsed = bitVectCplAnd (bitVectCopy (ebp->inDefs), + defsUsed); + + /* mark the end of the defintions */ + if (!bitVectIsZero (defsNotUsed) && ebp->sch) + { + for (i = 0; i < defsNotUsed->size; i++) + { + iCode *dic; + + if (bitVectBitValue (defsNotUsed, i) && + (dic = hTabItemWithKey (iCodehTab, i))) + { + + setToRange (IC_RESULT (dic), (ebp->fSeq - 1), TRUE); } } } - /* if we reach a lock with noPath to it then kill all - the live ranges alive at this point */ + /* if we reach a lock with noPath to it then kill all + the live ranges alive at this point */ /* if (ebp->noPath || ebp->entryLabel == returnLabel) */ - if (ebp->entryLabel == returnLabel) - killAllAlive(ebp->fSeq); + if (ebp->entryLabel == returnLabel) + killAllAlive (ebp->fSeq); } /*-----------------------------------------------------------------*/ /* rlivePoint - for each point compute the ranges that are alive */ /*-----------------------------------------------------------------*/ -void rlivePoint (eBBlock **ebbs, int count) +void +rlivePoint (eBBlock ** ebbs, int count) { - int i; - - /* for all blocks do */ - for ( i = 0 ; i < count ; i++ ) { - iCode *ic; - - /* for all instruction in the block do */ - for ( ic = ebbs[i]->sch ; ic ; ic = ic->next ) { - symbol *lrange; - int k; - - ic->rlive = newBitVect(operandKey); - /* for all symbols in the liverange table */ - for ( lrange = hTabFirstItem(liveRanges,&k); lrange; - lrange = hTabNextItem(liveRanges,&k)) { - - /* if it is live then add the lrange to ic->rlive */ - if (lrange->liveFrom <= ic->seq && - lrange->liveTo >= ic->seq ) { - lrange->isLiveFcall |= (ic->op == CALL || ic->op == PCALL || ic->op == SEND); - ic->rlive = bitVectSetBit(ic->rlive,lrange->key); + int i; + + /* for all blocks do */ + for (i = 0; i < count; i++) + { + iCode *ic; + + /* for all instruction in the block do */ + for (ic = ebbs[i]->sch; ic; ic = ic->next) + { + symbol *lrange; + int k; + + ic->rlive = newBitVect (operandKey); + /* for all symbols in the liverange table */ + for (lrange = hTabFirstItem (liveRanges, &k); lrange; + lrange = hTabNextItem (liveRanges, &k)) + { + + /* if it is live then add the lrange to ic->rlive */ + if (lrange->liveFrom <= ic->seq && + lrange->liveTo >= ic->seq) + { + lrange->isLiveFcall |= (ic->op == CALL || ic->op == PCALL || ic->op == SEND); + ic->rlive = bitVectSetBit (ic->rlive, lrange->key); } } } - } + } } /*-----------------------------------------------------------------*/ /* computeLiveRanges - computes the live ranges for variables */ /*-----------------------------------------------------------------*/ -void computeLiveRanges (eBBlock **ebbs, int count ) +void +computeLiveRanges (eBBlock ** ebbs, int count) { - int i = 0 ; - /* sequence the code the live ranges are computed - in terms of this sequence additionally the - routine will also create a hashtable of instructions */ - iCodeSeq = 0 ; - setToNull((void **)&iCodehTab); - iCodehTab = newHashTable (iCodeKey); - sequenceiCode(ebbs,count); - - /* call routine to mark the from & to live ranges for - variables used */ - setToNull((void **)&liveRanges); - for ( i = 0 ; i < count; i++ ) - markLiveRanges (ebbs[i],ebbs,count); - - /* mark the ranges live for each point */ - rlivePoint (ebbs,count); + int i = 0; + /* sequence the code the live ranges are computed + in terms of this sequence additionally the + routine will also create a hashtable of instructions */ + iCodeSeq = 0; + setToNull ((void **) &iCodehTab); + iCodehTab = newHashTable (iCodeKey); + sequenceiCode (ebbs, count); + + /* call routine to mark the from & to live ranges for + variables used */ + setToNull ((void **) &liveRanges); + for (i = 0; i < count; i++) + markLiveRanges (ebbs[i], ebbs, count); + + /* mark the ranges live for each point */ + rlivePoint (ebbs, count); } diff --git a/src/SDCClrange.h b/src/SDCClrange.h index 7e2be396..41f0148b 100644 --- a/src/SDCClrange.h +++ b/src/SDCClrange.h @@ -27,7 +27,7 @@ #define SDCCLRANGE_H 1 extern hTab *liveRanges; -extern hTab *iCodehTab ; +extern hTab *iCodehTab; void computeLiveRanges (eBBlock **, int); diff --git a/src/SDCCmain.c b/src/SDCCmain.c index fa42f4f7..c455429c 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -180,7 +180,7 @@ extern void pic14glue (); @param The name minus the option (eg 'mcs51') @return 0 on success. */ -static int +static int _setPort (const char *name) { int i; @@ -197,7 +197,7 @@ _setPort (const char *name) exit (1); } -static void +static void _validatePorts (void) { int i; @@ -212,7 +212,7 @@ _validatePorts (void) } #ifdef USE_SYSTEM_SYSTEM_CALLS -void +void buildCmdLine (char *into, const char **cmds, const char *p1, const char *p2, const char *p3, const char **list) @@ -273,7 +273,7 @@ buildCmdLine (char *into, const char **cmds, } } #else -void +void buildCmdLine (char *into, char **args, const char **cmds, const char *p1, const char *p2, const char *p3, const char **list) @@ -343,7 +343,7 @@ buildCmdLine (char *into, char **args, const char **cmds, /*-----------------------------------------------------------------*/ /* printVersionInfo - prints the version info */ /*-----------------------------------------------------------------*/ -void +void printVersionInfo () { int i; @@ -378,7 +378,7 @@ printVersionInfo () /*-----------------------------------------------------------------*/ /* printUsage - prints command line syntax */ /*-----------------------------------------------------------------*/ -void +void printUsage () { printVersionInfo (); @@ -412,7 +412,7 @@ printUsage () /*-----------------------------------------------------------------*/ /* parseWithComma - separates string with comma */ /*-----------------------------------------------------------------*/ -void +void parseWithComma (char **dest, char *src) { int i = 0; @@ -439,7 +439,7 @@ parseWithComma (char **dest, char *src) /*-----------------------------------------------------------------*/ /* setDefaultOptions - sets the default options */ /*-----------------------------------------------------------------*/ -static void +static void setDefaultOptions () { int i; @@ -479,7 +479,7 @@ setDefaultOptions () /*-----------------------------------------------------------------*/ /* processFile - determines the type of file from the extension */ /*-----------------------------------------------------------------*/ -static void +static void processFile (char *s) { char *fext = NULL; @@ -560,7 +560,7 @@ processFile (char *s) } -static void +static void _processC1Arg (char *s) { if (srcFileName) @@ -578,7 +578,7 @@ _processC1Arg (char *s) } } -static void +static void _addToList (const char **list, const char *str) { /* This is the bad way to do things :) */ @@ -593,7 +593,7 @@ _addToList (const char **list, const char *str) *(++list) = NULL; } -static void +static void _setModel (int model, const char *sz) { if (port->general.supported_models & model) @@ -605,7 +605,7 @@ _setModel (int model, const char *sz) /*-----------------------------------------------------------------*/ /* parseCmdLine - parses the command line and sets the options */ /*-----------------------------------------------------------------*/ -int +int parseCmdLine (int argc, char **argv) { int i; @@ -1269,11 +1269,11 @@ parseCmdLine (int argc, char **argv) //char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL}; char *try_dir[] = -{NULL, NULL}; /* First entry may be overwritten, so use two. */ +{NULL, NULL}; /* First entry may be overwritten, so use two. */ #ifdef USE_SYSTEM_SYSTEM_CALLS -int +int my_system (const char *cmd) { int argsStart, e, i = 0; @@ -1341,7 +1341,7 @@ my_system (const char *cmd) #else -int +int my_system (const char *cmd, char **cmd_argv) { char *dir, *got = NULL; @@ -1413,7 +1413,7 @@ my_system (const char *cmd, char **cmd_argv) /*-----------------------------------------------------------------*/ /* linkEdit : - calls the linkage editor with options */ /*-----------------------------------------------------------------*/ -static void +static void linkEdit (char **envp) { FILE *lnkfile; @@ -1534,8 +1534,8 @@ linkEdit (char **envp) if (my_system (buffer)) { /* either system() or the linker itself has reported an error - perror ("Cannot exec linker"); - */ + perror ("Cannot exec linker"); + */ exit (1); } #else @@ -1561,7 +1561,7 @@ linkEdit (char **envp) /*-----------------------------------------------------------------*/ /* assemble - spawns the assembler with arguments */ /*-----------------------------------------------------------------*/ -static void +static void assemble (char **envp) { #ifdef USE_SYSTEM_SYSTEM_CALLS @@ -1569,8 +1569,8 @@ assemble (char **envp) if (my_system (buffer)) { /* either system() or the assembler itself has reported an error - perror ("Cannot exec assembler"); - */ + perror ("Cannot exec assembler"); + */ exit (1); } #else @@ -1591,7 +1591,7 @@ assemble (char **envp) /*-----------------------------------------------------------------*/ /* preProcess - spawns the preprocessor with arguments */ /*-----------------------------------------------------------------*/ -static int +static int preProcess (char **envp) { #ifndef USE_SYSTEM_SYSTEM_CALLS @@ -1656,7 +1656,7 @@ preProcess (char **envp) { /* either system() or the preprocessor itself has reported an error perror ("Cannot exec Preprocessor"); - */ + */ exit (1); } #else @@ -1689,7 +1689,7 @@ preProcess (char **envp) return 0; } -static void +static void _findPort (int argc, char **argv) { _validatePorts (); @@ -1714,7 +1714,7 @@ _findPort (int argc, char **argv) * initialises and calls the parser */ -int +int main (int argc, char **argv, char **envp) { /* turn all optimizations off by default */ @@ -1727,16 +1727,16 @@ main (int argc, char **argv, char **envp) if (port->init) port->init (); - // Create a default exe search path from the path to the sdcc command + // Create a default exe search path from the path to the sdcc command - if (strchr(argv[0], DIR_SEPARATOR_CHAR)) - { - strcpy(DefaultExePath, argv[0]); - *(strrchr(DefaultExePath, DIR_SEPARATOR_CHAR)) = 0; + if (strchr (argv[0], DIR_SEPARATOR_CHAR)) + { + strcpy (DefaultExePath, argv[0]); + *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0; try_dir[0] = DefaultExePath; - } + } setDefaultOptions (); diff --git a/src/SDCCmem.c b/src/SDCCmem.c index 3fb5899f..cb1ecb0e 100644 --- a/src/SDCCmem.c +++ b/src/SDCCmem.c @@ -1,991 +1,1079 @@ /*-----------------------------------------------------------------*/ -/* SDCCmem.c - 8051 memory management routines */ +/* SDCCmem.c - 8051 memory management routines */ /*-----------------------------------------------------------------*/ #include "common.h" /* memory segments */ -memmap *xstack= NULL ; /* xternal stack data */ -memmap *istack= NULL; /* internal stack */ -memmap *code = NULL; /* code segment */ -memmap *data = NULL; /* internal data upto 128 */ -memmap *xdata = NULL; /* external data */ -memmap *idata = NULL; /* internal data upto 256 */ -memmap *bit = NULL; /* bit addressable space */ -memmap *statsg= NULL; /* the constant data segment */ -memmap *sfr = NULL; /* register space */ -memmap *reg = NULL; /* register space */ -memmap *sfrbit= NULL; /* sfr bit space */ -memmap *generic=NULL; /* is a generic pointer */ -memmap *overlay=NULL; /* overlay segment */ -memmap *eeprom =NULL; /* eeprom location */ -memmap *home =NULL; /* Unswitchable code bank */ +memmap *xstack = NULL; /* xternal stack data */ +memmap *istack = NULL; /* internal stack */ +memmap *code = NULL; /* code segment */ +memmap *data = NULL; /* internal data upto 128 */ +memmap *xdata = NULL; /* external data */ +memmap *idata = NULL; /* internal data upto 256 */ +memmap *bit = NULL; /* bit addressable space */ +memmap *statsg = NULL; /* the constant data segment */ +memmap *sfr = NULL; /* register space */ +memmap *reg = NULL; /* register space */ +memmap *sfrbit = NULL; /* sfr bit space */ +memmap *generic = NULL; /* is a generic pointer */ +memmap *overlay = NULL; /* overlay segment */ +memmap *eeprom = NULL; /* eeprom location */ +memmap *home = NULL; /* Unswitchable code bank */ /* this is a set of sets each set containing symbols in a single overlay */ -set *ovrSetSets = NULL; +set *ovrSetSets = NULL; int maxRegBank = 0; -int fatalError = 0 ;/* fatal error flag */ - -/*-----------------------------------------------------------------*/ -/* allocMap - allocates a memory map */ -/*-----------------------------------------------------------------*/ -memmap *allocMap (char rspace, /* sfr space */ - char farmap, /* far or near segment */ - char paged , /* can this segment be paged */ - char direct, /* directly addressable */ - char bitaddr, /* bit addressable space*/ - char codemap, /* this is code space */ - unsigned sloc, /* starting location */ - const char *name, /* 2 character name */ - char dbName , /* debug name */ - int ptrType /* pointer type for this space */ - ) +int fatalError = 0; /* fatal error flag */ + +/*-----------------------------------------------------------------*/ +/* allocMap - allocates a memory map */ +/*-----------------------------------------------------------------*/ +memmap * +allocMap (char rspace, /* sfr space */ + char farmap, /* far or near segment */ + char paged, /* can this segment be paged */ + char direct, /* directly addressable */ + char bitaddr, /* bit addressable space */ + char codemap, /* this is code space */ + unsigned sloc, /* starting location */ + const char *name, /* 2 character name */ + char dbName, /* debug name */ + int ptrType /* pointer type for this space */ +) { - memmap *map ; + memmap *map; - if (!(map = calloc(sizeof(memmap), 1))) { - werror(E_OUT_OF_MEM,__FILE__,sizeof(memmap)); - exit (1); - } + if (!(map = calloc (sizeof (memmap), 1))) + { + werror (E_OUT_OF_MEM, __FILE__, sizeof (memmap)); + exit (1); + } - memset(map, ZERO, sizeof(memmap)); - map->regsp = rspace ; - map->fmap = farmap ; - map->paged = paged ; - map->direct = direct ; - map->bitsp = bitaddr ; - map->codesp = codemap ; - map->sloc = sloc ; - map->sname = name ; - map->dbName = dbName ; - map->ptrType= ptrType; - if (!(map->oFile = tempfile())) { - werror(E_TMPFILE_FAILED); - exit (1); - } - addSetHead (&tmpfileSet,map->oFile); - map->syms = NULL ; - return map; + memset (map, ZERO, sizeof (memmap)); + map->regsp = rspace; + map->fmap = farmap; + map->paged = paged; + map->direct = direct; + map->bitsp = bitaddr; + map->codesp = codemap; + map->sloc = sloc; + map->sname = name; + map->dbName = dbName; + map->ptrType = ptrType; + if (!(map->oFile = tempfile ())) + { + werror (E_TMPFILE_FAILED); + exit (1); + } + addSetHead (&tmpfileSet, map->oFile); + map->syms = NULL; + return map; } /*-----------------------------------------------------------------*/ -/* initMem - allocates and initializes all the segments */ -/*-----------------------------------------------------------------*/ -void initMem () -{ - /* allocate all the segments */ - /* xternal stack segment ; - SFRSPACE - NO - FAR-SPACE - YES - PAGED - YES - DIRECT-ACCESS - NO - BIT-ACCESS - NO - CODE-ACESS - NO - DEBUG-NAME - 'A' - POINTER-TYPE - FPOINTER - */ - xstack = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME,'A',PPOINTER); - - /* internal stack segment ; - SFRSPACE - NO - FAR-SPACE - NO - PAGED - NO - DIRECT-ACCESS - NO - BIT-ACCESS - NO - CODE-ACESS - NO - DEBUG-NAME - 'B' - POINTER-TYPE - POINTER - */ - istack = allocMap (0, 0, 0, 0, 0, 0,options.stack_loc, ISTACK_NAME,'B',POINTER); - - /* code segment ; - SFRSPACE - NO - FAR-SPACE - YES - PAGED - NO - DIRECT-ACCESS - NO - BIT-ACCESS - NO - CODE-ACESS - YES - DEBUG-NAME - 'C' - POINTER-TYPE - CPOINTER - */ - code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME,'C',CPOINTER); - - /* home segment ; - SFRSPACE - NO - FAR-SPACE - YES - PAGED - NO - DIRECT-ACCESS - NO - BIT-ACCESS - NO - CODE-ACESS - YES - DEBUG-NAME - 'C' - POINTER-TYPE - CPOINTER - */ - home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME,'C',CPOINTER); - - /* Static segment (code for variables ); - SFRSPACE - NO - FAR-SPACE - YES - PAGED - NO - DIRECT-ACCESS - NO - BIT-ACCESS - NO - CODE-ACESS - YES - DEBUG-NAME - 'D' - POINTER-TYPE - CPOINTER - */ - statsg = allocMap (0, 1, 0, 0, 0, 1,0, STATIC_NAME,'D',CPOINTER); - - /* Data segment - internal storage segment ; - SFRSPACE - NO - FAR-SPACE - NO - PAGED - NO - DIRECT-ACCESS - YES - BIT-ACCESS - NO - CODE-ACESS - NO - DEBUG-NAME - 'E' - POINTER-TYPE - POINTER - */ - data = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME,'E',POINTER); - - /* overlay segment - same as internal storage segment ; - SFRSPACE - NO - FAR-SPACE - NO - PAGED - NO - DIRECT-ACCESS - YES - BIT-ACCESS - NO - CODE-ACESS - NO - DEBUG-NAME - 'E' - POINTER-TYPE - POINTER - */ - overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME,'E',POINTER); - - /* Xternal Data segment - - SFRSPACE - NO - FAR-SPACE - YES - PAGED - NO - DIRECT-ACCESS - NO - BIT-ACCESS - NO - CODE-ACESS - NO - DEBUG-NAME - 'F' - POINTER-TYPE - FPOINTER - */ - xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME,'F',FPOINTER); - - /* Inderectly addressed internal data segment - SFRSPACE - NO - FAR-SPACE - NO - PAGED - NO - DIRECT-ACCESS - NO - BIT-ACCESS - NO - CODE-ACESS - NO - DEBUG-NAME - 'G' - POINTER-TYPE - IPOINTER - */ - idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc,IDATA_NAME,'G',IPOINTER); - - /* Static segment (code for variables ); - SFRSPACE - NO - FAR-SPACE - NO - PAGED - NO - DIRECT-ACCESS - YES - BIT-ACCESS - YES - CODE-ACESS - NO - DEBUG-NAME - 'H' - POINTER-TYPE - _NONE_ - */ - bit = allocMap (0, 0, 0, 1, 1, 0,0, BIT_NAME,'H',0); - - /* Special function register space :- - SFRSPACE - YES - FAR-SPACE - NO - PAGED - NO - DIRECT-ACCESS - YES - BIT-ACCESS - NO - CODE-ACESS - NO - DEBUG-NAME - 'I' - POINTER-TYPE - _NONE_ - */ - sfr = allocMap (1,0, 0, 1, 0, 0,0, REG_NAME,'I',0); - - /* Register space ; - SFRSPACE - YES - FAR-SPACE - NO - PAGED - NO - DIRECT-ACCESS - NO - BIT-ACCESS - NO - CODE-ACESS - NO - DEBUG-NAME - ' ' - POINTER-TYPE - _NONE_ - */ - reg = allocMap (1,0, 0, 0, 0, 0, 0,REG_NAME,' ',0); - - /* SFR bit space - SFRSPACE - YES - FAR-SPACE - NO - PAGED - NO - DIRECT-ACCESS - YES - BIT-ACCESS - YES - CODE-ACESS - NO - DEBUG-NAME - 'J' - POINTER-TYPE - _NONE_ - */ - sfrbit = allocMap (1,0, 0, 1, 1, 0,0, REG_NAME,'J',0); - - /* EEPROM bit space - SFRSPACE - NO - FAR-SPACE - YES - PAGED - NO - DIRECT-ACCESS - NO - BIT-ACCESS - NO - CODE-ACESS - NO - DEBUG-NAME - 'K' - POINTER-TYPE - EEPPOINTER - */ - eeprom = allocMap (0,1, 0, 0, 0, 0,0, REG_NAME,'K',EEPPOINTER); - - /* the unknown map */ - generic = allocMap (1,0, 0, 1, 1, 0,0, REG_NAME,' ',GPOINTER); - +/* initMem - allocates and initializes all the segments */ +/*-----------------------------------------------------------------*/ +void +initMem () +{ + /* allocate all the segments */ + /* xternal stack segment ; + SFRSPACE - NO + FAR-SPACE - YES + PAGED - YES + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACESS - NO + DEBUG-NAME - 'A' + POINTER-TYPE - FPOINTER + */ + xstack = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, XSTACK_NAME, 'A', PPOINTER); + + /* internal stack segment ; + SFRSPACE - NO + FAR-SPACE - NO + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACESS - NO + DEBUG-NAME - 'B' + POINTER-TYPE - POINTER + */ + istack = allocMap (0, 0, 0, 0, 0, 0, options.stack_loc, ISTACK_NAME, 'B', POINTER); + + /* code segment ; + SFRSPACE - NO + FAR-SPACE - YES + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACESS - YES + DEBUG-NAME - 'C' + POINTER-TYPE - CPOINTER + */ + code = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER); + + /* home segment ; + SFRSPACE - NO + FAR-SPACE - YES + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACESS - YES + DEBUG-NAME - 'C' + POINTER-TYPE - CPOINTER + */ + home = allocMap (0, 1, 0, 0, 0, 1, options.code_loc, CODE_NAME, 'C', CPOINTER); + + /* Static segment (code for variables ); + SFRSPACE - NO + FAR-SPACE - YES + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACESS - YES + DEBUG-NAME - 'D' + POINTER-TYPE - CPOINTER + */ + statsg = allocMap (0, 1, 0, 0, 0, 1, 0, STATIC_NAME, 'D', CPOINTER); + + /* Data segment - internal storage segment ; + SFRSPACE - NO + FAR-SPACE - NO + PAGED - NO + DIRECT-ACCESS - YES + BIT-ACCESS - NO + CODE-ACESS - NO + DEBUG-NAME - 'E' + POINTER-TYPE - POINTER + */ + data = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER); + + /* overlay segment - same as internal storage segment ; + SFRSPACE - NO + FAR-SPACE - NO + PAGED - NO + DIRECT-ACCESS - YES + BIT-ACCESS - NO + CODE-ACESS - NO + DEBUG-NAME - 'E' + POINTER-TYPE - POINTER + */ + overlay = allocMap (0, 0, 0, 1, 0, 0, options.data_loc, DATA_NAME, 'E', POINTER); + + /* Xternal Data segment - + SFRSPACE - NO + FAR-SPACE - YES + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACESS - NO + DEBUG-NAME - 'F' + POINTER-TYPE - FPOINTER + */ + xdata = allocMap (0, 1, 0, 0, 0, 0, options.xdata_loc, XDATA_NAME, 'F', FPOINTER); + + /* Inderectly addressed internal data segment + SFRSPACE - NO + FAR-SPACE - NO + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACESS - NO + DEBUG-NAME - 'G' + POINTER-TYPE - IPOINTER + */ + idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc, IDATA_NAME, 'G', IPOINTER); + + /* Static segment (code for variables ); + SFRSPACE - NO + FAR-SPACE - NO + PAGED - NO + DIRECT-ACCESS - YES + BIT-ACCESS - YES + CODE-ACESS - NO + DEBUG-NAME - 'H' + POINTER-TYPE - _NONE_ + */ + bit = allocMap (0, 0, 0, 1, 1, 0, 0, BIT_NAME, 'H', 0); + + /* Special function register space :- + SFRSPACE - YES + FAR-SPACE - NO + PAGED - NO + DIRECT-ACCESS - YES + BIT-ACCESS - NO + CODE-ACESS - NO + DEBUG-NAME - 'I' + POINTER-TYPE - _NONE_ + */ + sfr = allocMap (1, 0, 0, 1, 0, 0, 0, REG_NAME, 'I', 0); + + /* Register space ; + SFRSPACE - YES + FAR-SPACE - NO + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACESS - NO + DEBUG-NAME - ' ' + POINTER-TYPE - _NONE_ + */ + reg = allocMap (1, 0, 0, 0, 0, 0, 0, REG_NAME, ' ', 0); + + /* SFR bit space + SFRSPACE - YES + FAR-SPACE - NO + PAGED - NO + DIRECT-ACCESS - YES + BIT-ACCESS - YES + CODE-ACESS - NO + DEBUG-NAME - 'J' + POINTER-TYPE - _NONE_ + */ + sfrbit = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, 'J', 0); + + /* EEPROM bit space + SFRSPACE - NO + FAR-SPACE - YES + PAGED - NO + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACESS - NO + DEBUG-NAME - 'K' + POINTER-TYPE - EEPPOINTER + */ + eeprom = allocMap (0, 1, 0, 0, 0, 0, 0, REG_NAME, 'K', EEPPOINTER); + + /* the unknown map */ + generic = allocMap (1, 0, 0, 1, 1, 0, 0, REG_NAME, ' ', GPOINTER); + } /*-----------------------------------------------------------------*/ /* allocIntoSeg - puts a symbol into a memory segment */ /*-----------------------------------------------------------------*/ -void allocIntoSeg (symbol *sym) +void +allocIntoSeg (symbol * sym) { - memmap *segment = SPEC_OCLS(sym->etype); - addSet (&segment->syms,sym); + memmap *segment = SPEC_OCLS (sym->etype); + addSet (&segment->syms, sym); } /*-----------------------------------------------------------------*/ -/* allocGlobal - aassigns the output segment to a global var */ +/* allocGlobal - aassigns the output segment to a global var */ /*-----------------------------------------------------------------*/ -void allocGlobal ( symbol *sym ) +void +allocGlobal (symbol * sym) { - - /* symbol name is internal name */ - if (!sym->level) /* local statics can come here */ - sprintf (sym->rname,"%s%s", port->fun_prefix, sym->name); - - /* add it to the operandKey reset */ - addSet(&operKeyReset,sym); - - /* if this is a literal e.g. enumerated type */ - /* put it in the data segment & do nothing */ - if (IS_LITERAL(sym->etype)) { - SPEC_OCLS(sym->etype) = data ; - return ; - } - - /* if this is a function then assign code space */ - if (IS_FUNC(sym->type)) { - SPEC_OCLS(sym->etype) = code ; - /* if this is an interrupt service routine - then put it in the interrupt service array */ - if (IS_ISR(sym->etype)) { - - if (interrupts[SPEC_INTN(sym->etype)]) - werror(E_INT_DEFINED, - SPEC_INTN(sym->etype), - interrupts[SPEC_INTN(sym->etype)]->name); - else - interrupts[SPEC_INTN(sym->etype)] = sym; - - /* automagically extend the maximum interrupts */ - if (SPEC_INTN(sym->etype) >= maxInterrupts ) - maxInterrupts = SPEC_INTN(sym->etype) + 1; - } - /* if it is not compiler defined */ - if (!sym->cdef) - allocIntoSeg(sym); - - return ; - } - - /* if this is a SFR or SBIT */ - if ( SPEC_SCLS(sym->etype) == S_SFR || - SPEC_SCLS(sym->etype) == S_SBIT ) { - - /* if both absolute address & initial */ - /* value specified then error */ - if ( IS_ABSOLUTE (sym->etype) && sym->ival ) { - werror(E_SFR_INIT,sym->name); - sym->ival = NULL ; + + /* symbol name is internal name */ + if (!sym->level) /* local statics can come here */ + sprintf (sym->rname, "%s%s", port->fun_prefix, sym->name); + + /* add it to the operandKey reset */ + addSet (&operKeyReset, sym); + + /* if this is a literal e.g. enumerated type */ + /* put it in the data segment & do nothing */ + if (IS_LITERAL (sym->etype)) + { + SPEC_OCLS (sym->etype) = data; + return; + } + + /* if this is a function then assign code space */ + if (IS_FUNC (sym->type)) + { + SPEC_OCLS (sym->etype) = code; + /* if this is an interrupt service routine + then put it in the interrupt service array */ + if (IS_ISR (sym->etype)) + { + + if (interrupts[SPEC_INTN (sym->etype)]) + werror (E_INT_DEFINED, + SPEC_INTN (sym->etype), + interrupts[SPEC_INTN (sym->etype)]->name); + else + interrupts[SPEC_INTN (sym->etype)] = sym; + + /* automagically extend the maximum interrupts */ + if (SPEC_INTN (sym->etype) >= maxInterrupts) + maxInterrupts = SPEC_INTN (sym->etype) + 1; } - - SPEC_OCLS(sym->etype) = - (SPEC_SCLS(sym->etype) == S_SFR ? sfr : sfrbit); - + /* if it is not compiler defined */ + if (!sym->cdef) allocIntoSeg (sym); - return ; + + return; } - - /* if this is a bit variable and no storage class */ - if ( SPEC_NOUN(sym->etype) == V_BIT - && SPEC_SCLS(sym->etype) == S_BIT ) { - SPEC_OCLS(sym->etype) = bit ; - allocIntoSeg (sym); - return ; - } - - /* if bit storage class */ - if ( SPEC_SCLS(sym->etype) == S_SBIT ) { - SPEC_OCLS(sym->etype) = bit; - allocIntoSeg(sym); - return ; - } - - /* register storage class ignored changed to FIXED */ - if ( SPEC_SCLS(sym->etype) == S_REGISTER ) - SPEC_SCLS(sym->etype) = S_FIXED ; - - /* if data specified then */ - if (SPEC_SCLS(sym->etype) == S_DATA) { - /* set the output class */ - SPEC_OCLS(sym->etype) = data ; - /* generate the symbol */ - allocIntoSeg (sym) ; - return ; - } - - /* if it is fixed, then allocate depending on the */ - /* current memory model,same for automatics */ - if ( SPEC_SCLS(sym->etype) == S_FIXED || - SPEC_SCLS(sym->etype) == S_AUTO ) { - /* set the output class */ - SPEC_OCLS(sym->etype) = port->mem.default_globl_map ; - /* generate the symbol */ - allocIntoSeg (sym) ; - return ; - } - - /* if code change to constant */ - if ( SPEC_SCLS(sym->etype) == S_CODE || - SPEC_SCLS(sym->etype) == S_CONSTANT ) { - SPEC_OCLS(sym->etype) = statsg ; - allocIntoSeg (sym) ; - return ; - } - - if ( SPEC_SCLS(sym->etype) == S_XDATA ) { - SPEC_OCLS(sym->etype) = xdata ; - allocIntoSeg(sym) ; - return ; - } - - if ( SPEC_SCLS(sym->etype) == S_IDATA ) { - SPEC_OCLS(sym->etype) = idata ; - sym->iaccess = 1; - allocIntoSeg (sym) ; - return ; - } - - if ( SPEC_SCLS(sym->etype) == S_EEPROM ) { - SPEC_OCLS(sym->etype) = eeprom ; - allocIntoSeg (sym) ; - return ; - } - - return ; + + /* if this is a SFR or SBIT */ + if (SPEC_SCLS (sym->etype) == S_SFR || + SPEC_SCLS (sym->etype) == S_SBIT) + { + + /* if both absolute address & initial */ + /* value specified then error */ + if (IS_ABSOLUTE (sym->etype) && sym->ival) + { + werror (E_SFR_INIT, sym->name); + sym->ival = NULL; + } + + SPEC_OCLS (sym->etype) = + (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit); + + allocIntoSeg (sym); + return; + } + + /* if this is a bit variable and no storage class */ + if (SPEC_NOUN (sym->etype) == V_BIT + && SPEC_SCLS (sym->etype) == S_BIT) + { + SPEC_OCLS (sym->etype) = bit; + allocIntoSeg (sym); + return; + } + + /* if bit storage class */ + if (SPEC_SCLS (sym->etype) == S_SBIT) + { + SPEC_OCLS (sym->etype) = bit; + allocIntoSeg (sym); + return; + } + + /* register storage class ignored changed to FIXED */ + if (SPEC_SCLS (sym->etype) == S_REGISTER) + SPEC_SCLS (sym->etype) = S_FIXED; + + /* if data specified then */ + if (SPEC_SCLS (sym->etype) == S_DATA) + { + /* set the output class */ + SPEC_OCLS (sym->etype) = data; + /* generate the symbol */ + allocIntoSeg (sym); + return; + } + + /* if it is fixed, then allocate depending on the */ + /* current memory model,same for automatics */ + if (SPEC_SCLS (sym->etype) == S_FIXED || + SPEC_SCLS (sym->etype) == S_AUTO) + { + /* set the output class */ + SPEC_OCLS (sym->etype) = port->mem.default_globl_map; + /* generate the symbol */ + allocIntoSeg (sym); + return; + } + + /* if code change to constant */ + if (SPEC_SCLS (sym->etype) == S_CODE || + SPEC_SCLS (sym->etype) == S_CONSTANT) + { + SPEC_OCLS (sym->etype) = statsg; + allocIntoSeg (sym); + return; + } + + if (SPEC_SCLS (sym->etype) == S_XDATA) + { + SPEC_OCLS (sym->etype) = xdata; + allocIntoSeg (sym); + return; + } + + if (SPEC_SCLS (sym->etype) == S_IDATA) + { + SPEC_OCLS (sym->etype) = idata; + sym->iaccess = 1; + allocIntoSeg (sym); + return; + } + + if (SPEC_SCLS (sym->etype) == S_EEPROM) + { + SPEC_OCLS (sym->etype) = eeprom; + allocIntoSeg (sym); + return; + } + + return; } /*-----------------------------------------------------------------*/ -/* allocParms - parameters are always passed on stack */ +/* allocParms - parameters are always passed on stack */ /*-----------------------------------------------------------------*/ -void allocParms ( value *val ) +void +allocParms (value * val) { - value *lval ; - int pNum = 1; - - for ( lval = val ; lval ; lval = lval->next, pNum++ ) { - - /* check the declaration */ - checkDecl (lval->sym); - - /* if this a register parm then allocate - it as a local variable by adding it - to the first block we see in the body */ - if (IS_REGPARM(lval->etype)) - continue ; - - /* mark it as my parameter */ - lval->sym->ismyparm = 1; - lval->sym->localof = currFunc; - - - /* if automatic variables r 2b stacked */ - if ( options.stackAuto || IS_RENT(currFunc->etype)) { - - if (lval->sym) - lval->sym->onStack = 1; - - /* choose which stack 2 use */ - /* use xternal stack */ - if ( options.useXstack ) { - /* PENDING: stack direction support */ - SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = xstack ; - SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack = - xstackPtr - getSize(lval->type); - xstackPtr -= getSize (lval->type); + value *lval; + int pNum = 1; + + for (lval = val; lval; lval = lval->next, pNum++) + { + + /* check the declaration */ + checkDecl (lval->sym); + + /* if this a register parm then allocate + it as a local variable by adding it + to the first block we see in the body */ + if (IS_REGPARM (lval->etype)) + continue; + + /* mark it as my parameter */ + lval->sym->ismyparm = 1; + lval->sym->localof = currFunc; + + + /* if automatic variables r 2b stacked */ + if (options.stackAuto || IS_RENT (currFunc->etype)) + { + + if (lval->sym) + lval->sym->onStack = 1; + + /* choose which stack 2 use */ + /* use xternal stack */ + if (options.useXstack) + { + /* PENDING: stack direction support */ + SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack; + SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack = + xstackPtr - getSize (lval->type); + xstackPtr -= getSize (lval->type); } - else { /* use internal stack */ - SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = istack ; - if (port->stack.direction > 0) { - SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack = - stackPtr - ( SPEC_BANK(currFunc->etype) ? port->stack.bank_overhead : 0) - - getSize(lval->type) - - (IS_ISR(currFunc->etype) ? port->stack.isr_overhead : 0); - stackPtr -= getSize (lval->type); + else + { /* use internal stack */ + SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = istack; + if (port->stack.direction > 0) + { + SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack = + stackPtr - (SPEC_BANK (currFunc->etype) ? port->stack.bank_overhead : 0) - + getSize (lval->type) - + (IS_ISR (currFunc->etype) ? port->stack.isr_overhead : 0); + stackPtr -= getSize (lval->type); + } + else + { + /* This looks like the wrong order but it turns out OK... */ + /* PENDING: isr, bank overhead, ... */ + SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack = + stackPtr + + (IS_BANKEDCALL (currFunc->etype) ? port->stack.banked_overhead : 0) + + (IS_ISR (currFunc->etype) ? port->stack.isr_overhead : 0) + + 0; + stackPtr += getSize (lval->type); } - else { - /* This looks like the wrong order but it turns out OK... */ - /* PENDING: isr, bank overhead, ... */ - SPEC_STAK(lval->etype) = SPEC_STAK(lval->sym->etype) = lval->sym->stack = - stackPtr + - (IS_BANKEDCALL(currFunc->etype) ? port->stack.banked_overhead : 0) + - (IS_ISR(currFunc->etype) ? port->stack.isr_overhead : 0) + - 0; - stackPtr += getSize (lval->type); - } } - allocIntoSeg(lval->sym); + allocIntoSeg (lval->sym); } - else { /* allocate them in the automatic space */ - /* generate a unique name */ - sprintf (lval->sym->rname,"%s%s_PARM_%d", port->fun_prefix, currFunc->name,pNum); - strcpy (lval->name,lval->sym->rname); - - /* if declared in external storage */ - if (SPEC_SCLS(lval->etype) == S_XDATA) - SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = xdata; - else - /* other wise depending on the memory model - note here that we put it into the overlay segment - first, we will remove it from the overlay segment - after the overlay determination has been done */ - if (options.model == MODEL_SMALL) { - SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = - ( options.model == MODEL_SMALL ? port->mem.default_local_map : - (options.noOverlay ? port->mem.default_local_map - :overlay )); - } else { - SPEC_SCLS(lval->etype) = S_XDATA; - SPEC_OCLS(lval->etype) = SPEC_OCLS(lval->sym->etype) = xdata; - } - allocIntoSeg(lval->sym); + else + { /* allocate them in the automatic space */ + /* generate a unique name */ + sprintf (lval->sym->rname, "%s%s_PARM_%d", port->fun_prefix, currFunc->name, pNum); + strcpy (lval->name, lval->sym->rname); + + /* if declared in external storage */ + if (SPEC_SCLS (lval->etype) == S_XDATA) + SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata; + else + /* other wise depending on the memory model + note here that we put it into the overlay segment + first, we will remove it from the overlay segment + after the overlay determination has been done */ + if (options.model == MODEL_SMALL) + { + SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = + (options.model == MODEL_SMALL ? port->mem.default_local_map : + (options.noOverlay ? port->mem.default_local_map + : overlay)); + } + else + { + SPEC_SCLS (lval->etype) = S_XDATA; + SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xdata; + } + allocIntoSeg (lval->sym); } } - - return ; + + return; } /*-----------------------------------------------------------------*/ -/* deallocParms - parameters are always passed on stack */ +/* deallocParms - parameters are always passed on stack */ /*-----------------------------------------------------------------*/ -void deallocParms ( value *val ) +void +deallocParms (value * val) { - value *lval ; - - for ( lval = val ; lval ; lval = lval->next ) { - - /* unmark is myparm */ - lval->sym->ismyparm = 0; - /* if on stack then depending on which stack */ - - /* delete it from the symbol table */ - deleteSym (SymbolTab,lval->sym,lval->sym->name); - - if (!lval->sym->isref) { - lval->sym->allocreq = 1; - werror(W_NO_REFERENCE,currFunc->name, - "function argument",lval->sym->name); + value *lval; + + for (lval = val; lval; lval = lval->next) + { + + /* unmark is myparm */ + lval->sym->ismyparm = 0; + /* if on stack then depending on which stack */ + + /* delete it from the symbol table */ + deleteSym (SymbolTab, lval->sym, lval->sym->name); + + if (!lval->sym->isref) + { + lval->sym->allocreq = 1; + werror (W_NO_REFERENCE, currFunc->name, + "function argument", lval->sym->name); } - /* move the rname if any to the name for both val & sym */ - /* and leave a copy of it in the symbol table */ - if (lval->sym->rname[0]) { - char buffer[SDCC_NAME_MAX]; - strcpy(buffer,lval->sym->rname); - lval->sym = copySymbol(lval->sym); - strcpy(lval->sym->rname,buffer); - strcpy(lval->name,strcpy(lval->sym->name,lval->sym->rname)); - addSym (SymbolTab, lval->sym, lval->sym->name, - lval->sym->level,lval->sym->block); - lval->sym->_isparm = 1; - addSet(&operKeyReset,lval->sym); + /* move the rname if any to the name for both val & sym */ + /* and leave a copy of it in the symbol table */ + if (lval->sym->rname[0]) + { + char buffer[SDCC_NAME_MAX]; + strcpy (buffer, lval->sym->rname); + lval->sym = copySymbol (lval->sym); + strcpy (lval->sym->rname, buffer); + strcpy (lval->name, strcpy (lval->sym->name, lval->sym->rname)); + addSym (SymbolTab, lval->sym, lval->sym->name, + lval->sym->level, lval->sym->block); + lval->sym->_isparm = 1; + addSet (&operKeyReset, lval->sym); } } - - return ; + + return; } /*-----------------------------------------------------------------*/ -/* allocLocal - allocate local variables */ -/*-----------------------------------------------------------------*/ -void allocLocal ( symbol *sym ) -{ - - /* generate an unique name */ - sprintf(sym->rname,"%s%s_%s_%d_%d", - port->fun_prefix, - currFunc->name,sym->name,sym->level,sym->block); - - sym->islocal = 1; - sym->localof = currFunc; - - /* if this is a static variable */ - if ( IS_STATIC (sym->etype)) { - allocGlobal(sym); - sym->allocreq = 1; - return ; - } - - /* if volatile then */ - if (IS_VOLATILE(sym->etype)) - sym->allocreq = 1; - - /* this is automatic */ - - /* if it to be placed on the stack */ - if ( options.stackAuto || reentrant) { - - sym->onStack = 1; - if ( options.useXstack ) { - /* PENDING: stack direction for xstack */ - SPEC_OCLS(sym->etype) = xstack ; - SPEC_STAK(sym->etype) = sym->stack = (xstackPtr + 1); - xstackPtr += getSize (sym->type) ; +/* allocLocal - allocate local variables */ +/*-----------------------------------------------------------------*/ +void +allocLocal (symbol * sym) +{ + + /* generate an unique name */ + sprintf (sym->rname, "%s%s_%s_%d_%d", + port->fun_prefix, + currFunc->name, sym->name, sym->level, sym->block); + + sym->islocal = 1; + sym->localof = currFunc; + + /* if this is a static variable */ + if (IS_STATIC (sym->etype)) + { + allocGlobal (sym); + sym->allocreq = 1; + return; + } + + /* if volatile then */ + if (IS_VOLATILE (sym->etype)) + sym->allocreq = 1; + + /* this is automatic */ + + /* if it to be placed on the stack */ + if (options.stackAuto || reentrant) + { + + sym->onStack = 1; + if (options.useXstack) + { + /* PENDING: stack direction for xstack */ + SPEC_OCLS (sym->etype) = xstack; + SPEC_STAK (sym->etype) = sym->stack = (xstackPtr + 1); + xstackPtr += getSize (sym->type); } - else { - SPEC_OCLS(sym->etype) = istack ; - if (port->stack.direction > 0) { - SPEC_STAK(sym->etype) = sym->stack = ( stackPtr + 1); - stackPtr += getSize (sym->type) ; + else + { + SPEC_OCLS (sym->etype) = istack; + if (port->stack.direction > 0) + { + SPEC_STAK (sym->etype) = sym->stack = (stackPtr + 1); + stackPtr += getSize (sym->type); } - else { - stackPtr -= getSize (sym->type); - SPEC_STAK(sym->etype) = sym->stack = stackPtr; + else + { + stackPtr -= getSize (sym->type); + SPEC_STAK (sym->etype) = sym->stack = stackPtr; } } - allocIntoSeg(sym); - return ; - } - - /* else depending on the storage class specified */ - if ( SPEC_SCLS(sym->etype) == S_XDATA ) { - SPEC_OCLS(sym->etype) = xdata ; - allocIntoSeg(sym) ; - return ; - } - - if ( (SPEC_SCLS(sym->etype) == S_CODE || - SPEC_SCLS(sym->etype) == S_CONSTANT) && - !sym->_isparm) { - SPEC_OCLS(sym->etype) = statsg ; - allocIntoSeg (sym) ; - return ; - } - - if ( SPEC_SCLS(sym->etype) == S_IDATA ) { - SPEC_OCLS(sym->etype) = idata ; - sym->iaccess = 1; - allocIntoSeg (sym) ; - return ; - } - - /* if this is a function then assign code space */ - if (IS_FUNC(sym->type)) { - SPEC_OCLS(sym->etype) = code ; - return ; - } - - /* if this is a SFR or SBIT */ - if ( SPEC_SCLS(sym->etype) == S_SFR || - SPEC_SCLS(sym->etype) == S_SBIT ) { - - /* if both absolute address & initial */ - /* value specified then error */ - if ( IS_ABSOLUTE (sym->etype) && sym->ival ) { - werror(E_SFR_INIT,sym->name); - sym->ival = NULL ; + allocIntoSeg (sym); + return; + } + + /* else depending on the storage class specified */ + if (SPEC_SCLS (sym->etype) == S_XDATA) + { + SPEC_OCLS (sym->etype) = xdata; + allocIntoSeg (sym); + return; + } + + if ((SPEC_SCLS (sym->etype) == S_CODE || + SPEC_SCLS (sym->etype) == S_CONSTANT) && + !sym->_isparm) + { + SPEC_OCLS (sym->etype) = statsg; + allocIntoSeg (sym); + return; + } + + if (SPEC_SCLS (sym->etype) == S_IDATA) + { + SPEC_OCLS (sym->etype) = idata; + sym->iaccess = 1; + allocIntoSeg (sym); + return; + } + + /* if this is a function then assign code space */ + if (IS_FUNC (sym->type)) + { + SPEC_OCLS (sym->etype) = code; + return; + } + + /* if this is a SFR or SBIT */ + if (SPEC_SCLS (sym->etype) == S_SFR || + SPEC_SCLS (sym->etype) == S_SBIT) + { + + /* if both absolute address & initial */ + /* value specified then error */ + if (IS_ABSOLUTE (sym->etype) && sym->ival) + { + werror (E_SFR_INIT, sym->name); + sym->ival = NULL; } - - SPEC_OCLS(sym->etype) = - (SPEC_SCLS(sym->etype) == S_SFR ? sfr : sfrbit); - - allocIntoSeg (sym); - return ; + + SPEC_OCLS (sym->etype) = + (SPEC_SCLS (sym->etype) == S_SFR ? sfr : sfrbit); + + allocIntoSeg (sym); + return; } - - /* if this is a bit variable and no storage class */ - if ( SPEC_NOUN(sym->etype) == V_BIT - && (SPEC_SCLS(sym->etype) == S_BIT)) { - SPEC_OCLS(sym->etype) = bit ; - allocIntoSeg (sym); - return ; + + /* if this is a bit variable and no storage class */ + if (SPEC_NOUN (sym->etype) == V_BIT + && (SPEC_SCLS (sym->etype) == S_BIT)) + { + SPEC_OCLS (sym->etype) = bit; + allocIntoSeg (sym); + return; } - if ( SPEC_SCLS(sym->etype) == S_DATA ) { - SPEC_OCLS(sym->etype) = (options.noOverlay ? data : overlay ); - allocIntoSeg(sym) ; - return ; + if (SPEC_SCLS (sym->etype) == S_DATA) + { + SPEC_OCLS (sym->etype) = (options.noOverlay ? data : overlay); + allocIntoSeg (sym); + return; } - if ( SPEC_SCLS(sym->etype) == S_EEPROM ) { - SPEC_OCLS(sym->etype) = eeprom; - allocIntoSeg(sym) ; - return ; + if (SPEC_SCLS (sym->etype) == S_EEPROM) + { + SPEC_OCLS (sym->etype) = eeprom; + allocIntoSeg (sym); + return; } - - /* again note that we have put it into the overlay segment - will remove and put into the 'data' segment if required after - overlay analysis has been done */ - SPEC_OCLS(sym->etype) = ( options.model == MODEL_SMALL ? port->mem.default_local_map : - (options.noOverlay ? port->mem.default_local_map - : overlay )) ; - allocIntoSeg (sym); + + /* again note that we have put it into the overlay segment + will remove and put into the 'data' segment if required after + overlay analysis has been done */ + SPEC_OCLS (sym->etype) = (options.model == MODEL_SMALL ? port->mem.default_local_map : + (options.noOverlay ? port->mem.default_local_map + : overlay)); + allocIntoSeg (sym); } /*-----------------------------------------------------------------*/ /* deallocLocal - deallocates the local variables */ /*-----------------------------------------------------------------*/ -void deallocLocal ( symbol *csym ) +void +deallocLocal (symbol * csym) { - symbol *sym ; - - for ( sym = csym ; sym ; sym = sym->next) { - if (sym->_isparm) - continue ; - - /* if it is on the stack */ - if (sym->onStack) { - if (options.useXstack) - xstackPtr -= getSize(sym->type); - else - stackPtr -= getSize(sym->type); + symbol *sym; + + for (sym = csym; sym; sym = sym->next) + { + if (sym->_isparm) + continue; + + /* if it is on the stack */ + if (sym->onStack) + { + if (options.useXstack) + xstackPtr -= getSize (sym->type); + else + stackPtr -= getSize (sym->type); } - /* if not used give a warning */ - if (!sym->isref && !IS_STATIC(sym->etype)) - werror(W_NO_REFERENCE,currFunc->name, - "local variable",sym->name); - /* now delete it from the symbol table */ - deleteSym (SymbolTab,sym,sym->name); + /* if not used give a warning */ + if (!sym->isref && !IS_STATIC (sym->etype)) + werror (W_NO_REFERENCE, currFunc->name, + "local variable", sym->name); + /* now delete it from the symbol table */ + deleteSym (SymbolTab, sym, sym->name); } } /*-----------------------------------------------------------------*/ /* overlay2data - moves declarations from the overlay seg to data */ /*-----------------------------------------------------------------*/ -void overlay2data() +void +overlay2data () { - symbol *sym; + symbol *sym; - for (sym = setFirstItem(overlay->syms); sym; - sym = setNextItem(overlay->syms)) { + for (sym = setFirstItem (overlay->syms); sym; + sym = setNextItem (overlay->syms)) + { - SPEC_OCLS(sym->etype) = data; - allocIntoSeg(sym); + SPEC_OCLS (sym->etype) = data; + allocIntoSeg (sym); } - setToNull((void **) &overlay->syms); - + setToNull ((void **) &overlay->syms); + } /*-----------------------------------------------------------------*/ /* overlay2Set - will add all symbols from the overlay segment to */ /* the set of sets containing the overlable symbols */ /*-----------------------------------------------------------------*/ -void overlay2Set () +void +overlay2Set () { - symbol *sym; - set *oset = NULL; + symbol *sym; + set *oset = NULL; - for (sym = setFirstItem(overlay->syms); sym; - sym = setNextItem(overlay->syms)) { + for (sym = setFirstItem (overlay->syms); sym; + sym = setNextItem (overlay->syms)) + { - addSet(&oset,sym); + addSet (&oset, sym); } - - setToNull((void **) &overlay->syms); - addSet (&ovrSetSets,oset); + + setToNull ((void **) &overlay->syms); + addSet (&ovrSetSets, oset); } /*-----------------------------------------------------------------*/ /* allocVariables - creates decl & assign storage class for a v */ /*-----------------------------------------------------------------*/ -int allocVariables ( symbol *symChain ) +int +allocVariables (symbol * symChain) { - symbol *sym; - symbol *csym; - int stack = 0; - int saveLevel = 0 ; - - /* go thru the symbol chain */ - for ( sym = symChain ; sym ; sym = sym->next ) { - - /* if this is a typedef then add it */ - /* to the typedef table */ - if (IS_TYPEDEF(sym->etype)) { - /* check if the typedef already exists */ - csym = findSym (TypedefTab, NULL, sym->name ); - if ( csym && csym->level == sym->level ) - werror(E_DUPLICATE_TYPEDEF,sym->name); - - addSym (TypedefTab, sym , sym->name,sym->level,sym->block); - continue ; /* go to the next one */ + symbol *sym; + symbol *csym; + int stack = 0; + int saveLevel = 0; + + /* go thru the symbol chain */ + for (sym = symChain; sym; sym = sym->next) + { + + /* if this is a typedef then add it */ + /* to the typedef table */ + if (IS_TYPEDEF (sym->etype)) + { + /* check if the typedef already exists */ + csym = findSym (TypedefTab, NULL, sym->name); + if (csym && csym->level == sym->level) + werror (E_DUPLICATE_TYPEDEF, sym->name); + + addSym (TypedefTab, sym, sym->name, sym->level, sym->block); + continue; /* go to the next one */ } - /* make sure it already exist */ - csym = findSymWithLevel (SymbolTab, sym); - if (! csym || (csym && csym->level != sym->level) ) - csym = sym; - - /* check the declaration */ - checkDecl (csym); - - /* if this is a function or a pointer to function */ - /* then args processing */ - if (funcInChain(csym->type)) { - - processFuncArgs (csym, 1); - /* if register bank specified then update maxRegBank */ - if (maxRegBank < SPEC_BANK(csym->etype)) - maxRegBank = SPEC_BANK(csym->etype); + /* make sure it already exist */ + csym = findSymWithLevel (SymbolTab, sym); + if (!csym || (csym && csym->level != sym->level)) + csym = sym; + + /* check the declaration */ + checkDecl (csym); + + /* if this is a function or a pointer to function */ + /* then args processing */ + if (funcInChain (csym->type)) + { + + processFuncArgs (csym, 1); + /* if register bank specified then update maxRegBank */ + if (maxRegBank < SPEC_BANK (csym->etype)) + maxRegBank = SPEC_BANK (csym->etype); } - - /* if this is a extern variable then change the */ - /* level to zero temporarily */ - if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type) ) { - saveLevel = csym->level ; - csym->level = 0 ; + + /* if this is a extern variable then change the */ + /* level to zero temporarily */ + if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type)) + { + saveLevel = csym->level; + csym->level = 0; } - - /* if this is a literal then it is an enumerated */ - /* type so need not allocate it space for it */ - if (IS_LITERAL(sym->etype)) - continue ; - - /* generate the actual declaration */ - if ( csym->level ) { - allocLocal (csym); - if (csym->onStack) - stack += getSize(csym->type) ; + + /* if this is a literal then it is an enumerated */ + /* type so need not allocate it space for it */ + if (IS_LITERAL (sym->etype)) + continue; + + /* generate the actual declaration */ + if (csym->level) + { + allocLocal (csym); + if (csym->onStack) + stack += getSize (csym->type); } - else - allocGlobal (csym); + else + allocGlobal (csym); - /* restore the level */ - if (IS_EXTERN(csym->etype) || IS_FUNC(csym->type)) - csym->level = saveLevel; + /* restore the level */ + if (IS_EXTERN (csym->etype) || IS_FUNC (csym->type)) + csym->level = saveLevel; } - - return stack ; + + return stack; } /*-----------------------------------------------------------------*/ /* redoStackOffsets :- will reassign the values for stack offsets */ /*-----------------------------------------------------------------*/ -void redoStackOffsets(void) +void +redoStackOffsets (void) { - symbol *sym; - int sPtr = 0; - int xsPtr=-1; - - /* after register allocation is complete we know - which variables will need to be assigned space - on the stack. We will eliminate those variables - which do not have the allocReq flag thus reducing - the stack space */ - for ( sym = setFirstItem(istack->syms); sym; - sym = setNextItem(istack->syms)) { - - int size = getSize(sym->type); - /* nothing to do with parameters so continue */ - if ((sym->_isparm && !IS_REGPARM(sym->etype))) - continue ; - - if ( IS_AGGREGATE(sym->type)) { - if (port->stack.direction > 0) { - SPEC_STAK(sym->etype) = sym->stack = ( sPtr + 1); - sPtr += size; + symbol *sym; + int sPtr = 0; + int xsPtr = -1; + + /* after register allocation is complete we know + which variables will need to be assigned space + on the stack. We will eliminate those variables + which do not have the allocReq flag thus reducing + the stack space */ + for (sym = setFirstItem (istack->syms); sym; + sym = setNextItem (istack->syms)) + { + + int size = getSize (sym->type); + /* nothing to do with parameters so continue */ + if ((sym->_isparm && !IS_REGPARM (sym->etype))) + continue; + + if (IS_AGGREGATE (sym->type)) + { + if (port->stack.direction > 0) + { + SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1); + sPtr += size; } - else { - sPtr -= size; - SPEC_STAK(sym->etype) = sym->stack = sPtr; + else + { + sPtr -= size; + SPEC_STAK (sym->etype) = sym->stack = sPtr; } - continue; + continue; } - /* if allocation not required then subtract - size from overall stack size & continue */ - if (!sym->allocreq) { - currFunc->stack -= size; - SPEC_STAK(currFunc->etype) -= size; - continue ; + /* if allocation not required then subtract + size from overall stack size & continue */ + if (!sym->allocreq) + { + currFunc->stack -= size; + SPEC_STAK (currFunc->etype) -= size; + continue; } - if (port->stack.direction > 0) { - SPEC_STAK(sym->etype) = sym->stack = ( sPtr + 1); - sPtr += size ; + if (port->stack.direction > 0) + { + SPEC_STAK (sym->etype) = sym->stack = (sPtr + 1); + sPtr += size; } - else { - sPtr -= size ; - SPEC_STAK(sym->etype) = sym->stack = sPtr; + else + { + sPtr -= size; + SPEC_STAK (sym->etype) = sym->stack = sPtr; } } - /* do the same for the external stack */ - - for ( sym = setFirstItem(xstack->syms); sym; - sym = setNextItem(xstack->syms)) { - - int size = getSize(sym->type); - /* nothing to do with parameters so continue */ - if ((sym->_isparm && !IS_REGPARM(sym->etype))) - continue ; - - if (IS_AGGREGATE(sym->type)) { - SPEC_STAK(sym->etype) = sym->stack = ( xsPtr + 1); - xsPtr += size ; - continue ; - } - - /* if allocation not required then subtract - size from overall stack size & continue */ - if (!sym->allocreq) { - currFunc->xstack -= size; - SPEC_STAK(currFunc->etype) -= size; - continue ; + /* do the same for the external stack */ + + for (sym = setFirstItem (xstack->syms); sym; + sym = setNextItem (xstack->syms)) + { + + int size = getSize (sym->type); + /* nothing to do with parameters so continue */ + if ((sym->_isparm && !IS_REGPARM (sym->etype))) + continue; + + if (IS_AGGREGATE (sym->type)) + { + SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1); + xsPtr += size; + continue; } - SPEC_STAK(sym->etype) = sym->stack = ( xsPtr + 1); - xsPtr += size ; - } + /* if allocation not required then subtract + size from overall stack size & continue */ + if (!sym->allocreq) + { + currFunc->xstack -= size; + SPEC_STAK (currFunc->etype) -= size; + continue; + } - /* if the debug option is set then output the - symbols to the map file */ - if (options.debug && !options.nodebug) { - for (sym = setFirstItem(istack->syms); sym; - sym = setNextItem(istack->syms)) - cdbSymbol(sym,cdbFile,FALSE,FALSE); + SPEC_STAK (sym->etype) = sym->stack = (xsPtr + 1); + xsPtr += size; + } - for (sym = setFirstItem(xstack->syms); sym; - sym = setNextItem(xstack->syms)) - cdbSymbol(sym,cdbFile,FALSE,FALSE); + /* if the debug option is set then output the + symbols to the map file */ + if (options.debug && !options.nodebug) + { + for (sym = setFirstItem (istack->syms); sym; + sym = setNextItem (istack->syms)) + cdbSymbol (sym, cdbFile, FALSE, FALSE); + + for (sym = setFirstItem (xstack->syms); sym; + sym = setNextItem (xstack->syms)) + cdbSymbol (sym, cdbFile, FALSE, FALSE); } } /*-----------------------------------------------------------------*/ /* printAllocInfoSeg- print the allocation for a given section */ /*-----------------------------------------------------------------*/ -static void printAllocInfoSeg ( memmap *map, symbol *func, FILE *of) +static void +printAllocInfoSeg (memmap * map, symbol * func, FILE * of) { - symbol *sym; - - if (!map) return; - if (!map->syms) return; - - for (sym = setFirstItem(map->syms); sym; - sym = setNextItem(map->syms)) { - - if (sym->level == 0) continue; - if (sym->localof != func) continue ; - fprintf(of,";%-25s Allocated to ",sym->name); - - /* if assigned to registers */ - if (!sym->allocreq && sym->reqv) { - int i; - sym = OP_SYMBOL(sym->reqv); - fprintf(of,"registers "); - for (i = 0 ; i < 4 && sym->regs[i] ; i++) - fprintf(of,"%s ",port->getRegName(sym->regs[i])); - fprintf(of,"\n"); - continue ; + symbol *sym; + + if (!map) + return; + if (!map->syms) + return; + + for (sym = setFirstItem (map->syms); sym; + sym = setNextItem (map->syms)) + { + + if (sym->level == 0) + continue; + if (sym->localof != func) + continue; + fprintf (of, ";%-25s Allocated to ", sym->name); + + /* if assigned to registers */ + if (!sym->allocreq && sym->reqv) + { + int i; + sym = OP_SYMBOL (sym->reqv); + fprintf (of, "registers "); + for (i = 0; i < 4 && sym->regs[i]; i++) + fprintf (of, "%s ", port->getRegName (sym->regs[i])); + fprintf (of, "\n"); + continue; } - /* if on stack */ - if (sym->onStack) { - fprintf(of,"stack - offset %d\n",sym->stack); - continue; + /* if on stack */ + if (sym->onStack) + { + fprintf (of, "stack - offset %d\n", sym->stack); + continue; } - - /* otherwise give rname */ - fprintf(of,"in memory with name '%s'\n",sym->rname); + + /* otherwise give rname */ + fprintf (of, "in memory with name '%s'\n", sym->rname); } } /*-----------------------------------------------------------------*/ /* canOverlayLocals - returns true if the local variables can overlayed */ /*-----------------------------------------------------------------*/ -static bool canOverlayLocals (eBBlock **ebbs, int count) +static bool +canOverlayLocals (eBBlock ** ebbs, int count) { - int i; - /* if staticAuto is in effect or the current function - being compiled is reentrant or the overlay segment - is empty or no overlay option is in effect then */ - if (options.noOverlay || - options.stackAuto || - (currFunc && - (IS_RENT(currFunc->etype) || - IS_ISR(currFunc->etype))) || - elementsInSet(overlay->syms) == 0) - - return FALSE; - - /* otherwise do thru the blocks and see if there - any function calls if found then return false */ - for (i = 0; i < count ; i++ ) { - iCode *ic; - - for (ic = ebbs[i]->sch; ic ; ic = ic->next) - if (ic && ( ic->op == CALL || ic->op == PCALL)) - return FALSE; - } - - /* no function calls found return TRUE */ - return TRUE; + int i; + /* if staticAuto is in effect or the current function + being compiled is reentrant or the overlay segment + is empty or no overlay option is in effect then */ + if (options.noOverlay || + options.stackAuto || + (currFunc && + (IS_RENT (currFunc->etype) || + IS_ISR (currFunc->etype))) || + elementsInSet (overlay->syms) == 0) + + return FALSE; + + /* otherwise do thru the blocks and see if there + any function calls if found then return false */ + for (i = 0; i < count; i++) + { + iCode *ic; + + for (ic = ebbs[i]->sch; ic; ic = ic->next) + if (ic && (ic->op == CALL || ic->op == PCALL)) + return FALSE; + } + + /* no function calls found return TRUE */ + return TRUE; } /*-----------------------------------------------------------------*/ /* doOverlays - move the overlay segment to appropriate location */ /*-----------------------------------------------------------------*/ -void doOverlays( eBBlock **ebbs, int count) +void +doOverlays (eBBlock ** ebbs, int count) { - /* check if the parameters and local variables - of this function can be put in the overlay segment - This check is essentially to see if the function - calls any other functions if yes then we cannot - overlay */ - if (canOverlayLocals(ebbs,count)) - /* if we can then put the parameters & - local variables in the overlay set */ - overlay2Set(); - else - /* otherwise put them into data where - they belong */ - overlay2data(); + /* check if the parameters and local variables + of this function can be put in the overlay segment + This check is essentially to see if the function + calls any other functions if yes then we cannot + overlay */ + if (canOverlayLocals (ebbs, count)) + /* if we can then put the parameters & + local variables in the overlay set */ + overlay2Set (); + else + /* otherwise put them into data where + they belong */ + overlay2data (); } /*-----------------------------------------------------------------*/ /* printAllocInfo - prints allocation information for a function */ /*-----------------------------------------------------------------*/ -void printAllocInfo( symbol * func, FILE *of) +void +printAllocInfo (symbol * func, FILE * of) { - if (!of) of = stdout; - - /* must be called after register allocation is complete */ - fprintf(of,";------------------------------------------------------------\n"); - fprintf(of,";Allocation info for local variables in function '%s'\n",func->name); - fprintf(of,";------------------------------------------------------------\n"); - - printAllocInfoSeg(xstack,func,of); - printAllocInfoSeg(istack,func,of); - printAllocInfoSeg(code,func,of); - printAllocInfoSeg(data,func,of); - printAllocInfoSeg(xdata,func,of); - printAllocInfoSeg(idata,func,of); - printAllocInfoSeg(sfr,func,of); - printAllocInfoSeg(sfrbit,func,of); + if (!of) + of = stdout; + + /* must be called after register allocation is complete */ + fprintf (of, ";------------------------------------------------------------\n"); + fprintf (of, ";Allocation info for local variables in function '%s'\n", func->name); + fprintf (of, ";------------------------------------------------------------\n"); + + printAllocInfoSeg (xstack, func, of); + printAllocInfoSeg (istack, func, of); + printAllocInfoSeg (code, func, of); + printAllocInfoSeg (data, func, of); + printAllocInfoSeg (xdata, func, of); + printAllocInfoSeg (idata, func, of); + printAllocInfoSeg (sfr, func, of); + printAllocInfoSeg (sfrbit, func, of); } diff --git a/src/SDCCmem.h b/src/SDCCmem.h index ce734cf5..11be2566 100644 --- a/src/SDCCmem.h +++ b/src/SDCCmem.h @@ -5,28 +5,30 @@ #ifndef SDCCMEM_H #define SDCCMEM_H -struct set ; -struct value ; +struct set; +struct value; struct eBBlock; -typedef struct memmap{ - unsigned char pageno; /* page no for this variable */ - const char *sname; /* character prefix for map */ - char dbName ; /* debugger address space name */ - int ptrType; /* pointer Type for this space */ - int slbl ; /* label counter for space */ - unsigned sloc ; /* starting location */ - unsigned fmap : 1; /* 1 = 16bit addressing reqd */ - unsigned paged : 1; /* this is a paged mem space */ - unsigned direct: 1; /* 1= indirect access only */ - unsigned bitsp: 1; /* 1 = bit addressable space */ - unsigned codesp:1; /* 1 = code space */ - unsigned regsp: 1; /* 1= sfr space */ - FILE *oFile ; /* object file associated */ - struct set *syms; /* symbols defined in this segment */ -} memmap ; +typedef struct memmap + { + unsigned char pageno; /* page no for this variable */ + const char *sname; /* character prefix for map */ + char dbName; /* debugger address space name */ + int ptrType; /* pointer Type for this space */ + int slbl; /* label counter for space */ + unsigned sloc; /* starting location */ + unsigned fmap:1; /* 1 = 16bit addressing reqd */ + unsigned paged:1; /* this is a paged mem space */ + unsigned direct:1; /* 1= indirect access only */ + unsigned bitsp:1; /* 1 = bit addressable space */ + unsigned codesp:1; /* 1 = code space */ + unsigned regsp:1; /* 1= sfr space */ + FILE *oFile; /* object file associated */ + struct set *syms; /* symbols defined in this segment */ + } +memmap; -extern FILE *junkFile ; +extern FILE *junkFile; /* memory map prefixes MOF added the DATA,CODE,XDATA,BIT */ #define XSTACK_NAME port->mem.xstack_name @@ -39,29 +41,29 @@ extern FILE *junkFile ; #define REG_NAME port->mem.reg_name #define STATIC_NAME port->mem.static_name #define HOME_NAME port->mem.home_name - + /* forward definition for variables */ -extern memmap *xstack; /* xternal stack data */ -extern memmap *istack; /* internal stack */ -extern memmap *code ; /* code segment */ -extern memmap *data ; /* internal data upto 128 */ -extern memmap *xdata ; /* external data */ -extern memmap *idata ; /* internal data upto 256 */ -extern memmap *bit ; /* bit addressable space */ -extern memmap *statsg; /* static code segment */ -extern memmap *sfr ; /* register space */ -extern memmap *sfrbit; /* sfr bit space */ -extern memmap *reg ; /* register space */ -extern memmap *_const; /* constant segment */ -extern memmap *generic; /* unknown */ -extern memmap *overlay; /* the overlay segment */ -extern memmap *eeprom; /* eepromp space */ -extern memmap *eeprom; /* eepromp space */ -extern memmap *home; /* Non-banked home space */ +extern memmap *xstack; /* xternal stack data */ +extern memmap *istack; /* internal stack */ +extern memmap *code; /* code segment */ +extern memmap *data; /* internal data upto 128 */ +extern memmap *xdata; /* external data */ +extern memmap *idata; /* internal data upto 256 */ +extern memmap *bit; /* bit addressable space */ +extern memmap *statsg; /* static code segment */ +extern memmap *sfr; /* register space */ +extern memmap *sfrbit; /* sfr bit space */ +extern memmap *reg; /* register space */ +extern memmap *_const; /* constant segment */ +extern memmap *generic; /* unknown */ +extern memmap *overlay; /* the overlay segment */ +extern memmap *eeprom; /* eepromp space */ +extern memmap *eeprom; /* eepromp space */ +extern memmap *home; /* Non-banked home space */ extern int fatalError; -extern struct set *ovrSetSets; +extern struct set *ovrSetSets; extern int maxRegBank; @@ -77,17 +79,17 @@ extern int maxRegBank; : GPOINTER) /* forward decls for functions */ -memmap *allocMap (char,char,char,char,char,char,unsigned, const char *,char,int ); -void initMem ( ); -void allocGlobal (struct symbol * ); -void allocLocal (struct symbol * ); -void allocParms (struct value * ); -void deallocParms (struct value * ); -void deallocLocal (struct symbol * ); -int allocVariables (struct symbol * ); -void overlay2Set ( ); -void overlay2data ( ); -void redoStackOffsets( ); -void printAllocInfo (struct symbol *, FILE * ); -void doOverlays (struct eBBlock **, int count ); +memmap *allocMap (char, char, char, char, char, char, unsigned, const char *, char, int); +void initMem (); +void allocGlobal (struct symbol *); +void allocLocal (struct symbol *); +void allocParms (struct value *); +void deallocParms (struct value *); +void deallocLocal (struct symbol *); +int allocVariables (struct symbol *); +void overlay2Set (); +void overlay2data (); +void redoStackOffsets (); +void printAllocInfo (struct symbol *, FILE *); +void doOverlays (struct eBBlock **, int count); #endif diff --git a/src/SDCCopt.c b/src/SDCCopt.c index 1f12948b..0a67c5bd 100644 --- a/src/SDCCopt.c +++ b/src/SDCCopt.c @@ -30,7 +30,7 @@ /*-----------------------------------------------------------------*/ /* global variables */ -int cseDefNum = 0 ; +int cseDefNum = 0; char flowChanged = 0; @@ -38,364 +38,416 @@ char flowChanged = 0; /*-----------------------------------------------------------------*/ /* printSymName - prints the symbol names */ /*-----------------------------------------------------------------*/ -int printSymName (void *vsym) +int +printSymName (void *vsym) { - symbol *sym = vsym ; - fprintf (stdout, " %s ", sym->name); - return 0; + symbol *sym = vsym; + fprintf (stdout, " %s ", sym->name); + return 0; } /*-----------------------------------------------------------------*/ /* cnvToFcall - does the actual conversion to function call */ /*-----------------------------------------------------------------*/ -static void cnvToFcall (iCode *ic,eBBlock *ebp) +static void +cnvToFcall (iCode * ic, eBBlock * ebp) { - iCode *ip ; - iCode *newic; - operand *left ; - operand *right; - symbol *func = NULL; - int lineno = ic->lineno; - - ip = ic->next ; /* insertion point */ - /* remove it from the iCode */ - remiCodeFromeBBlock (ebp,ic); - - left = IC_LEFT(ic); - right= IC_RIGHT(ic); - - switch (ic->op) { - case '+' : - func = __fsadd ; - break; - case '-' : - func = __fssub; - break; - case '/' : - func = __fsdiv; - break; - case '*' : - func = __fsmul; - break; - case EQ_OP : - func = __fseq; - break; - case NE_OP : - func = __fsneq ; - break; - case '<' : - func = __fslt ; - break; + iCode *ip; + iCode *newic; + operand *left; + operand *right; + symbol *func = NULL; + int lineno = ic->lineno; + + ip = ic->next; /* insertion point */ + /* remove it from the iCode */ + remiCodeFromeBBlock (ebp, ic); + + left = IC_LEFT (ic); + right = IC_RIGHT (ic); + + switch (ic->op) + { + case '+': + func = __fsadd; + break; + case '-': + func = __fssub; + break; + case '/': + func = __fsdiv; + break; + case '*': + func = __fsmul; + break; + case EQ_OP: + func = __fseq; + break; + case NE_OP: + func = __fsneq; + break; + case '<': + func = __fslt; + break; case '>': - func = __fsgt; - break; - case LE_OP : - func = __fslteq; - break; - case GE_OP : - func = __fsgteq ; - break; + func = __fsgt; + break; + case LE_OP: + func = __fslteq; + break; + case GE_OP: + func = __fsgteq; + break; } - /* if float support routines NOT compiled as reentrant */ - if (! options.float_rent) { - - /* first one */ - if (IS_REGPARM(func->args->etype)) { - newic = newiCode(SEND,IC_LEFT(ic),NULL); - } else { - newic = newiCode('=',NULL,IC_LEFT(ic)); - IC_RESULT(newic) = operandFromValue(func->args); + /* if float support routines NOT compiled as reentrant */ + if (!options.float_rent) + { + + /* first one */ + if (IS_REGPARM (func->args->etype)) + { + newic = newiCode (SEND, IC_LEFT (ic), NULL); + } + else + { + newic = newiCode ('=', NULL, IC_LEFT (ic)); + IC_RESULT (newic) = operandFromValue (func->args); } - addiCodeToeBBlock(ebp,newic,ip); - newic->lineno = lineno; + addiCodeToeBBlock (ebp, newic, ip); + newic->lineno = lineno; - /* second one */ - if (IS_REGPARM(func->args->next->etype)) { - newic = newiCode(SEND,IC_LEFT(ic),NULL); - } else { - newic = newiCode('=',NULL,IC_RIGHT(ic)); - IC_RESULT(newic) = operandFromValue(func->args->next); + /* second one */ + if (IS_REGPARM (func->args->next->etype)) + { + newic = newiCode (SEND, IC_LEFT (ic), NULL); } - addiCodeToeBBlock(ebp,newic,ip); - newic->lineno = lineno; - - } else { - - /* push right */ - if (IS_REGPARM(func->args->next->etype)) { - newic = newiCode(SEND,right,NULL); - } else { - newic = newiCode(IPUSH,right,NULL); - newic->parmPush = 1; + else + { + newic = newiCode ('=', NULL, IC_RIGHT (ic)); + IC_RESULT (newic) = operandFromValue (func->args->next); } + addiCodeToeBBlock (ebp, newic, ip); + newic->lineno = lineno; - addiCodeToeBBlock (ebp,newic,ip); - newic->lineno = lineno; + } + else + { - /* insert push left */ - if (IS_REGPARM(func->args->etype)) { - newic = newiCode(SEND,left,NULL); - } else { - newic = newiCode(IPUSH,left,NULL); - newic->parmPush = 1; + /* push right */ + if (IS_REGPARM (func->args->next->etype)) + { + newic = newiCode (SEND, right, NULL); + } + else + { + newic = newiCode (IPUSH, right, NULL); + newic->parmPush = 1; } - addiCodeToeBBlock (ebp,newic,ip); - newic->lineno = lineno; + + addiCodeToeBBlock (ebp, newic, ip); + newic->lineno = lineno; + + /* insert push left */ + if (IS_REGPARM (func->args->etype)) + { + newic = newiCode (SEND, left, NULL); + } + else + { + newic = newiCode (IPUSH, left, NULL); + newic->parmPush = 1; + } + addiCodeToeBBlock (ebp, newic, ip); + newic->lineno = lineno; } - /* insert the call */ - newic = newiCode(CALL,operandFromSymbol(func),NULL); - IC_RESULT(newic) = IC_RESULT(ic); - addiCodeToeBBlock(ebp,newic,ip); - newic->lineno = lineno; + /* insert the call */ + newic = newiCode (CALL, operandFromSymbol (func), NULL); + IC_RESULT (newic) = IC_RESULT (ic); + addiCodeToeBBlock (ebp, newic, ip); + newic->lineno = lineno; } /*-----------------------------------------------------------------*/ /* cnvToFloatCast - converts casts to floats to function calls */ /*-----------------------------------------------------------------*/ -static void cnvToFloatCast (iCode *ic, eBBlock *ebp) -{ - iCode *ip, *newic; - symbol *func; - sym_link *type = operandType(IC_RIGHT(ic)); - int linenno = ic->lineno; - int bwd, su; - - ip = ic->next ; - /* remove it from the iCode */ - remiCodeFromeBBlock (ebp,ic); - /* depending on the type */ - for (bwd = 0; bwd < 3; bwd++) { - for (su = 0; su < 2; su++) { - if (checkType(type, __multypes[bwd][su]) == 1) { - func = __conv[0][bwd][su]; - goto found; +static void +cnvToFloatCast (iCode * ic, eBBlock * ebp) +{ + iCode *ip, *newic; + symbol *func; + sym_link *type = operandType (IC_RIGHT (ic)); + int linenno = ic->lineno; + int bwd, su; + + ip = ic->next; + /* remove it from the iCode */ + remiCodeFromeBBlock (ebp, ic); + /* depending on the type */ + for (bwd = 0; bwd < 3; bwd++) + { + for (su = 0; su < 2; su++) + { + if (checkType (type, __multypes[bwd][su]) == 1) + { + func = __conv[0][bwd][su]; + goto found; } } } - assert(0); - found: - - /* if float support routines NOT compiled as reentrant */ - if (! options.float_rent) { - /* first one */ - if (IS_REGPARM(func->args->etype)) - newic = newiCode(SEND,IC_RIGHT(ic),NULL); - else { - newic = newiCode('=',NULL,IC_RIGHT(ic)); - IC_RESULT(newic) = operandFromValue(func->args); + assert (0); +found: + + /* if float support routines NOT compiled as reentrant */ + if (!options.float_rent) + { + /* first one */ + if (IS_REGPARM (func->args->etype)) + newic = newiCode (SEND, IC_RIGHT (ic), NULL); + else + { + newic = newiCode ('=', NULL, IC_RIGHT (ic)); + IC_RESULT (newic) = operandFromValue (func->args); } - addiCodeToeBBlock(ebp,newic,ip); - newic->lineno = linenno; - - } else { - /* push the left */ - if (IS_REGPARM(func->args->etype)) - newic = newiCode(SEND,IC_RIGHT(ic),NULL); - else { - newic = newiCode(IPUSH,IC_RIGHT(ic),NULL); - newic->parmPush = 1; + addiCodeToeBBlock (ebp, newic, ip); + newic->lineno = linenno; + + } + else + { + /* push the left */ + if (IS_REGPARM (func->args->etype)) + newic = newiCode (SEND, IC_RIGHT (ic), NULL); + else + { + newic = newiCode (IPUSH, IC_RIGHT (ic), NULL); + newic->parmPush = 1; } - addiCodeToeBBlock(ebp,newic,ip); - newic->lineno = linenno; - + addiCodeToeBBlock (ebp, newic, ip); + newic->lineno = linenno; + } - /* make the call */ - newic = newiCode(CALL,operandFromSymbol(func),NULL); - IC_RESULT(newic) = IC_RESULT(ic); - addiCodeToeBBlock(ebp,newic,ip); - newic->lineno = linenno; + /* make the call */ + newic = newiCode (CALL, operandFromSymbol (func), NULL); + IC_RESULT (newic) = IC_RESULT (ic); + addiCodeToeBBlock (ebp, newic, ip); + newic->lineno = linenno; } /*-----------------------------------------------------------------*/ /* cnvFromFloatCast - converts casts From floats to function calls */ /*-----------------------------------------------------------------*/ -static void cnvFromFloatCast (iCode *ic, eBBlock *ebp) +static void +cnvFromFloatCast (iCode * ic, eBBlock * ebp) { - iCode *ip, *newic; - symbol *func; - sym_link *type = operandType(IC_LEFT(ic)); - int lineno = ic->lineno ; - int bwd, su; - - ip = ic->next ; - /* remove it from the iCode */ - remiCodeFromeBBlock (ebp,ic); - - /* depending on the type */ - for (bwd = 0; bwd < 3; bwd++) { - for (su = 0; su < 2; su++) { - if (checkType(type, __multypes[bwd][su]) == 1) { - func = __conv[1][bwd][su]; - goto found; + iCode *ip, *newic; + symbol *func; + sym_link *type = operandType (IC_LEFT (ic)); + int lineno = ic->lineno; + int bwd, su; + + ip = ic->next; + /* remove it from the iCode */ + remiCodeFromeBBlock (ebp, ic); + + /* depending on the type */ + for (bwd = 0; bwd < 3; bwd++) + { + for (su = 0; su < 2; su++) + { + if (checkType (type, __multypes[bwd][su]) == 1) + { + func = __conv[1][bwd][su]; + goto found; } } } - assert(0); - found: - - /* if float support routines NOT compiled as reentrant */ - if (! options.float_rent) { - /* first one */ - if (IS_REGPARM(func->args->etype)) - newic = newiCode(SEND,IC_RIGHT(ic),NULL); - else { - newic = newiCode('=',NULL,IC_RIGHT(ic)); - IC_RESULT(newic) = operandFromValue(func->args); + assert (0); +found: + + /* if float support routines NOT compiled as reentrant */ + if (!options.float_rent) + { + /* first one */ + if (IS_REGPARM (func->args->etype)) + newic = newiCode (SEND, IC_RIGHT (ic), NULL); + else + { + newic = newiCode ('=', NULL, IC_RIGHT (ic)); + IC_RESULT (newic) = operandFromValue (func->args); } - addiCodeToeBBlock(ebp,newic,ip); - newic->lineno = lineno; + addiCodeToeBBlock (ebp, newic, ip); + newic->lineno = lineno; - } else { + } + else + { - /* push the left */ - if (IS_REGPARM(func->args->etype)) - newic = newiCode(SEND,IC_RIGHT(ic),NULL); - else { - newic = newiCode(IPUSH,IC_RIGHT(ic),NULL); - newic->parmPush = 1; + /* push the left */ + if (IS_REGPARM (func->args->etype)) + newic = newiCode (SEND, IC_RIGHT (ic), NULL); + else + { + newic = newiCode (IPUSH, IC_RIGHT (ic), NULL); + newic->parmPush = 1; } - addiCodeToeBBlock(ebp,newic,ip); - newic->lineno = lineno; + addiCodeToeBBlock (ebp, newic, ip); + newic->lineno = lineno; } - /* make the call */ - newic = newiCode(CALL,operandFromSymbol(func),NULL); - IC_RESULT(newic) = IC_RESULT(ic); - addiCodeToeBBlock(ebp,newic,ip); - newic->lineno = lineno; + /* make the call */ + newic = newiCode (CALL, operandFromSymbol (func), NULL); + IC_RESULT (newic) = IC_RESULT (ic); + addiCodeToeBBlock (ebp, newic, ip); + newic->lineno = lineno; } /*-----------------------------------------------------------------*/ /* convilong - converts int or long mults or divs to fcalls */ /*-----------------------------------------------------------------*/ -static void convilong (iCode *ic, eBBlock *ebp, sym_link *type, int op) -{ - symbol *func = NULL; - iCode *ip = ic->next; - iCode *newic ; - int lineno = ic->lineno; - int bwd; - int su; - remiCodeFromeBBlock (ebp,ic); - - /* depending on the type */ - for (bwd = 0; bwd < 3; bwd++) { - for (su = 0; su < 2; su++) { - if (checkType(type, __multypes[bwd][su]) == 1) { - if (op == '*') - func = __muldiv[0][bwd][su]; - else if (op == '/') - func = __muldiv[1][bwd][su]; - else if (op == '%') - func = __muldiv[2][bwd][su]; - else - assert(0); - goto found; +static void +convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op) +{ + symbol *func = NULL; + iCode *ip = ic->next; + iCode *newic; + int lineno = ic->lineno; + int bwd; + int su; + remiCodeFromeBBlock (ebp, ic); + + /* depending on the type */ + for (bwd = 0; bwd < 3; bwd++) + { + for (su = 0; su < 2; su++) + { + if (checkType (type, __multypes[bwd][su]) == 1) + { + if (op == '*') + func = __muldiv[0][bwd][su]; + else if (op == '/') + func = __muldiv[1][bwd][su]; + else if (op == '%') + func = __muldiv[2][bwd][su]; + else + assert (0); + goto found; } } } - assert(0); - found: - /* if int & long support routines NOT compiled as reentrant */ - if (! options.intlong_rent) { - /* first one */ - if (IS_REGPARM(func->args->etype)) - newic = newiCode(SEND,IC_LEFT(ic),NULL); - else { - newic = newiCode('=',NULL,IC_LEFT(ic)); - IC_RESULT(newic) = operandFromValue(func->args); + assert (0); +found: + /* if int & long support routines NOT compiled as reentrant */ + if (!options.intlong_rent) + { + /* first one */ + if (IS_REGPARM (func->args->etype)) + newic = newiCode (SEND, IC_LEFT (ic), NULL); + else + { + newic = newiCode ('=', NULL, IC_LEFT (ic)); + IC_RESULT (newic) = operandFromValue (func->args); } - addiCodeToeBBlock(ebp,newic,ip); - newic->lineno = lineno; - - /* second one */ - if (IS_REGPARM(func->args->next->etype)) - newic = newiCode(SEND,IC_RIGHT(ic),NULL); - else { - newic = newiCode('=',NULL,IC_RIGHT(ic)); - IC_RESULT(newic) = operandFromValue(func->args->next); + addiCodeToeBBlock (ebp, newic, ip); + newic->lineno = lineno; + + /* second one */ + if (IS_REGPARM (func->args->next->etype)) + newic = newiCode (SEND, IC_RIGHT (ic), NULL); + else + { + newic = newiCode ('=', NULL, IC_RIGHT (ic)); + IC_RESULT (newic) = operandFromValue (func->args->next); } - addiCodeToeBBlock(ebp,newic,ip); - newic->lineno = lineno; + addiCodeToeBBlock (ebp, newic, ip); + newic->lineno = lineno; - } else { + } + else + { - /* compiled as reentrant then push */ - /* push right */ - if (IS_REGPARM(func->args->next->etype)) - newic = newiCode(SEND,IC_RIGHT(ic),NULL); - else { - newic = newiCode(IPUSH,IC_RIGHT(ic),NULL); - newic->parmPush = 1; + /* compiled as reentrant then push */ + /* push right */ + if (IS_REGPARM (func->args->next->etype)) + newic = newiCode (SEND, IC_RIGHT (ic), NULL); + else + { + newic = newiCode (IPUSH, IC_RIGHT (ic), NULL); + newic->parmPush = 1; } - addiCodeToeBBlock (ebp,newic,ip); - newic->lineno = lineno; - - /* insert push left */ - if (IS_REGPARM(func->args->etype)) - newic = newiCode(SEND,IC_LEFT(ic),NULL); - else { - newic = newiCode(IPUSH,IC_LEFT(ic),NULL); - newic->parmPush = 1; + addiCodeToeBBlock (ebp, newic, ip); + newic->lineno = lineno; + + /* insert push left */ + if (IS_REGPARM (func->args->etype)) + newic = newiCode (SEND, IC_LEFT (ic), NULL); + else + { + newic = newiCode (IPUSH, IC_LEFT (ic), NULL); + newic->parmPush = 1; } - addiCodeToeBBlock (ebp,newic,ip); - newic->lineno = lineno; + addiCodeToeBBlock (ebp, newic, ip); + newic->lineno = lineno; } - /* for the result */ - newic = newiCode(CALL,operandFromSymbol(func),NULL); - IC_RESULT(newic) = IC_RESULT(ic); - addiCodeToeBBlock(ebp,newic,ip); - newic->lineno = lineno; + /* for the result */ + newic = newiCode (CALL, operandFromSymbol (func), NULL); + IC_RESULT (newic) = IC_RESULT (ic); + addiCodeToeBBlock (ebp, newic, ip); + newic->lineno = lineno; } /*-----------------------------------------------------------------*/ /* convertToFcall - converts some operations to fcalls */ /*-----------------------------------------------------------------*/ -static void convertToFcall (eBBlock **ebbs, int count) +static void +convertToFcall (eBBlock ** ebbs, int count) { - int i ; - - /* for all blocks do */ - for (i = 0 ; i < count ; i++ ) { - iCode *ic ; - - /* for all instructions in the block do */ - for (ic = ebbs[i]->sch ; ic ; ic = ic->next ) { - - /* floating point operations are - converted to function calls */ - if ((IS_CONDITIONAL(ic) || - IS_ARITHMETIC_OP(ic) ) && - (IS_FLOAT(operandType(IC_RIGHT(ic))))) { - - cnvToFcall(ic,ebbs[i]); + int i; + + /* for all blocks do */ + for (i = 0; i < count; i++) + { + iCode *ic; + + /* for all instructions in the block do */ + for (ic = ebbs[i]->sch; ic; ic = ic->next) + { + + /* floating point operations are + converted to function calls */ + if ((IS_CONDITIONAL (ic) || + IS_ARITHMETIC_OP (ic)) && + (IS_FLOAT (operandType (IC_RIGHT (ic))))) + { + + cnvToFcall (ic, ebbs[i]); } - - /* casting is a little different */ - if (ic->op == CAST ) { - if (IS_FLOAT(operandType(IC_RIGHT(ic)))) - cnvFromFloatCast (ic,ebbs[i]); - else - if (IS_FLOAT(operandType(IC_LEFT(ic)))) - cnvToFloatCast (ic,ebbs[i]); + + /* casting is a little different */ + if (ic->op == CAST) + { + if (IS_FLOAT (operandType (IC_RIGHT (ic)))) + cnvFromFloatCast (ic, ebbs[i]); + else if (IS_FLOAT (operandType (IC_LEFT (ic)))) + cnvToFloatCast (ic, ebbs[i]); } - /* if long / int mult or divide or mod */ - if (ic->op == '*' || ic->op == '/' || ic->op == '%' ) { + /* if long / int mult or divide or mod */ + if (ic->op == '*' || ic->op == '/' || ic->op == '%') + { - sym_link *type = operandType(IC_LEFT(ic)); - if (IS_INTEGRAL(type) && getSize(type) > port->muldiv.native_below) - convilong (ic,ebbs[i],type,ic->op); + sym_link *type = operandType (IC_LEFT (ic)); + if (IS_INTEGRAL (type) && getSize (type) > port->muldiv.native_below) + convilong (ic, ebbs[i], type, ic->op); } } } @@ -404,244 +456,264 @@ static void convertToFcall (eBBlock **ebbs, int count) /*-----------------------------------------------------------------*/ /* replaceRegEqv - replace all local variables with their reqv */ /*-----------------------------------------------------------------*/ -static void replaceRegEqv ( eBBlock **ebbs, int count) +static void +replaceRegEqv (eBBlock ** ebbs, int count) { - int i; - - for (i = 0 ; i < count ; i++ ) { - - iCode *ic ; - - for (ic = ebbs[i]->sch ; ic ; ic = ic->next) { - - if (SKIP_IC2(ic)) - continue ; - - if (ic->op == IFX) { - - if (IS_TRUE_SYMOP(IC_COND(ic)) && - OP_REQV(IC_COND(ic))) - IC_COND(ic) = opFromOpWithDU(OP_REQV(IC_COND(ic)), - OP_SYMBOL(IC_COND(ic))->defs, - OP_SYMBOL(IC_COND(ic))->uses); - - continue ; + int i; + + for (i = 0; i < count; i++) + { + + iCode *ic; + + for (ic = ebbs[i]->sch; ic; ic = ic->next) + { + + if (SKIP_IC2 (ic)) + continue; + + if (ic->op == IFX) + { + + if (IS_TRUE_SYMOP (IC_COND (ic)) && + OP_REQV (IC_COND (ic))) + IC_COND (ic) = opFromOpWithDU (OP_REQV (IC_COND (ic)), + OP_SYMBOL (IC_COND (ic))->defs, + OP_SYMBOL (IC_COND (ic))->uses); + + continue; } - if (ic->op == JUMPTABLE) { - if (IS_TRUE_SYMOP(IC_JTCOND(ic)) && - OP_REQV(IC_JTCOND(ic))) - IC_JTCOND(ic) = opFromOpWithDU(OP_REQV(IC_JTCOND(ic)), - OP_SYMBOL(IC_JTCOND(ic))->defs, - OP_SYMBOL(IC_JTCOND(ic))->uses); - continue ; + if (ic->op == JUMPTABLE) + { + if (IS_TRUE_SYMOP (IC_JTCOND (ic)) && + OP_REQV (IC_JTCOND (ic))) + IC_JTCOND (ic) = opFromOpWithDU (OP_REQV (IC_JTCOND (ic)), + OP_SYMBOL (IC_JTCOND (ic))->defs, + OP_SYMBOL (IC_JTCOND (ic))->uses); + continue; } - if (ic->op == RECEIVE) { - if (OP_SYMBOL(IC_RESULT(ic))->addrtaken) - OP_SYMBOL(IC_RESULT(ic))->isspilt = 1; + if (ic->op == RECEIVE) + { + if (OP_SYMBOL (IC_RESULT (ic))->addrtaken) + OP_SYMBOL (IC_RESULT (ic))->isspilt = 1; } - /* general case */ - if (IC_RESULT(ic) && - IS_TRUE_SYMOP(IC_RESULT(ic)) && - OP_REQV(IC_RESULT(ic)) ) { - if (POINTER_SET(ic)) { - IC_RESULT(ic) = opFromOpWithDU(OP_REQV(IC_RESULT(ic)), - OP_SYMBOL(IC_RESULT(ic))->defs, - OP_SYMBOL(IC_RESULT(ic))->uses); - IC_RESULT(ic)->isaddr = 1; - } else - IC_RESULT(ic) = opFromOpWithDU(OP_REQV(IC_RESULT(ic)), - OP_SYMBOL(IC_RESULT(ic))->defs, - OP_SYMBOL(IC_RESULT(ic))->uses); + /* general case */ + if (IC_RESULT (ic) && + IS_TRUE_SYMOP (IC_RESULT (ic)) && + OP_REQV (IC_RESULT (ic))) + { + if (POINTER_SET (ic)) + { + IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)), + OP_SYMBOL (IC_RESULT (ic))->defs, + OP_SYMBOL (IC_RESULT (ic))->uses); + IC_RESULT (ic)->isaddr = 1; + } + else + IC_RESULT (ic) = opFromOpWithDU (OP_REQV (IC_RESULT (ic)), + OP_SYMBOL (IC_RESULT (ic))->defs, + OP_SYMBOL (IC_RESULT (ic))->uses); } - if (IC_RIGHT(ic) && - IS_TRUE_SYMOP(IC_RIGHT(ic)) && - OP_REQV(IC_RIGHT(ic)) ) { - IC_RIGHT(ic) = opFromOpWithDU(OP_REQV(IC_RIGHT(ic)), - OP_SYMBOL(IC_RIGHT(ic))->defs, - OP_SYMBOL(IC_RIGHT(ic))->uses); - IC_RIGHT(ic)->isaddr = 0; + if (IC_RIGHT (ic) && + IS_TRUE_SYMOP (IC_RIGHT (ic)) && + OP_REQV (IC_RIGHT (ic))) + { + IC_RIGHT (ic) = opFromOpWithDU (OP_REQV (IC_RIGHT (ic)), + OP_SYMBOL (IC_RIGHT (ic))->defs, + OP_SYMBOL (IC_RIGHT (ic))->uses); + IC_RIGHT (ic)->isaddr = 0; } - - if (IC_LEFT(ic) && - IS_TRUE_SYMOP(IC_LEFT(ic)) && - OP_REQV(IC_LEFT(ic)) ) { - IC_LEFT(ic) = opFromOpWithDU(OP_REQV(IC_LEFT(ic)), - OP_SYMBOL(IC_LEFT(ic))->defs, - OP_SYMBOL(IC_LEFT(ic))->uses); - IC_LEFT(ic)->isaddr = 0; + + if (IC_LEFT (ic) && + IS_TRUE_SYMOP (IC_LEFT (ic)) && + OP_REQV (IC_LEFT (ic))) + { + IC_LEFT (ic) = opFromOpWithDU (OP_REQV (IC_LEFT (ic)), + OP_SYMBOL (IC_LEFT (ic))->defs, + OP_SYMBOL (IC_LEFT (ic))->uses); + IC_LEFT (ic)->isaddr = 0; } - } + } } } /*-----------------------------------------------------------------*/ /* killDeadCode - eliminates dead assignments */ /*-----------------------------------------------------------------*/ -int killDeadCode ( eBBlock **ebbs, int count) +int +killDeadCode (eBBlock ** ebbs, int count) { - int change = 1; - int gchange = 0 ; - int i = 0 ; - - - /* basic algorithm :- */ - /* first the exclusion rules :- */ - /* 1. if result is a global or volatile then skip */ - /* 2. if assignment and result is a temp & isaddr then skip */ - /* since this means array & pointer access, will be taken */ - /* care of by alias analysis. */ - /* 3. if the result is used in the remainder of the block skip*/ - /* 4. if this definition does not reach the end of the block */ - /* i.e. the result is not present in the outExprs then KILL*/ - /* 5. if it reaches the end of block & is used by some success*/ - /* or then skip */ - /* else KILL */ - /* this whole process is carried on iteratively till no change */ - while (1) { - - change = 0 ; - /* for all blocks do */ - for ( i = 0 ; i < count ; i++ ) { - iCode *ic ; - - /* for all instructions in the block do */ - for ( ic = ebbs[i]->sch ; ic ; ic = ic->next ) { - int kill, j ; - kill = 0 ; - - if (SKIP_IC(ic) || - ic->op == IFX || - ic->op == RETURN ) - continue ; - - /* if the result is volatile then continue */ - if (IC_RESULT(ic) && isOperandVolatile(IC_RESULT(ic),FALSE)) - continue ; - - /* if the result is a temp & isaddr then skip */ - if (IC_RESULT(ic) && POINTER_SET(ic)) - continue ; - - /* if the result is used in the remainder of the */ - /* block then skip */ - if (usedInRemaining (IC_RESULT(ic),ic->next)) - continue ; - - /* does this definition reach the end of the block - or the usage is zero then we can kill */ - if (! bitVectBitValue(ebbs[i]->outDefs,ic->key)) - kill = 1; /* if not we can kill it */ - else { - /* if this is a global variable or function parameter */ - /* we cannot kill anyway */ - if (isOperandGlobal(IC_RESULT(ic)) || - (OP_SYMBOL(IC_RESULT(ic))->_isparm && - !OP_SYMBOL(IC_RESULT(ic))->ismyparm)) - continue ; - - /* if we are sure there are no usages */ - if (bitVectIsZero(OP_USES(IC_RESULT(ic)))) { - kill = 1 ; - goto kill ; + int change = 1; + int gchange = 0; + int i = 0; + + + /* basic algorithm :- */ + /* first the exclusion rules :- */ + /* 1. if result is a global or volatile then skip */ + /* 2. if assignment and result is a temp & isaddr then skip */ + /* since this means array & pointer access, will be taken */ + /* care of by alias analysis. */ + /* 3. if the result is used in the remainder of the block skip */ + /* 4. if this definition does not reach the end of the block */ + /* i.e. the result is not present in the outExprs then KILL */ + /* 5. if it reaches the end of block & is used by some success */ + /* or then skip */ + /* else KILL */ + /* this whole process is carried on iteratively till no change */ + while (1) + { + + change = 0; + /* for all blocks do */ + for (i = 0; i < count; i++) + { + iCode *ic; + + /* for all instructions in the block do */ + for (ic = ebbs[i]->sch; ic; ic = ic->next) + { + int kill, j; + kill = 0; + + if (SKIP_IC (ic) || + ic->op == IFX || + ic->op == RETURN) + continue; + + /* if the result is volatile then continue */ + if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE)) + continue; + + /* if the result is a temp & isaddr then skip */ + if (IC_RESULT (ic) && POINTER_SET (ic)) + continue; + + /* if the result is used in the remainder of the */ + /* block then skip */ + if (usedInRemaining (IC_RESULT (ic), ic->next)) + continue; + + /* does this definition reach the end of the block + or the usage is zero then we can kill */ + if (!bitVectBitValue (ebbs[i]->outDefs, ic->key)) + kill = 1; /* if not we can kill it */ + else + { + /* if this is a global variable or function parameter */ + /* we cannot kill anyway */ + if (isOperandGlobal (IC_RESULT (ic)) || + (OP_SYMBOL (IC_RESULT (ic))->_isparm && + !OP_SYMBOL (IC_RESULT (ic))->ismyparm)) + continue; + + /* if we are sure there are no usages */ + if (bitVectIsZero (OP_USES (IC_RESULT (ic)))) + { + kill = 1; + goto kill; } - /* reset visited flag */ - for(j=0; j < count ; ebbs[j++]->visited = 0); - - /* find out if this definition is alive */ - if ( applyToSet (ebbs[i]->succList, - isDefAlive, - ic)) - continue ; + /* reset visited flag */ + for (j = 0; j < count; ebbs[j++]->visited = 0); + + /* find out if this definition is alive */ + if (applyToSet (ebbs[i]->succList, + isDefAlive, + ic)) + continue; + + kill = 1; + } + + kill: + /* kill this one if required */ + if (kill) + { + change = 1; + gchange++; + /* eliminate this */ + remiCodeFromeBBlock (ebbs[i], ic); - kill = 1; + /* now delete from defUseSet */ + deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic); + bitVectUnSetBit (ebbs[i]->outDefs, ic->key); + + /* and defset of the block */ + bitVectUnSetBit (ebbs[i]->defSet, ic->key); + + /* for the left & right remove the usage */ + if (IS_SYMOP (IC_LEFT (ic))) + bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key); + + if (IS_SYMOP (IC_RIGHT (ic))) + bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key); } - kill : - /* kill this one if required */ - if (kill) { - change = 1; - gchange++ ; - /* eliminate this */ - remiCodeFromeBBlock(ebbs[i],ic); - - /* now delete from defUseSet */ - deleteItemIf (&ebbs[i]->outExprs,ifDiCodeIsX,ic); - bitVectUnSetBit (ebbs[i]->outDefs,ic->key); - - /* and defset of the block */ - bitVectUnSetBit (ebbs[i]->defSet,ic->key); - - /* for the left & right remove the usage */ - if (IS_SYMOP(IC_LEFT(ic))) - bitVectUnSetBit(OP_USES(IC_LEFT(ic)),ic->key); - - if (IS_SYMOP(IC_RIGHT(ic))) - bitVectUnSetBit(OP_USES(IC_RIGHT(ic)),ic->key); - } - - } /* end of all instructions */ - - if (!ebbs[i]->sch && !ebbs[i]->noPath) - disconBBlock(ebbs[i],ebbs,count); - - } /* end of for all blocks */ - - if (!change) - break; - } /* end of while(1) */ - - return gchange ; + } /* end of all instructions */ + + if (!ebbs[i]->sch && !ebbs[i]->noPath) + disconBBlock (ebbs[i], ebbs, count); + + } /* end of for all blocks */ + + if (!change) + break; + } /* end of while(1) */ + + return gchange; } /*-----------------------------------------------------------------*/ /* printCyclomatic - prints the cyclomatic information */ /*-----------------------------------------------------------------*/ -static void printCyclomatic (eBBlock **ebbs, int count) +static void +printCyclomatic (eBBlock ** ebbs, int count) { - int nEdges = elementsInSet(graphEdges); - int i, nNodes =0; + int nEdges = elementsInSet (graphEdges); + int i, nNodes = 0; - for (i = 0 ; i < count ; i++) - nNodes += (! ebbs[i]->noPath); + for (i = 0; i < count; i++) + nNodes += (!ebbs[i]->noPath); - /* print the information */ - werror(I_CYCLOMATIC,currFunc->name,nEdges,nNodes, nEdges - nNodes + 2); + /* print the information */ + werror (I_CYCLOMATIC, currFunc->name, nEdges, nNodes, nEdges - nNodes + 2); } /*-----------------------------------------------------------------*/ /* discardDeadParamReceives - remove any RECEIVE opcodes which */ -/* refer to dead variables. */ +/* refer to dead variables. */ /*-----------------------------------------------------------------*/ -static void discardDeadParamReceives(eBBlock **ebbs, int count) +static void +discardDeadParamReceives (eBBlock ** ebbs, int count) { - int i; - iCode *ic; - iCode dummyIcode; + int i; + iCode *ic; + iCode dummyIcode; - for (i = 0 ; i < count ; i++) + for (i = 0; i < count; i++) { - for ( ic = ebbs[i]->sch ; ic ; ic = ic->next ) - { - if (ic->op == RECEIVE) - { - if (IC_RESULT(ic) && OP_SYMBOL(IC_RESULT(ic)) - && !OP_SYMBOL(IC_RESULT(ic))->used) - { -#if 0 - fprintf(stderr, "discarding dead receive for %s\n", - OP_SYMBOL(IC_RESULT(ic))->name); -#endif - dummyIcode.next = ic->next; - remiCodeFromeBBlock(ebbs[i], ic); - ic = &dummyIcode; - } - } - } + for (ic = ebbs[i]->sch; ic; ic = ic->next) + { + if (ic->op == RECEIVE) + { + if (IC_RESULT (ic) && OP_SYMBOL (IC_RESULT (ic)) + && !OP_SYMBOL (IC_RESULT (ic))->used) + { +#if 0 + fprintf (stderr, "discarding dead receive for %s\n", + OP_SYMBOL (IC_RESULT (ic))->name); +#endif + dummyIcode.next = ic->next; + remiCodeFromeBBlock (ebbs[i], ic); + ic = &dummyIcode; + } + } + } } } @@ -649,144 +721,147 @@ static void discardDeadParamReceives(eBBlock **ebbs, int count) /* eBBlockFromiCode - creates extended basic blocks from iCode */ /* will return an array of eBBlock pointers */ /*-----------------------------------------------------------------*/ -eBBlock **eBBlockFromiCode (iCode *ic) -{ - eBBlock **ebbs = NULL ; - int count = 0; - int saveCount = 0 ; - int change = 1; - int lchange = 0 ; - int kchange = 0; - hTab *loops ; - - /* if nothing passed then return nothing */ - if (!ic) - return NULL ; - - count = 0; - eBBNum = 0; - - /* optimize the chain for labels & gotos - this will eliminate redundant labels and - will change jump to jumps by jumps */ - ic = iCodeLabelOptimize (ic); - - /* break it down into basic blocks */ - ebbs = iCodeBreakDown (ic,&count); - saveCount = count ; - - /* compute the control flow */ - computeControlFlow (ebbs,count,0); - - /* dumpraw if asked for */ - if (options.dump_raw) - dumpEbbsToFileExt(".dumpraw0",ebbs,count); - - /* replace the local variables with their - register equivalents : the liveRange computation - along with the register allocation will determine - if it finally stays in the registers */ - replaceRegEqv (ebbs,count); - - /* create loop regions */ - loops = createLoopRegions (ebbs,count); - - /* dumpraw if asked for */ - if (options.dump_raw) - dumpEbbsToFileExt(".dumpraw1",ebbs,count); - - /* do common subexpression elimination for each block */ - change = cseAllBlocks(ebbs,saveCount); - - /* dumpraw if asked for */ - if (options.dump_raw) - dumpEbbsToFileExt(".dumpcse",ebbs,count); - - /* compute the data flow */ - computeDataFlow (ebbs,saveCount); - - /* dumpraw if asked for */ - if (options.dump_raw) - dumpEbbsToFileExt(".dumpdflow",ebbs,count); - - /* global common subexpression elimination */ - if ( optimize.global_cse ) { - change += cseAllBlocks(ebbs,saveCount); - if (options.dump_gcse) - dumpEbbsToFileExt(".dumpgcse",ebbs,saveCount); +eBBlock ** +eBBlockFromiCode (iCode * ic) +{ + eBBlock **ebbs = NULL; + int count = 0; + int saveCount = 0; + int change = 1; + int lchange = 0; + int kchange = 0; + hTab *loops; + + /* if nothing passed then return nothing */ + if (!ic) + return NULL; + + count = 0; + eBBNum = 0; + + /* optimize the chain for labels & gotos + this will eliminate redundant labels and + will change jump to jumps by jumps */ + ic = iCodeLabelOptimize (ic); + + /* break it down into basic blocks */ + ebbs = iCodeBreakDown (ic, &count); + saveCount = count; + + /* compute the control flow */ + computeControlFlow (ebbs, count, 0); + + /* dumpraw if asked for */ + if (options.dump_raw) + dumpEbbsToFileExt (".dumpraw0", ebbs, count); + + /* replace the local variables with their + register equivalents : the liveRange computation + along with the register allocation will determine + if it finally stays in the registers */ + replaceRegEqv (ebbs, count); + + /* create loop regions */ + loops = createLoopRegions (ebbs, count); + + /* dumpraw if asked for */ + if (options.dump_raw) + dumpEbbsToFileExt (".dumpraw1", ebbs, count); + + /* do common subexpression elimination for each block */ + change = cseAllBlocks (ebbs, saveCount); + + /* dumpraw if asked for */ + if (options.dump_raw) + dumpEbbsToFileExt (".dumpcse", ebbs, count); + + /* compute the data flow */ + computeDataFlow (ebbs, saveCount); + + /* dumpraw if asked for */ + if (options.dump_raw) + dumpEbbsToFileExt (".dumpdflow", ebbs, count); + + /* global common subexpression elimination */ + if (optimize.global_cse) + { + change += cseAllBlocks (ebbs, saveCount); + if (options.dump_gcse) + dumpEbbsToFileExt (".dumpgcse", ebbs, saveCount); } - /* kill dead code */ - kchange = killDeadCode (ebbs, saveCount); - - if (options.dump_kill) - dumpEbbsToFileExt(".dumpdeadcode",ebbs,count); - - /* do loop optimizations */ - change += (lchange = loopOptimizations (loops,ebbs,count)); - if (options.dump_loop) - dumpEbbsToFileExt(".dumploop",ebbs,count); - - /* recompute the data flow and apply global cse again - if loops optimizations or dead code caused a change: - loops will brings out of the loop which then may be - available for use in the later blocks: dead code - elimination could potentially disconnect some blocks - conditional flow may be efected so we need to apply - subexpression once more */ - if ( lchange || kchange ) { - - computeDataFlow (ebbs,saveCount); - change += cseAllBlocks(ebbs,saveCount); - if (options.dump_loop) - dumpEbbsToFileExt(".dumploopg",ebbs,count); - - /* if loop optimizations caused a change then do - dead code elimination once more : this will - get rid of the extra assignments to the induction - variables created during loop optimizations */ - killDeadCode (ebbs, saveCount); - - if (options.dump_loop) - dumpEbbsToFileExt(".dumploopd",ebbs,count); - - } - - - /* sort it back by block number */ - qsort (ebbs,saveCount,sizeof(eBBlock *),bbNumCompare); + /* kill dead code */ + kchange = killDeadCode (ebbs, saveCount); + + if (options.dump_kill) + dumpEbbsToFileExt (".dumpdeadcode", ebbs, count); + + /* do loop optimizations */ + change += (lchange = loopOptimizations (loops, ebbs, count)); + if (options.dump_loop) + dumpEbbsToFileExt (".dumploop", ebbs, count); + + /* recompute the data flow and apply global cse again + if loops optimizations or dead code caused a change: + loops will brings out of the loop which then may be + available for use in the later blocks: dead code + elimination could potentially disconnect some blocks + conditional flow may be efected so we need to apply + subexpression once more */ + if (lchange || kchange) + { - /* if cyclomatic info requested then print it */ - if (options.cyclomatic) - printCyclomatic(ebbs,saveCount); + computeDataFlow (ebbs, saveCount); + change += cseAllBlocks (ebbs, saveCount); + if (options.dump_loop) + dumpEbbsToFileExt (".dumploopg", ebbs, count); + /* if loop optimizations caused a change then do + dead code elimination once more : this will + get rid of the extra assignments to the induction + variables created during loop optimizations */ + killDeadCode (ebbs, saveCount); - /* convert operations with support routines - written in C to function calls : Iam doing - this at this point since I want all the - operations to be as they are for optimzations */ - convertToFcall (ebbs,count); + if (options.dump_loop) + dumpEbbsToFileExt (".dumploopd", ebbs, count); + } - /* compute the live ranges */ - computeLiveRanges (ebbs,count); - if (options.dump_range) - dumpEbbsToFileExt(".dumprange",ebbs,count); + /* sort it back by block number */ + qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare); - /* Now that we have the live ranges, discard parameter - * receives for unused parameters. - */ - discardDeadParamReceives(ebbs,count); + /* if cyclomatic info requested then print it */ + if (options.cyclomatic) + printCyclomatic (ebbs, saveCount); - /* allocate registers & generate code */ - port->assignRegisters(ebbs,count); - - /* throw away blocks */ - setToNull ((void **)&graphEdges); - ebbs = NULL ; + /* convert operations with support routines + written in C to function calls : Iam doing + this at this point since I want all the + operations to be as they are for optimzations */ + convertToFcall (ebbs, count); - return NULL; + + /* compute the live ranges */ + computeLiveRanges (ebbs, count); + + if (options.dump_range) + dumpEbbsToFileExt (".dumprange", ebbs, count); + + /* Now that we have the live ranges, discard parameter + * receives for unused parameters. + */ + discardDeadParamReceives (ebbs, count); + + /* allocate registers & generate code */ + port->assignRegisters (ebbs, count); + + /* throw away blocks */ + setToNull ((void **) &graphEdges); + ebbs = NULL; + + + return NULL; } diff --git a/src/SDCCopt.h b/src/SDCCopt.h index 234086e7..221de7e7 100644 --- a/src/SDCCopt.h +++ b/src/SDCCopt.h @@ -30,8 +30,8 @@ /*----------------------------------------------------------------------------*/ eBBlock **eBBlockFromiCode (iCode *); -void printEbbs (eBBlock **) ; -iCode *iCodeLabelOptimize (iCode *); -eBBlock *iCode2eBBlock (iCode *ic); +void printEbbs (eBBlock **); +iCode *iCodeLabelOptimize (iCode *); +eBBlock *iCode2eBBlock (iCode * ic); #endif diff --git a/src/SDCCpeeph.c b/src/SDCCpeeph.c index f554ffca..dbcb3eb0 100644 --- a/src/SDCCpeeph.c +++ b/src/SDCCpeeph.c @@ -28,19 +28,20 @@ #include "newalloc.h" peepRule *rootRules = NULL; -peepRule *currRule = NULL; +peepRule *currRule = NULL; #define HTAB_SIZE 53 typedef struct -{ + { char name[SDCC_NAME_MAX + 1]; int refCount; -} labelHashEntry; + } +labelHashEntry; hTab *labelHash = NULL; -static int hashSymbolName(const char *name); -static void buildLabelRefCountHash(lineNode *head); +static int hashSymbolName (const char *name); +static void buildLabelRefCountHash (lineNode * head); static bool matchLine (char *, char *, hTab **); @@ -50,276 +51,300 @@ static bool matchLine (char *, char *, hTab **); /*-----------------------------------------------------------------*/ /* pcDistance - afinds a label back ward or forward */ /*-----------------------------------------------------------------*/ -int pcDistance (lineNode *cpos, char *lbl, bool back) +int +pcDistance (lineNode * cpos, char *lbl, bool back) { - lineNode *pl = cpos; - char buff[MAX_PATTERN_LEN]; - int dist = 0 ; + lineNode *pl = cpos; + char buff[MAX_PATTERN_LEN]; + int dist = 0; - sprintf(buff,"%s:",lbl); - while (pl) { + sprintf (buff, "%s:", lbl); + while (pl) + { - if (pl->line && - *pl->line != ';' && - pl->line[strlen(pl->line)-1] != ':' && - !pl->isDebug) + if (pl->line && + *pl->line != ';' && + pl->line[strlen (pl->line) - 1] != ':' && + !pl->isDebug) - dist ++; + dist++; - if (strncmp(pl->line,buff,strlen(buff)) == 0) - return dist; + if (strncmp (pl->line, buff, strlen (buff)) == 0) + return dist; - if (back) - pl = pl->prev; - else - pl = pl->next; + if (back) + pl = pl->prev; + else + pl = pl->next; } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* flat24bitMode - will check to see if we are in flat24 mode */ /*-----------------------------------------------------------------*/ -FBYNAME(flat24bitMode) +FBYNAME (flat24bitMode) { - return (options.model == MODEL_FLAT24); + return (options.model == MODEL_FLAT24); } /*-----------------------------------------------------------------*/ /* labelInRange - will check to see if label %5 is within range */ /*-----------------------------------------------------------------*/ -FBYNAME(labelInRange) +FBYNAME (labelInRange) { - /* assumes that %5 pattern variable has the label name */ - char *lbl = hTabItemWithKey(vars,5); - int dist = 0 ; + /* assumes that %5 pattern variable has the label name */ + char *lbl = hTabItemWithKey (vars, 5); + int dist = 0; - if (!lbl) + if (!lbl) return FALSE; - /* if the previous teo instructions are "ljmp"s then don't - do it since it can be part of a jump table */ - if (currPl->prev && currPl->prev->prev && - strstr(currPl->prev->line,"ljmp") && - strstr(currPl->prev->prev->line,"ljmp")) - return FALSE ; - - /* calculate the label distance : the jump for reladdr can be - +/- 127 bytes, here Iam assuming that an average 8051 - instruction is 2 bytes long, so if the label is more than - 63 intructions away, the label is considered out of range - for a relative jump. we could get more precise this will - suffice for now since it catches > 90% cases */ - dist = (pcDistance(currPl,lbl,TRUE) + - pcDistance(currPl,lbl,FALSE)) ; + /* if the previous teo instructions are "ljmp"s then don't + do it since it can be part of a jump table */ + if (currPl->prev && currPl->prev->prev && + strstr (currPl->prev->line, "ljmp") && + strstr (currPl->prev->prev->line, "ljmp")) + return FALSE; + + /* calculate the label distance : the jump for reladdr can be + +/- 127 bytes, here Iam assuming that an average 8051 + instruction is 2 bytes long, so if the label is more than + 63 intructions away, the label is considered out of range + for a relative jump. we could get more precise this will + suffice for now since it catches > 90% cases */ + dist = (pcDistance (currPl, lbl, TRUE) + + pcDistance (currPl, lbl, FALSE)); /* if (!dist || dist > 45) has produced wrong sjmp */ - /* 07-Sep-2000 Michael Schmitt */ - /* FIX for Peephole 132 */ - /* switch with lots of case can lead to a sjmp with a distance */ - /* out of the range for sjmp */ - if (!dist || dist > 43) + /* 07-Sep-2000 Michael Schmitt */ + /* FIX for Peephole 132 */ + /* switch with lots of case can lead to a sjmp with a distance */ + /* out of the range for sjmp */ + if (!dist || dist > 43) return FALSE; - return TRUE; + return TRUE; } /*-----------------------------------------------------------------*/ /* operandsNotSame - check if %1 & %2 are the same */ /*-----------------------------------------------------------------*/ -FBYNAME(operandsNotSame) +FBYNAME (operandsNotSame) { - char *op1 = hTabItemWithKey(vars,1); - char *op2 = hTabItemWithKey(vars,2); + char *op1 = hTabItemWithKey (vars, 1); + char *op2 = hTabItemWithKey (vars, 2); - if (strcmp(op1,op2) == 0) + if (strcmp (op1, op2) == 0) return FALSE; - else + else return TRUE; } /* labelRefCount: - * + * takes two parameters: a variable (bound to a label name) * and an expected reference count. * * Returns TRUE if that label is defined and referenced exactly * the given number of times. */ -FBYNAME(labelRefCount) +FBYNAME (labelRefCount) { - int varNumber, expectedRefCount; - bool rc = FALSE; + int varNumber, expectedRefCount; + bool rc = FALSE; - /* If we don't have the label hash table yet, build it. */ - if (!labelHash) + /* If we don't have the label hash table yet, build it. */ + if (!labelHash) { - buildLabelRefCountHash(head); + buildLabelRefCountHash (head); } - if (sscanf(cmdLine, "%*[ \t%]%d %d", &varNumber, &expectedRefCount) == 2) + if (sscanf (cmdLine, "%*[ \t%]%d %d", &varNumber, &expectedRefCount) == 2) { - char *label = hTabItemWithKey(vars, varNumber); - - if (label) - { - labelHashEntry *entry; - - entry = hTabFirstItemWK(labelHash, hashSymbolName(label)); - - while (entry) - { - if (!strcmp(label, entry->name)) - { - break; - } - entry = hTabNextItemWK(labelHash); - } - if (entry) - { + char *label = hTabItemWithKey (vars, varNumber); + + if (label) + { + labelHashEntry *entry; + + entry = hTabFirstItemWK (labelHash, hashSymbolName (label)); + + while (entry) + { + if (!strcmp (label, entry->name)) + { + break; + } + entry = hTabNextItemWK (labelHash); + } + if (entry) + { #if 0 - /* debug spew. */ - fprintf(stderr, "labelRefCount: %s has refCount %d, want %d\n", - label, entry->refCount, expectedRefCount); + /* debug spew. */ + fprintf (stderr, "labelRefCount: %s has refCount %d, want %d\n", + label, entry->refCount, expectedRefCount); #endif - rc = (expectedRefCount == entry->refCount); - } + rc = (expectedRefCount == entry->refCount); + } + else + { + fprintf (stderr, "*** internal error: no label has entry for" + " %s in labelRefCount peephole.\n", + label); + } + } else - { - fprintf(stderr, "*** internal error: no label has entry for" - " %s in labelRefCount peephole.\n", - label); - } - } - else - { - fprintf(stderr, "*** internal error: var %d not bound" - " in peephole labelRefCount rule.\n", - varNumber); - } + { + fprintf (stderr, "*** internal error: var %d not bound" + " in peephole labelRefCount rule.\n", + varNumber); + } } - else + else { - fprintf(stderr, - "*** internal error: labelRefCount peephole restriction" - " malformed: %s\n", cmdLine); + fprintf (stderr, + "*** internal error: labelRefCount peephole restriction" + " malformed: %s\n", cmdLine); } - return rc; + return rc; } /*-----------------------------------------------------------------*/ /* callFuncByName - calls a function as defined in the table */ /*-----------------------------------------------------------------*/ -int callFuncByName ( char *fname, - hTab *vars, - lineNode *currPl, - lineNode *head) +int +callFuncByName (char *fname, + hTab * vars, + lineNode * currPl, + lineNode * head) { - struct ftab + struct ftab + { + char *fname; + int (*func) (hTab *, lineNode *, lineNode *, const char *); + } + ftab[] = + { { - char *fname ; - int (*func)(hTab *,lineNode *,lineNode *,const char *) ; - } ftab[] = + "labelInRange", labelInRange + } + , { - {"labelInRange", labelInRange }, - {"operandsNotSame", operandsNotSame }, - {"24bitMode", flat24bitMode }, - {"labelRefCount", labelRefCount }, - }; - int i; - - for ( i = 0 ; i < ((sizeof (ftab))/(sizeof(struct ftab))); i++) - if (strncmp(ftab[i].fname,fname,strlen(ftab[i].fname)) == 0) + "operandsNotSame", operandsNotSame + } + , { - return (*ftab[i].func)(vars,currPl,head, - fname + strlen(ftab[i].fname)); + "24bitMode", flat24bitMode } - fprintf(stderr,"could not find named function in function table\n"); - return TRUE; + , + { + "labelRefCount", labelRefCount + } + , + }; + int i; + + for (i = 0; i < ((sizeof (ftab)) / (sizeof (struct ftab))); i++) + if (strncmp (ftab[i].fname, fname, strlen (ftab[i].fname)) == 0) + { + return (*ftab[i].func) (vars, currPl, head, + fname + strlen (ftab[i].fname)); + } + fprintf (stderr, "could not find named function in function table\n"); + return TRUE; } /*-----------------------------------------------------------------*/ /* printLine - prints a line chain into a given file */ /*-----------------------------------------------------------------*/ -void printLine (lineNode *head, FILE *of) +void +printLine (lineNode * head, FILE * of) { - if (!of) - of = stdout ; - - while (head) { - /* don't indent comments & labels */ - if (head->line && - ( *head->line == ';' || - head->line[strlen(head->line)-1] == ':')) - fprintf(of,"%s\n",head->line); - else - fprintf(of,"\t%s\n",head->line); - head = head->next; + if (!of) + of = stdout; + + while (head) + { + /* don't indent comments & labels */ + if (head->line && + (*head->line == ';' || + head->line[strlen (head->line) - 1] == ':')) + fprintf (of, "%s\n", head->line); + else + fprintf (of, "\t%s\n", head->line); + head = head->next; } } /*-----------------------------------------------------------------*/ /* newPeepRule - creates a new peeprule and attach it to the root */ /*-----------------------------------------------------------------*/ -peepRule *newPeepRule (lineNode *match , - lineNode *replace, - char *cond , - int restart) +peepRule * +newPeepRule (lineNode * match, + lineNode * replace, + char *cond, + int restart) { - peepRule *pr ; + peepRule *pr; - pr= Safe_calloc(1,sizeof(peepRule)); - pr->match = match; - pr->replace= replace; - pr->restart = restart; + pr = Safe_calloc (1, sizeof (peepRule)); + pr->match = match; + pr->replace = replace; + pr->restart = restart; - if (cond && *cond) { - pr->cond = Safe_calloc(1,strlen(cond)+1); - strcpy(pr->cond,cond); - } else - pr->cond = NULL ; + if (cond && *cond) + { + pr->cond = Safe_calloc (1, strlen (cond) + 1); + strcpy (pr->cond, cond); + } + else + pr->cond = NULL; - pr->vars = newHashTable(100); + pr->vars = newHashTable (100); - /* if root is empty */ - if (!rootRules) + /* if root is empty */ + if (!rootRules) rootRules = currRule = pr; - else + else currRule = currRule->next = pr; - return pr; + return pr; } /*-----------------------------------------------------------------*/ /* newLineNode - creates a new peep line */ /*-----------------------------------------------------------------*/ -lineNode *newLineNode (char *line) +lineNode * +newLineNode (char *line) { - lineNode *pl; + lineNode *pl; - pl = Safe_calloc(1,sizeof(lineNode)); - pl->line = Safe_calloc(1,strlen(line)+1); - strcpy(pl->line,line); - return pl; + pl = Safe_calloc (1, sizeof (lineNode)); + pl->line = Safe_calloc (1, strlen (line) + 1); + strcpy (pl->line, line); + return pl; } /*-----------------------------------------------------------------*/ /* connectLine - connects two lines */ /*-----------------------------------------------------------------*/ -lineNode *connectLine (lineNode *pl1, lineNode *pl2) +lineNode * +connectLine (lineNode * pl1, lineNode * pl2) { - if (!pl1 || !pl2) { - fprintf (stderr,"trying to connect null line\n"); - return NULL ; + if (!pl1 || !pl2) + { + fprintf (stderr, "trying to connect null line\n"); + return NULL; } - pl2->prev = pl1; - pl1->next = pl2; + pl2->prev = pl1; + pl1->next = pl2; - return pl2; + return pl2; } #define SKIP_SPACE(x,y) { while (*x && (isspace(*x) || *x == '\n')) x++; \ @@ -333,509 +358,574 @@ lineNode *connectLine (lineNode *pl1, lineNode *pl2) /*-----------------------------------------------------------------*/ /* getPeepLine - parses the peep lines */ /*-----------------------------------------------------------------*/ -static void getPeepLine (lineNode **head, char **bpp) +static void +getPeepLine (lineNode ** head, char **bpp) { - char lines[MAX_PATTERN_LEN]; - char *lp; - - lineNode *currL = NULL ; - char *bp = *bpp; - while (1) { + char lines[MAX_PATTERN_LEN]; + char *lp; - if (!*bp) { - fprintf(stderr,"unexpected end of match pattern\n"); - return ; - } - - if (*bp == '\n') { - bp++ ; - while (isspace(*bp) || - *bp == '\n') bp++; - } - - if (*bp == '}') { - bp++ ; - break; - } - - /* read till end of line */ - lp = lines ; - while ((*bp != '\n' && *bp != '}' ) && *bp) - *lp++ = *bp++ ; + lineNode *currL = NULL; + char *bp = *bpp; + while (1) + { - *lp = '\0'; - if (!currL) - *head = currL = newLineNode (lines); - else - currL = connectLine(currL,newLineNode(lines)); + if (!*bp) + { + fprintf (stderr, "unexpected end of match pattern\n"); + return; + } + + if (*bp == '\n') + { + bp++; + while (isspace (*bp) || + *bp == '\n') + bp++; + } + + if (*bp == '}') + { + bp++; + break; + } + + /* read till end of line */ + lp = lines; + while ((*bp != '\n' && *bp != '}') && *bp) + *lp++ = *bp++; + + *lp = '\0'; + if (!currL) + *head = currL = newLineNode (lines); + else + currL = connectLine (currL, newLineNode (lines)); } - *bpp = bp; + *bpp = bp; } /*-----------------------------------------------------------------*/ /* readRules - reads the rules from a string buffer */ /*-----------------------------------------------------------------*/ -static void readRules (char *bp) +static void +readRules (char *bp) { - char restart = 0 ; - char lines[MAX_PATTERN_LEN]; - char *lp; - lineNode *match; - lineNode *replace; - lineNode *currL = NULL; - - if (!bp) + char restart = 0; + char lines[MAX_PATTERN_LEN]; + char *lp; + lineNode *match; + lineNode *replace; + lineNode *currL = NULL; + + if (!bp) return; - top: - restart = 0; - /* look for the token "replace" that is the - start of a rule */ - while (*bp && strncmp(bp,"replace",7)) bp++; - - /* if not found */ - if (!*bp) - return ; - - /* then look for either "restart" or '{' */ - while (strncmp(bp,"restart",7) && - *bp != '{' && bp ) bp++ ; - - /* not found */ - if (!*bp) { - fprintf(stderr,"expected 'restart' or '{'\n"); - return ; - } - - /* if brace */ - if (*bp == '{') - bp++ ; - else { /* must be restart */ - restart++; - bp += strlen("restart"); - /* look for '{' */ - EXPECT_CHR(bp,'{',"expected '{'\n"); +top: + restart = 0; + /* look for the token "replace" that is the + start of a rule */ + while (*bp && strncmp (bp, "replace", 7)) bp++; + + /* if not found */ + if (!*bp) + return; + + /* then look for either "restart" or '{' */ + while (strncmp (bp, "restart", 7) && + *bp != '{' && bp) + bp++; + + /* not found */ + if (!*bp) + { + fprintf (stderr, "expected 'restart' or '{'\n"); + return; } - /* skip thru all the blank space */ - SKIP_SPACE(bp,"unexpected end of rule\n"); + /* if brace */ + if (*bp == '{') + bp++; + else + { /* must be restart */ + restart++; + bp += strlen ("restart"); + /* look for '{' */ + EXPECT_CHR (bp, '{', "expected '{'\n"); + bp++; + } - match = replace = currL = NULL ; - /* we are the start of a rule */ - getPeepLine(&match, &bp); + /* skip thru all the blank space */ + SKIP_SPACE (bp, "unexpected end of rule\n"); - /* now look for by */ - EXPECT_STR(bp,"by","expected 'by'\n"); + match = replace = currL = NULL; + /* we are the start of a rule */ + getPeepLine (&match, &bp); - /* then look for a '{' */ - EXPECT_CHR(bp,'{',"expected '{'\n"); - bp++ ; + /* now look for by */ + EXPECT_STR (bp, "by", "expected 'by'\n"); - SKIP_SPACE(bp,"unexpected end of rule\n"); - getPeepLine (&replace, &bp); + /* then look for a '{' */ + EXPECT_CHR (bp, '{', "expected '{'\n"); + bp++; - /* look for a 'if' */ - while ((isspace(*bp) || *bp == '\n') && *bp) bp++; + SKIP_SPACE (bp, "unexpected end of rule\n"); + getPeepLine (&replace, &bp); - if (strncmp(bp,"if",2) == 0) { - bp += 2; - while ((isspace(*bp) || *bp == '\n') && *bp) bp++; - if (!*bp) { - fprintf(stderr,"expected condition name\n"); - return; - } + /* look for a 'if' */ + while ((isspace (*bp) || *bp == '\n') && *bp) + bp++; - /* look for the condition */ - lp = lines; - while (*bp && (*bp != '\n')) { - *lp++ = *bp++; + if (strncmp (bp, "if", 2) == 0) + { + bp += 2; + while ((isspace (*bp) || *bp == '\n') && *bp) + bp++; + if (!*bp) + { + fprintf (stderr, "expected condition name\n"); + return; + } + + /* look for the condition */ + lp = lines; + while (*bp && (*bp != '\n')) + { + *lp++ = *bp++; + } + *lp = '\0'; + + newPeepRule (match, replace, lines, restart); } - *lp = '\0'; - - newPeepRule(match,replace,lines,restart); - } else - newPeepRule(match,replace,NULL,restart); - goto top; + else + newPeepRule (match, replace, NULL, restart); + goto top; } /*-----------------------------------------------------------------*/ /* keyForVar - returns the numeric key for a var */ /*-----------------------------------------------------------------*/ -static int keyForVar (char *d) +static int +keyForVar (char *d) { - int i = 0; + int i = 0; - while (isdigit(*d)) { - i *= 10 ; - i += (*d++ - '0') ; + while (isdigit (*d)) + { + i *= 10; + i += (*d++ - '0'); } - return i; + return i; } /*-----------------------------------------------------------------*/ /* bindVar - binds a value to a variable in the given hashtable */ /*-----------------------------------------------------------------*/ -static void bindVar (int key, char **s, hTab **vtab) +static void +bindVar (int key, char **s, hTab ** vtab) { - char vval[MAX_PATTERN_LEN]; - char *vvx; - char *vv = vval; - - /* first get the value of the variable */ - vvx = *s; - /* the value is ended by a ',' or space or newline or null */ - while (*vvx && - *vvx != ',' && - !isspace(*vvx) && - *vvx != '\n' && - *vvx != ':' ) { - char ubb = 0 ; - /* if we find a '(' then we need to balance it */ - if (*vvx == '(') { - ubb++ ; - while (ubb) { - *vv++ = *vvx++ ; - if (*vvx == '(') ubb++; - if (*vvx == ')') ubb--; - } - } else - *vv++ = *vvx++ ; - } - *s = vvx ; - *vv = '\0'; - /* got value */ - vvx = Safe_calloc(1,strlen(vval)+1); - strcpy(vvx,vval); - hTabAddItem(vtab,key,vvx); + char vval[MAX_PATTERN_LEN]; + char *vvx; + char *vv = vval; + + /* first get the value of the variable */ + vvx = *s; + /* the value is ended by a ',' or space or newline or null */ + while (*vvx && + *vvx != ',' && + !isspace (*vvx) && + *vvx != '\n' && + *vvx != ':') + { + char ubb = 0; + /* if we find a '(' then we need to balance it */ + if (*vvx == '(') + { + ubb++; + while (ubb) + { + *vv++ = *vvx++; + if (*vvx == '(') + ubb++; + if (*vvx == ')') + ubb--; + } + } + else + *vv++ = *vvx++; + } + *s = vvx; + *vv = '\0'; + /* got value */ + vvx = Safe_calloc (1, strlen (vval) + 1); + strcpy (vvx, vval); + hTabAddItem (vtab, key, vvx); } /*-----------------------------------------------------------------*/ /* matchLine - matches one line */ /*-----------------------------------------------------------------*/ -static bool matchLine (char *s, char *d, hTab **vars) +static bool +matchLine (char *s, char *d, hTab ** vars) { - if (!s || !(*s)) + if (!s || !(*s)) return FALSE; - while (*s && *d) { - - /* skip white space in both */ - while (isspace(*s)) s++; - while (isspace(*d)) d++; - - /* if the destination is a var */ - if (*d == '%' && isdigit(*(d+1))) { - char *v = hTabItemWithKey(*vars,keyForVar(d+1)); - /* if the variable is already bound - then it MUST match with dest */ - if (v) { - while (*v) - if (*v++ != *s++) return FALSE; - } else - /* variable not bound we need to - bind it */ - bindVar (keyForVar(d+1),&s,vars); - - /* in either case go past the variable */ - d++ ; - while (isdigit(*d)) d++; - } + while (*s && *d) + { - /* they should be an exact match other wise */ - if (*s && *d) { - while (isspace(*s))s++; - while (isspace(*d))d++; - if (*s++ != *d++) - return FALSE; - } + /* skip white space in both */ + while (isspace (*s)) + s++; + while (isspace (*d)) + d++; + + /* if the destination is a var */ + if (*d == '%' && isdigit (*(d + 1))) + { + char *v = hTabItemWithKey (*vars, keyForVar (d + 1)); + /* if the variable is already bound + then it MUST match with dest */ + if (v) + { + while (*v) + if (*v++ != *s++) + return FALSE; + } + else + /* variable not bound we need to + bind it */ + bindVar (keyForVar (d + 1), &s, vars); + + /* in either case go past the variable */ + d++; + while (isdigit (*d)) + d++; + } + + /* they should be an exact match other wise */ + if (*s && *d) + { + while (isspace (*s)) + s++; + while (isspace (*d)) + d++; + if (*s++ != *d++) + return FALSE; + } } - /* get rid of the trailing spaces - in both source & destination */ - if (*s) - while (isspace(*s)) s++; + /* get rid of the trailing spaces + in both source & destination */ + if (*s) + while (isspace (*s)) + s++; - if (*d) - while (isspace(*d)) d++; + if (*d) + while (isspace (*d)) + d++; - /* after all this if only one of them - has something left over then no match */ - if (*s || *d) - return FALSE ; + /* after all this if only one of them + has something left over then no match */ + if (*s || *d) + return FALSE; - return TRUE ; + return TRUE; } /*-----------------------------------------------------------------*/ /* matchRule - matches a all the rule lines */ /*-----------------------------------------------------------------*/ -static bool matchRule (lineNode *pl, - lineNode **mtail, - peepRule *pr, - lineNode *head) +static bool +matchRule (lineNode * pl, + lineNode ** mtail, + peepRule * pr, + lineNode * head) { - lineNode *spl ; /* source pl */ - lineNode *rpl ; /* rule peep line */ + lineNode *spl; /* source pl */ + lineNode *rpl; /* rule peep line */ - hTabClearAll(pr->vars); + hTabClearAll (pr->vars); /* setToNull((void **) &pr->vars); */ /* pr->vars = newHashTable(100); */ - /* for all the lines defined in the rule */ - rpl = pr->match; - spl = pl ; - while (spl && rpl) { - - /* if the source line starts with a ';' then - comment line don't process or the source line - contains == . debugger information skip it */ - if (spl->line && - (*spl->line == ';' || spl->isDebug)) { - spl = spl->next; - continue; - } - - if (!matchLine(spl->line,rpl->line,&pr->vars)) - return FALSE ; + /* for all the lines defined in the rule */ + rpl = pr->match; + spl = pl; + while (spl && rpl) + { - rpl = rpl->next ; - if (rpl) - spl = spl->next ; + /* if the source line starts with a ';' then + comment line don't process or the source line + contains == . debugger information skip it */ + if (spl->line && + (*spl->line == ';' || spl->isDebug)) + { + spl = spl->next; + continue; + } + + if (!matchLine (spl->line, rpl->line, &pr->vars)) + return FALSE; + + rpl = rpl->next; + if (rpl) + spl = spl->next; } - /* if rules ended */ - if (!rpl) { - /* if this rule has additional conditions */ - if ( pr->cond) { - if (callFuncByName (pr->cond, pr->vars,pl,head) ) { - *mtail = spl; - return TRUE; - } else - return FALSE; - } else { - *mtail = spl; - return TRUE; - } + /* if rules ended */ + if (!rpl) + { + /* if this rule has additional conditions */ + if (pr->cond) + { + if (callFuncByName (pr->cond, pr->vars, pl, head)) + { + *mtail = spl; + return TRUE; + } + else + return FALSE; + } + else + { + *mtail = spl; + return TRUE; + } } - else + else return FALSE; } /*-----------------------------------------------------------------*/ /* replaceRule - does replacement of a matching pattern */ /*-----------------------------------------------------------------*/ -static void replaceRule (lineNode **shead, lineNode *stail, peepRule *pr) +static void +replaceRule (lineNode ** shead, lineNode * stail, peepRule * pr) { - lineNode *cl = NULL; - lineNode *pl = NULL , *lhead = NULL; - char lb[MAX_PATTERN_LEN]; - char *lbp; - lineNode *comment = NULL; - - /* collect all the comment lines in the source */ - for (cl = *shead ; cl != stail ; cl = cl->next) { - if (cl->line && ( *cl->line == ';' || cl->isDebug)) { - pl = (pl ? connectLine (pl,newLineNode(cl->line)) : - (comment = newLineNode(cl->line))); - pl->isDebug = cl->isDebug; - } - } - cl = NULL; - - /* for all the lines in the replacement pattern do */ - for ( pl = pr->replace ; pl ; pl = pl->next ) { - char *v; - char *l; - lbp = lb; - - l = pl->line; - while (*l) { - /* if the line contains a variable */ - if (*l == '%' && isdigit(*(l+1))) { - v = hTabItemWithKey(pr->vars,keyForVar(l+1)); - if (!v) { - fprintf(stderr,"used unbound variable in replacement\n"); - l++; - continue; - } - while (*v) - *lbp++ = *v++; - l++; - while (isdigit(*l)) l++; - continue ; - } - *lbp++ = *l++; - } - - *lbp = '\0'; - if (cl) - cl = connectLine(cl,newLineNode(lb)); - else - lhead = cl = newLineNode(lb); - } - - /* add the comments if any to the head of list */ - if (comment) { - lineNode *lc = comment; - while (lc->next) lc = lc->next; - lc->next = lhead; - if (lhead) - lhead->prev = lc; - lhead = comment; - } - - /* now we need to connect / replace the original chain */ - /* if there is a prev then change it */ - if ((*shead)->prev) { - (*shead)->prev->next = lhead; - lhead->prev = (*shead)->prev; - } else + lineNode *cl = NULL; + lineNode *pl = NULL, *lhead = NULL; + char lb[MAX_PATTERN_LEN]; + char *lbp; + lineNode *comment = NULL; + + /* collect all the comment lines in the source */ + for (cl = *shead; cl != stail; cl = cl->next) + { + if (cl->line && (*cl->line == ';' || cl->isDebug)) + { + pl = (pl ? connectLine (pl, newLineNode (cl->line)) : + (comment = newLineNode (cl->line))); + pl->isDebug = cl->isDebug; + } + } + cl = NULL; + + /* for all the lines in the replacement pattern do */ + for (pl = pr->replace; pl; pl = pl->next) + { + char *v; + char *l; + lbp = lb; + + l = pl->line; + while (*l) + { + /* if the line contains a variable */ + if (*l == '%' && isdigit (*(l + 1))) + { + v = hTabItemWithKey (pr->vars, keyForVar (l + 1)); + if (!v) + { + fprintf (stderr, "used unbound variable in replacement\n"); + l++; + continue; + } + while (*v) + *lbp++ = *v++; + l++; + while (isdigit (*l)) + l++; + continue; + } + *lbp++ = *l++; + } + + *lbp = '\0'; + if (cl) + cl = connectLine (cl, newLineNode (lb)); + else + lhead = cl = newLineNode (lb); + } + + /* add the comments if any to the head of list */ + if (comment) + { + lineNode *lc = comment; + while (lc->next) + lc = lc->next; + lc->next = lhead; + if (lhead) + lhead->prev = lc; + lhead = comment; + } + + /* now we need to connect / replace the original chain */ + /* if there is a prev then change it */ + if ((*shead)->prev) + { + (*shead)->prev->next = lhead; + lhead->prev = (*shead)->prev; + } + else *shead = lhead; - /* now for the tail */ - if (stail && stail->next) { - stail->next->prev = cl; - if (cl) - cl->next = stail->next; + /* now for the tail */ + if (stail && stail->next) + { + stail->next->prev = cl; + if (cl) + cl->next = stail->next; } } /* Returns TRUE if this line is a label definition. - * + * If so, start will point to the start of the label name, * and len will be it's length. */ -bool isLabelDefinition(const char *line, const char **start, int *len) +bool +isLabelDefinition (const char *line, const char **start, int *len) { - const char *cp = line; + const char *cp = line; - /* This line is a label if if consists of: - * [optional whitespace] followed by identifier chars - * (alnum | $ | _ ) followed by a colon. - */ + /* This line is a label if if consists of: + * [optional whitespace] followed by identifier chars + * (alnum | $ | _ ) followed by a colon. + */ - while (*cp && isspace(*cp)) + while (*cp && isspace (*cp)) { - cp++; + cp++; } - if (!*cp) + if (!*cp) { - return FALSE; + return FALSE; } - *start = cp; + *start = cp; - while (isalnum(*cp) || (*cp == '$') || (*cp == '_')) + while (isalnum (*cp) || (*cp == '$') || (*cp == '_')) { cp++; } - if ((cp == *start) || (*cp != ':')) + if ((cp == *start) || (*cp != ':')) { - return FALSE; + return FALSE; } - *len = (cp - (*start)); - return TRUE; + *len = (cp - (*start)); + return TRUE; } /* Quick & dirty string hash function. */ -static int hashSymbolName(const char *name) +static int +hashSymbolName (const char *name) { - int hash = 0; + int hash = 0; - while (*name) + while (*name) { - hash = (hash << 6) ^ *name; - name++; + hash = (hash << 6) ^ *name; + name++; } - if (hash < 0) + if (hash < 0) { hash = -hash; } - return hash % HTAB_SIZE; + return hash % HTAB_SIZE; } /* Build a hash of all labels in the passed set of lines * and how many times they are referenced. */ -static void buildLabelRefCountHash(lineNode *head) +static void +buildLabelRefCountHash (lineNode * head) { - lineNode *line; - const char *label; - int labelLen; - int i; + lineNode *line; + const char *label; + int labelLen; + int i; - assert(labelHash == NULL); - labelHash = newHashTable(HTAB_SIZE); + assert (labelHash == NULL); + labelHash = newHashTable (HTAB_SIZE); - /* First pass: locate all the labels. */ - line = head; + /* First pass: locate all the labels. */ + line = head; - while (line) + while (line) { - if (isLabelDefinition(line->line, &label, &labelLen) - && labelLen <= SDCC_NAME_MAX) - { - labelHashEntry *entry; + if (isLabelDefinition (line->line, &label, &labelLen) + && labelLen <= SDCC_NAME_MAX) + { + labelHashEntry *entry; - entry = Safe_calloc(1,sizeof(labelHashEntry)); + entry = Safe_calloc (1, sizeof (labelHashEntry)); - memcpy(entry->name, label, labelLen); - entry->name[labelLen] = 0; - entry->refCount = -1; + memcpy (entry->name, label, labelLen); + entry->name[labelLen] = 0; + entry->refCount = -1; - hTabAddItem(&labelHash, hashSymbolName(entry->name), entry); - } - line = line->next; + hTabAddItem (&labelHash, hashSymbolName (entry->name), entry); + } + line = line->next; } - /* Second pass: for each line, note all the referenced labels. */ - /* This is ugly, O(N^2) stuff. Optimizations welcome... */ - line = head; - while (line) + /* Second pass: for each line, note all the referenced labels. */ + /* This is ugly, O(N^2) stuff. Optimizations welcome... */ + line = head; + while (line) { for (i = 0; i < HTAB_SIZE; i++) - { - labelHashEntry *thisEntry; - - thisEntry = hTabFirstItemWK(labelHash, i); - - while (thisEntry) - { - if (strstr(line->line, thisEntry->name)) - { - thisEntry->refCount++; - } - thisEntry = hTabNextItemWK(labelHash); - } - } - line = line->next; + { + labelHashEntry *thisEntry; + + thisEntry = hTabFirstItemWK (labelHash, i); + + while (thisEntry) + { + if (strstr (line->line, thisEntry->name)) + { + thisEntry->refCount++; + } + thisEntry = hTabNextItemWK (labelHash); + } + } + line = line->next; } #if 0 - /* Spew the contents of the table. Debugging fun only. */ - for (i = 0; i < HTAB_SIZE; i++) + /* Spew the contents of the table. Debugging fun only. */ + for (i = 0; i < HTAB_SIZE; i++) { - labelHashEntry *thisEntry; + labelHashEntry *thisEntry; - thisEntry = hTabFirstItemWK(labelHash, i); + thisEntry = hTabFirstItemWK (labelHash, i); - while (thisEntry) - { - fprintf(stderr, "label: %s ref %d\n", - thisEntry->name, thisEntry->refCount); - thisEntry = hTabNextItemWK(labelHash); - } + while (thisEntry) + { + fprintf (stderr, "label: %s ref %d\n", + thisEntry->name, thisEntry->refCount); + thisEntry = hTabNextItemWK (labelHash); + } } #endif } @@ -843,45 +933,49 @@ static void buildLabelRefCountHash(lineNode *head) /*-----------------------------------------------------------------*/ /* peepHole - matches & substitutes rules */ /*-----------------------------------------------------------------*/ -void peepHole (lineNode **pls ) +void +peepHole (lineNode ** pls) { - lineNode *spl ; - peepRule *pr ; - lineNode *mtail = NULL; + lineNode *spl; + peepRule *pr; + lineNode *mtail = NULL; - if (labelHash) + if (labelHash) { - hTabDeleteAll(labelHash); + hTabDeleteAll (labelHash); } - labelHash = NULL; + labelHash = NULL; - top: - /* for all rules */ - for (pr = rootRules ; pr ; pr = pr->next ) { +top: + /* for all rules */ + for (pr = rootRules; pr; pr = pr->next) + { - for (spl = *pls ; spl ; spl = spl->next ) { + for (spl = *pls; spl; spl = spl->next) + { - /* if inline assembler then no peep hole */ - if (spl->isInline) - continue ; + /* if inline assembler then no peep hole */ + if (spl->isInline) + continue; - mtail = NULL ; + mtail = NULL; - /* if it matches */ - if (matchRule (spl,&mtail,pr, *pls)) { + /* if it matches */ + if (matchRule (spl, &mtail, pr, *pls)) + { - /* then replace */ - if (spl == *pls) - replaceRule(pls, mtail, pr); - else - replaceRule (&spl, mtail,pr); + /* then replace */ + if (spl == *pls) + replaceRule (pls, mtail, pr); + else + replaceRule (&spl, mtail, pr); - /* if restart rule type then - start at the top again */ - if (pr->restart) - goto top; - } - } + /* if restart rule type then + start at the top again */ + if (pr->restart) + goto top; + } + } } } @@ -889,65 +983,78 @@ void peepHole (lineNode **pls ) /*-----------------------------------------------------------------*/ /* readFileIntoBuffer - reads a file into a string buffer */ /*-----------------------------------------------------------------*/ -static char *readFileIntoBuffer (char *fname) +static char * +readFileIntoBuffer (char *fname) { - FILE *f; - char *rs = NULL; - int nch = 0 ; - int ch; - char lb[MAX_PATTERN_LEN]; - - if (!(f = fopen(fname,"r"))) { - fprintf(stderr,"cannot open peep rule file\n"); - return NULL; - } - - while ((ch = fgetc(f)) != EOF) { - lb[nch++] = ch; - - /* if we maxed out our local buffer */ - if (nch >= (MAX_PATTERN_LEN - 2)) { - lb[nch] = '\0'; - /* copy it into allocated buffer */ - if (rs) { - rs = Safe_realloc(rs,strlen(rs)+strlen(lb)+1); - strcat(rs,lb); - } else { - rs = Safe_calloc(1,strlen(lb)+1); - strcpy(rs,lb); - } - nch = 0 ; - } - } - - /* if some charaters left over */ - if (nch) { - lb[nch] = '\0'; - /* copy it into allocated buffer */ - if (rs) { - rs = Safe_realloc(rs,strlen(rs)+strlen(lb)+1); - strcat(rs,lb); - } else { - rs = Safe_calloc(1,strlen(lb)+1); - strcpy(rs,lb); - } - } - return rs; + FILE *f; + char *rs = NULL; + int nch = 0; + int ch; + char lb[MAX_PATTERN_LEN]; + + if (!(f = fopen (fname, "r"))) + { + fprintf (stderr, "cannot open peep rule file\n"); + return NULL; + } + + while ((ch = fgetc (f)) != EOF) + { + lb[nch++] = ch; + + /* if we maxed out our local buffer */ + if (nch >= (MAX_PATTERN_LEN - 2)) + { + lb[nch] = '\0'; + /* copy it into allocated buffer */ + if (rs) + { + rs = Safe_realloc (rs, strlen (rs) + strlen (lb) + 1); + strcat (rs, lb); + } + else + { + rs = Safe_calloc (1, strlen (lb) + 1); + strcpy (rs, lb); + } + nch = 0; + } + } + + /* if some charaters left over */ + if (nch) + { + lb[nch] = '\0'; + /* copy it into allocated buffer */ + if (rs) + { + rs = Safe_realloc (rs, strlen (rs) + strlen (lb) + 1); + strcat (rs, lb); + } + else + { + rs = Safe_calloc (1, strlen (lb) + 1); + strcpy (rs, lb); + } + } + return rs; } /*-----------------------------------------------------------------*/ /* initPeepHole - initiaises the peep hole optimizer stuff */ /*-----------------------------------------------------------------*/ -void initPeepHole () +void +initPeepHole () { - char *s; + char *s; - /* read in the default rules */ - readRules(port->peep.default_rules); + /* read in the default rules */ + readRules (port->peep.default_rules); - /* if we have any additional file read it too */ - if (options.peep_file) { - readRules(s=readFileIntoBuffer(options.peep_file)); - setToNull((void **) &s); + /* if we have any additional file read it too */ + if (options.peep_file) + { + readRules (s = readFileIntoBuffer (options.peep_file)); + setToNull ((void **) &s); } } diff --git a/src/SDCCpeeph.h b/src/SDCCpeeph.h index a53adc21..4fa53a59 100644 --- a/src/SDCCpeeph.h +++ b/src/SDCCpeeph.h @@ -29,29 +29,31 @@ #define MAX_PATTERN_LEN 128 typedef struct lineNode -{ - char *line ; + { + char *line; unsigned int isInline:1; unsigned int isComment:1; unsigned int isDebug:1; struct lineNode *prev; struct lineNode *next; -} lineNode; + } +lineNode; typedef struct peepRule -{ - lineNode *match ; - lineNode *replace ; - unsigned int restart : 1; + { + lineNode *match; + lineNode *replace; + unsigned int restart:1; char *cond; hTab *vars; struct peepRule *next; -} peepRule; + } +peepRule; -void printLine (lineNode *,FILE *); +void printLine (lineNode *, FILE *); lineNode *newLineNode (char *); -lineNode *connectLine (lineNode *,lineNode *); -void initPeepHole(void); +lineNode *connectLine (lineNode *, lineNode *); +void initPeepHole (void); void peepHole (lineNode **); #endif diff --git a/src/SDCCptropt.c b/src/SDCCptropt.c index dec83e5f..1e09a49a 100644 --- a/src/SDCCptropt.c +++ b/src/SDCCptropt.c @@ -28,84 +28,94 @@ /*-----------------------------------------------------------------------*/ /* findPointerGetSet - find the pointer get or set for a operand */ /*-----------------------------------------------------------------------*/ -static iCode *findPointerGetSet(iCode *sic,operand *op) +static iCode * +findPointerGetSet (iCode * sic, operand * op) { - iCode *ic = sic; + iCode *ic = sic; - for (; ic ; ic = ic->next) { - if ((POINTER_SET(ic) && isOperandEqual(op,IC_RESULT(ic))) || - (POINTER_GET(ic) && isOperandEqual(op,IC_LEFT(ic)))) - return ic; + for (; ic; ic = ic->next) + { + if ((POINTER_SET (ic) && isOperandEqual (op, IC_RESULT (ic))) || + (POINTER_GET (ic) && isOperandEqual (op, IC_LEFT (ic)))) + return ic; - /* if we find any other usage or definition of op null */ - if (IC_RESULT(ic) && isOperandEqual(IC_RESULT(ic),op)) - return NULL; + /* if we find any other usage or definition of op null */ + if (IC_RESULT (ic) && isOperandEqual (IC_RESULT (ic), op)) + return NULL; - if (IC_RIGHT(ic) && isOperandEqual(IC_RIGHT(ic),op)) - return NULL; - - if (IC_LEFT(ic) && isOperandEqual(IC_LEFT(ic),op)) - return NULL; + if (IC_RIGHT (ic) && isOperandEqual (IC_RIGHT (ic), op)) + return NULL; + + if (IC_LEFT (ic) && isOperandEqual (IC_LEFT (ic), op)) + return NULL; } - return NULL; + return NULL; } /*-----------------------------------------------------------------------*/ /* ptrPostIncDecOpts - will do some pointer post increment optimizations */ /* this will help register allocation amongst others */ /*-----------------------------------------------------------------------*/ -void ptrPostIncDecOpt (iCode *sic) +void +ptrPostIncDecOpt (iCode * sic) { - /* this is what we do. look for sequences like - - iTempX := _SOME_POINTER_; - iTempY := _SOME_POINTER_ + nn ; nn = sizeof (pointed to object) - _SOME_POINTER_ := iTempY; - either - iTempZ := @[iTempX]; - or - *(iTempX) := ..something.. - if we find this then transform this to - iTempX := _SOME_POINTER_; - either - iTempZ := @[iTempX]; - or - *(iTempX) := ..something.. - iTempY := _SOME_POINTER_ + nn ; nn = sizeof (pointed to object) - _SOME_POINTER_ := iTempY; */ - - /* sounds simple enough so lets start , here I use -ve - tests all the way to return if any test fails */ - iCode *pgs, *sh,*st; - - if (!( sic->next && sic->next->next && sic->next->next->next)) - return ; - if (sic->next->op != '+' && sic->next->op != '-') return; - if (!(sic->next->next->op == '=' && - !POINTER_SET(sic->next->next))) return; - if (!isOperandEqual(IC_LEFT(sic->next),IC_RIGHT(sic)) || - !IS_OP_LITERAL(IC_RIGHT(sic->next)) ) return; - if (operandLitValue(IC_RIGHT(sic->next)) != - getSize(operandType(IC_RIGHT(sic))->next)) return; - if (!isOperandEqual(IC_RESULT(sic->next->next), - IC_RIGHT(sic))) return; - if (!isOperandEqual(IC_RESULT(sic->next),IC_RIGHT(sic->next->next))) return; - if (!(pgs = findPointerGetSet(sic->next->next,IC_RESULT(sic)))) - return; - - /* found the patter .. now do the transformation */ - sh = sic->next; st = sic->next->next ; - - /* take the two out of the chain */ - sic->next = st->next; - st->next->prev = sic; - - /* and put them after the pointer get/set icode */ - if ((st->next = pgs->next)) - st->next->prev = st; - pgs->next = sh; - sh->prev = pgs; - + /* this is what we do. look for sequences like + + iTempX := _SOME_POINTER_; + iTempY := _SOME_POINTER_ + nn ; nn = sizeof (pointed to object) + _SOME_POINTER_ := iTempY; + either + iTempZ := @[iTempX]; + or + *(iTempX) := ..something.. + if we find this then transform this to + iTempX := _SOME_POINTER_; + either + iTempZ := @[iTempX]; + or + *(iTempX) := ..something.. + iTempY := _SOME_POINTER_ + nn ; nn = sizeof (pointed to object) + _SOME_POINTER_ := iTempY; */ + + /* sounds simple enough so lets start , here I use -ve + tests all the way to return if any test fails */ + iCode *pgs, *sh, *st; + + if (!(sic->next && sic->next->next && sic->next->next->next)) + return; + if (sic->next->op != '+' && sic->next->op != '-') + return; + if (!(sic->next->next->op == '=' && + !POINTER_SET (sic->next->next))) + return; + if (!isOperandEqual (IC_LEFT (sic->next), IC_RIGHT (sic)) || + !IS_OP_LITERAL (IC_RIGHT (sic->next))) + return; + if (operandLitValue (IC_RIGHT (sic->next)) != + getSize (operandType (IC_RIGHT (sic))->next)) + return; + if (!isOperandEqual (IC_RESULT (sic->next->next), + IC_RIGHT (sic))) + return; + if (!isOperandEqual (IC_RESULT (sic->next), IC_RIGHT (sic->next->next))) + return; + if (!(pgs = findPointerGetSet (sic->next->next, IC_RESULT (sic)))) + return; + + /* found the patter .. now do the transformation */ + sh = sic->next; + st = sic->next->next; + + /* take the two out of the chain */ + sic->next = st->next; + st->next->prev = sic; + + /* and put them after the pointer get/set icode */ + if ((st->next = pgs->next)) + st->next->prev = st; + pgs->next = sh; + sh->prev = pgs; + } diff --git a/src/SDCCset.c b/src/SDCCset.c index 0843b719..24e936aa 100644 --- a/src/SDCCset.c +++ b/src/SDCCset.c @@ -30,17 +30,18 @@ /*-----------------------------------------------------------------*/ /* newSet - will allocate & return a new set entry */ /*-----------------------------------------------------------------*/ -set *newSet () +set * +newSet () { - set *lp ; + set *lp; - lp = Safe_calloc(1,sizeof(set)); + lp = Safe_calloc (1, sizeof (set)); // if (lp == 0) { -// fprintf(stderr, "out of virtual memory: %s\n", __FILE__); -// exit(1); -// } + // fprintf(stderr, "out of virtual memory: %s\n", __FILE__); + // exit(1); + // } - lp->item = lp->curr= lp->next = NULL; + lp->item = lp->curr = lp->next = NULL; return lp; } @@ -48,16 +49,18 @@ set *newSet () /*-----------------------------------------------------------------*/ /* setFromSet - creates a list from another list */ /*-----------------------------------------------------------------*/ -set *setFromSet (set *lp) +set * +setFromSet (set * lp) { - set *lfl = NULL ; + set *lfl = NULL; - while (lp) { - addSetHead(&lfl,lp->item); - lp = lp->next ; - } + while (lp) + { + addSetHead (&lfl, lp->item); + lp = lp->next; + } - return lfl ; + return lfl; } @@ -65,444 +68,487 @@ set *setFromSet (set *lp) /* isSetsEqual - are the lists equal, they are equal if they have */ /* the same objects & the same number of objects */ /*-----------------------------------------------------------------*/ -int isSetsEqual ( set *dest, set *src ) +int +isSetsEqual (set * dest, set * src) { - set *src1 = src ; + set *src1 = src; - for (; dest && src ; dest=dest->next , src=src->next) { - if (!isinSet(src1, dest->item)) - return 0; + for (; dest && src; dest = dest->next, src = src->next) + { + if (!isinSet (src1, dest->item)) + return 0; } - if ( !dest && !src) - return 1; - return 0; + if (!dest && !src) + return 1; + return 0; } /*-----------------------------------------------------------------*/ /* isSetsEqualWith - are the lists equal, they are equal if they have */ /* the same objects & the same number of objects , compare function */ /*-----------------------------------------------------------------*/ -int isSetsEqualWith ( set *dest, set *src , int (*cFunc)(void *,void *)) +int +isSetsEqualWith (set * dest, set * src, int (*cFunc) (void *, void *)) { - set *src1 = src ; + set *src1 = src; - for (; dest && src ; dest=dest->next , src=src->next) { - if (!isinSetWith(src1, dest->item,cFunc)) - return 0; + for (; dest && src; dest = dest->next, src = src->next) + { + if (!isinSetWith (src1, dest->item, cFunc)) + return 0; } - if ( !dest && !src) - return 1; - return 0; + if (!dest && !src) + return 1; + return 0; } /*-----------------------------------------------------------------*/ /* addSetIfnotP - adds to a linked list if not already present */ /*-----------------------------------------------------------------*/ -void *addSetIfnotP ( set **list, void *item) +void * +addSetIfnotP (set ** list, void *item) { - if (isinSet(*list,item)) - return item ; + if (isinSet (*list, item)) + return item; - addSetHead(list,item); + addSetHead (list, item); - return item; + return item; } /*-----------------------------------------------------------------*/ /* addSetHead - add item to head of linked list */ /*-----------------------------------------------------------------*/ -void *addSetHead (set **list, void *item ) +void * +addSetHead (set ** list, void *item) { - set *lp = newSet(); + set *lp = newSet (); - lp->item = item ; - lp->next = *list ; + lp->item = item; + lp->next = *list; - assert(lp != lp->item); - *list = lp ; - return item ; + assert (lp != lp->item); + *list = lp; + return item; } /*-----------------------------------------------------------------*/ /* addSet - add an item to a linear linked list */ /*-----------------------------------------------------------------*/ -void *addSet ( set **list , void *item ) +void * +addSet (set ** list, void *item) { - set *lp ; + set *lp; - /* item added to the tail of the list */ + /* item added to the tail of the list */ - /* if the list is empty */ - if (*list == NULL ) { - lp = *list = newSet(); - } else { - /* go to the end of the list */ - for (lp = *list ; lp->next ; lp = lp->next ); - lp = lp->next = newSet(); + /* if the list is empty */ + if (*list == NULL) + { + lp = *list = newSet (); + } + else + { + /* go to the end of the list */ + for (lp = *list; lp->next; lp = lp->next); + lp = lp->next = newSet (); } - /* lp now all set */ - lp->item = item ; + /* lp now all set */ + lp->item = item; - return item ; + return item; } /*-----------------------------------------------------------------*/ /* deleteItemIf - will delete from set if cond function returns 1 */ /*-----------------------------------------------------------------*/ -void deleteItemIf ( set **sset, int (*cond) (void *, va_list), ... ) +void +deleteItemIf (set ** sset, int (*cond) (void *, va_list),...) { - set *sp = *sset ; - va_list ap; + set *sp = *sset; + va_list ap; - va_start(ap,cond); + va_start (ap, cond); - while (sp) { - if ((*cond)(sp->item,ap)) { - deleteSetItem(sset,sp->item); - sp = *sset ; - continue ; - } + while (sp) + { + if ((*cond) (sp->item, ap)) + { + deleteSetItem (sset, sp->item); + sp = *sset; + continue; + } - sp = sp->next ; + sp = sp->next; } } /*-----------------------------------------------------------------*/ /* deleteSetItem - will delete a given item from the list */ /*-----------------------------------------------------------------*/ -void deleteSetItem ( set **list, void *item ) +void +deleteSetItem (set ** list, void *item) { - set *lp , *lp1; - - /* if list is empty */ - if (*list == NULL ) - return ; - - /* if this item is at the head of the list */ - if ((*list)->item == item ) { - lp = *list ; - *list = (*list)->next ; - return ; + set *lp, *lp1; + + /* if list is empty */ + if (*list == NULL) + return; + + /* if this item is at the head of the list */ + if ((*list)->item == item) + { + lp = *list; + *list = (*list)->next; + return; } - /* find the item in the list */ - for (lp = *list ; lp->next ; lp = lp->next ) { - if (lp->next->item == item ) /* the next one is it */ { - lp1 = lp->next ; /* this one will need to be freed */ - lp->next = lp->next->next ; /* take out of list */ - return ; - } + /* find the item in the list */ + for (lp = *list; lp->next; lp = lp->next) + { + if (lp->next->item == item) /* the next one is it */ + { + lp1 = lp->next; /* this one will need to be freed */ + lp->next = lp->next->next; /* take out of list */ + return; + } } - /* could not find it */ - return ; + /* could not find it */ + return; } /*-----------------------------------------------------------------*/ /* isinSet - the item is present in the linked list */ /*-----------------------------------------------------------------*/ -int isinSet (set *list, void *item ) +int +isinSet (set * list, void *item) { - set *lp ; + set *lp; - for (lp = list ; lp ; lp = lp->next ) - if ( lp->item == item ) + for (lp = list; lp; lp = lp->next) + if (lp->item == item) return 1; - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* isinSetWith - the item is present in the linked list */ /*-----------------------------------------------------------------*/ -int isinSetWith (set *list, void *item , int (*cFunc)(void *,void *) ) +int +isinSetWith (set * list, void *item, int (*cFunc) (void *, void *)) { - set *lp ; + set *lp; - for (lp = list ; lp ; lp = lp->next ) - if ( (*cFunc)(lp->item,item) ) + for (lp = list; lp; lp = lp->next) + if ((*cFunc) (lp->item, item)) return 1; - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* unionSets - will return the union of the two lists */ /*-----------------------------------------------------------------*/ -set *unionSets (set *list1 , set *list2, int throw) +set * +unionSets (set * list1, set * list2, int throw) { - set *un = NULL ; - set *lp ; - - /* add all elements in the first list */ - for (lp = list1 ; lp ; lp = lp->next ) - addSet(&un,lp->item); - - /* now for all those in list2 which does not */ - /* already exist in the list add */ - for (lp = list2 ; lp ; lp = lp->next ) - if (!isinSet(un,lp->item)) - addSet (&un,lp->item); - - switch (throw) { - case THROW_SRC : - setToNull ((void **)&list2); - break; - case THROW_DEST : - setToNull ((void **)&list1); - break; - case THROW_BOTH : - setToNull ((void **)&list1); - setToNull ((void **)&list2); + set *un = NULL; + set *lp; + + /* add all elements in the first list */ + for (lp = list1; lp; lp = lp->next) + addSet (&un, lp->item); + + /* now for all those in list2 which does not */ + /* already exist in the list add */ + for (lp = list2; lp; lp = lp->next) + if (!isinSet (un, lp->item)) + addSet (&un, lp->item); + + switch (throw) + { + case THROW_SRC: + setToNull ((void **) &list2); + break; + case THROW_DEST: + setToNull ((void **) &list1); + break; + case THROW_BOTH: + setToNull ((void **) &list1); + setToNull ((void **) &list2); } - return un; + return un; } /*-----------------------------------------------------------------*/ /* unionSetsWith - will return the union of the two lists */ /*-----------------------------------------------------------------*/ -set *unionSetsWith (set *list1 , set *list2, int (*cFunc)(),int throw) +set * +unionSetsWith (set * list1, set * list2, int (*cFunc) (), int throw) { - set *un = NULL ; - set *lp ; - - /* add all elements in the first list */ - for (lp = list1 ; lp ; lp = lp->next ) - addSet (&un,lp->item); - - /* now for all those in list2 which does not */ - /* already exist in the list add */ - for (lp = list2 ; lp ; lp = lp->next ) - if (!isinSetWith(un,lp->item,(int(*)(void*,void*))cFunc)) - addSet (&un,lp->item); - - switch (throw) { - case THROW_SRC : - setToNull ((void **)&list2); - break; - case THROW_DEST : - setToNull ((void **)&list1); - break; - case THROW_BOTH : - setToNull ((void **)&list1); - setToNull ((void **)&list2); + set *un = NULL; + set *lp; + + /* add all elements in the first list */ + for (lp = list1; lp; lp = lp->next) + addSet (&un, lp->item); + + /* now for all those in list2 which does not */ + /* already exist in the list add */ + for (lp = list2; lp; lp = lp->next) + if (!isinSetWith (un, lp->item, (int (*)(void *, void *)) cFunc)) + addSet (&un, lp->item); + + switch (throw) + { + case THROW_SRC: + setToNull ((void **) &list2); + break; + case THROW_DEST: + setToNull ((void **) &list1); + break; + case THROW_BOTH: + setToNull ((void **) &list1); + setToNull ((void **) &list2); } - return un; + return un; } /*-----------------------------------------------------------------*/ /* intersectSets - returns list of items in common to two lists */ /*-----------------------------------------------------------------*/ -set *intersectSets (set *list1, set *list2, int throw) +set * +intersectSets (set * list1, set * list2, int throw) { - set *in = NULL; - set *lp ; - - /* we can take any one of the lists and iterate over it */ - for (lp = list1 ; lp ; lp = lp->next ) - if (isinSet (list2,lp->item) ) - addSetHead(&in,lp->item); - - switch (throw) { - case THROW_SRC : - setToNull ((void **)&list2); - break; - case THROW_DEST : - setToNull ((void **)&list1); - break; - case THROW_BOTH : - setToNull ((void **)&list1); - setToNull ((void **)&list2); + set *in = NULL; + set *lp; + + /* we can take any one of the lists and iterate over it */ + for (lp = list1; lp; lp = lp->next) + if (isinSet (list2, lp->item)) + addSetHead (&in, lp->item); + + switch (throw) + { + case THROW_SRC: + setToNull ((void **) &list2); + break; + case THROW_DEST: + setToNull ((void **) &list1); + break; + case THROW_BOTH: + setToNull ((void **) &list1); + setToNull ((void **) &list2); } - return in; + return in; } /*-----------------------------------------------------------------*/ -/* intersectSetsWith - returns list of items in common to two lists*/ +/* intersectSetsWith - returns list of items in common to two lists */ /*-----------------------------------------------------------------*/ -set *intersectSetsWith (set *list1, set *list2, - int (*cFunc)(void *,void *),int throw) +set * +intersectSetsWith (set * list1, set * list2, + int (*cFunc) (void *, void *), int throw) { - set *in = NULL; - set *lp ; - - /* we can take any one of the lists and iterate over it */ - for (lp = list1 ; lp ; lp = lp->next ) - if (isinSetWith (list2,lp->item,cFunc) ) - addSetHead(&in,lp->item); - - switch (throw) { - case THROW_SRC : - setToNull ((void **)&list2); - break; - case THROW_DEST : - setToNull ((void **)&list1); - break; - case THROW_BOTH : - setToNull ((void **)&list1); - setToNull ((void **)&list2); + set *in = NULL; + set *lp; + + /* we can take any one of the lists and iterate over it */ + for (lp = list1; lp; lp = lp->next) + if (isinSetWith (list2, lp->item, cFunc)) + addSetHead (&in, lp->item); + + switch (throw) + { + case THROW_SRC: + setToNull ((void **) &list2); + break; + case THROW_DEST: + setToNull ((void **) &list1); + break; + case THROW_BOTH: + setToNull ((void **) &list1); + setToNull ((void **) &list2); } - return in; + return in; } /*-----------------------------------------------------------------*/ /* elementsInSet - elements count of a set */ /*-----------------------------------------------------------------*/ -int elementsInSet (set *s) +int +elementsInSet (set * s) { - set *loop = s; - int count = 0 ; + set *loop = s; + int count = 0; - while (loop) { - count++ ; - loop = loop->next ; + while (loop) + { + count++; + loop = loop->next; } - return count ; + return count; } /*-----------------------------------------------------------------*/ /* subtractFromSet - take away from set1 elements of set2 */ /*-----------------------------------------------------------------*/ -set *subtractFromSet (set *left, set *right, int throw) +set * +subtractFromSet (set * left, set * right, int throw) { - set *result = setFromSet(left); - set *loop ; - - if (right) { - for (loop = right ; loop ; loop = loop->next) - if (isinSet(result,loop->item)) - deleteSetItem (&result,loop->item); + set *result = setFromSet (left); + set *loop; + + if (right) + { + for (loop = right; loop; loop = loop->next) + if (isinSet (result, loop->item)) + deleteSetItem (&result, loop->item); } - switch (throw) { - case THROW_SRC : - setToNull ((void **)&right); - break; - case THROW_DEST : - setToNull ((void **)&left); - break; - case THROW_BOTH : - setToNull ((void **)&left); - setToNull ((void **)&right); - break ; + switch (throw) + { + case THROW_SRC: + setToNull ((void **) &right); + break; + case THROW_DEST: + setToNull ((void **) &left); + break; + case THROW_BOTH: + setToNull ((void **) &left); + setToNull ((void **) &right); + break; } - return result ; + return result; } /*-----------------------------------------------------------------*/ /* applyToSet - will call the supplied function with each item */ /*-----------------------------------------------------------------*/ -int applyToSet ( set *list , int (*somefunc)(void *, va_list ), ...) +int +applyToSet (set * list, int (*somefunc) (void *, va_list),...) { - set *lp ; - va_list ap; - int rvalue = 0 ; - - for (lp = list ; lp ; lp = lp->next ) { - va_start(ap,somefunc); - rvalue += (*somefunc)(lp->item,ap) ; - va_end(ap); + set *lp; + va_list ap; + int rvalue = 0; + + for (lp = list; lp; lp = lp->next) + { + va_start (ap, somefunc); + rvalue += (*somefunc) (lp->item, ap); + va_end (ap); } - return rvalue; + return rvalue; } /*-----------------------------------------------------------------*/ -/* applyToSetFTrue - will call the supplied function with each item*/ +/* applyToSetFTrue - will call the supplied function with each item */ /* until list is exhausted or a true is returned */ /*-----------------------------------------------------------------*/ -int applyToSetFTrue ( set *list , int (*somefunc)(void *, va_list ), ...) +int +applyToSetFTrue (set * list, int (*somefunc) (void *, va_list),...) { - set *lp ; - va_list ap; - int rvalue = 0 ; - - for (lp = list ; lp ; lp = lp->next ) { - va_start(ap,somefunc); - rvalue += (*somefunc)(lp->item,ap); - va_end(ap); - if (rvalue) - break; + set *lp; + va_list ap; + int rvalue = 0; + + for (lp = list; lp; lp = lp->next) + { + va_start (ap, somefunc); + rvalue += (*somefunc) (lp->item, ap); + va_end (ap); + if (rvalue) + break; } - return rvalue; + return rvalue; } /*-----------------------------------------------------------------*/ /* peekSet - will return the first element of the set */ /*-----------------------------------------------------------------*/ -void *peekSet ( set *sp) +void * +peekSet (set * sp) { - if (!sp) - return NULL ; + if (!sp) + return NULL; - return sp->item; + return sp->item; } /*-----------------------------------------------------------------*/ /* setFirstItem - gets the first item in the set, begins iteration */ /*-----------------------------------------------------------------*/ -void *setFirstItem (set *sset) +void * +setFirstItem (set * sset) { - if (sset) { - sset->curr = sset ; - return sset->item ; + if (sset) + { + sset->curr = sset; + return sset->item; } - return NULL ; + return NULL; } /*-----------------------------------------------------------------*/ /* setNextItem - gets the next item, changes the iteration */ /*-----------------------------------------------------------------*/ -void *setNextItem (set *sset) +void * +setNextItem (set * sset) { - if (sset && sset->curr ) { - sset->curr = sset->curr->next ; - if ( sset->curr ) - return sset->curr->item ; + if (sset && sset->curr) + { + sset->curr = sset->curr->next; + if (sset->curr) + return sset->curr->item; } - return NULL ; + return NULL; } /*-----------------------------------------------------------------*/ /* getSet - will delete & return the first item from the set */ /*-----------------------------------------------------------------*/ -void *getSet (set **list) +void * +getSet (set ** list) { - set *lp; - void *item ; + set *lp; + void *item; - /* if list is empty then we cannot delete */ - if (*list == NULL ) - return (void *) NULL ; + /* if list is empty then we cannot delete */ + if (*list == NULL) + return (void *) NULL; - /* find the item in the list */ - lp = *list ; - item = lp->item; /* save the item */ + /* find the item in the list */ + lp = *list; + item = lp->item; /* save the item */ - *list = lp->next ; - return item ; + *list = lp->next; + return item; } /*-----------------------------------------------------------------*/ /* setToNull - will throw away the entire list */ /*-----------------------------------------------------------------*/ -void setToNull (void **item ) +void +setToNull (void **item) { - if ( !item ) - return ; + if (!item) + return; - if (! *item ) - return ; - free(*item); - *item = NULL ; + if (!*item) + return; + free (*item); + *item = NULL; } diff --git a/src/SDCCset.h b/src/SDCCset.h index 298ab89c..f5179baa 100644 --- a/src/SDCCset.h +++ b/src/SDCCset.h @@ -27,55 +27,56 @@ #include #if defined(_MSC_VER) -# include "sdcc_vc.h" +#include "sdcc_vc.h" #else -# include "sdccconf.h" -#endif // _MSC_VER +#include "sdccconf.h" +#endif // _MSC_VER #ifndef THROWS #define THROWS -#define THROW_NONE 0 -#define THROW_SRC 1 +#define THROW_NONE 0 +#define THROW_SRC 1 #define THROW_DEST 2 #define THROW_BOTH 3 #endif /* linear linked list generic */ typedef struct set -{ - void *item ; - struct set *curr ; - struct set *next ; -} set ; + { + void *item; + struct set *curr; + struct set *next; + } +set; #define DEFSETFUNC(fname) int fname ( void *item, va_list ap) -#define V_ARG(type,var) type var = va_arg(ap,type) +#define V_ARG(type,var) type var = va_arg(ap,type) /* set related functions */ -void *addSet ( set ** , void * ); -void *addSetHead ( set ** , void * ); -void *getSet ( set ** ); -void deleteSetItem ( set ** , void * ); -void deleteItemIf ( set ** , int (*cond) (void *, va_list), ... ); -int isinSet ( set * , void * ); -int isinSetWith ( set *, void *, int (*cfunc)(void*,void*)); -int applyToSet ( set *list ,int (*somefunc)(void *,va_list), ...); -int applyToSetFTrue ( set *list ,int (*somefunc)(void *,va_list), ...); -set *unionSets ( set *, set *, int); -set *unionSetsWith ( set *, set *, int (*cFunc)(),int); -set *intersectSets ( set *, set *, int); -void *addSetIfnotP ( set **, void *); -set *setFromSet ( set * ); -int isSetsEqual ( set *, set *); -set *subtractFromSet ( set *, set *,int); -int elementsInSet (set *); -set *intersectSetsWith (set *, set *,int (*cFunc)(void *,void *),int ); -int isSetsEqualWith ( set *, set *, int (*cFunc)(void *,void *)); -void *peekSet ( set *); -void *setFirstItem ( set *); -void *setNextItem ( set *); -void setToNull (void ** ); +void *addSet (set **, void *); +void *addSetHead (set **, void *); +void *getSet (set **); +void deleteSetItem (set **, void *); +void deleteItemIf (set **, int (*cond) (void *, va_list),...); +int isinSet (set *, void *); +int isinSetWith (set *, void *, int (*cfunc) (void *, void *)); +int applyToSet (set * list, int (*somefunc) (void *, va_list),...); +int applyToSetFTrue (set * list, int (*somefunc) (void *, va_list),...); +set *unionSets (set *, set *, int); +set *unionSetsWith (set *, set *, int (*cFunc) (), int); +set *intersectSets (set *, set *, int); +void *addSetIfnotP (set **, void *); +set *setFromSet (set *); +int isSetsEqual (set *, set *); +set *subtractFromSet (set *, set *, int); +int elementsInSet (set *); +set *intersectSetsWith (set *, set *, int (*cFunc) (void *, void *), int); +int isSetsEqualWith (set *, set *, int (*cFunc) (void *, void *)); +void *peekSet (set *); +void *setFirstItem (set *); +void *setNextItem (set *); +void setToNull (void **); #endif diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 9898c870..a537c705 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -24,116 +24,126 @@ #include "common.h" #include "newalloc.h" -bucket *SymbolTab [256] ; /* the symbol table */ -bucket *StructTab [256] ; /* the structure table */ -bucket *TypedefTab[256] ; /* the typedef table */ -bucket *LabelTab [256] ; /* the Label table */ -bucket *enumTab [256] ; /* enumerated table */ +bucket *SymbolTab[256]; /* the symbol table */ +bucket *StructTab[256]; /* the structure table */ +bucket *TypedefTab[256]; /* the typedef table */ +bucket *LabelTab[256]; /* the Label table */ +bucket *enumTab[256]; /* enumerated table */ /*------------------------------------------------------------------*/ /* initSymt () - initialises symbol table related stuff */ /*------------------------------------------------------------------*/ -void initSymt () +void +initSymt () { - int i = 0 ; + int i = 0; - for ( i = 0 ; i < 256 ; i++ ) - SymbolTab[i] = StructTab[i] = (void *) NULL ; + for (i = 0; i < 256; i++) + SymbolTab[i] = StructTab[i] = (void *) NULL; } /*-----------------------------------------------------------------*/ /* newBucket - allocates & returns a new bucket */ /*-----------------------------------------------------------------*/ -bucket *newBucket () +bucket * +newBucket () { - bucket *bp ; + bucket *bp; - bp = Safe_calloc(1,sizeof(bucket)); + bp = Safe_calloc (1, sizeof (bucket)); - return bp ; + return bp; } /*-----------------------------------------------------------------*/ /* hashKey - computes the hashkey given a symbol name */ /*-----------------------------------------------------------------*/ -int hashKey (const char *s) +int +hashKey (const char *s) { - unsigned long key = 0; + unsigned long key = 0; - while (*s) - key += *s++ ; - return key % 256 ; + while (*s) + key += *s++; + return key % 256; } /*-----------------------------------------------------------------*/ /* addSym - adds a symbol to the hash Table */ /*-----------------------------------------------------------------*/ -void addSym ( bucket **stab , - void *sym , - char *sname , - int level , - int block) +void +addSym (bucket ** stab, + void *sym, + char *sname, + int level, + int block) { - int i ; /* index into the hash Table */ - bucket *bp ; /* temp bucket * */ - - /* the symbols are always added at the head of the list */ - i = hashKey(sname) ; - /* get a free entry */ - bp = Safe_calloc(1,sizeof(bucket)); - - bp->sym = sym ; /* update the symbol pointer */ - bp->level = level; /* update the nest level */ - bp->block = block; - strcpy(bp->name,sname); /* copy the name into place */ - - /* if this is the first entry */ - if (stab[i] == NULL) { - bp->prev = bp->next = (void *) NULL ; /* point to nothing */ - stab[i] = bp ; - } - /* not first entry then add @ head of list */ - else { - bp->prev = NULL ; - stab[i]->prev = bp ; - bp->next = stab[i] ; - stab[i] = bp ; + int i; /* index into the hash Table */ + bucket *bp; /* temp bucket * */ + + /* the symbols are always added at the head of the list */ + i = hashKey (sname); + /* get a free entry */ + bp = Safe_calloc (1, sizeof (bucket)); + + bp->sym = sym; /* update the symbol pointer */ + bp->level = level; /* update the nest level */ + bp->block = block; + strcpy (bp->name, sname); /* copy the name into place */ + + /* if this is the first entry */ + if (stab[i] == NULL) + { + bp->prev = bp->next = (void *) NULL; /* point to nothing */ + stab[i] = bp; + } + /* not first entry then add @ head of list */ + else + { + bp->prev = NULL; + stab[i]->prev = bp; + bp->next = stab[i]; + stab[i] = bp; } } /*-----------------------------------------------------------------*/ /* deleteSym - deletes a symbol from the hash Table entry */ /*-----------------------------------------------------------------*/ -void deleteSym ( bucket **stab, void *sym, char *sname) +void +deleteSym (bucket ** stab, void *sym, char *sname) { - int i = 0 ; - bucket *bp ; + int i = 0; + bucket *bp; - i = hashKey(sname) ; + i = hashKey (sname); - bp = stab[i] ; - /* find the symbol */ - while (bp) { - if (bp->sym == sym) /* found it then break out */ - break ; /* of the loop */ - bp = bp->next ; + bp = stab[i]; + /* find the symbol */ + while (bp) + { + if (bp->sym == sym) /* found it then break out */ + break; /* of the loop */ + bp = bp->next; } - if (!bp) /* did not find it */ - return ; - /* if this is the first one in the chain */ - if ( ! bp->prev ) { - stab[i] = bp->next ; - if ( stab[i] ) /* if chain ! empty */ - stab[i]->prev = (void *) NULL ; + if (!bp) /* did not find it */ + return; + /* if this is the first one in the chain */ + if (!bp->prev) + { + stab[i] = bp->next; + if (stab[i]) /* if chain ! empty */ + stab[i]->prev = (void *) NULL; } - /* middle || end of chain */ - else { - if ( bp->next ) /* if not end of chain */ - bp->next->prev = bp->prev ; + /* middle || end of chain */ + else + { + if (bp->next) /* if not end of chain */ + bp->next->prev = bp->prev; - bp->prev->next = bp->next ; + bp->prev->next = bp->next; } } @@ -141,29 +151,31 @@ void deleteSym ( bucket **stab, void *sym, char *sname) /*-----------------------------------------------------------------*/ /* findSym - finds a symbol in a table */ /*-----------------------------------------------------------------*/ -void *findSym ( bucket **stab, void *sym, const char *sname) +void * +findSym (bucket ** stab, void *sym, const char *sname) { - bucket *bp ; + bucket *bp; - bp = stab[hashKey(sname)] ; - while (bp) - { - if ( bp->sym == sym || strcmp (bp->name,sname) == 0 ) - break ; - bp = bp->next ; - } + bp = stab[hashKey (sname)]; + while (bp) + { + if (bp->sym == sym || strcmp (bp->name, sname) == 0) + break; + bp = bp->next; + } - return ( bp ? bp->sym : (void *) NULL ) ; + return (bp ? bp->sym : (void *) NULL); } /*-----------------------------------------------------------------*/ /* findSymWithLevel - finds a symbol with a name & level */ /*-----------------------------------------------------------------*/ -void *findSymWithLevel ( bucket **stab, symbol *sym) +void * +findSymWithLevel (bucket ** stab, symbol * sym) { - bucket *bp ; + bucket *bp; - bp = stab[hashKey(sym->name)]; + bp = stab[hashKey (sym->name)]; /** ** do the search from the head of the list since the @@ -173,155 +185,166 @@ void *findSymWithLevel ( bucket **stab, symbol *sym) ** level <= to the level given, if levels match then block ** numbers need to match as well **/ - while (bp) { - - if ( strcmp(bp->name,sym->name) == 0 && bp->level <= sym->level) { - /* if this is parameter then nothing else need to be checked */ - if (((symbol *)(bp->sym))->_isparm) - return (bp->sym) ; - /* if levels match then block numbers hsould also match */ - if (bp->level && bp->level == sym->level && bp->block == sym->block ) - return ( bp->sym ); - /* if levels don't match then we are okay */ - if (bp->level && bp->level != sym->level) - return ( bp->sym ); - /* if this is a global variable then we are ok too */ - if (bp->level == 0 ) - return (bp->sym); - } - - bp = bp->next; - } - - return (void *) NULL ; + while (bp) + { + + if (strcmp (bp->name, sym->name) == 0 && bp->level <= sym->level) + { + /* if this is parameter then nothing else need to be checked */ + if (((symbol *) (bp->sym))->_isparm) + return (bp->sym); + /* if levels match then block numbers hsould also match */ + if (bp->level && bp->level == sym->level && bp->block == sym->block) + return (bp->sym); + /* if levels don't match then we are okay */ + if (bp->level && bp->level != sym->level) + return (bp->sym); + /* if this is a global variable then we are ok too */ + if (bp->level == 0) + return (bp->sym); + } + + bp = bp->next; + } + + return (void *) NULL; } /*-----------------------------------------------------------------*/ /* findSymWithBlock - finds a symbol with name in with a block */ /*-----------------------------------------------------------------*/ -void *findSymWithBlock ( bucket **stab, symbol *sym, int block) +void * +findSymWithBlock (bucket ** stab, symbol * sym, int block) { - bucket *bp ; - - bp = stab[hashKey(sym->name)] ; - while (bp) - { - if ( strcmp (bp->name,sym->name) == 0 && - bp->block <= block ) - break ; - bp = bp->next ; - } - - return ( bp ? bp->sym : (void *) NULL ) ; + bucket *bp; + + bp = stab[hashKey (sym->name)]; + while (bp) + { + if (strcmp (bp->name, sym->name) == 0 && + bp->block <= block) + break; + bp = bp->next; + } + + return (bp ? bp->sym : (void *) NULL); } /*------------------------------------------------------------------*/ /* newSymbol () - returns a new pointer to a symbol */ /*------------------------------------------------------------------*/ -symbol *newSymbol (char *name, int scope ) +symbol * +newSymbol (char *name, int scope) { - symbol *sym ; + symbol *sym; - sym = Safe_calloc(1,sizeof(symbol)); + sym = Safe_calloc (1, sizeof (symbol)); - strcpy(sym->name,name); /* copy the name */ - sym->level = scope ; /* set the level */ - sym->block = currBlockno ; - sym->lineDef = yylineno ; /* set the line number */ - return sym ; + strcpy (sym->name, name); /* copy the name */ + sym->level = scope; /* set the level */ + sym->block = currBlockno; + sym->lineDef = yylineno; /* set the line number */ + return sym; } /*------------------------------------------------------------------*/ /* newLink - creates a new link (declarator,specifier) */ /*------------------------------------------------------------------*/ -sym_link *newLink () +sym_link * +newLink () { - sym_link *p ; + sym_link *p; - p = Safe_calloc(1,sizeof(sym_link)); + p = Safe_calloc (1, sizeof (sym_link)); - return p; + return p; } /*------------------------------------------------------------------*/ /* newStruct - creats a new structdef from the free list */ /*------------------------------------------------------------------*/ -structdef *newStruct ( char *tag ) +structdef * +newStruct (char *tag) { - structdef *s; + structdef *s; - s = Safe_calloc(1,sizeof(structdef)); + s = Safe_calloc (1, sizeof (structdef)); - strcpy(s->tag,tag) ; /* copy the tag */ - return s ; + strcpy (s->tag, tag); /* copy the tag */ + return s; } /*------------------------------------------------------------------*/ /* pointerTypes - do the computation for the pointer types */ /*------------------------------------------------------------------*/ -void pointerTypes (sym_link *ptr, sym_link *type) +void +pointerTypes (sym_link * ptr, sym_link * type) { - if (IS_SPEC(ptr)) - return ; - - /* find the first pointer type */ - while (ptr && !IS_PTR(ptr)) - ptr = ptr->next; - - /* could not find it */ - if (!ptr || IS_SPEC(ptr) || - DCL_TYPE(ptr) != UPOINTER) - return ; - - /* change the pointer type depending on the - storage class of the type */ - if (IS_SPEC(type)) { - DCL_PTR_CONST(ptr) = SPEC_CONST(type); - DCL_PTR_VOLATILE(ptr) = SPEC_VOLATILE(type); - switch (SPEC_SCLS(type)) { - case S_XDATA: - DCL_TYPE(ptr) = FPOINTER; - break; - case S_IDATA: - DCL_TYPE(ptr) = IPOINTER ; - break; - case S_PDATA: - DCL_TYPE(ptr) = PPOINTER ; - break; - case S_DATA: - DCL_TYPE(ptr) = POINTER ; - break; - case S_CODE: - DCL_PTR_CONST(ptr) = port->mem.code_ro; - DCL_TYPE(ptr) = CPOINTER ; - break; - case S_EEPROM: - DCL_TYPE(ptr) = EEPPOINTER; - break; - default: - DCL_TYPE(ptr) = GPOINTER; - break; - } - /* the storage class of type ends here */ - SPEC_SCLS(type) = - SPEC_CONST(type) = - SPEC_VOLATILE(type) = 0; - } - - /* now change all the remaining unknown pointers - to generic pointers */ - while (ptr) { - if (!IS_SPEC(ptr) && DCL_TYPE(ptr) == UPOINTER) - DCL_TYPE(ptr) = GPOINTER; - ptr = ptr->next; - } - - /* same for the type although it is highly unlikely that - type will have a pointer */ - while (type) { - if (!IS_SPEC(type) && DCL_TYPE(type) == UPOINTER) - DCL_TYPE(type) = GPOINTER; - type = type->next; + if (IS_SPEC (ptr)) + return; + + /* find the first pointer type */ + while (ptr && !IS_PTR (ptr)) + ptr = ptr->next; + + /* could not find it */ + if (!ptr || IS_SPEC (ptr) || + DCL_TYPE (ptr) != UPOINTER) + return; + + /* change the pointer type depending on the + storage class of the type */ + if (IS_SPEC (type)) + { + DCL_PTR_CONST (ptr) = SPEC_CONST (type); + DCL_PTR_VOLATILE (ptr) = SPEC_VOLATILE (type); + switch (SPEC_SCLS (type)) + { + case S_XDATA: + DCL_TYPE (ptr) = FPOINTER; + break; + case S_IDATA: + DCL_TYPE (ptr) = IPOINTER; + break; + case S_PDATA: + DCL_TYPE (ptr) = PPOINTER; + break; + case S_DATA: + DCL_TYPE (ptr) = POINTER; + break; + case S_CODE: + DCL_PTR_CONST (ptr) = port->mem.code_ro; + DCL_TYPE (ptr) = CPOINTER; + break; + case S_EEPROM: + DCL_TYPE (ptr) = EEPPOINTER; + break; + default: + DCL_TYPE (ptr) = GPOINTER; + break; + } + /* the storage class of type ends here */ + SPEC_SCLS (type) = + SPEC_CONST (type) = + SPEC_VOLATILE (type) = 0; + } + + /* now change all the remaining unknown pointers + to generic pointers */ + while (ptr) + { + if (!IS_SPEC (ptr) && DCL_TYPE (ptr) == UPOINTER) + DCL_TYPE (ptr) = GPOINTER; + ptr = ptr->next; + } + + /* same for the type although it is highly unlikely that + type will have a pointer */ + while (type) + { + if (!IS_SPEC (type) && DCL_TYPE (type) == UPOINTER) + DCL_TYPE (type) = GPOINTER; + type = type->next; } } @@ -329,342 +352,373 @@ void pointerTypes (sym_link *ptr, sym_link *type) /*------------------------------------------------------------------*/ /* addDecl - adds a declarator @ the end of a chain */ /*------------------------------------------------------------------*/ -void addDecl ( symbol *sym, int type , sym_link *p ) +void +addDecl (symbol * sym, int type, sym_link * p) { - sym_link *head; - sym_link *tail; - sym_link *t ; - - /* if we are passed a link then set head & tail */ - if ( p ) { - tail = head = p ; - while ( tail->next ) - tail = tail->next ; - } - else { - head = tail = newLink() ; - DCL_TYPE(head) = type ; - } - - /* if this is the first entry */ - if ( !sym->type ) { - sym->type = head ; - sym->etype = tail ; - } - else { - if ( IS_SPEC(sym->etype) && IS_SPEC(head) && head == tail ) { - sym->etype = mergeSpec(sym->etype,head); - } - else { - if ( IS_SPEC(sym->etype) && !IS_SPEC(head) && head == tail ) { - t = sym->type ; - while (t->next != sym->etype) t = t->next ; - t->next = head ; - tail->next = sym->etype; - } else { - sym->etype->next = head; - sym->etype = tail; - } - } - } - - /* if the type is a unknown pointer and has - a tspec then take the storage class const & volatile - attribute from the tspec & make it those of this - symbol */ - if (p && - !IS_SPEC(p) && - DCL_TYPE(p) == UPOINTER && - DCL_TSPEC(p)) { - if (!IS_SPEC(sym->etype)) { - sym->etype = sym->etype->next = newLink(); - sym->etype->class = SPECIFIER; - } - SPEC_SCLS(sym->etype) = SPEC_SCLS(DCL_TSPEC(p)); - SPEC_CONST(sym->etype) = SPEC_CONST(DCL_TSPEC(p)); - SPEC_VOLATILE(sym->etype) = SPEC_VOLATILE(DCL_TSPEC(p)); - DCL_TSPEC(p) = NULL; - } - return ; + sym_link *head; + sym_link *tail; + sym_link *t; + + /* if we are passed a link then set head & tail */ + if (p) + { + tail = head = p; + while (tail->next) + tail = tail->next; + } + else + { + head = tail = newLink (); + DCL_TYPE (head) = type; + } + + /* if this is the first entry */ + if (!sym->type) + { + sym->type = head; + sym->etype = tail; + } + else + { + if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail) + { + sym->etype = mergeSpec (sym->etype, head); + } + else + { + if (IS_SPEC (sym->etype) && !IS_SPEC (head) && head == tail) + { + t = sym->type; + while (t->next != sym->etype) + t = t->next; + t->next = head; + tail->next = sym->etype; + } + else + { + sym->etype->next = head; + sym->etype = tail; + } + } + } + + /* if the type is a unknown pointer and has + a tspec then take the storage class const & volatile + attribute from the tspec & make it those of this + symbol */ + if (p && + !IS_SPEC (p) && + DCL_TYPE (p) == UPOINTER && + DCL_TSPEC (p)) + { + if (!IS_SPEC (sym->etype)) + { + sym->etype = sym->etype->next = newLink (); + sym->etype->class = SPECIFIER; + } + SPEC_SCLS (sym->etype) = SPEC_SCLS (DCL_TSPEC (p)); + SPEC_CONST (sym->etype) = SPEC_CONST (DCL_TSPEC (p)); + SPEC_VOLATILE (sym->etype) = SPEC_VOLATILE (DCL_TSPEC (p)); + DCL_TSPEC (p) = NULL; + } + return; } /*------------------------------------------------------------------*/ /* mergeSpec - merges two specifiers and returns the new one */ /*------------------------------------------------------------------*/ -sym_link *mergeSpec ( sym_link *dest, sym_link *src ) +sym_link * +mergeSpec (sym_link * dest, sym_link * src) { - /* if noun different then src overrides */ - if ( SPEC_NOUN(dest) != SPEC_NOUN(src) && !SPEC_NOUN(dest)) - SPEC_NOUN(dest) = SPEC_NOUN(src) ; - - if (! SPEC_SCLS(dest)) /* if destination has no storage class */ - SPEC_SCLS(dest) = SPEC_SCLS(src) ; - - /* copy all the specifications */ - SPEC_LONG(dest) |= SPEC_LONG(src); - SPEC_SHORT(dest) |= SPEC_SHORT(src); - SPEC_USIGN(dest) |= SPEC_USIGN(src); - SPEC_STAT(dest) |= SPEC_STAT(src); - SPEC_EXTR(dest) |= SPEC_EXTR(src); - SPEC_ABSA(dest) |= SPEC_ABSA(src); - SPEC_RENT(dest) |= SPEC_RENT(src); - SPEC_INTN(dest) |= SPEC_INTN(src); - SPEC_BANK(dest) |= SPEC_BANK(src); - SPEC_VOLATILE(dest) |= SPEC_VOLATILE(src); - SPEC_CRTCL(dest) |= SPEC_CRTCL(src); - SPEC_ADDR(dest) |= SPEC_ADDR(src); - SPEC_OCLS(dest) = SPEC_OCLS(src); - SPEC_BLEN(dest) |= SPEC_BLEN(src); - SPEC_BSTR(dest) |= SPEC_BSTR(src); - SPEC_TYPEDEF(dest) |= SPEC_TYPEDEF(src); - SPEC_NONBANKED(dest) |= SPEC_NONBANKED(src); - - if ( IS_STRUCT(dest) && SPEC_STRUCT(dest) == NULL ) - SPEC_STRUCT(dest) = SPEC_STRUCT(src); - - return dest ; + /* if noun different then src overrides */ + if (SPEC_NOUN (dest) != SPEC_NOUN (src) && !SPEC_NOUN (dest)) + SPEC_NOUN (dest) = SPEC_NOUN (src); + + if (!SPEC_SCLS (dest)) /* if destination has no storage class */ + SPEC_SCLS (dest) = SPEC_SCLS (src); + + /* copy all the specifications */ + SPEC_LONG (dest) |= SPEC_LONG (src); + SPEC_SHORT (dest) |= SPEC_SHORT (src); + SPEC_USIGN (dest) |= SPEC_USIGN (src); + SPEC_STAT (dest) |= SPEC_STAT (src); + SPEC_EXTR (dest) |= SPEC_EXTR (src); + SPEC_ABSA (dest) |= SPEC_ABSA (src); + SPEC_RENT (dest) |= SPEC_RENT (src); + SPEC_INTN (dest) |= SPEC_INTN (src); + SPEC_BANK (dest) |= SPEC_BANK (src); + SPEC_VOLATILE (dest) |= SPEC_VOLATILE (src); + SPEC_CRTCL (dest) |= SPEC_CRTCL (src); + SPEC_ADDR (dest) |= SPEC_ADDR (src); + SPEC_OCLS (dest) = SPEC_OCLS (src); + SPEC_BLEN (dest) |= SPEC_BLEN (src); + SPEC_BSTR (dest) |= SPEC_BSTR (src); + SPEC_TYPEDEF (dest) |= SPEC_TYPEDEF (src); + SPEC_NONBANKED (dest) |= SPEC_NONBANKED (src); + + if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL) + SPEC_STRUCT (dest) = SPEC_STRUCT (src); + + return dest; } /*------------------------------------------------------------------*/ /* cloneSpec - copies the entire spec and returns a new spec */ /*------------------------------------------------------------------*/ -sym_link *cloneSpec ( sym_link *src ) +sym_link * +cloneSpec (sym_link * src) { - sym_link *spec ; + sym_link *spec; - /* go thru chain till we find the specifier */ - while ( src && src->class != SPECIFIER ) - src = src->next ; + /* go thru chain till we find the specifier */ + while (src && src->class != SPECIFIER) + src = src->next; - spec = newLink() ; - memcpy (spec,src,sizeof(sym_link)); - return spec ; + spec = newLink (); + memcpy (spec, src, sizeof (sym_link)); + return spec; } /*------------------------------------------------------------------*/ -/* genSymName - generates and returns a name used for anonymous vars*/ +/* genSymName - generates and returns a name used for anonymous vars */ /*------------------------------------------------------------------*/ -char *genSymName ( int level ) +char * +genSymName (int level) { - static int gCount = 0 ; - static char gname[SDCC_NAME_MAX+1] ; + static int gCount = 0; + static char gname[SDCC_NAME_MAX + 1]; - sprintf (gname,"__%04d%04d",level,gCount++); - return gname ; + sprintf (gname, "__%04d%04d", level, gCount++); + return gname; } /*------------------------------------------------------------------*/ /* getSpec - returns the specifier part from a declaration chain */ /*------------------------------------------------------------------*/ -sym_link *getSpec ( sym_link *p ) +sym_link * +getSpec (sym_link * p) { - sym_link *loop ; + sym_link *loop; - loop = p ; - while ( p && ! (IS_SPEC(p))) - p = p->next ; + loop = p; + while (p && !(IS_SPEC (p))) + p = p->next; - return p ; + return p; } /*------------------------------------------------------------------*/ /* newCharLink() - creates an int type */ /*------------------------------------------------------------------*/ -sym_link *newCharLink() +sym_link * +newCharLink () { - sym_link *p; + sym_link *p; - p = newLink(); - p->class = SPECIFIER ; - SPEC_NOUN(p) = V_CHAR ; + p = newLink (); + p->class = SPECIFIER; + SPEC_NOUN (p) = V_CHAR; - return p; + return p; } /*------------------------------------------------------------------*/ /* newFloatLink - a new Float type */ /*------------------------------------------------------------------*/ -sym_link *newFloatLink() +sym_link * +newFloatLink () { - sym_link *p; + sym_link *p; - p = newLink(); - p->class = SPECIFIER ; - SPEC_NOUN(p) = V_FLOAT ; + p = newLink (); + p->class = SPECIFIER; + SPEC_NOUN (p) = V_FLOAT; - return p; + return p; } /*------------------------------------------------------------------*/ /* newLongLink() - new long type */ /*------------------------------------------------------------------*/ -sym_link *newLongLink() +sym_link * +newLongLink () { - sym_link *p; + sym_link *p; - p = newLink(); - p->class = SPECIFIER ; - SPEC_NOUN(p) = V_INT ; - SPEC_LONG(p) = 1; + p = newLink (); + p->class = SPECIFIER; + SPEC_NOUN (p) = V_INT; + SPEC_LONG (p) = 1; - return p; + return p; } /*------------------------------------------------------------------*/ /* newIntLink() - creates an int type */ /*------------------------------------------------------------------*/ -sym_link *newIntLink() +sym_link * +newIntLink () { - sym_link *p; + sym_link *p; - p = newLink(); - p->class = SPECIFIER ; - SPEC_NOUN(p) = V_INT ; + p = newLink (); + p->class = SPECIFIER; + SPEC_NOUN (p) = V_INT; - return p; + return p; } /*------------------------------------------------------------------*/ /* getSize - returns size of a type chain in bits */ /*------------------------------------------------------------------*/ -unsigned int getSize ( sym_link *p ) +unsigned int +getSize (sym_link * p) { - /* if nothing return 0 */ - if ( ! p ) - return 0 ; - if ( IS_SPEC(p) ) { /* if this is the specifier then */ - switch (SPEC_NOUN(p)) { /* depending on the specifier type */ - case V_INT: - return (IS_LONG(p) ? LONGSIZE : ( IS_SHORT(p) ? SHORTSIZE: INTSIZE)) ; - case V_FLOAT: - return FLOATSIZE ; - case V_CHAR: - return CHARSIZE ; - case V_VOID: - return 0 ; - case V_STRUCT: - return SPEC_STRUCT(p)->size ; - case V_LABEL: - return 0 ; - case V_SBIT: - return BITSIZE ; - case V_BIT: - return ((SPEC_BLEN(p) / 8) + (SPEC_BLEN(p) % 8 ? 1 : 0)) ; - default : - return 0 ; - } - } - - /* this is a specifier */ - switch (DCL_TYPE(p)) { + /* if nothing return 0 */ + if (!p) + return 0; + if (IS_SPEC (p)) + { /* if this is the specifier then */ + switch (SPEC_NOUN (p)) + { /* depending on the specifier type */ + case V_INT: + return (IS_LONG (p) ? LONGSIZE : (IS_SHORT (p) ? SHORTSIZE : INTSIZE)); + case V_FLOAT: + return FLOATSIZE; + case V_CHAR: + return CHARSIZE; + case V_VOID: + return 0; + case V_STRUCT: + return SPEC_STRUCT (p)->size; + case V_LABEL: + return 0; + case V_SBIT: + return BITSIZE; + case V_BIT: + return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0)); + default: + return 0; + } + } + + /* this is a specifier */ + switch (DCL_TYPE (p)) + { case FUNCTION: - return 2; + return 2; case ARRAY: - return DCL_ELEM(p) * getSize (p->next) ; + return DCL_ELEM (p) * getSize (p->next); case IPOINTER: case PPOINTER: case POINTER: - return ( PTRSIZE ) ; + return (PTRSIZE); case EEPPOINTER: case FPOINTER: case CPOINTER: - return ( FPTRSIZE ); + return (FPTRSIZE); case GPOINTER: - return ( GPTRSIZE ); + return (GPTRSIZE); - default : - return 0 ; + default: + return 0; } } /*------------------------------------------------------------------*/ /* bitsForType - returns # of bits required to store this type */ /*------------------------------------------------------------------*/ -unsigned int bitsForType ( sym_link *p ) +unsigned int +bitsForType (sym_link * p) { - /* if nothing return 0 */ - if ( ! p ) - return 0 ; - - if ( IS_SPEC(p) ) { /* if this is the specifier then */ - - switch (SPEC_NOUN(p)) { /* depending on the specifier type */ - case V_INT: - return (IS_LONG(p) ? LONGSIZE*8 : ( IS_SHORT(p) ? SHORTSIZE*8: INTSIZE*8)) ; - case V_FLOAT: - return FLOATSIZE*8 ; - case V_CHAR: - return CHARSIZE*8 ; - case V_VOID: - return 0 ; - case V_STRUCT: - return SPEC_STRUCT(p)->size*8 ; - case V_LABEL: - return 0 ; - case V_SBIT: - return 1 ; - case V_BIT: - return SPEC_BLEN(p); - default : - return 0 ; - } - } - - /* this is a specifier */ - switch (DCL_TYPE(p)) { + /* if nothing return 0 */ + if (!p) + return 0; + + if (IS_SPEC (p)) + { /* if this is the specifier then */ + + switch (SPEC_NOUN (p)) + { /* depending on the specifier type */ + case V_INT: + return (IS_LONG (p) ? LONGSIZE * 8 : (IS_SHORT (p) ? SHORTSIZE * 8 : INTSIZE * 8)); + case V_FLOAT: + return FLOATSIZE * 8; + case V_CHAR: + return CHARSIZE * 8; + case V_VOID: + return 0; + case V_STRUCT: + return SPEC_STRUCT (p)->size * 8; + case V_LABEL: + return 0; + case V_SBIT: + return 1; + case V_BIT: + return SPEC_BLEN (p); + default: + return 0; + } + } + + /* this is a specifier */ + switch (DCL_TYPE (p)) + { case FUNCTION: - return 2; + return 2; case ARRAY: - return DCL_ELEM(p) * getSize (p->next) *8 ; + return DCL_ELEM (p) * getSize (p->next) * 8; case IPOINTER: case PPOINTER: case POINTER: - return ( PTRSIZE * 8) ; + return (PTRSIZE * 8); case EEPPOINTER: case FPOINTER: case CPOINTER: - return ( FPTRSIZE * 8); + return (FPTRSIZE * 8); case GPOINTER: - return ( GPTRSIZE * 8); + return (GPTRSIZE * 8); - default : - return 0 ; + default: + return 0; } } /*------------------------------------------------------------------*/ /* copySymbolChain - copies a symbol chain */ /*------------------------------------------------------------------*/ -symbol *copySymbolChain (symbol *src) +symbol * +copySymbolChain (symbol * src) { - symbol *dest ; + symbol *dest; if (!src) - return NULL ; + return NULL; - dest = copySymbol(src); - dest->next = copySymbolChain(src->next); - return dest ; + dest = copySymbol (src); + dest->next = copySymbolChain (src->next); + return dest; } /*------------------------------------------------------------------*/ /* copySymbol - makes a copy of a symbol */ /*------------------------------------------------------------------*/ -symbol *copySymbol (symbol *src) +symbol * +copySymbol (symbol * src) { symbol *dest; - if (!src ) - return NULL ; - - dest = newSymbol( src->name, src->level ); - memcpy(dest,src,sizeof(symbol)); - dest->level = src->level ; - dest->block = src->block ; - dest->ival = copyIlist(src->ival); - dest->type = copyLinkChain(src->type); - dest->etype= getSpec(dest->type); - dest->next = NULL ; + if (!src) + return NULL; + + dest = newSymbol (src->name, src->level); + memcpy (dest, src, sizeof (symbol)); + dest->level = src->level; + dest->block = src->block; + dest->ival = copyIlist (src->ival); + dest->type = copyLinkChain (src->type); + dest->etype = getSpec (dest->type); + dest->next = NULL; dest->args = copyValueChain (src->args); dest->key = src->key; dest->calleeSave = src->calleeSave; @@ -675,418 +729,459 @@ symbol *copySymbol (symbol *src) /*------------------------------------------------------------------*/ /* reverseSyms - reverses the links for a symbol chain */ /*------------------------------------------------------------------*/ -symbol *reverseSyms ( symbol *sym) +symbol * +reverseSyms (symbol * sym) { - symbol *prev , *curr, *next ; - - if (!sym) - return NULL ; - - prev = sym ; - curr = sym->next ; - - while (curr) - { - next = curr->next ; - curr->next = prev ; - prev = curr ; - curr = next ; - } - sym->next = (void *) NULL ; - return prev ; + symbol *prev, *curr, *next; + + if (!sym) + return NULL; + + prev = sym; + curr = sym->next; + + while (curr) + { + next = curr->next; + curr->next = prev; + prev = curr; + curr = next; + } + sym->next = (void *) NULL; + return prev; } /*------------------------------------------------------------------*/ /* reverseLink - reverses the links for a type chain */ /*------------------------------------------------------------------*/ -sym_link *reverseLink ( sym_link *type) +sym_link * +reverseLink (sym_link * type) { - sym_link *prev , *curr, *next ; - - if (!type) - return NULL ; - - prev = type ; - curr = type->next ; - - while (curr) - { - next = curr->next ; - curr->next = prev ; - prev = curr ; - curr = next ; - } - type->next = (void *) NULL ; - return prev ; + sym_link *prev, *curr, *next; + + if (!type) + return NULL; + + prev = type; + curr = type->next; + + while (curr) + { + next = curr->next; + curr->next = prev; + prev = curr; + curr = next; + } + type->next = (void *) NULL; + return prev; } /*------------------------------------------------------------------*/ /* addSymChain - adds a symbol chain to the symboltable */ /*------------------------------------------------------------------*/ -void addSymChain ( symbol *symHead ) +void +addSymChain (symbol * symHead) { - symbol *sym = symHead ; - symbol *csym = NULL ; - - for (;sym != NULL ; sym = sym->next ) { - - /* if already exists in the symbol table then check if - the previous was an extern definition if yes then - then check if the type match, if the types match then - delete the current entry and add the new entry */ - if ((csym = findSymWithLevel (SymbolTab,sym)) && - csym->level == sym->level) { - - /* previous definition extern ? */ - if ( IS_EXTERN(csym->etype) ) { - /* do types match ? */ - if (checkType ( csym->type,sym->type) != 1) - /* no then error */ - werror (E_DUPLICATE,csym->name); - - /* delete current entry */ - deleteSym (SymbolTab, csym, csym->name ); - /* add new entry */ - addSym (SymbolTab, sym, sym->name, sym->level,sym->block); - } else /* not extern */ - werror(E_DUPLICATE,sym->name) ; - continue ; - } - - /* check if previously defined */ - if (csym && csym->level == sym->level ) { - /* if the previous one was declared as extern */ - /* then check the type with the current one */ - if ( IS_EXTERN(csym->etype) ) { - if ( checkType (csym->type, sym->type ) <= 0 ) - werror (W_EXTERN_MISMATCH,csym->name); - } - } - - addSym (SymbolTab,sym,sym->name,sym->level,sym->block) ; - } + symbol *sym = symHead; + symbol *csym = NULL; + + for (; sym != NULL; sym = sym->next) + { + + /* if already exists in the symbol table then check if + the previous was an extern definition if yes then + then check if the type match, if the types match then + delete the current entry and add the new entry */ + if ((csym = findSymWithLevel (SymbolTab, sym)) && + csym->level == sym->level) + { + + /* previous definition extern ? */ + if (IS_EXTERN (csym->etype)) + { + /* do types match ? */ + if (checkType (csym->type, sym->type) != 1) + /* no then error */ + werror (E_DUPLICATE, csym->name); + + /* delete current entry */ + deleteSym (SymbolTab, csym, csym->name); + /* add new entry */ + addSym (SymbolTab, sym, sym->name, sym->level, sym->block); + } + else /* not extern */ + werror (E_DUPLICATE, sym->name); + continue; + } + + /* check if previously defined */ + if (csym && csym->level == sym->level) + { + /* if the previous one was declared as extern */ + /* then check the type with the current one */ + if (IS_EXTERN (csym->etype)) + { + if (checkType (csym->type, sym->type) <= 0) + werror (W_EXTERN_MISMATCH, csym->name); + } + } + + addSym (SymbolTab, sym, sym->name, sym->level, sym->block); + } } /*------------------------------------------------------------------*/ /* funcInChain - DCL Type 'FUNCTION' found in type chain */ /*------------------------------------------------------------------*/ -int funcInChain (sym_link *lnk) +int +funcInChain (sym_link * lnk) { - while (lnk) { - if (IS_FUNC(lnk)) - return 1; - lnk = lnk->next; + while (lnk) + { + if (IS_FUNC (lnk)) + return 1; + lnk = lnk->next; } - return 0; + return 0; } /*------------------------------------------------------------------*/ /* structElemType - returns the type info of a sturct member */ /*------------------------------------------------------------------*/ -sym_link *structElemType (sym_link *stype, value *id ,value **argsp) +sym_link * +structElemType (sym_link * stype, value * id, value ** argsp) { - symbol *fields = (SPEC_STRUCT(stype) ? SPEC_STRUCT(stype)->fields : NULL); - sym_link *type, *etype; - sym_link *petype = getSpec(stype); - - if ( ! fields || ! id) - return NULL ; - - /* look for the id */ - while (fields) { - if (strcmp(fields->rname,id->name) == 0) { - if (argsp) { - *argsp = fields->args; - } - type = copyLinkChain (fields->type) ; - etype=getSpec(type); - SPEC_SCLS(etype) = (SPEC_SCLS(petype) == S_REGISTER ? - SPEC_SCLS(etype) : SPEC_SCLS(petype)); - return type; - } - fields = fields->next ; - } - werror(E_NOT_MEMBER,id->name); - - return NULL ; + symbol *fields = (SPEC_STRUCT (stype) ? SPEC_STRUCT (stype)->fields : NULL); + sym_link *type, *etype; + sym_link *petype = getSpec (stype); + + if (!fields || !id) + return NULL; + + /* look for the id */ + while (fields) + { + if (strcmp (fields->rname, id->name) == 0) + { + if (argsp) + { + *argsp = fields->args; + } + type = copyLinkChain (fields->type); + etype = getSpec (type); + SPEC_SCLS (etype) = (SPEC_SCLS (petype) == S_REGISTER ? + SPEC_SCLS (etype) : SPEC_SCLS (petype)); + return type; + } + fields = fields->next; + } + werror (E_NOT_MEMBER, id->name); + + return NULL; } /*------------------------------------------------------------------*/ /* getStructElement - returns element of a tructure definition */ /*------------------------------------------------------------------*/ -symbol *getStructElement ( structdef *sdef, symbol *sym) +symbol * +getStructElement (structdef * sdef, symbol * sym) { - symbol *field ; + symbol *field; - for ( field = sdef->fields ; field ; field = field->next ) - if ( strcmp(field->name,sym->name) == 0) - return field ; + for (field = sdef->fields; field; field = field->next) + if (strcmp (field->name, sym->name) == 0) + return field; - werror(E_NOT_MEMBER,sym->name); + werror (E_NOT_MEMBER, sym->name); - return sdef->fields ; + return sdef->fields; } /*------------------------------------------------------------------*/ /* compStructSize - computes the size of a structure */ /*------------------------------------------------------------------*/ -int compStructSize (int su, structdef *sdef ) +int +compStructSize (int su, structdef * sdef) { - int sum = 0 , usum =0; - int bitOffset = 0 ; - symbol *loop ; - - /* for the identifiers */ - loop = sdef->fields ; - while ( loop ) { - - /* create the internal name for this variable */ - sprintf (loop->rname,"_%s",loop->name); - loop->offset = ( su == UNION ? sum = 0 : sum ) ; - SPEC_VOLATILE(loop->etype) |= (su == UNION ? 1 : 0); - - /* if this is a bit field */ - if (loop->bitVar) { - - /* change it to a unsigned bit */ - SPEC_NOUN(loop->etype) = V_BIT ; - SPEC_USIGN(loop->etype) = 1 ; - /* check if this fit into the remaining */ - /* bits of this byte else align it to the */ - /* next byte boundary */ - if ((SPEC_BLEN(loop->etype)=loop->bitVar) <= (8 - bitOffset)) { - SPEC_BSTR(loop->etype) = bitOffset ; - if ((bitOffset += (loop->bitVar % 8)) == 8) sum++; - } - else /* does not fit */ + int sum = 0, usum = 0; + int bitOffset = 0; + symbol *loop; + + /* for the identifiers */ + loop = sdef->fields; + while (loop) { - bitOffset = 0 ; - SPEC_BSTR(loop->etype) = bitOffset ; - sum += (loop->bitVar / 8) ; - bitOffset += (loop->bitVar % 8); - } - /* if this is the last field then pad */ - if (!loop->next && bitOffset && bitOffset != 8) { - bitOffset = 0 ; - sum++ ; - } - } - else { - checkDecl (loop); - sum += getSize (loop->type) ; - } - - /* if function then do the arguments for it */ - if (funcInChain(loop->type)) { - processFuncArgs (loop, 1); - } - - loop = loop->next ; - - /* if this is not a bitfield but the */ - /* previous one was and did not take */ - /* the whole byte then pad the rest */ - if ((loop && !loop->bitVar) && bitOffset) { - bitOffset = 0 ; - sum++ ; - } - - /* if union then size = sizeof larget field */ - if (su == UNION) - usum = max(usum,sum); - - } - - return (su == UNION ? usum : sum); + + /* create the internal name for this variable */ + sprintf (loop->rname, "_%s", loop->name); + loop->offset = (su == UNION ? sum = 0 : sum); + SPEC_VOLATILE (loop->etype) |= (su == UNION ? 1 : 0); + + /* if this is a bit field */ + if (loop->bitVar) + { + + /* change it to a unsigned bit */ + SPEC_NOUN (loop->etype) = V_BIT; + SPEC_USIGN (loop->etype) = 1; + /* check if this fit into the remaining */ + /* bits of this byte else align it to the */ + /* next byte boundary */ + if ((SPEC_BLEN (loop->etype) = loop->bitVar) <= (8 - bitOffset)) + { + SPEC_BSTR (loop->etype) = bitOffset; + if ((bitOffset += (loop->bitVar % 8)) == 8) + sum++; + } + else + /* does not fit */ + { + bitOffset = 0; + SPEC_BSTR (loop->etype) = bitOffset; + sum += (loop->bitVar / 8); + bitOffset += (loop->bitVar % 8); + } + /* if this is the last field then pad */ + if (!loop->next && bitOffset && bitOffset != 8) + { + bitOffset = 0; + sum++; + } + } + else + { + checkDecl (loop); + sum += getSize (loop->type); + } + + /* if function then do the arguments for it */ + if (funcInChain (loop->type)) + { + processFuncArgs (loop, 1); + } + + loop = loop->next; + + /* if this is not a bitfield but the */ + /* previous one was and did not take */ + /* the whole byte then pad the rest */ + if ((loop && !loop->bitVar) && bitOffset) + { + bitOffset = 0; + sum++; + } + + /* if union then size = sizeof larget field */ + if (su == UNION) + usum = max (usum, sum); + + } + + return (su == UNION ? usum : sum); } /*------------------------------------------------------------------*/ /* checkSClass - check the storage class specification */ /*------------------------------------------------------------------*/ -static void checkSClass ( symbol *sym ) +static void +checkSClass (symbol * sym) { - /* type is literal can happen foe enums change - to auto */ - if (SPEC_SCLS(sym->etype) == S_LITERAL && !SPEC_ENUM(sym->etype)) - SPEC_SCLS(sym->etype) = S_AUTO; - - /* if sfr or sbit then must also be */ - /* volatile the initial value will be xlated */ - /* to an absolute address */ - if (SPEC_SCLS(sym->etype) == S_SBIT || - SPEC_SCLS(sym->etype) == S_SFR ) { - SPEC_VOLATILE(sym->etype) = 1; - /* if initial value given */ - if (sym->ival) { - SPEC_ABSA(sym->etype) = 1; - SPEC_ADDR(sym->etype) = - (int) list2int(sym->ival); + /* type is literal can happen foe enums change + to auto */ + if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype)) + SPEC_SCLS (sym->etype) = S_AUTO; + + /* if sfr or sbit then must also be */ + /* volatile the initial value will be xlated */ + /* to an absolute address */ + if (SPEC_SCLS (sym->etype) == S_SBIT || + SPEC_SCLS (sym->etype) == S_SFR) + { + SPEC_VOLATILE (sym->etype) = 1; + /* if initial value given */ + if (sym->ival) + { + SPEC_ABSA (sym->etype) = 1; + SPEC_ADDR (sym->etype) = + (int) list2int (sym->ival); + sym->ival = NULL; + } + } + + /* if absolute address given then it mark it as + volatile */ + if (IS_ABSOLUTE (sym->etype)) + SPEC_VOLATILE (sym->etype) = 1; + + /* global variables declared const put into code */ + if (sym->level == 0 && + SPEC_SCLS (sym->etype) == S_CONSTANT) + { + SPEC_SCLS (sym->etype) = S_CODE; + SPEC_CONST (sym->etype) = 1; + } + + /* global variable in code space is a constant */ + if (sym->level == 0 && + SPEC_SCLS (sym->etype) == S_CODE && + port->mem.code_ro) + SPEC_CONST (sym->etype) = 1; + + + /* if bit variable then no storage class can be */ + /* specified since bit is already a storage */ + if (IS_BITVAR (sym->etype) && + (SPEC_SCLS (sym->etype) != S_FIXED && + SPEC_SCLS (sym->etype) != S_SBIT && + SPEC_SCLS (sym->etype) != S_BIT) + ) + { + werror (E_BITVAR_STORAGE, sym->name); + SPEC_SCLS (sym->etype) = S_FIXED; + } + + /* extern variables cannot be initialized */ + if (IS_EXTERN (sym->etype) && sym->ival) + { + werror (E_EXTERN_INIT, sym->name); sym->ival = NULL; - } - } - - /* if absolute address given then it mark it as - volatile */ - if (IS_ABSOLUTE(sym->etype)) - SPEC_VOLATILE(sym->etype) = 1; - - /* global variables declared const put into code */ - if (sym->level == 0 && - SPEC_SCLS(sym->etype) == S_CONSTANT) { - SPEC_SCLS(sym->etype) = S_CODE ; - SPEC_CONST(sym->etype) = 1; - } - - /* global variable in code space is a constant */ - if (sym->level == 0 && - SPEC_SCLS(sym->etype) == S_CODE && - port->mem.code_ro ) - SPEC_CONST(sym->etype) = 1; - - - /* if bit variable then no storage class can be */ - /* specified since bit is already a storage */ - if ( IS_BITVAR(sym->etype) && - ( SPEC_SCLS(sym->etype) != S_FIXED && - SPEC_SCLS(sym->etype) != S_SBIT && - SPEC_SCLS(sym->etype) != S_BIT ) - ) { - werror (E_BITVAR_STORAGE,sym->name); - SPEC_SCLS(sym->etype) = S_FIXED ; - } - - /* extern variables cannot be initialized */ - if (IS_EXTERN(sym->etype) && sym->ival) { - werror(E_EXTERN_INIT,sym->name); - sym->ival = NULL; - } - - /* if this is an automatic symbol then */ - /* storage class will be ignored and */ - /* symbol will be allocated on stack/ */ - /* data depending on flag */ - if ( sym->level && - (options.stackAuto || reentrant ) && - ( SPEC_SCLS(sym->etype) != S_AUTO && - SPEC_SCLS(sym->etype) != S_FIXED && - SPEC_SCLS(sym->etype) != S_REGISTER && - SPEC_SCLS(sym->etype) != S_STACK && - SPEC_SCLS(sym->etype) != S_XSTACK && - SPEC_SCLS(sym->etype) != S_CONSTANT )) { - - werror(E_AUTO_ASSUMED,sym->name) ; - SPEC_SCLS(sym->etype) = S_AUTO ; - } - - /* automatic symbols cannot be given */ - /* an absolute address ignore it */ - if ( sym->level && - SPEC_ABSA(sym->etype) && - (options.stackAuto || reentrant) ) { - werror(E_AUTO_ABSA,sym->name); - SPEC_ABSA(sym->etype) = 0 ; - } - - /* arrays & pointers cannot be defined for bits */ - /* SBITS or SFRs or BIT */ - if ((IS_ARRAY(sym->type) || IS_PTR(sym->type)) && - ( SPEC_NOUN(sym->etype) == V_BIT || - SPEC_NOUN(sym->etype) == V_SBIT || - SPEC_SCLS(sym->etype) == S_SFR )) - werror(E_BIT_ARRAY,sym->name); - - /* if this is a bit|sbit then set length & start */ - if (SPEC_NOUN(sym->etype) == V_BIT || - SPEC_NOUN(sym->etype) == V_SBIT ) { - SPEC_BLEN(sym->etype) = 1 ; - SPEC_BSTR(sym->etype) = 0 ; - } - - /* variables declared in CODE space must have */ - /* initializers if not an extern */ - if (SPEC_SCLS(sym->etype) == S_CODE && - sym->ival == NULL && - !sym->level && - port->mem.code_ro && - !IS_EXTERN(sym->etype) && - !funcInChain(sym->type)) - werror(E_CODE_NO_INIT,sym->name); - - /* if parameter or local variable then change */ - /* the storage class to reflect where the var will go */ - if ( sym->level && SPEC_SCLS(sym->etype) == S_FIXED) { - if ( options.stackAuto || (currFunc && IS_RENT(currFunc->etype))) - { - SPEC_SCLS(sym->etype) = (options.useXstack ? - S_XSTACK : S_STACK ) ; - } - else - { - /* hack-o-matic! I see no reason why the useXstack option should ever - * control this allcoation, but the code was originally that way, and - * changing it for non-390 ports breaks the compiler badly. - */ - bool useXdata = IS_DS390_PORT ? options.model : options.useXstack; - SPEC_SCLS(sym->etype) = (useXdata ? - S_XDATA : S_FIXED ) ; - } + } + + /* if this is an automatic symbol then */ + /* storage class will be ignored and */ + /* symbol will be allocated on stack/ */ + /* data depending on flag */ + if (sym->level && + (options.stackAuto || reentrant) && + (SPEC_SCLS (sym->etype) != S_AUTO && + SPEC_SCLS (sym->etype) != S_FIXED && + SPEC_SCLS (sym->etype) != S_REGISTER && + SPEC_SCLS (sym->etype) != S_STACK && + SPEC_SCLS (sym->etype) != S_XSTACK && + SPEC_SCLS (sym->etype) != S_CONSTANT)) + { + + werror (E_AUTO_ASSUMED, sym->name); + SPEC_SCLS (sym->etype) = S_AUTO; + } + + /* automatic symbols cannot be given */ + /* an absolute address ignore it */ + if (sym->level && + SPEC_ABSA (sym->etype) && + (options.stackAuto || reentrant)) + { + werror (E_AUTO_ABSA, sym->name); + SPEC_ABSA (sym->etype) = 0; + } + + /* arrays & pointers cannot be defined for bits */ + /* SBITS or SFRs or BIT */ + if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) && + (SPEC_NOUN (sym->etype) == V_BIT || + SPEC_NOUN (sym->etype) == V_SBIT || + SPEC_SCLS (sym->etype) == S_SFR)) + werror (E_BIT_ARRAY, sym->name); + + /* if this is a bit|sbit then set length & start */ + if (SPEC_NOUN (sym->etype) == V_BIT || + SPEC_NOUN (sym->etype) == V_SBIT) + { + SPEC_BLEN (sym->etype) = 1; + SPEC_BSTR (sym->etype) = 0; + } + + /* variables declared in CODE space must have */ + /* initializers if not an extern */ + if (SPEC_SCLS (sym->etype) == S_CODE && + sym->ival == NULL && + !sym->level && + port->mem.code_ro && + !IS_EXTERN (sym->etype) && + !funcInChain (sym->type)) + werror (E_CODE_NO_INIT, sym->name); + + /* if parameter or local variable then change */ + /* the storage class to reflect where the var will go */ + if (sym->level && SPEC_SCLS (sym->etype) == S_FIXED) + { + if (options.stackAuto || (currFunc && IS_RENT (currFunc->etype))) + { + SPEC_SCLS (sym->etype) = (options.useXstack ? + S_XSTACK : S_STACK); + } + else + { + /* hack-o-matic! I see no reason why the useXstack option should ever + * control this allcoation, but the code was originally that way, and + * changing it for non-390 ports breaks the compiler badly. + */ + bool useXdata = IS_DS390_PORT ? options.model : options.useXstack; + SPEC_SCLS (sym->etype) = (useXdata ? + S_XDATA : S_FIXED); + } } } /*------------------------------------------------------------------*/ /* changePointer - change pointer to functions */ /*------------------------------------------------------------------*/ -void changePointer (symbol *sym) +void +changePointer (symbol * sym) { - sym_link *p ; - - /* go thru the chain of declarations */ - /* if we find a pointer to a function */ - /* unconditionally change it to a ptr */ - /* to code area */ - for ( p = sym->type ; p ; p = p->next) { - if ( !IS_SPEC(p) && DCL_TYPE(p) == UPOINTER) - DCL_TYPE(p) = GPOINTER ; - if ( IS_PTR(p) && IS_FUNC(p->next)) - DCL_TYPE(p) = CPOINTER ; + sym_link *p; + + /* go thru the chain of declarations */ + /* if we find a pointer to a function */ + /* unconditionally change it to a ptr */ + /* to code area */ + for (p = sym->type; p; p = p->next) + { + if (!IS_SPEC (p) && DCL_TYPE (p) == UPOINTER) + DCL_TYPE (p) = GPOINTER; + if (IS_PTR (p) && IS_FUNC (p->next)) + DCL_TYPE (p) = CPOINTER; } } /*------------------------------------------------------------------*/ /* checkDecl - does semantic validation of a declaration */ /*------------------------------------------------------------------*/ -int checkDecl ( symbol *sym ) +int +checkDecl (symbol * sym) { - checkSClass (sym); /* check the storage class */ - changePointer(sym); /* change pointers if required */ + checkSClass (sym); /* check the storage class */ + changePointer (sym); /* change pointers if required */ - /* if this is an array without any dimension - then update the dimension from the initial value */ - if (IS_ARRAY(sym->type) && !DCL_ELEM(sym->type)) - DCL_ELEM(sym->type) = getNelements (sym->type,sym->ival); + /* if this is an array without any dimension + then update the dimension from the initial value */ + if (IS_ARRAY (sym->type) && !DCL_ELEM (sym->type)) + DCL_ELEM (sym->type) = getNelements (sym->type, sym->ival); - return 0 ; + return 0; } /*------------------------------------------------------------------*/ /* copyLinkChain - makes a copy of the link chain & rets ptr 2 head */ /*------------------------------------------------------------------*/ -sym_link *copyLinkChain ( sym_link *p) +sym_link * +copyLinkChain (sym_link * p) { - sym_link *head, *curr , *loop; + sym_link *head, *curr, *loop; - curr = p ; - head = loop = ( curr ? newLink() : (void *) NULL) ; - while (curr) { - memcpy(loop,curr,sizeof(sym_link)) ; /* copy it */ - loop->next = (curr->next ? newLink() : (void *) NULL) ; - loop = loop->next ; - curr = curr->next ; + curr = p; + head = loop = (curr ? newLink () : (void *) NULL); + while (curr) + { + memcpy (loop, curr, sizeof (sym_link)); /* copy it */ + loop->next = (curr->next ? newLink () : (void *) NULL); + loop = loop->next; + curr = curr->next; } - return head ; + return head; } @@ -1094,18 +1189,22 @@ sym_link *copyLinkChain ( sym_link *p) /* cleanUpBlock - cleansup the symbol table specified for all the */ /* symbols in the given block */ /*------------------------------------------------------------------*/ -void cleanUpBlock ( bucket **table, int block) +void +cleanUpBlock (bucket ** table, int block) { - int i ; - bucket *chain; + int i; + bucket *chain; - /* go thru the entire table */ - for ( i = 0 ; i < 256; i++ ) { - for ( chain = table[i]; chain ; chain = chain->next ) { - if (chain->block >= block) { - deleteSym (table,chain->sym,chain->name); - } - } + /* go thru the entire table */ + for (i = 0; i < 256; i++) + { + for (chain = table[i]; chain; chain = chain->next) + { + if (chain->block >= block) + { + deleteSym (table, chain->sym, chain->name); + } + } } } @@ -1113,804 +1212,859 @@ void cleanUpBlock ( bucket **table, int block) /* cleanUpLevel - cleansup the symbol table specified for all the */ /* symbols in the given level */ /*------------------------------------------------------------------*/ -void cleanUpLevel (bucket **table, int level ) +void +cleanUpLevel (bucket ** table, int level) { - int i ; - bucket *chain; + int i; + bucket *chain; - /* go thru the entire table */ - for ( i = 0 ; i < 256; i++ ) { - for ( chain = table[i]; chain ; chain = chain->next ) { - if (chain->level >= level) { - deleteSym (table,chain->sym,chain->name); - } - } + /* go thru the entire table */ + for (i = 0; i < 256; i++) + { + for (chain = table[i]; chain; chain = chain->next) + { + if (chain->level >= level) + { + deleteSym (table, chain->sym, chain->name); + } + } } } /*------------------------------------------------------------------*/ /* computeType - computes the resultant type from two types */ /*------------------------------------------------------------------*/ -sym_link *computeType ( sym_link *type1, sym_link *type2) +sym_link * +computeType (sym_link * type1, sym_link * type2) { - sym_link *rType ; - sym_link *reType; - sym_link *etype1 = getSpec(type1); - sym_link *etype2 = getSpec(type2); - - /* if one of them is a float then result is a float */ - /* here we assume that the types passed are okay */ - /* and can be cast to one another */ - /* which ever is greater in size */ - if (IS_FLOAT(etype1) || IS_FLOAT(etype2)) - rType = newFloatLink(); - else - /* if only one of them is a bit variable - then the other one prevails */ - if (IS_BITVAR(etype1) && !IS_BITVAR(etype2)) - rType = copyLinkChain(type2); + sym_link *rType; + sym_link *reType; + sym_link *etype1 = getSpec (type1); + sym_link *etype2 = getSpec (type2); + + /* if one of them is a float then result is a float */ + /* here we assume that the types passed are okay */ + /* and can be cast to one another */ + /* which ever is greater in size */ + if (IS_FLOAT (etype1) || IS_FLOAT (etype2)) + rType = newFloatLink (); + else + /* if only one of them is a bit variable + then the other one prevails */ + if (IS_BITVAR (etype1) && !IS_BITVAR (etype2)) + rType = copyLinkChain (type2); + else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1)) + rType = copyLinkChain (type1); else - if (IS_BITVAR(etype2) && !IS_BITVAR(etype1)) - rType = copyLinkChain(type1); - else /* if one of them is a pointer then that prevails */ - if (IS_PTR(type1)) - rType = copyLinkChain(type1); - else - if (IS_PTR(type2)) - rType = copyLinkChain(type2); - else - if (getSize (type1) > getSize(type2) ) - rType = copyLinkChain(type1); - else - rType = copyLinkChain(type2); + if (IS_PTR (type1)) + rType = copyLinkChain (type1); + else if (IS_PTR (type2)) + rType = copyLinkChain (type2); + else if (getSize (type1) > getSize (type2)) + rType = copyLinkChain (type1); + else + rType = copyLinkChain (type2); - reType = getSpec(rType); + reType = getSpec (rType); - /* if either of them unsigned then make this unsigned */ - if ((SPEC_USIGN(etype1) || SPEC_USIGN(etype2)) && !IS_FLOAT(reType)) - SPEC_USIGN(reType) = 1; + /* if either of them unsigned then make this unsigned */ + if ((SPEC_USIGN (etype1) || SPEC_USIGN (etype2)) && !IS_FLOAT (reType)) + SPEC_USIGN (reType) = 1; - /* if result is a literal then make not so */ - if (IS_LITERAL(reType)) - SPEC_SCLS(reType) = S_REGISTER ; + /* if result is a literal then make not so */ + if (IS_LITERAL (reType)) + SPEC_SCLS (reType) = S_REGISTER; - return rType; + return rType; } /*------------------------------------------------------------------*/ /* checkType - will do type check return 1 if match */ /*------------------------------------------------------------------*/ -int checkType ( sym_link *dest, sym_link *src ) +int +checkType (sym_link * dest, sym_link * src) { - if ( !dest && !src) - return 1; + if (!dest && !src) + return 1; - if (dest && !src) - return 0; + if (dest && !src) + return 0; - if (src && !dest) - return 0; + if (src && !dest) + return 0; - /* if dest is a declarator then */ - if (IS_DECL(dest)) { - if (IS_DECL(src)) { - if (DCL_TYPE(src) == DCL_TYPE(dest)) - return checkType(dest->next,src->next); - else - if (IS_PTR(src) && IS_PTR(dest)) - return -1; - else - if (IS_PTR(dest) && IS_ARRAY(src)) - return -1; - else - if (IS_PTR(dest) && IS_FUNC(dest->next) && IS_FUNC(src)) - return -1 * checkType (dest->next,src) ; - else - return 0; - } - else - if (IS_PTR(dest) && IS_INTEGRAL(src)) - return -1; + /* if dest is a declarator then */ + if (IS_DECL (dest)) + { + if (IS_DECL (src)) + { + if (DCL_TYPE (src) == DCL_TYPE (dest)) + return checkType (dest->next, src->next); + else if (IS_PTR (src) && IS_PTR (dest)) + return -1; + else if (IS_PTR (dest) && IS_ARRAY (src)) + return -1; + else if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src)) + return -1 * checkType (dest->next, src); + else + return 0; + } + else if (IS_PTR (dest) && IS_INTEGRAL (src)) + return -1; else - return 0; + return 0; } - /* if one is a specifier and the other is not */ - if ((IS_SPEC(src) && !IS_SPEC(dest)) || - (IS_SPEC(dest) && !IS_SPEC(src))) return 0; - - /* if one of them is a void then ok */ - if (SPEC_NOUN(dest) == V_VOID && - SPEC_NOUN(src) != V_VOID ) - return -1 ; - - if (SPEC_NOUN(dest) != V_VOID && - SPEC_NOUN(src) == V_VOID ) - return -1; - - /* char === to short */ - if (SPEC_NOUN(dest) == V_CHAR && - SPEC_NOUN(src) == V_INT && - SPEC_SHORT(src) ) - return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2); - - if (SPEC_NOUN(src) == V_CHAR && - SPEC_NOUN(dest) == V_INT && - SPEC_SHORT(dest) ) - return (SPEC_USIGN(src) == SPEC_USIGN(dest) ? 1 : -2); - - /* if they are both bitfields then if the lengths - and starts don't match */ - if (IS_BITFIELD(dest) && IS_BITFIELD(src) && - (SPEC_BLEN(dest) != SPEC_BLEN(src) || - SPEC_BSTR(dest) != SPEC_BSTR(src))) - return -1; - - /* it is a specifier */ - if (SPEC_NOUN(dest) != SPEC_NOUN(src)) { - if (SPEC_USIGN(dest) == SPEC_USIGN(src) && - IS_INTEGRAL(dest) && IS_INTEGRAL(src) && - getSize(dest) == getSize(src)) - return 1; - else - if (IS_ARITHMETIC(dest) && IS_ARITHMETIC(src)) + /* if one is a specifier and the other is not */ + if ((IS_SPEC (src) && !IS_SPEC (dest)) || + (IS_SPEC (dest) && !IS_SPEC (src))) + return 0; + + /* if one of them is a void then ok */ + if (SPEC_NOUN (dest) == V_VOID && + SPEC_NOUN (src) != V_VOID) return -1; - else - return 0; + + if (SPEC_NOUN (dest) != V_VOID && + SPEC_NOUN (src) == V_VOID) + return -1; + + /* char === to short */ + if (SPEC_NOUN (dest) == V_CHAR && + SPEC_NOUN (src) == V_INT && + SPEC_SHORT (src)) + return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2); + + if (SPEC_NOUN (src) == V_CHAR && + SPEC_NOUN (dest) == V_INT && + SPEC_SHORT (dest)) + return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2); + + /* if they are both bitfields then if the lengths + and starts don't match */ + if (IS_BITFIELD (dest) && IS_BITFIELD (src) && + (SPEC_BLEN (dest) != SPEC_BLEN (src) || + SPEC_BSTR (dest) != SPEC_BSTR (src))) + return -1; + + /* it is a specifier */ + if (SPEC_NOUN (dest) != SPEC_NOUN (src)) + { + if (SPEC_USIGN (dest) == SPEC_USIGN (src) && + IS_INTEGRAL (dest) && IS_INTEGRAL (src) && + getSize (dest) == getSize (src)) + return 1; + else if (IS_ARITHMETIC (dest) && IS_ARITHMETIC (src)) + return -1; + else + return 0; } - else - if (IS_STRUCT(dest)) { - if (SPEC_STRUCT(dest) != SPEC_STRUCT(src)) - return 0 ; + else if (IS_STRUCT (dest)) + { + if (SPEC_STRUCT (dest) != SPEC_STRUCT (src)) + return 0; else - return 1 ; - } - if (SPEC_LONG(dest) != SPEC_LONG(src)) - return -1; + return 1; + } + if (SPEC_LONG (dest) != SPEC_LONG (src)) + return -1; - if (SPEC_SHORT(dest) != SPEC_SHORT(src)) - return -1; + if (SPEC_SHORT (dest) != SPEC_SHORT (src)) + return -1; - if (SPEC_USIGN(dest) != SPEC_USIGN(src)) - return -2; + if (SPEC_USIGN (dest) != SPEC_USIGN (src)) + return -2; - return 1; + return 1; } /*------------------------------------------------------------------*/ /* inCalleeSaveList - return 1 if found in calle save list */ /*------------------------------------------------------------------*/ -bool inCalleeSaveList ( char *s) +bool +inCalleeSaveList (char *s) { - int i; + int i; - for (i = 0 ; options.calleeSaves[i] ; i++ ) - if (strcmp(options.calleeSaves[i],s) == 0) + for (i = 0; options.calleeSaves[i]; i++) + if (strcmp (options.calleeSaves[i], s) == 0) return 1; - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* aggregateArgToPointer: change an agggregate type function */ /* argument to a pointer to that type. */ /*-----------------------------------------------------------------*/ -void aggregateArgToPointer(value *val) +void +aggregateArgToPointer (value * val) { - if ( IS_AGGREGATE(val->type)) { + if (IS_AGGREGATE (val->type)) + { /* if this is a structure */ /* then we need to add a new link */ - if (IS_STRUCT(val->type)) { - /* first lets add DECLARATOR type */ - sym_link *p = val->type ; + if (IS_STRUCT (val->type)) + { + /* first lets add DECLARATOR type */ + sym_link *p = val->type; - werror(W_STRUCT_AS_ARG,val->name); - val->type = newLink(); - val->type->next = p ; - } + werror (W_STRUCT_AS_ARG, val->name); + val->type = newLink (); + val->type->next = p; + } /* change to a pointer depending on the */ /* storage class specified */ - switch (SPEC_SCLS(val->etype)) { - case S_IDATA: - DCL_TYPE(val->type) = IPOINTER; - break; - case S_PDATA: - DCL_TYPE(val->type) = PPOINTER; - break; - case S_FIXED: - if (IS_DS390_PORT) - { - /* The AUTO and REGISTER classes should probably - * also become generic pointers, but I haven't yet - * devised a test case for that. - */ - DCL_TYPE(val->type) = GPOINTER; - break; - } - /* fall through! */ - case S_AUTO: - case S_DATA: - case S_REGISTER: - DCL_TYPE(val->type) = POINTER ; - break; - case S_CODE: - DCL_TYPE(val->type) = CPOINTER; - break; - case S_XDATA: - DCL_TYPE(val->type) = FPOINTER; - break; - case S_EEPROM: - DCL_TYPE(val->type) = EEPPOINTER; - break; - default : - DCL_TYPE(val->type) = GPOINTER; - } + switch (SPEC_SCLS (val->etype)) + { + case S_IDATA: + DCL_TYPE (val->type) = IPOINTER; + break; + case S_PDATA: + DCL_TYPE (val->type) = PPOINTER; + break; + case S_FIXED: + if (IS_DS390_PORT) + { + /* The AUTO and REGISTER classes should probably + * also become generic pointers, but I haven't yet + * devised a test case for that. + */ + DCL_TYPE (val->type) = GPOINTER; + break; + } + /* fall through! */ + case S_AUTO: + case S_DATA: + case S_REGISTER: + DCL_TYPE (val->type) = POINTER; + break; + case S_CODE: + DCL_TYPE (val->type) = CPOINTER; + break; + case S_XDATA: + DCL_TYPE (val->type) = FPOINTER; + break; + case S_EEPROM: + DCL_TYPE (val->type) = EEPPOINTER; + break; + default: + DCL_TYPE (val->type) = GPOINTER; + } /* is there is a symbol associated then */ - /* change the type of the symbol as well*/ - if ( val->sym ) { - val->sym->type = copyLinkChain(val->type); - val->sym->etype = getSpec(val->sym->type); - } - } + /* change the type of the symbol as well */ + if (val->sym) + { + val->sym->type = copyLinkChain (val->type); + val->sym->etype = getSpec (val->sym->type); + } + } } /*------------------------------------------------------------------*/ /* checkFunction - does all kinds of check on a function */ /*------------------------------------------------------------------*/ -int checkFunction (symbol *sym) +int +checkFunction (symbol * sym) { - symbol *csym ; - value *exargs, *acargs ; - int argCnt = 0 ; + symbol *csym; + value *exargs, *acargs; + int argCnt = 0; - /* if not type then some kind of error */ - if ( !sym->type ) - return 0; + /* if not type then some kind of error */ + if (!sym->type) + return 0; - /* if the function has no type then make it return int */ - if ( !sym->type->next ) - sym->type->next = sym->etype = newIntLink(); + /* if the function has no type then make it return int */ + if (!sym->type->next) + sym->type->next = sym->etype = newIntLink (); - /* function cannot return aggregate */ - if (IS_AGGREGATE(sym->type->next)) { - werror(E_FUNC_AGGR,sym->name); - return 0; + /* function cannot return aggregate */ + if (IS_AGGREGATE (sym->type->next)) + { + werror (E_FUNC_AGGR, sym->name); + return 0; } - /* function cannot return bit */ - if (IS_BITVAR(sym->type->next)) { - werror(E_FUNC_BIT,sym->name); - return 0; + /* function cannot return bit */ + if (IS_BITVAR (sym->type->next)) + { + werror (E_FUNC_BIT, sym->name); + return 0; } - /* check if this function is defined as calleeSaves - then mark it as such */ - sym->calleeSave = inCalleeSaveList(sym->name); + /* check if this function is defined as calleeSaves + then mark it as such */ + sym->calleeSave = inCalleeSaveList (sym->name); - /* if interrupt service routine */ - /* then it cannot have arguments */ - if ( sym->args && IS_ISR(sym->etype) && !IS_VOID(sym->args->type)) { - werror(E_INT_ARGS,sym->name); - sym->args = NULL ; + /* if interrupt service routine */ + /* then it cannot have arguments */ + if (sym->args && IS_ISR (sym->etype) && !IS_VOID (sym->args->type)) + { + werror (E_INT_ARGS, sym->name); + sym->args = NULL; } - if (!(csym = findSym (SymbolTab, sym, sym->name ))) - return 1 ; /* not defined nothing more to check */ + if (!(csym = findSym (SymbolTab, sym, sym->name))) + return 1; /* not defined nothing more to check */ - /* check if body already present */ - if ( csym && csym->fbody ) { - werror(E_FUNC_BODY,sym->name); - return 0; + /* check if body already present */ + if (csym && csym->fbody) + { + werror (E_FUNC_BODY, sym->name); + return 0; } - /* check the return value type */ - if (checkType (csym->type,sym->type) <= 0) { - werror(E_PREV_DEF_CONFLICT,csym->name,"type") ; - werror (E_CONTINUE,"previous defintion type "); - printTypeChain(csym->type,stderr);fprintf(stderr,"\n"); - werror (E_CONTINUE,"current definition type "); - printTypeChain(sym->type,stderr);fprintf(stderr,"\n"); - return 0; + /* check the return value type */ + if (checkType (csym->type, sym->type) <= 0) + { + werror (E_PREV_DEF_CONFLICT, csym->name, "type"); + werror (E_CONTINUE, "previous defintion type "); + printTypeChain (csym->type, stderr); + fprintf (stderr, "\n"); + werror (E_CONTINUE, "current definition type "); + printTypeChain (sym->type, stderr); + fprintf (stderr, "\n"); + return 0; } - if ( SPEC_INTRTN(csym->etype) != SPEC_INTRTN(sym->etype)) { - werror (E_PREV_DEF_CONFLICT,csym->name,"interrupt"); - return 0; + if (SPEC_INTRTN (csym->etype) != SPEC_INTRTN (sym->etype)) + { + werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt"); + return 0; } - if (SPEC_BANK(csym->etype) != SPEC_BANK(sym->etype)) { - werror (E_PREV_DEF_CONFLICT,csym->name,"using"); - return 0; + if (SPEC_BANK (csym->etype) != SPEC_BANK (sym->etype)) + { + werror (E_PREV_DEF_CONFLICT, csym->name, "using"); + return 0; } - /* compare expected agrs with actual args */ - exargs = csym->args ; - acargs = sym->args ; + /* compare expected agrs with actual args */ + exargs = csym->args; + acargs = sym->args; - /* for all the expected args do */ - for (argCnt = 1 ; - exargs && acargs ; - exargs = exargs->next, acargs = acargs->next, argCnt++ ) + /* for all the expected args do */ + for (argCnt = 1; + exargs && acargs; + exargs = exargs->next, acargs = acargs->next, argCnt++) { - value *checkValue; - /* If the actual argument is an array, any prototype - * will have modified it to a pointer. Duplicate that - * change here. - */ - if ( IS_AGGREGATE(acargs->type)) - { - checkValue = copyValue(acargs); - aggregateArgToPointer(checkValue); - } - else - { - checkValue = acargs; - } - - if ( checkType(exargs->type,checkValue->type) <= 0) - { - werror(E_ARG_TYPE,argCnt); - return 0; - } + value *checkValue; + /* If the actual argument is an array, any prototype + * will have modified it to a pointer. Duplicate that + * change here. + */ + if (IS_AGGREGATE (acargs->type)) + { + checkValue = copyValue (acargs); + aggregateArgToPointer (checkValue); + } + else + { + checkValue = acargs; + } + + if (checkType (exargs->type, checkValue->type) <= 0) + { + werror (E_ARG_TYPE, argCnt); + return 0; + } } - /* if one them ended we have a problem */ - if ((exargs && !acargs && !IS_VOID(exargs->type)) || - (!exargs && acargs && !IS_VOID(acargs->type))) - werror(E_ARG_COUNT); - - /* replace with this defition */ - sym->cdef = csym->cdef; - deleteSym (SymbolTab,csym,csym->name); - addSym (SymbolTab,sym,sym->name,sym->level,sym->block); - if (IS_EXTERN(csym->etype) && ! - IS_EXTERN(sym->etype)) { - addSet(&publics,sym); + /* if one them ended we have a problem */ + if ((exargs && !acargs && !IS_VOID (exargs->type)) || + (!exargs && acargs && !IS_VOID (acargs->type))) + werror (E_ARG_COUNT); + + /* replace with this defition */ + sym->cdef = csym->cdef; + deleteSym (SymbolTab, csym, csym->name); + addSym (SymbolTab, sym, sym->name, sym->level, sym->block); + if (IS_EXTERN (csym->etype) && ! + IS_EXTERN (sym->etype)) + { + addSet (&publics, sym); } - return 1 ; + return 1; } /*-----------------------------------------------------------------*/ /* processFuncArgs - does some processing with function args */ /*-----------------------------------------------------------------*/ -void processFuncArgs (symbol *func, int ignoreName) +void +processFuncArgs (symbol * func, int ignoreName) { - value *val ; - int pNum = 1; - - - /* if this function has variable argument list */ - /* then make the function a reentrant one */ - if (func->hasVargs) - SPEC_RENT(func->etype) = 1; - - /* check if this function is defined as calleeSaves - then mark it as such */ - func->calleeSave = inCalleeSaveList(func->name); - - val = func->args; /* loop thru all the arguments */ - - /* if it is void then remove parameters */ - if (val && IS_VOID(val->type)) { - func->args = NULL ; - return ; - } - - /* reset regparm for the port */ - (*port->reset_regparms)(); - /* if any of the arguments is an aggregate */ - /* change it to pointer to the same type */ - while (val) { - /* mark it as a register parameter if - the function does not have VA_ARG - and as port dictates - not inhibited by command line option or #pragma */ - if (!func->hasVargs && - !options.noregparms && - !IS_RENT(func->etype) && - (*port->reg_parm)(val->type)) { - SPEC_REGPARM(val->etype) = 1; - } - - if ( IS_AGGREGATE(val->type)) { - aggregateArgToPointer(val); - } - val = val->next ; - pNum++; - } - - /* if this function is reentrant or */ - /* automatics r 2b stacked then nothing */ - if (IS_RENT(func->etype) || options.stackAuto ) - return ; - - val = func->args; - pNum = 1; - while (val) { - - /* if a symbolname is not given */ - /* synthesize a variable name */ - if (!val->sym) { - - sprintf(val->name,"_%s_PARM_%d",func->name,pNum++); - val->sym = newSymbol(val->name,1); - SPEC_OCLS(val->etype) = port->mem.default_local_map; - val->sym->type = copyLinkChain (val->type); - val->sym->etype = getSpec (val->sym->type); - val->sym->_isparm = 1; - strcpy (val->sym->rname,val->name); - SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) = - SPEC_STAT(func->etype); - addSymChain(val->sym); - - } - else /* symbol name given create synth name */ { - - sprintf(val->name,"_%s_PARM_%d",func->name,pNum++); - strcpy (val->sym->rname,val->name); - val->sym->_isparm = 1; - SPEC_OCLS(val->etype) = SPEC_OCLS(val->sym->etype) = - (options.model != MODEL_SMALL ? xdata : data); - SPEC_STAT(val->etype) = SPEC_STAT(val->sym->etype) = - SPEC_STAT(func->etype); - } - val = val->next ; + value *val; + int pNum = 1; + + + /* if this function has variable argument list */ + /* then make the function a reentrant one */ + if (func->hasVargs) + SPEC_RENT (func->etype) = 1; + + /* check if this function is defined as calleeSaves + then mark it as such */ + func->calleeSave = inCalleeSaveList (func->name); + + val = func->args; /* loop thru all the arguments */ + + /* if it is void then remove parameters */ + if (val && IS_VOID (val->type)) + { + func->args = NULL; + return; + } + + /* reset regparm for the port */ + (*port->reset_regparms) (); + /* if any of the arguments is an aggregate */ + /* change it to pointer to the same type */ + while (val) + { + /* mark it as a register parameter if + the function does not have VA_ARG + and as port dictates + not inhibited by command line option or #pragma */ + if (!func->hasVargs && + !options.noregparms && + !IS_RENT (func->etype) && + (*port->reg_parm) (val->type)) + { + SPEC_REGPARM (val->etype) = 1; + } + + if (IS_AGGREGATE (val->type)) + { + aggregateArgToPointer (val); + } + val = val->next; + pNum++; + } + + /* if this function is reentrant or */ + /* automatics r 2b stacked then nothing */ + if (IS_RENT (func->etype) || options.stackAuto) + return; + + val = func->args; + pNum = 1; + while (val) + { + + /* if a symbolname is not given */ + /* synthesize a variable name */ + if (!val->sym) + { + + sprintf (val->name, "_%s_PARM_%d", func->name, pNum++); + val->sym = newSymbol (val->name, 1); + SPEC_OCLS (val->etype) = port->mem.default_local_map; + val->sym->type = copyLinkChain (val->type); + val->sym->etype = getSpec (val->sym->type); + val->sym->_isparm = 1; + strcpy (val->sym->rname, val->name); + SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) = + SPEC_STAT (func->etype); + addSymChain (val->sym); + + } + else /* symbol name given create synth name */ + { + + sprintf (val->name, "_%s_PARM_%d", func->name, pNum++); + strcpy (val->sym->rname, val->name); + val->sym->_isparm = 1; + SPEC_OCLS (val->etype) = SPEC_OCLS (val->sym->etype) = + (options.model != MODEL_SMALL ? xdata : data); + SPEC_STAT (val->etype) = SPEC_STAT (val->sym->etype) = + SPEC_STAT (func->etype); + } + val = val->next; } } /*-----------------------------------------------------------------*/ /* isSymbolEqual - compares two symbols return 1 if they match */ /*-----------------------------------------------------------------*/ -int isSymbolEqual (symbol *dest, symbol *src) +int +isSymbolEqual (symbol * dest, symbol * src) { - /* if pointers match then equal */ - if (dest == src) - return 1; + /* if pointers match then equal */ + if (dest == src) + return 1; - /* if one of them is null then don't match */ - if (!dest || !src) - return 0; + /* if one of them is null then don't match */ + if (!dest || !src) + return 0; - /* if both of them have rname match on rname */ - if (dest->rname[0] && src->rname[0]) - return (!strcmp(dest->rname,src->rname)); + /* if both of them have rname match on rname */ + if (dest->rname[0] && src->rname[0]) + return (!strcmp (dest->rname, src->rname)); - /* otherwise match on name */ - return (!strcmp(dest->name,src->name)); + /* otherwise match on name */ + return (!strcmp (dest->name, src->name)); } /*-----------------------------------------------------------------*/ /* printTypeChain - prints the type chain in human readable form */ /*-----------------------------------------------------------------*/ -void printTypeChain (sym_link *type, FILE *of) +void +printTypeChain (sym_link * type, FILE * of) { - int nlr = 0; - - if (!of) { - of = stdout; - nlr = 1; - } - - while (type) { - if (IS_DECL(type)) { - switch (DCL_TYPE(type)) { - case FUNCTION: - fprintf (of,"function "); - break; - case GPOINTER: - fprintf (of,"_generic * "); - if (DCL_PTR_CONST(type)) - fprintf(of,"const "); - break; - case CPOINTER: - fprintf (of,"_code * "); - if (DCL_PTR_CONST(type)) - fprintf(of,"const "); - break; - case FPOINTER: - fprintf (of,"_far * "); - if (DCL_PTR_CONST(type)) - fprintf(of,"const "); - break; - case EEPPOINTER: - fprintf (of,"_eeprom * "); - if (DCL_PTR_CONST(type)) - fprintf(of,"const "); - break; - - case POINTER: - fprintf (of,"_near * "); - if (DCL_PTR_CONST(type)) - fprintf(of,"const "); - break; - case IPOINTER: - fprintf (of,"_idata *"); - if (DCL_PTR_CONST(type)) - fprintf(of,"const "); - break; - case PPOINTER: - fprintf (of,"_pdata *"); - if (DCL_PTR_CONST(type)) - fprintf(of,"const "); - break; - case UPOINTER: - fprintf (of," _unkown *"); - if (DCL_PTR_CONST(type)) - fprintf(of,"const "); - break; - - case ARRAY : - fprintf (of,"array of "); - break; - } - } else { - if (SPEC_VOLATILE(type)) - fprintf (of,"volatile "); - if (SPEC_USIGN(type)) - fprintf (of,"unsigned "); - - switch (SPEC_NOUN(type)) { - case V_INT: - if (IS_LONG(type)) - fprintf (of,"long "); - else - if (IS_SHORT(type)) - fprintf (of,"short "); - else - fprintf (of,"int "); - break; - - case V_CHAR: - fprintf(of,"char "); - break; - - case V_VOID: - fprintf(of,"void "); - break; - - case V_FLOAT: - fprintf(of,"float "); - break; - - case V_STRUCT: - fprintf(of,"struct %s",SPEC_STRUCT(type)->tag); - break; - - case V_SBIT: - fprintf(of,"sbit "); - break; - - case V_BIT: - fprintf(of,"bit {%d,%d}",SPEC_BSTR(type),SPEC_BLEN(type)); - break; - - default: - break; - } - } - type = type->next; - } - if (nlr) - fprintf(of,"\n"); + int nlr = 0; + + if (!of) + { + of = stdout; + nlr = 1; + } + + while (type) + { + if (IS_DECL (type)) + { + switch (DCL_TYPE (type)) + { + case FUNCTION: + fprintf (of, "function "); + break; + case GPOINTER: + fprintf (of, "_generic * "); + if (DCL_PTR_CONST (type)) + fprintf (of, "const "); + break; + case CPOINTER: + fprintf (of, "_code * "); + if (DCL_PTR_CONST (type)) + fprintf (of, "const "); + break; + case FPOINTER: + fprintf (of, "_far * "); + if (DCL_PTR_CONST (type)) + fprintf (of, "const "); + break; + case EEPPOINTER: + fprintf (of, "_eeprom * "); + if (DCL_PTR_CONST (type)) + fprintf (of, "const "); + break; + + case POINTER: + fprintf (of, "_near * "); + if (DCL_PTR_CONST (type)) + fprintf (of, "const "); + break; + case IPOINTER: + fprintf (of, "_idata *"); + if (DCL_PTR_CONST (type)) + fprintf (of, "const "); + break; + case PPOINTER: + fprintf (of, "_pdata *"); + if (DCL_PTR_CONST (type)) + fprintf (of, "const "); + break; + case UPOINTER: + fprintf (of, " _unkown *"); + if (DCL_PTR_CONST (type)) + fprintf (of, "const "); + break; + + case ARRAY: + fprintf (of, "array of "); + break; + } + } + else + { + if (SPEC_VOLATILE (type)) + fprintf (of, "volatile "); + if (SPEC_USIGN (type)) + fprintf (of, "unsigned "); + + switch (SPEC_NOUN (type)) + { + case V_INT: + if (IS_LONG (type)) + fprintf (of, "long "); + else if (IS_SHORT (type)) + fprintf (of, "short "); + else + fprintf (of, "int "); + break; + + case V_CHAR: + fprintf (of, "char "); + break; + + case V_VOID: + fprintf (of, "void "); + break; + + case V_FLOAT: + fprintf (of, "float "); + break; + + case V_STRUCT: + fprintf (of, "struct %s", SPEC_STRUCT (type)->tag); + break; + + case V_SBIT: + fprintf (of, "sbit "); + break; + + case V_BIT: + fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type)); + break; + + default: + break; + } + } + type = type->next; + } + if (nlr) + fprintf (of, "\n"); } /*-----------------------------------------------------------------*/ /* cdbTypeInfo - print the type information for debugger */ /*-----------------------------------------------------------------*/ -void cdbTypeInfo (sym_link *type,FILE *of) +void +cdbTypeInfo (sym_link * type, FILE * of) { - fprintf(of,"{%d}",getSize(type)); - while (type) { - if (IS_DECL(type)) { - switch (DCL_TYPE(type)) { - case FUNCTION: - fprintf (of,"DF,"); - break; - case GPOINTER: - fprintf (of,"DG,"); - break; - case CPOINTER: - fprintf (of,"DC,"); - break; - case FPOINTER: - fprintf (of,"DX,"); - break; - case POINTER: - fprintf (of,"DD,"); - break; - case IPOINTER: - fprintf (of,"DI,"); - break; - case PPOINTER: - fprintf (of,"DP,"); - break; - case EEPPOINTER: - fprintf (of,"DA,"); - break; - case ARRAY : - fprintf (of,"DA%d,",DCL_ELEM(type)); - break; - default: - break; - } - } else { - switch (SPEC_NOUN(type)) { - case V_INT: - if (IS_LONG(type)) - fprintf (of,"SL"); - else - if (IS_SHORT(type)) - fprintf (of,"SS"); - else - fprintf (of,"SI"); - break; - - case V_CHAR: - fprintf(of,"SC"); - break; - - case V_VOID: - fprintf(of,"SV"); - break; - - case V_FLOAT: - fprintf(of,"SF"); - break; - - case V_STRUCT: - fprintf(of,"ST%s",SPEC_STRUCT(type)->tag); - break; - - case V_SBIT: - fprintf(of,"SX"); - break; - - case V_BIT: - fprintf(of,"SB%d$%d",SPEC_BSTR(type),SPEC_BLEN(type)); - break; - - default: - break; - } - fputs(":",of); - if (SPEC_USIGN(type)) - fputs("U",of); + fprintf (of, "{%d}", getSize (type)); + while (type) + { + if (IS_DECL (type)) + { + switch (DCL_TYPE (type)) + { + case FUNCTION: + fprintf (of, "DF,"); + break; + case GPOINTER: + fprintf (of, "DG,"); + break; + case CPOINTER: + fprintf (of, "DC,"); + break; + case FPOINTER: + fprintf (of, "DX,"); + break; + case POINTER: + fprintf (of, "DD,"); + break; + case IPOINTER: + fprintf (of, "DI,"); + break; + case PPOINTER: + fprintf (of, "DP,"); + break; + case EEPPOINTER: + fprintf (of, "DA,"); + break; + case ARRAY: + fprintf (of, "DA%d,", DCL_ELEM (type)); + break; + default: + break; + } + } else - fputs("S",of); - } - type = type->next; + { + switch (SPEC_NOUN (type)) + { + case V_INT: + if (IS_LONG (type)) + fprintf (of, "SL"); + else if (IS_SHORT (type)) + fprintf (of, "SS"); + else + fprintf (of, "SI"); + break; + + case V_CHAR: + fprintf (of, "SC"); + break; + + case V_VOID: + fprintf (of, "SV"); + break; + + case V_FLOAT: + fprintf (of, "SF"); + break; + + case V_STRUCT: + fprintf (of, "ST%s", SPEC_STRUCT (type)->tag); + break; + + case V_SBIT: + fprintf (of, "SX"); + break; + + case V_BIT: + fprintf (of, "SB%d$%d", SPEC_BSTR (type), SPEC_BLEN (type)); + break; + + default: + break; + } + fputs (":", of); + if (SPEC_USIGN (type)) + fputs ("U", of); + else + fputs ("S", of); + } + type = type->next; } } /*-----------------------------------------------------------------*/ /* cdbSymbol - prints a symbol & its type information for debugger */ /*-----------------------------------------------------------------*/ -void cdbSymbol ( symbol *sym, FILE *of, int isStructSym, int isFunc) +void +cdbSymbol (symbol * sym, FILE * of, int isStructSym, int isFunc) { - memmap *map; - - if (!sym) - return ; - if (!of) - of = stdout; - - if (isFunc) - fprintf(of,"F:"); - else - fprintf(of,"S:"); /* symbol record */ - /* if this is not a structure symbol then - we need to figure out the scope information */ - if (!isStructSym) { - if (!sym->level) { - /* global */ - if (IS_STATIC(sym->etype)) - fprintf(of,"F%s$",moduleName); /* scope is file */ + memmap *map; + + if (!sym) + return; + if (!of) + of = stdout; + + if (isFunc) + fprintf (of, "F:"); + else + fprintf (of, "S:"); /* symbol record */ + /* if this is not a structure symbol then + we need to figure out the scope information */ + if (!isStructSym) + { + if (!sym->level) + { + /* global */ + if (IS_STATIC (sym->etype)) + fprintf (of, "F%s$", moduleName); /* scope is file */ + else + fprintf (of, "G$"); /* scope is global */ + } else - fprintf(of,"G$"); /* scope is global */ - } + /* symbol is local */ + fprintf (of, "L%s$", (sym->localof ? sym->localof->name : "-null-")); + } else - /* symbol is local */ - fprintf(of,"L%s$",(sym->localof ? sym->localof->name : "-null-")); - } else - fprintf(of,"S$"); /* scope is structure */ - - /* print the name, & mangled name */ - fprintf(of,"%s$%d$%d(",sym->name, - sym->level,sym->block); - - cdbTypeInfo(sym->type,of); - fprintf(of,"),"); - - /* print the address space */ - map = SPEC_OCLS(sym->etype); - fprintf(of,"%c,%d,%d", - (map ? map->dbName : 'Z') ,sym->onStack,SPEC_STAK(sym->etype)); - - /* if assigned to registers then output register names */ - /* if this is a function then print - if is it an interrupt routine & interrupt number - and the register bank it is using */ - if (isFunc) - fprintf(of,",%d,%d,%d",SPEC_INTRTN(sym->etype), - SPEC_INTN(sym->etype),SPEC_BANK(sym->etype)); - /* alternate location to find this symbol @ : eg registers - or spillication */ - - if (!isStructSym) - fprintf(of,"\n"); + fprintf (of, "S$"); /* scope is structure */ + + /* print the name, & mangled name */ + fprintf (of, "%s$%d$%d(", sym->name, + sym->level, sym->block); + + cdbTypeInfo (sym->type, of); + fprintf (of, "),"); + + /* print the address space */ + map = SPEC_OCLS (sym->etype); + fprintf (of, "%c,%d,%d", + (map ? map->dbName : 'Z'), sym->onStack, SPEC_STAK (sym->etype)); + + /* if assigned to registers then output register names */ + /* if this is a function then print + if is it an interrupt routine & interrupt number + and the register bank it is using */ + if (isFunc) + fprintf (of, ",%d,%d,%d", SPEC_INTRTN (sym->etype), + SPEC_INTN (sym->etype), SPEC_BANK (sym->etype)); + /* alternate location to find this symbol @ : eg registers + or spillication */ + + if (!isStructSym) + fprintf (of, "\n"); } /*-----------------------------------------------------------------*/ /* cdbStruct - print a structure for debugger */ /*-----------------------------------------------------------------*/ -void cdbStruct ( structdef *sdef,int block,FILE *of, - int inStruct, char *tag) +void +cdbStruct (structdef * sdef, int block, FILE * of, + int inStruct, char *tag) { - symbol *sym; - - fprintf(of,"T:"); - /* if block # then must have function scope */ - fprintf(of,"F%s$",moduleName); - fprintf(of,"%s[",(tag ? tag : sdef->tag)); - for (sym=sdef->fields ; sym ; sym = sym->next) { - fprintf(of,"({%d}",sym->offset); - cdbSymbol(sym,of,TRUE,FALSE); - fprintf(of,")"); - } - fprintf(of,"]"); - if (!inStruct) - fprintf(of,"\n"); + symbol *sym; + + fprintf (of, "T:"); + /* if block # then must have function scope */ + fprintf (of, "F%s$", moduleName); + fprintf (of, "%s[", (tag ? tag : sdef->tag)); + for (sym = sdef->fields; sym; sym = sym->next) + { + fprintf (of, "({%d}", sym->offset); + cdbSymbol (sym, of, TRUE, FALSE); + fprintf (of, ")"); + } + fprintf (of, "]"); + if (!inStruct) + fprintf (of, "\n"); } /*------------------------------------------------------------------*/ /* cdbStructBlock - calls struct printing for a blcks */ /*------------------------------------------------------------------*/ -void cdbStructBlock (int block , FILE *of) +void +cdbStructBlock (int block, FILE * of) { - int i ; - bucket **table = StructTab; - bucket *chain; - wassert(of); - - /* go thru the entire table */ - for ( i = 0 ; i < 256; i++ ) { - for ( chain = table[i]; chain ; chain = chain->next ) { - if (chain->block >= block) { - cdbStruct((structdef *)chain->sym, chain->block ,of,0,NULL); - } - } + int i; + bucket **table = StructTab; + bucket *chain; + wassert (of); + + /* go thru the entire table */ + for (i = 0; i < 256; i++) + { + for (chain = table[i]; chain; chain = chain->next) + { + if (chain->block >= block) + { + cdbStruct ((structdef *) chain->sym, chain->block, of, 0, NULL); + } + } } } /*-----------------------------------------------------------------*/ /* powof2 - returns power of two for the number if number is pow 2 */ /*-----------------------------------------------------------------*/ -int powof2 (unsigned long num) +int +powof2 (unsigned long num) { - int nshifts = 0; - int n1s = 0 ; + int nshifts = 0; + int n1s = 0; - while (num) { - if (num & 1) n1s++ ; - num >>= 1 ; - nshifts++ ; + while (num) + { + if (num & 1) + n1s++; + num >>= 1; + nshifts++; } - if (n1s > 1 || nshifts == 0) return 0; - return nshifts - 1 ; + if (n1s > 1 || nshifts == 0) + return 0; + return nshifts - 1; } -symbol *__fsadd ; -symbol *__fssub ; -symbol *__fsmul ; -symbol *__fsdiv ; -symbol *__fseq ; -symbol *__fsneq ; -symbol *__fslt ; +symbol *__fsadd; +symbol *__fssub; +symbol *__fsmul; +symbol *__fsdiv; +symbol *__fseq; +symbol *__fsneq; +symbol *__fslt; symbol *__fslteq; -symbol *__fsgt ; +symbol *__fsgt; symbol *__fsgteq; /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */ @@ -1922,98 +2076,114 @@ symbol *__conv[2][3][2]; sym_link *floatType; -static void _makeRegParam(symbol *sym) +static void +_makeRegParam (symbol * sym) { - value *val ; + value *val; - val = sym->args; /* loop thru all the arguments */ + val = sym->args; /* loop thru all the arguments */ - /* reset regparm for the port */ - (*port->reset_regparms)(); - while (val) { - SPEC_REGPARM(val->etype) = 1; - sym->argStack -= getSize(val->type); - val = val->next ; + /* reset regparm for the port */ + (*port->reset_regparms) (); + while (val) + { + SPEC_REGPARM (val->etype) = 1; + sym->argStack -= getSize (val->type); + val = val->next; } } /*-----------------------------------------------------------------*/ /* initCSupport - create functions for C support routines */ /*-----------------------------------------------------------------*/ -void initCSupport () +void +initCSupport () { - const char *smuldivmod[] = { - "mul", "div", "mod" - }; - const char *sbwd[] = { - "char", "int", "long" - }; - const char *ssu[] = { - "s", "u" - }; - - int bwd, su, muldivmod, tofrom; - - floatType= newFloatLink(); - - for (bwd = 0; bwd < 3; bwd++) { - sym_link *l; - switch (bwd) { - case 0: - l = newCharLink(); - break; - case 1: - l = newIntLink(); - break; - case 2: - l = newLongLink(); - break; - default: - assert(0); - } - __multypes[bwd][0] = l; - __multypes[bwd][1] = copyLinkChain(l); - SPEC_USIGN(__multypes[bwd][1]) = 1; - } - - __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent); - __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent); - __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent); - __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent); - __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent); - __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent); - __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent); - __fslteq= funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent); - __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent); - __fsgteq= funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent); - - for (tofrom = 0; tofrom < 2; tofrom++) { - for (bwd = 0; bwd < 3; bwd++) { - for (su = 0; su < 2; su++) { - if (tofrom) { - sprintf(buffer, "__fs2%s%s", ssu[su], sbwd[bwd]); - __conv[tofrom][bwd][su] = funcOfType(buffer, __multypes[bwd][su], floatType, 1, options.float_rent); - } - else { - sprintf(buffer, "__%s%s2fs", ssu[su], sbwd[bwd]); - __conv[tofrom][bwd][su] = funcOfType(buffer, floatType, __multypes[bwd][su], 1, options.float_rent); - } - } - } - } - - for (muldivmod = 0; muldivmod < 3; muldivmod++) { - for (bwd = 0; bwd < 3; bwd++) { - for (su = 0; su < 2; su++) { - sprintf(buffer, "_%s%s%s", - smuldivmod[muldivmod], - ssu[su], - sbwd[bwd]); - __muldiv[muldivmod][bwd][su] = funcOfType(buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent); - SPEC_NONBANKED(__muldiv[muldivmod][bwd][su]->etype) = 1; - if (bwd < port->muldiv.force_reg_param_below) - _makeRegParam(__muldiv[muldivmod][bwd][su]); - } - } + const char *smuldivmod[] = + { + "mul", "div", "mod" + }; + const char *sbwd[] = + { + "char", "int", "long" + }; + const char *ssu[] = + { + "s", "u" + }; + + int bwd, su, muldivmod, tofrom; + + floatType = newFloatLink (); + + for (bwd = 0; bwd < 3; bwd++) + { + sym_link *l; + switch (bwd) + { + case 0: + l = newCharLink (); + break; + case 1: + l = newIntLink (); + break; + case 2: + l = newLongLink (); + break; + default: + assert (0); + } + __multypes[bwd][0] = l; + __multypes[bwd][1] = copyLinkChain (l); + SPEC_USIGN (__multypes[bwd][1]) = 1; + } + + __fsadd = funcOfType ("__fsadd", floatType, floatType, 2, options.float_rent); + __fssub = funcOfType ("__fssub", floatType, floatType, 2, options.float_rent); + __fsmul = funcOfType ("__fsmul", floatType, floatType, 2, options.float_rent); + __fsdiv = funcOfType ("__fsdiv", floatType, floatType, 2, options.float_rent); + __fseq = funcOfType ("__fseq", CHARTYPE, floatType, 2, options.float_rent); + __fsneq = funcOfType ("__fsneq", CHARTYPE, floatType, 2, options.float_rent); + __fslt = funcOfType ("__fslt", CHARTYPE, floatType, 2, options.float_rent); + __fslteq = funcOfType ("__fslteq", CHARTYPE, floatType, 2, options.float_rent); + __fsgt = funcOfType ("__fsgt", CHARTYPE, floatType, 2, options.float_rent); + __fsgteq = funcOfType ("__fsgteq", CHARTYPE, floatType, 2, options.float_rent); + + for (tofrom = 0; tofrom < 2; tofrom++) + { + for (bwd = 0; bwd < 3; bwd++) + { + for (su = 0; su < 2; su++) + { + if (tofrom) + { + sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]); + __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent); + } + else + { + sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]); + __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent); + } + } + } + } + + for (muldivmod = 0; muldivmod < 3; muldivmod++) + { + for (bwd = 0; bwd < 3; bwd++) + { + for (su = 0; su < 2; su++) + { + sprintf (buffer, "_%s%s%s", + smuldivmod[muldivmod], + ssu[su], + sbwd[bwd]); + __muldiv[muldivmod][bwd][su] = funcOfType (buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent); + SPEC_NONBANKED (__muldiv[muldivmod][bwd][su]->etype) = 1; + if (bwd < port->muldiv.force_reg_param_below) + _makeRegParam (__muldiv[muldivmod][bwd][su]); + } + } } } diff --git a/src/SDCCsymt.h b/src/SDCCsymt.h index 55d95ec8..172497b1 100644 --- a/src/SDCCsymt.h +++ b/src/SDCCsymt.h @@ -33,219 +33,242 @@ /* hash table bucket */ typedef struct bucket -{ - void *sym ; /* pointer to the object */ - char name[SDCC_NAME_MAX+1]; /* name of this symbol */ - int level ; /* nest level for this symbol */ - int block ; /* belongs to which block */ - struct bucket *prev ; /* ptr 2 previous bucket */ - struct bucket *next ; /* ptr 2 next bucket */ -} bucket ; - -typedef struct structdef { - char tag[SDCC_NAME_MAX+1]; /* tag part of structure */ - unsigned char level ; /* Nesting level */ - struct symbol *fields ; /* pointer to fields */ - unsigned size ; /* sizeof the table in bytes */ -} structdef ; + { + void *sym; /* pointer to the object */ + char name[SDCC_NAME_MAX + 1]; /* name of this symbol */ + int level; /* nest level for this symbol */ + int block; /* belongs to which block */ + struct bucket *prev; /* ptr 2 previous bucket */ + struct bucket *next; /* ptr 2 next bucket */ + } +bucket; + +typedef struct structdef + { + char tag[SDCC_NAME_MAX + 1]; /* tag part of structure */ + unsigned char level; /* Nesting level */ + struct symbol *fields; /* pointer to fields */ + unsigned size; /* sizeof the table in bytes */ + } +structdef; /* noun definitions */ -typedef enum { - V_INT = 0, - V_FLOAT , - V_CHAR , - V_VOID , - V_STRUCT , - V_LABEL , - V_BIT , - V_SBIT -} NOUN; +typedef enum + { + V_INT = 0, + V_FLOAT, + V_CHAR, + V_VOID, + V_STRUCT, + V_LABEL, + V_BIT, + V_SBIT + } +NOUN; /* storage class */ -typedef enum { - S_FIXED = 0, - S_AUTO , - S_REGISTER , - S_CONSTANT , - S_SFR , - S_SBIT , - S_CODE , - S_XDATA , - S_DATA , - S_IDATA , - S_PDATA , - S_LITERAL , - S_STACK , - S_XSTACK , - S_BIT , - S_EEPROM -} STORAGE_CLASS; +typedef enum + { + S_FIXED = 0, + S_AUTO, + S_REGISTER, + S_CONSTANT, + S_SFR, + S_SBIT, + S_CODE, + S_XDATA, + S_DATA, + S_IDATA, + S_PDATA, + S_LITERAL, + S_STACK, + S_XSTACK, + S_BIT, + S_EEPROM + } +STORAGE_CLASS; /* specifier is the last in the type-chain */ -typedef struct specifier { - NOUN noun ; /* CHAR INT STRUCTURE LABEL */ - STORAGE_CLASS sclass ; /* REGISTER,AUTO,FIX,CONSTANT */ - struct memmap *oclass ; /* output storage class */ - unsigned _long : 1 ; /* 1=long */ - unsigned _short: 1 ; /* 1=short int */ - unsigned _unsigned: 1 ; /* 1=unsigned, 0=signed */ - unsigned _static: 1 ; /* 1=static keyword found */ - unsigned _extern: 1 ; /* 1=extern found */ - unsigned _absadr: 1 ; /* absolute address specfied */ - unsigned _reent : 1 ; /* function is reentrant */ - unsigned _intrtn: 1 ; /* this is an interrupt routin*/ - unsigned _rbank : 1 ; /* seperate register bank */ - unsigned _volatile : 1; /* is marked as volatile */ - unsigned _const:1 ; /* is a constant */ - unsigned _critical:1 ; /* critical function */ - unsigned _typedef :1 ; /* is typedefed */ - unsigned _isregparm:1 ; /* is the first parameter */ - unsigned _isenum :1 ; /* is an enumerated type */ - unsigned nonbanked :1 ; /* function has the nonbanked attribute */ - unsigned banked :1 ; /* function has the banked attribute */ - unsigned _IntNo ; /* 1=Interrupt svc routine */ - short _regbank ; /* register bank 2b used */ - unsigned _addr ; /* address of symbol */ - unsigned _stack ; /* stack offset for stacked v */ - unsigned _bitStart ; /* bit start position */ - int _bitLength ; /* bit length */ - - union { /* Values if constant or enum */ - int v_int ; /* int and char values */ - char *v_char; /* character string */ - unsigned v_uint; /* unsigned int const value */ - long v_long; /* long constant value */ - unsigned long v_ulong; /* unsigned long constant val */ - double v_float; /* floating point constant value */ - struct symbol *v_enum; /* ptr 2 enum_list if enum==1 */ - } const_val ; - struct structdef *v_struct; /* structure pointer */ -} specifier ; +typedef struct specifier + { + NOUN noun; /* CHAR INT STRUCTURE LABEL */ + STORAGE_CLASS sclass; /* REGISTER,AUTO,FIX,CONSTANT */ + struct memmap *oclass; /* output storage class */ + unsigned _long:1; /* 1=long */ + unsigned _short:1; /* 1=short int */ + unsigned _unsigned:1; /* 1=unsigned, 0=signed */ + unsigned _static:1; /* 1=static keyword found */ + unsigned _extern:1; /* 1=extern found */ + unsigned _absadr:1; /* absolute address specfied */ + unsigned _reent:1; /* function is reentrant */ + unsigned _intrtn:1; /* this is an interrupt routin */ + unsigned _rbank:1; /* seperate register bank */ + unsigned _volatile:1; /* is marked as volatile */ + unsigned _const:1; /* is a constant */ + unsigned _critical:1; /* critical function */ + unsigned _typedef:1; /* is typedefed */ + unsigned _isregparm:1; /* is the first parameter */ + unsigned _isenum:1; /* is an enumerated type */ + unsigned nonbanked:1; /* function has the nonbanked attribute */ + unsigned banked:1; /* function has the banked attribute */ + unsigned _IntNo; /* 1=Interrupt svc routine */ + short _regbank; /* register bank 2b used */ + unsigned _addr; /* address of symbol */ + unsigned _stack; /* stack offset for stacked v */ + unsigned _bitStart; /* bit start position */ + int _bitLength; /* bit length */ + + union + { /* Values if constant or enum */ + int v_int; /* int and char values */ + char *v_char; /* character string */ + unsigned v_uint; /* unsigned int const value */ + long v_long; /* long constant value */ + unsigned long v_ulong; /* unsigned long constant val */ + double v_float; /* floating point constant value */ + struct symbol *v_enum; /* ptr 2 enum_list if enum==1 */ + } + const_val; + struct structdef *v_struct; /* structure pointer */ + } +specifier; /* types of declarators */ -typedef enum { - POINTER = 0, /* pointer to near data */ - FPOINTER , /* pointer to far data */ - CPOINTER , /* pointer to code space */ - GPOINTER , /* _generic pointer */ - PPOINTER , /* paged area pointer */ - IPOINTER , /* pointer to upper 128 bytes */ - UPOINTER , /* unknown pointer used only when parsing */ - EEPPOINTER , /* pointer to eeprom */ - ARRAY , - FUNCTION -} DECLARATOR_TYPE; - -typedef struct declarator { - DECLARATOR_TYPE dcl_type; /* POINTER,ARRAY or FUNCTION */ - unsigned int num_elem; /* # of elems if type==array */ - short ptr_const :1; /* pointer is constant */ - short ptr_volatile:1; /* pointer is volatile */ - struct sym_link *tspec; /* pointer type specifier */ -} declarator ; +typedef enum + { + POINTER = 0, /* pointer to near data */ + FPOINTER, /* pointer to far data */ + CPOINTER, /* pointer to code space */ + GPOINTER, /* _generic pointer */ + PPOINTER, /* paged area pointer */ + IPOINTER, /* pointer to upper 128 bytes */ + UPOINTER, /* unknown pointer used only when parsing */ + EEPPOINTER, /* pointer to eeprom */ + ARRAY, + FUNCTION + } +DECLARATOR_TYPE; + +typedef struct declarator + { + DECLARATOR_TYPE dcl_type; /* POINTER,ARRAY or FUNCTION */ + unsigned int num_elem; /* # of elems if type==array */ + short ptr_const:1; /* pointer is constant */ + short ptr_volatile:1; /* pointer is volatile */ + struct sym_link *tspec; /* pointer type specifier */ + } +declarator; #define DECLARATOR 0 #define SPECIFIER 1 -typedef struct sym_link { - unsigned class : 1 ; /* DECLARATOR or SPECIFIER */ - unsigned tdef : 1 ; /* current link created by */ - /* typedef if this flag is set*/ - union { - specifier s ; /* if CLASS == SPECIFIER */ - declarator d ; /* if CLASS == DECLARATOR */ - } select ; - - struct sym_link *next ; /* next element on the chain */ -} sym_link ; - -typedef struct symbol { - char name [SDCC_NAME_MAX+1] ; /* Input Variable Name */ - char rname[SDCC_NAME_MAX+1] ; /* internal name */ - - short level ; /* declration lev,fld offset */ - short block ; /* sequential block # of defintion */ - int key; - unsigned fbody :1 ; /* function body defined */ - unsigned implicit :1 ; /* implicit flag */ - unsigned undefined :1 ; /* undefined variable */ - unsigned ret :1 ; /* return statement for a function */ - unsigned hasVargs :1 ; /* has a variable argument list */ - unsigned _isparm :1 ; /* is a parameter */ - unsigned ismyparm :1 ; /* is parameter of the function being generated */ - unsigned isitmp :1 ; /* is an intermediate temp */ - unsigned islbl :1 ; /* is a temporary label */ - unsigned isref :1 ; /* has been referenced */ - unsigned isind :1 ; /* is a induction variable */ - unsigned isinvariant:1 ; /* is a loop invariant */ - unsigned isstrlit :1 ; /* is a string literal */ - unsigned cdef :1 ; /* compiler defined symbol */ - unsigned allocreq :1 ; /* allocation is required for this variable */ - unsigned addrtaken :1 ; /* address of the symbol was taken */ - unsigned isreqv :1 ; /* is the register quivalent of a symbol */ - unsigned hasFcall :1 ; /* for functions does it call other functions */ - unsigned calleeSave :1 ; /* for functions uses callee save paradigm */ - unsigned udChked :1 ; /* use def checking has been already done */ +typedef struct sym_link + { + unsigned class:1; /* DECLARATOR or SPECIFIER */ + unsigned tdef:1; /* current link created by */ + /* typedef if this flag is set */ + union + { + specifier s; /* if CLASS == SPECIFIER */ + declarator d; /* if CLASS == DECLARATOR */ + } + select; + + struct sym_link *next; /* next element on the chain */ + } +sym_link; + +typedef struct symbol + { + char name[SDCC_NAME_MAX + 1]; /* Input Variable Name */ + char rname[SDCC_NAME_MAX + 1]; /* internal name */ + + short level; /* declration lev,fld offset */ + short block; /* sequential block # of defintion */ + int key; + unsigned fbody:1; /* function body defined */ + unsigned implicit:1; /* implicit flag */ + unsigned undefined:1; /* undefined variable */ + unsigned ret:1; /* return statement for a function */ + unsigned hasVargs:1; /* has a variable argument list */ + unsigned _isparm:1; /* is a parameter */ + unsigned ismyparm:1; /* is parameter of the function being generated */ + unsigned isitmp:1; /* is an intermediate temp */ + unsigned islbl:1; /* is a temporary label */ + unsigned isref:1; /* has been referenced */ + unsigned isind:1; /* is a induction variable */ + unsigned isinvariant:1; /* is a loop invariant */ + unsigned isstrlit:1; /* is a string literal */ + unsigned cdef:1; /* compiler defined symbol */ + unsigned allocreq:1; /* allocation is required for this variable */ + unsigned addrtaken:1; /* address of the symbol was taken */ + unsigned isreqv:1; /* is the register quivalent of a symbol */ + unsigned hasFcall:1; /* for functions does it call other functions */ + unsigned calleeSave:1; /* for functions uses callee save paradigm */ + unsigned udChked:1; /* use def checking has been already done */ /* following flags are used by the backend for code generation and can be changed if a better scheme for backend is thought of */ - unsigned isLiveFcall:1 ; /* is live at or across a function call */ - unsigned isspilt :1 ; /* has to be spilt */ - unsigned remat :1 ; /* can be remateriazed */ - unsigned isptr :1 ; /* is a pointer */ - unsigned uptr :1 ; /* used as a pointer */ - unsigned isFree :1 ; /* used by register allocator */ - unsigned islocal :1 ; /* is a local variable */ - unsigned blockSpil :1 ; /* spilt at block level */ - unsigned remainSpil :1 ; /* spilt because not used in remainder */ - unsigned stackSpil :1 ; /* has been spilt on temp stack location */ - unsigned onStack :1 ; /* this symbol allocated on the stack */ - unsigned iaccess :1 ; /* indirect access */ - unsigned ruonly :1 ; /* used in return statement only */ - unsigned spildir :1 ; /* spilt in direct space */ - unsigned ptrreg :1 ; /* this symbol assigned to a ptr reg */ - unsigned accuse ; /* can be left in the accumulator - On the Z80 accuse is devided into - ACCUSE_A and ACCUSE_HL as the idea - is quite similar. - */ - - int stack ; /* offset on stack */ - int xstack ; /* offset on xternal stack */ - short nRegs ; /* number of registers required */ - short regType ; /* type of register required */ - - struct regs *regs[4] ; /* can have at the most 4 registers */ - struct asmop *aop ; /* asmoperand for this symbol */ - struct iCode *fuse ; /* furthest use */ - struct iCode *rematiCode ; /* rematerialse with which instruction */ - struct operand *reqv ; /* register equivalent of a local variable */ - union { - struct symbol *spillLoc; /* register spil location */ - struct set *itmpStack; /* symbols spilt @ this stack location */ - } usl; - short bitVar ; /* this is a bit variable */ - unsigned offset ; /* offset from top if struct */ - - int lineDef ; /* defined line number */ - int lastLine ; /* for functions the last line*/ - struct sym_link *type ; /* 1st link to declator chain */ - struct sym_link *etype ; /* last link to declarator chn*/ - struct value *args ; /* arguments if function */ - struct symbol *next ; /* crosslink to next symbol */ - struct symbol *localof ; /* local variable of which function */ - struct initList *ival ; /* ptr to initializer if any */ - struct bitVect *defs ; /* bit vector for definitions */ - struct bitVect *uses ; /* bit vector for uses */ - struct bitVect *regsUsed ; /* for functions registers used */ - int liveFrom ; /* live from iCode sequence number */ - int liveTo ; /* live to sequence number */ - int used ; /* no. of times this was used */ - int recvSize ; /* size of first argument */ - int argStack ; /* stacks used by parameters */ - -} symbol ; + unsigned isLiveFcall:1; /* is live at or across a function call */ + unsigned isspilt:1; /* has to be spilt */ + unsigned remat:1; /* can be remateriazed */ + unsigned isptr:1; /* is a pointer */ + unsigned uptr:1; /* used as a pointer */ + unsigned isFree:1; /* used by register allocator */ + unsigned islocal:1; /* is a local variable */ + unsigned blockSpil:1; /* spilt at block level */ + unsigned remainSpil:1; /* spilt because not used in remainder */ + unsigned stackSpil:1; /* has been spilt on temp stack location */ + unsigned onStack:1; /* this symbol allocated on the stack */ + unsigned iaccess:1; /* indirect access */ + unsigned ruonly:1; /* used in return statement only */ + unsigned spildir:1; /* spilt in direct space */ + unsigned ptrreg:1; /* this symbol assigned to a ptr reg */ + unsigned accuse; /* can be left in the accumulator + On the Z80 accuse is devided into + ACCUSE_A and ACCUSE_HL as the idea + is quite similar. + */ + + int stack; /* offset on stack */ + int xstack; /* offset on xternal stack */ + short nRegs; /* number of registers required */ + short regType; /* type of register required */ + + struct regs *regs[4]; /* can have at the most 4 registers */ + struct asmop *aop; /* asmoperand for this symbol */ + struct iCode *fuse; /* furthest use */ + struct iCode *rematiCode; /* rematerialse with which instruction */ + struct operand *reqv; /* register equivalent of a local variable */ + union + { + struct symbol *spillLoc; /* register spil location */ + struct set *itmpStack; /* symbols spilt @ this stack location */ + } + usl; + short bitVar; /* this is a bit variable */ + unsigned offset; /* offset from top if struct */ + + int lineDef; /* defined line number */ + int lastLine; /* for functions the last line */ + struct sym_link *type; /* 1st link to declator chain */ + struct sym_link *etype; /* last link to declarator chn */ + struct value *args; /* arguments if function */ + struct symbol *next; /* crosslink to next symbol */ + struct symbol *localof; /* local variable of which function */ + struct initList *ival; /* ptr to initializer if any */ + struct bitVect *defs; /* bit vector for definitions */ + struct bitVect *uses; /* bit vector for uses */ + struct bitVect *regsUsed; /* for functions registers used */ + int liveFrom; /* live from iCode sequence number */ + int liveTo; /* live to sequence number */ + int used; /* no. of times this was used */ + int recvSize; /* size of first argument */ + int argStack; /* stacks used by parameters */ + + } +symbol; /* Easy Access Macros */ #define DCL_TYPE(l) l->select.d.dcl_type @@ -253,13 +276,13 @@ typedef struct symbol { #define DCL_PTR_CONST(l) l->select.d.ptr_const #define DCL_PTR_VOLATILE(l) l->select.d.ptr_volatile #define DCL_TSPEC(l) l->select.d.tspec -#define SPEC_NOUN(x) x->select.s.noun +#define SPEC_NOUN(x) x->select.s.noun #define SPEC_LONG(x) x->select.s._long #define SPEC_SHORT(x) x->select.s._short #define SPEC_USIGN(x) x->select.s._unsigned #define SPEC_SCLS(x) x->select.s.sclass #define SPEC_ENUM(x) x->select.s._isenum -#define SPEC_OCLS(x) x->select.s.oclass +#define SPEC_OCLS(x) x->select.s.oclass #define SPEC_STAT(x) x->select.s._static #define SPEC_EXTR(x) x->select.s._extern #define SPEC_CODE(x) x->select.s._codesg @@ -333,20 +356,20 @@ typedef struct symbol { #define IS_BANKEDCALL(x) (IS_SPEC(x) && !SPEC_NONBANKED(x) && !SPEC_STAT(x) && (options.model == MODEL_LARGE || options.model == MODEL_MEDIUM || SPEC_BANKED(x))) /* forward declaration for the global vars */ -extern bucket *SymbolTab[] ; -extern bucket *StructTab[] ; +extern bucket *SymbolTab[]; +extern bucket *StructTab[]; extern bucket *TypedefTab[]; -extern bucket *LabelTab[] ; +extern bucket *LabelTab[]; extern bucket *enumTab[]; -extern symbol *__fsadd ; -extern symbol *__fssub ; -extern symbol *__fsmul ; -extern symbol *__fsdiv ; -extern symbol *__fseq ; -extern symbol *__fsneq ; -extern symbol *__fslt ; +extern symbol *__fsadd; +extern symbol *__fssub; +extern symbol *__fsmul; +extern symbol *__fsdiv; +extern symbol *__fseq; +extern symbol *__fsneq; +extern symbol *__fslt; extern symbol *__fslteq; -extern symbol *__fsgt ; +extern symbol *__fsgt; extern symbol *__fsgteq; /* Dims: mul/div/mod, BYTE/WORD/DWORD, SIGNED/UNSIGNED */ @@ -369,61 +392,61 @@ extern sym_link *floatType; #include "SDCCval.h" /* forward definitions for the symbol table related functions */ -void initSymt ( ); -symbol *newSymbol ( char *, int ); -sym_link *newLink ( ); -sym_link *newFloatLink ( ); -structdef *newStruct ( char * ); -void addDecl ( symbol *, int , sym_link * ); -sym_link *mergeSpec ( sym_link *, sym_link * ); -sym_link *cloneSpec ( sym_link * ); -symbol *reverseSyms ( symbol * ); -sym_link *reverseLink ( sym_link * ); -symbol *copySymbol ( symbol * ); -symbol *copySymbolChain ( symbol * ); -void printSymChain ( symbol *, int ); -void printStruct ( structdef *, int ); -char *genSymName ( int ); -sym_link *getSpec ( sym_link * ); -char *genSymName ( int ); -int compStructSize ( int ,structdef * ); -sym_link *copyLinkChain ( sym_link * ); -int checkDecl ( symbol * ); -void checkBasic ( sym_link *, sym_link * ); -value *checkPointerIval ( sym_link *, value * ); -value *checkStructIval ( symbol *, value * ); -value *checkArrayIval ( sym_link *, value * ); -value *checkIval ( sym_link *, value * ); -unsigned int getSize ( sym_link * ); -unsigned int bitsForType ( sym_link * ); -sym_link *newIntLink ( ); -sym_link *newCharLink ( ); -sym_link *newLongLink ( ); -int checkType ( sym_link *, sym_link * ); -int checkFunction ( symbol * ); -void cleanUpLevel ( bucket **,int ); -void cleanUpBlock ( bucket **,int ); -int funcInChain ( sym_link * ); -void addSymChain ( symbol * ); -sym_link *structElemType ( sym_link *, value * , value ** ); -symbol *getStructElement ( structdef *, symbol *) ; -sym_link *computeType ( sym_link *, sym_link *); -void processFuncArgs (symbol *,int); -int isSymbolEqual (symbol *, symbol *); -int powof2 (unsigned long ); -void printTypeChain (sym_link *,FILE *); -void initCSupport (); -void pointerTypes (sym_link *, sym_link * ); -void cdbTypeInfo (sym_link *,FILE *); -void cdbSymbol (symbol *,FILE *,int,int); -void cdbStructBlock (int ,FILE *); -void initHashT ( ); -bucket *newBucket ( ); -void addSym ( bucket ** , void *, char *, int, int); -void deleteSym ( bucket ** , void *, char *); -void *findSym ( bucket ** , void *, const char *); -void *findSymWithLevel ( bucket ** , struct symbol * ); -void *findSymWithBlock ( bucket ** , struct symbol *,int ); +void initSymt (); +symbol *newSymbol (char *, int); +sym_link *newLink (); +sym_link *newFloatLink (); +structdef *newStruct (char *); +void addDecl (symbol *, int, sym_link *); +sym_link *mergeSpec (sym_link *, sym_link *); +sym_link *cloneSpec (sym_link *); +symbol *reverseSyms (symbol *); +sym_link *reverseLink (sym_link *); +symbol *copySymbol (symbol *); +symbol *copySymbolChain (symbol *); +void printSymChain (symbol *, int); +void printStruct (structdef *, int); +char *genSymName (int); +sym_link *getSpec (sym_link *); +char *genSymName (int); +int compStructSize (int, structdef *); +sym_link *copyLinkChain (sym_link *); +int checkDecl (symbol *); +void checkBasic (sym_link *, sym_link *); +value *checkPointerIval (sym_link *, value *); +value *checkStructIval (symbol *, value *); +value *checkArrayIval (sym_link *, value *); +value *checkIval (sym_link *, value *); +unsigned int getSize (sym_link *); +unsigned int bitsForType (sym_link *); +sym_link *newIntLink (); +sym_link *newCharLink (); +sym_link *newLongLink (); +int checkType (sym_link *, sym_link *); +int checkFunction (symbol *); +void cleanUpLevel (bucket **, int); +void cleanUpBlock (bucket **, int); +int funcInChain (sym_link *); +void addSymChain (symbol *); +sym_link *structElemType (sym_link *, value *, value **); +symbol *getStructElement (structdef *, symbol *); +sym_link *computeType (sym_link *, sym_link *); +void processFuncArgs (symbol *, int); +int isSymbolEqual (symbol *, symbol *); +int powof2 (unsigned long); +void printTypeChain (sym_link *, FILE *); +void initCSupport (); +void pointerTypes (sym_link *, sym_link *); +void cdbTypeInfo (sym_link *, FILE *); +void cdbSymbol (symbol *, FILE *, int, int); +void cdbStructBlock (int, FILE *); +void initHashT (); +bucket *newBucket (); +void addSym (bucket **, void *, char *, int, int); +void deleteSym (bucket **, void *, char *); +void *findSym (bucket **, void *, const char *); +void *findSymWithLevel (bucket **, struct symbol *); +void *findSymWithBlock (bucket **, struct symbol *, int); #include "SDCCmem.h" #endif diff --git a/src/SDCCval.c b/src/SDCCval.c index 46eab669..bfab1671 100644 --- a/src/SDCCval.c +++ b/src/SDCCval.c @@ -29,581 +29,622 @@ #include #include "newalloc.h" -int cNestLevel ; +int cNestLevel; /*-----------------------------------------------------------------*/ /* newValue - allocates and returns a new value */ /*-----------------------------------------------------------------*/ -value *newValue () +value * +newValue () { - value *val ; + value *val; - val = Safe_calloc(1,sizeof(value)); + val = Safe_calloc (1, sizeof (value)); - return val ; + return val; } /*-----------------------------------------------------------------*/ /* newiList - new initializer list */ /*-----------------------------------------------------------------*/ -initList *newiList ( int type, void *ilist) +initList * +newiList (int type, void *ilist) { - initList *nilist; + initList *nilist; - nilist = Safe_calloc(1,sizeof(initList)); + nilist = Safe_calloc (1, sizeof (initList)); - nilist->type = type ; - nilist->lineno = yylineno ; + nilist->type = type; + nilist->lineno = yylineno; - switch (type) { - case INIT_NODE : - nilist->init.node = (struct ast *) ilist ; - break ; + switch (type) + { + case INIT_NODE: + nilist->init.node = (struct ast *) ilist; + break; - case INIT_DEEP : - nilist->init.deep = (struct initList *) ilist ; - break ; + case INIT_DEEP: + nilist->init.deep = (struct initList *) ilist; + break; } - return nilist ; + return nilist; } /*------------------------------------------------------------------*/ /* revinit - reverses the initial values for a value chain */ /*------------------------------------------------------------------*/ -initList *revinit ( initList *val) +initList * +revinit (initList * val) { - initList *prev , *curr, *next ; + initList *prev, *curr, *next; - if (!val) - return NULL ; + if (!val) + return NULL; - prev = val ; - curr = val->next ; + prev = val; + curr = val->next; - while (curr) { - next = curr->next ; - curr->next = prev ; - prev = curr ; - curr = next ; + while (curr) + { + next = curr->next; + curr->next = prev; + prev = curr; + curr = next; } - val->next = (void *) NULL ; - return prev ; + val->next = (void *) NULL; + return prev; } /*------------------------------------------------------------------*/ /* copyIlist - copy initializer list */ /*------------------------------------------------------------------*/ -initList *copyIlist (initList *src) +initList * +copyIlist (initList * src) { - initList *dest = NULL; - - if (!src) - return NULL ; - - switch (src->type) { - case INIT_DEEP : - dest = newiList (INIT_DEEP,copyIlist (src->init.deep)); - break; - case INIT_NODE : - dest = newiList (INIT_NODE,copyAst (src->init.node)) ; - break; + initList *dest = NULL; + + if (!src) + return NULL; + + switch (src->type) + { + case INIT_DEEP: + dest = newiList (INIT_DEEP, copyIlist (src->init.deep)); + break; + case INIT_NODE: + dest = newiList (INIT_NODE, copyAst (src->init.node)); + break; } - if ( src->next ) - dest->next = copyIlist(src->next); + if (src->next) + dest->next = copyIlist (src->next); - return dest ; + return dest; } /*------------------------------------------------------------------*/ /* list2int - converts the first element of the list to value */ /*------------------------------------------------------------------*/ -double list2int (initList *val) +double +list2int (initList * val) { - initList *i = val; + initList *i = val; - if ( i->type == INIT_DEEP ) - return list2int (val->init.deep) ; + if (i->type == INIT_DEEP) + return list2int (val->init.deep); - return floatFromVal(constExprValue(val->init.node,TRUE)); + return floatFromVal (constExprValue (val->init.node, TRUE)); } /*------------------------------------------------------------------*/ /* list2val - converts the first element of the list to value */ /*------------------------------------------------------------------*/ -value *list2val (initList *val) +value * +list2val (initList * val) { - if (!val) - return NULL; + if (!val) + return NULL; - if ( val->type == INIT_DEEP ) - return list2val (val->init.deep) ; + if (val->type == INIT_DEEP) + return list2val (val->init.deep); - return constExprValue(val->init.node,TRUE); + return constExprValue (val->init.node, TRUE); } /*------------------------------------------------------------------*/ /* list2expr - returns the first expression in the initializer list */ /*------------------------------------------------------------------*/ -ast *list2expr ( initList *ilist) +ast * +list2expr (initList * ilist) { - if ( ilist->type == INIT_DEEP ) - return list2expr (ilist->init.deep) ; - return ilist->init.node ; + if (ilist->type == INIT_DEEP) + return list2expr (ilist->init.deep); + return ilist->init.node; } /*------------------------------------------------------------------*/ /* resolveIvalSym - resolve symbols in initial values */ /*------------------------------------------------------------------*/ -void resolveIvalSym ( initList *ilist) +void +resolveIvalSym (initList * ilist) { - if ( ! ilist ) - return ; + if (!ilist) + return; - if ( ilist->type == INIT_NODE ) - ilist->init.node = decorateType(resolveSymbols (ilist->init.node)); + if (ilist->type == INIT_NODE) + ilist->init.node = decorateType (resolveSymbols (ilist->init.node)); - if ( ilist->type == INIT_DEEP ) - resolveIvalSym (ilist->init.deep); + if (ilist->type == INIT_DEEP) + resolveIvalSym (ilist->init.deep); - resolveIvalSym (ilist->next); + resolveIvalSym (ilist->next); } /*-----------------------------------------------------------------*/ /* symbolVal - creates a value for a symbol */ /*-----------------------------------------------------------------*/ -value *symbolVal ( symbol *sym ) +value * +symbolVal (symbol * sym) { - value *val ; + value *val; - if (!sym) - return NULL ; + if (!sym) + return NULL; - val = newValue(); - val->sym = sym ; + val = newValue (); + val->sym = sym; - if ( sym->type ) { - val->type = sym->type; - val->etype= getSpec(val->type); + if (sym->type) + { + val->type = sym->type; + val->etype = getSpec (val->type); } - if ( *sym->rname ) - sprintf (val->name,"%s",sym->rname); - else - sprintf(val->name,"_%s",sym->name); + if (*sym->rname) + sprintf (val->name, "%s", sym->rname); + else + sprintf (val->name, "_%s", sym->name); - return val ; + return val; } /*-----------------------------------------------------------------*/ /* valueFromLit - creates a value from a literal */ /*-----------------------------------------------------------------*/ -value *valueFromLit (float lit) +value * +valueFromLit (float lit) { - char buffer[50]; + char buffer[50]; - if ( ( ((long) lit ) - lit ) == 0 ) { - sprintf(buffer,"%ld",(long) lit); - return constVal (buffer); + if ((((long) lit) - lit) == 0) + { + sprintf (buffer, "%ld", (long) lit); + return constVal (buffer); } - sprintf(buffer,"%f",lit); - return constFloatVal (buffer); + sprintf (buffer, "%f", lit); + return constFloatVal (buffer); } /*-----------------------------------------------------------------*/ /* constFloatVal - converts a FLOAT constant to value */ /*-----------------------------------------------------------------*/ -value *constFloatVal ( char *s ) +value * +constFloatVal (char *s) { - value *val = newValue(); - float sval; + value *val = newValue (); + float sval; - if(sscanf (s,"%f",&sval) != 1) { - werror(E_INVALID_FLOAT_CONST,s); - return constVal("0"); + if (sscanf (s, "%f", &sval) != 1) + { + werror (E_INVALID_FLOAT_CONST, s); + return constVal ("0"); } - val->type = val->etype = newLink(); - val->type->class = SPECIFIER ; - SPEC_NOUN(val->type) = V_FLOAT ; - SPEC_SCLS(val->type) = S_LITERAL; - SPEC_CVAL(val->type).v_float = sval; + val->type = val->etype = newLink (); + val->type->class = SPECIFIER; + SPEC_NOUN (val->type) = V_FLOAT; + SPEC_SCLS (val->type) = S_LITERAL; + SPEC_CVAL (val->type).v_float = sval; - return val; + return val; } /*-----------------------------------------------------------------*/ /* constVal - converts a INTEGER constant into a value */ /*-----------------------------------------------------------------*/ -value *constVal (char *s) +value * +constVal (char *s) { - value *val ; - short hex = 0 , octal = 0 ; - char scanFmt[10] ; - int scI = 0 ; - unsigned long sval ; - - val = newValue() ; /* alloc space for value */ - - val->type = val->etype = newLink() ; /* create the spcifier */ - val->type->class = SPECIFIER ; - SPEC_NOUN(val->type) = V_INT ; - SPEC_SCLS(val->type) = S_LITERAL ; - - /* set the _unsigned flag if 'uU' found */ - if (strchr(s,'u') || strchr(s,'U')) - SPEC_USIGN(val->type) = 1; - - /* set the _long flag if 'lL' is found */ - if (strchr(s,'l') || strchr(s,'L')) - SPEC_LONG(val->type) = 1; - - hex = ((strchr(s,'x') || strchr(s,'X')) ? 1 : 0) ; - - /* set the octal flag */ - if (!hex && *s == '0' && *(s+1) ) - octal = 1 ; - - /* create the scan string */ - scanFmt[scI++] = '%' ; - - if (octal) - scanFmt[scI++] = 'o' ; - else - if (hex) - scanFmt[scI++] = 'x' ; + value *val; + short hex = 0, octal = 0; + char scanFmt[10]; + int scI = 0; + unsigned long sval; + + val = newValue (); /* alloc space for value */ + + val->type = val->etype = newLink (); /* create the spcifier */ + val->type->class = SPECIFIER; + SPEC_NOUN (val->type) = V_INT; + SPEC_SCLS (val->type) = S_LITERAL; + + /* set the _unsigned flag if 'uU' found */ + if (strchr (s, 'u') || strchr (s, 'U')) + SPEC_USIGN (val->type) = 1; + + /* set the _long flag if 'lL' is found */ + if (strchr (s, 'l') || strchr (s, 'L')) + SPEC_LONG (val->type) = 1; + + hex = ((strchr (s, 'x') || strchr (s, 'X')) ? 1 : 0); + + /* set the octal flag */ + if (!hex && *s == '0' && *(s + 1)) + octal = 1; + + /* create the scan string */ + scanFmt[scI++] = '%'; + + if (octal) + scanFmt[scI++] = 'o'; + else if (hex) + scanFmt[scI++] = 'x'; + else if (SPEC_USIGN (val->type)) + scanFmt[scI++] = 'u'; else - if (SPEC_USIGN(val->type)) - scanFmt[scI++] = 'u' ; - else - scanFmt[scI++] = 'd' ; + scanFmt[scI++] = 'd'; - scanFmt[scI++] = '\0' ; + scanFmt[scI++] = '\0'; - /* if hex or octal then set the unsigned flag */ - if ( hex || octal ) { - SPEC_USIGN(val->type) = 1 ; - sscanf(s,scanFmt,&sval); - } else - sval = atol(s); + /* if hex or octal then set the unsigned flag */ + if (hex || octal) + { + SPEC_USIGN (val->type) = 1; + sscanf (s, scanFmt, &sval); + } + else + sval = atol (s); - if (SPEC_LONG(val->type) || sval > 32768) { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_ulong = sval ; - else - SPEC_CVAL(val->type).v_long = sval ; - SPEC_LONG(val->type) = 1; + if (SPEC_LONG (val->type) || sval > 32768) + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_ulong = sval; + else + SPEC_CVAL (val->type).v_long = sval; + SPEC_LONG (val->type) = 1; } - else { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_uint = sval ; else - SPEC_CVAL(val->type).v_int = sval ; + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_uint = sval; + else + SPEC_CVAL (val->type).v_int = sval; } - // check the size and make it a short if required - if (sval < 256 ) - SPEC_SHORT(val->etype) = 1; + // check the size and make it a short if required + if (sval < 256) + SPEC_SHORT (val->etype) = 1; - return val ; + return val; } /*------------------------------------------------------------------*/ /* copyStr - copies src to dest ignoring leading & trailing \"s */ /*------------------------------------------------------------------*/ -void copyStr (char *dest, char *src ) +void +copyStr (char *dest, char *src) { - unsigned int x; - while (*src) { - if (*src == '\"' ) - src++ ; - else - if ( *src == '\\' ) { - src++ ; - switch (*src) { - case 'n' : - *dest++ = '\n'; - break ; - case 't' : - *dest++ = '\t'; - break; - case 'v' : - *dest++ = '\v'; - break; - case 'b' : - *dest++ = '\b'; - break; - case 'r' : - *dest++ = '\r'; - break; - case 'f' : - *dest++ = '\f'; - break; - case 'a' : - *dest++ = '\a'; - break; - case '0': - /* embedded octal or hex constant */ - if (*(src+1) == 'x' || - *(src+1) == 'X') { - x = strtol(src,&src,16); - *dest++ = x; - } else { - /* must be octal */ - x = strtol(src,&src,8); - *dest++ = x; - } - break; - - case '\\': - *dest++ = '\\'; - break; - case '\?': - *dest++ = '\?'; - break; - case '\'': - *dest++ = '\''; - break; - case '\"': - *dest++ = '\"'; - break; - default : - *dest++ = *src ; - } - src++ ; - } + unsigned int x; + while (*src) + { + if (*src == '\"') + src++; + else if (*src == '\\') + { + src++; + switch (*src) + { + case 'n': + *dest++ = '\n'; + break; + case 't': + *dest++ = '\t'; + break; + case 'v': + *dest++ = '\v'; + break; + case 'b': + *dest++ = '\b'; + break; + case 'r': + *dest++ = '\r'; + break; + case 'f': + *dest++ = '\f'; + break; + case 'a': + *dest++ = '\a'; + break; + case '0': + /* embedded octal or hex constant */ + if (*(src + 1) == 'x' || + *(src + 1) == 'X') + { + x = strtol (src, &src, 16); + *dest++ = x; + } + else + { + /* must be octal */ + x = strtol (src, &src, 8); + *dest++ = x; + } + break; + + case '\\': + *dest++ = '\\'; + break; + case '\?': + *dest++ = '\?'; + break; + case '\'': + *dest++ = '\''; + break; + case '\"': + *dest++ = '\"'; + break; + default: + *dest++ = *src; + } + src++; + } else - *dest++ = *src++ ; + *dest++ = *src++; } - *dest = '\0' ; + *dest = '\0'; } /*------------------------------------------------------------------*/ /* strVal - converts a string constant to a value */ /*------------------------------------------------------------------*/ -value *strVal ( char *s ) +value * +strVal (char *s) { - value *val ; - - val = newValue() ; /* get a new one */ - - /* get a declarator */ - val->type = newLink(); - DCL_TYPE(val->type) = ARRAY ; - DCL_ELEM(val->type) = strlen(s) - 1; - val->type->next = val->etype = newLink() ; - val->etype->class = SPECIFIER; - SPEC_NOUN(val->etype) = V_CHAR ; - SPEC_SCLS(val->etype) = S_LITERAL; - - SPEC_CVAL(val->etype).v_char = Safe_calloc(1,strlen(s)+1); - copyStr (SPEC_CVAL(val->etype).v_char,s); - return val; + value *val; + + val = newValue (); /* get a new one */ + + /* get a declarator */ + val->type = newLink (); + DCL_TYPE (val->type) = ARRAY; + DCL_ELEM (val->type) = strlen (s) - 1; + val->type->next = val->etype = newLink (); + val->etype->class = SPECIFIER; + SPEC_NOUN (val->etype) = V_CHAR; + SPEC_SCLS (val->etype) = S_LITERAL; + + SPEC_CVAL (val->etype).v_char = Safe_calloc (1, strlen (s) + 1); + copyStr (SPEC_CVAL (val->etype).v_char, s); + return val; } /*------------------------------------------------------------------*/ /* reverseValWithType - reverses value chain with type & etype */ /*------------------------------------------------------------------*/ -value *reverseValWithType ( value *val ) +value * +reverseValWithType (value * val) { - sym_link *type ; - sym_link *etype; + sym_link *type; + sym_link *etype; - if (!val) - return NULL ; + if (!val) + return NULL; - /* save the type * etype chains */ - type = val->type ; - etype = val->etype ; + /* save the type * etype chains */ + type = val->type; + etype = val->etype; - /* set the current one 2b null */ - val->type = val->etype = NULL; - val = reverseVal (val); + /* set the current one 2b null */ + val->type = val->etype = NULL; + val = reverseVal (val); - /* restore type & etype */ - val->type = type ; - val->etype = etype ; + /* restore type & etype */ + val->type = type; + val->etype = etype; - return val; + return val; } /*------------------------------------------------------------------*/ /* reverseVal - reverses the values for a value chain */ /*------------------------------------------------------------------*/ -value *reverseVal ( value *val) +value * +reverseVal (value * val) { - value *prev , *curr, *next ; + value *prev, *curr, *next; - if (!val) - return NULL ; + if (!val) + return NULL; - prev = val ; - curr = val->next ; + prev = val; + curr = val->next; - while (curr) { - next = curr->next ; - curr->next = prev ; - prev = curr ; - curr = next ; + while (curr) + { + next = curr->next; + curr->next = prev; + prev = curr; + curr = next; } - val->next = (void *) NULL ; - return prev ; + val->next = (void *) NULL; + return prev; } /*------------------------------------------------------------------*/ /* copyValueChain - will copy a chain of values */ /*------------------------------------------------------------------*/ -value *copyValueChain ( value *src ) +value * +copyValueChain (value * src) { - value *dest ; + value *dest; - if ( ! src ) - return NULL ; + if (!src) + return NULL; - dest = copyValue (src); - dest->next = copyValueChain (src->next); + dest = copyValue (src); + dest->next = copyValueChain (src->next); - return dest ; + return dest; } /*------------------------------------------------------------------*/ /* copyValue - copies contents of a vlue to a fresh one */ /*------------------------------------------------------------------*/ -value *copyValue (value *src) +value * +copyValue (value * src) { - value *dest ; + value *dest; - dest = newValue(); - dest->sym = copySymbol(src->sym); - strcpy(dest->name,src->name); - dest->type = (src->type ? copyLinkChain(src->type) : NULL) ; - dest->etype = (src->type ? getSpec(dest->type) : NULL); + dest = newValue (); + dest->sym = copySymbol (src->sym); + strcpy (dest->name, src->name); + dest->type = (src->type ? copyLinkChain (src->type) : NULL); + dest->etype = (src->type ? getSpec (dest->type) : NULL); - return dest ; + return dest; } /*------------------------------------------------------------------*/ /* charVal - converts a character constant to a value */ /*------------------------------------------------------------------*/ -value *charVal ( char *s ) +value * +charVal (char *s) { - value *val ; - - val = newValue (); - - val->type = val->etype = newLink(); - val->type->class = SPECIFIER ; - SPEC_NOUN(val->type) = V_CHAR ; - SPEC_SCLS(val->type) = S_LITERAL ; - - s++ ; /* get rid of quotation */ - /* if \ then special processing */ - if ( *s == '\\' ) { - s++ ; /* go beyond the backslash */ - switch (*s) { - case 'n' : - SPEC_CVAL(val->type).v_int = '\n'; - break ; - case 't' : - SPEC_CVAL(val->type).v_int = '\t'; - break; - case 'v' : - SPEC_CVAL(val->type).v_int = '\v'; - break; - case 'b' : - SPEC_CVAL(val->type).v_int = '\b'; - break; - case 'r' : - SPEC_CVAL(val->type).v_int = '\r'; - break; - case 'f' : - SPEC_CVAL(val->type).v_int = '\f'; - break; - case 'a' : - SPEC_CVAL(val->type).v_int = '\a'; - break; - case '\\': - SPEC_CVAL(val->type).v_int = '\\'; - break; - case '\?': - SPEC_CVAL(val->type).v_int = '\?'; - break; - case '\'': - SPEC_CVAL(val->type).v_int = '\''; - break; - case '\"': - SPEC_CVAL(val->type).v_int = '\"'; - break; - case '0' : - sscanf(s,"%o",&SPEC_CVAL(val->type).v_int); - break; - case 'x' : - s++ ; /* go behond the 'x' */ - sscanf(s,"%x",&SPEC_CVAL(val->type).v_int); - break; - default : - SPEC_CVAL(val->type).v_int = *s; - break; - } + value *val; + + val = newValue (); + + val->type = val->etype = newLink (); + val->type->class = SPECIFIER; + SPEC_NOUN (val->type) = V_CHAR; + SPEC_SCLS (val->type) = S_LITERAL; + + s++; /* get rid of quotation */ + /* if \ then special processing */ + if (*s == '\\') + { + s++; /* go beyond the backslash */ + switch (*s) + { + case 'n': + SPEC_CVAL (val->type).v_int = '\n'; + break; + case 't': + SPEC_CVAL (val->type).v_int = '\t'; + break; + case 'v': + SPEC_CVAL (val->type).v_int = '\v'; + break; + case 'b': + SPEC_CVAL (val->type).v_int = '\b'; + break; + case 'r': + SPEC_CVAL (val->type).v_int = '\r'; + break; + case 'f': + SPEC_CVAL (val->type).v_int = '\f'; + break; + case 'a': + SPEC_CVAL (val->type).v_int = '\a'; + break; + case '\\': + SPEC_CVAL (val->type).v_int = '\\'; + break; + case '\?': + SPEC_CVAL (val->type).v_int = '\?'; + break; + case '\'': + SPEC_CVAL (val->type).v_int = '\''; + break; + case '\"': + SPEC_CVAL (val->type).v_int = '\"'; + break; + case '0': + sscanf (s, "%o", &SPEC_CVAL (val->type).v_int); + break; + case 'x': + s++; /* go behond the 'x' */ + sscanf (s, "%x", &SPEC_CVAL (val->type).v_int); + break; + default: + SPEC_CVAL (val->type).v_int = *s; + break; + } } - else /* not a backslash */ - SPEC_CVAL(val->type).v_int = *s; + else /* not a backslash */ + SPEC_CVAL (val->type).v_int = *s; - return val ; + return val; } /*------------------------------------------------------------------*/ /* valFromType - creates a value from type given */ /*------------------------------------------------------------------*/ -value *valFromType ( sym_link *type) +value * +valFromType (sym_link * type) { - value *val = newValue(); - val->type = copyLinkChain(type); - val->etype = getSpec(val->type); - return val; + value *val = newValue (); + val->type = copyLinkChain (type); + val->etype = getSpec (val->type); + return val; } /*------------------------------------------------------------------*/ /* floatFromVal - value to unsinged integer conversion */ /*------------------------------------------------------------------*/ -double floatFromVal ( value *val ) +double +floatFromVal (value * val) { - if (!val) - return 0; + if (!val) + return 0; - if (val->etype && SPEC_SCLS(val->etype) != S_LITERAL) { - werror(E_CONST_EXPECTED,val->name); - return 0; + if (val->etype && SPEC_SCLS (val->etype) != S_LITERAL) + { + werror (E_CONST_EXPECTED, val->name); + return 0; } - /* if it is not a specifier then we can assume that */ - /* it will be an unsigned long */ - if (!IS_SPEC(val->type)) - return (double) SPEC_CVAL(val->etype).v_ulong; - - if (SPEC_NOUN(val->etype) == V_FLOAT ) - return (double) SPEC_CVAL(val->etype).v_float ; - else { - if (SPEC_LONG(val->etype)) { - if (SPEC_USIGN(val->etype)) - return (double) SPEC_CVAL(val->etype).v_ulong ; - else - return (double) SPEC_CVAL(val->etype).v_long ; - } - else { - if (SPEC_USIGN(val->etype)) - return (double) SPEC_CVAL(val->etype).v_uint ; + /* if it is not a specifier then we can assume that */ + /* it will be an unsigned long */ + if (!IS_SPEC (val->type)) + return (double) SPEC_CVAL (val->etype).v_ulong; + + if (SPEC_NOUN (val->etype) == V_FLOAT) + return (double) SPEC_CVAL (val->etype).v_float; + else + { + if (SPEC_LONG (val->etype)) + { + if (SPEC_USIGN (val->etype)) + return (double) SPEC_CVAL (val->etype).v_ulong; + else + return (double) SPEC_CVAL (val->etype).v_long; + } else - return (double) SPEC_CVAL(val->etype).v_int ; - } + { + if (SPEC_USIGN (val->etype)) + return (double) SPEC_CVAL (val->etype).v_uint; + else + return (double) SPEC_CVAL (val->etype).v_int; + } } } @@ -611,705 +652,759 @@ double floatFromVal ( value *val ) /*------------------------------------------------------------------*/ /* valUnaryPM - dones the unary +/- operation on a constant */ /*------------------------------------------------------------------*/ -value *valUnaryPM (value *val) +value * +valUnaryPM (value * val) { - /* depending on type */ - if (SPEC_NOUN(val->etype) == V_FLOAT ) - SPEC_CVAL(val->etype).v_float = -1.0 * SPEC_CVAL(val->etype).v_float; - else { - if ( SPEC_LONG(val->etype)) { - if (SPEC_USIGN(val->etype)) - SPEC_CVAL(val->etype).v_ulong = - SPEC_CVAL(val->etype).v_ulong ; - else - SPEC_CVAL(val->etype).v_long = - SPEC_CVAL(val->etype).v_long; - } - else { - if (SPEC_USIGN(val->etype)) - SPEC_CVAL(val->etype).v_uint = - SPEC_CVAL(val->etype).v_uint ; + /* depending on type */ + if (SPEC_NOUN (val->etype) == V_FLOAT) + SPEC_CVAL (val->etype).v_float = -1.0 * SPEC_CVAL (val->etype).v_float; + else + { + if (SPEC_LONG (val->etype)) + { + if (SPEC_USIGN (val->etype)) + SPEC_CVAL (val->etype).v_ulong = -SPEC_CVAL (val->etype).v_ulong; + else + SPEC_CVAL (val->etype).v_long = -SPEC_CVAL (val->etype).v_long; + } else - SPEC_CVAL(val->etype).v_int = - SPEC_CVAL(val->etype).v_int ; - } + { + if (SPEC_USIGN (val->etype)) + SPEC_CVAL (val->etype).v_uint = -SPEC_CVAL (val->etype).v_uint; + else + SPEC_CVAL (val->etype).v_int = -SPEC_CVAL (val->etype).v_int; + } } - return val ; + return val; } /*------------------------------------------------------------------*/ /* valueComplement - complements a constant */ /*------------------------------------------------------------------*/ -value *valComplement ( value *val) +value * +valComplement (value * val) { - /* depending on type */ - if ( SPEC_LONG(val->etype)) { - if (SPEC_USIGN(val->etype)) - SPEC_CVAL(val->etype).v_ulong = ~SPEC_CVAL(val->etype).v_ulong ; - else - SPEC_CVAL(val->etype).v_long = ~SPEC_CVAL(val->etype).v_long; + /* depending on type */ + if (SPEC_LONG (val->etype)) + { + if (SPEC_USIGN (val->etype)) + SPEC_CVAL (val->etype).v_ulong = ~SPEC_CVAL (val->etype).v_ulong; + else + SPEC_CVAL (val->etype).v_long = ~SPEC_CVAL (val->etype).v_long; } - else { - if (SPEC_USIGN(val->etype)) - SPEC_CVAL(val->etype).v_uint = ~SPEC_CVAL(val->etype).v_uint ; else - SPEC_CVAL(val->etype).v_int = ~SPEC_CVAL(val->etype).v_int ; + { + if (SPEC_USIGN (val->etype)) + SPEC_CVAL (val->etype).v_uint = ~SPEC_CVAL (val->etype).v_uint; + else + SPEC_CVAL (val->etype).v_int = ~SPEC_CVAL (val->etype).v_int; } - return val ; + return val; } /*------------------------------------------------------------------*/ /* valueNot - complements a constant */ /*------------------------------------------------------------------*/ -value *valNot ( value *val) +value * +valNot (value * val) { - /* depending on type */ - if ( SPEC_LONG(val->etype)) { - if (SPEC_USIGN(val->etype)) - SPEC_CVAL(val->etype).v_ulong = !SPEC_CVAL(val->etype).v_ulong ; - else - SPEC_CVAL(val->etype).v_long = !SPEC_CVAL(val->etype).v_long; + /* depending on type */ + if (SPEC_LONG (val->etype)) + { + if (SPEC_USIGN (val->etype)) + SPEC_CVAL (val->etype).v_ulong = !SPEC_CVAL (val->etype).v_ulong; + else + SPEC_CVAL (val->etype).v_long = !SPEC_CVAL (val->etype).v_long; } - else { - if (SPEC_USIGN(val->etype)) - SPEC_CVAL(val->etype).v_uint = !SPEC_CVAL(val->etype).v_uint ; else - SPEC_CVAL(val->etype).v_int = !SPEC_CVAL(val->etype).v_int ; + { + if (SPEC_USIGN (val->etype)) + SPEC_CVAL (val->etype).v_uint = !SPEC_CVAL (val->etype).v_uint; + else + SPEC_CVAL (val->etype).v_int = !SPEC_CVAL (val->etype).v_int; } - return val ; + return val; } /*------------------------------------------------------------------*/ /* valMult - multiply constants */ /*------------------------------------------------------------------*/ -value *valMult (value *lval, value *rval) +value * +valMult (value * lval, value * rval) { - value *val ; - - /* create a new value */ - val = newValue(); - val->type = val->etype = newLink(); - val->type->class = SPECIFIER ; - SPEC_NOUN(val->type) = (IS_FLOAT(lval->etype) || - IS_FLOAT(rval->etype) ? V_FLOAT : V_INT ); - SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */ - SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype)); - SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype)); - - if (IS_FLOAT(val->type)) - SPEC_CVAL(val->type).v_float = floatFromVal(lval) * floatFromVal(rval); - else { - if (SPEC_LONG(val->type)) { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) * - (unsigned long) floatFromVal(rval); - else - SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) * - (long) floatFromVal(rval); - } - else { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) * - (unsigned) floatFromVal(rval); + value *val; + + /* create a new value */ + val = newValue (); + val->type = val->etype = newLink (); + val->type->class = SPECIFIER; + SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) || + IS_FLOAT (rval->etype) ? V_FLOAT : V_INT); + SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ + SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype)); + SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); + + if (IS_FLOAT (val->type)) + SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval); + else + { + if (SPEC_LONG (val->type)) + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) * + (unsigned long) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) * + (long) floatFromVal (rval); + } else - SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) * - (int) floatFromVal(rval); - } + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) * + (unsigned) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) * + (int) floatFromVal (rval); + } } - return val ; + return val; } /*------------------------------------------------------------------*/ /* valDiv - Divide constants */ /*------------------------------------------------------------------*/ -value *valDiv (value *lval, value *rval) +value * +valDiv (value * lval, value * rval) { - value *val ; + value *val; - if (floatFromVal(rval) == 0) { - werror(E_DIVIDE_BY_ZERO); - return rval; + if (floatFromVal (rval) == 0) + { + werror (E_DIVIDE_BY_ZERO); + return rval; } - /* create a new value */ - val = newValue(); - val->type = val->etype = ((floatFromVal(lval) / floatFromVal(rval)) < 256 ? - newCharLink() : newIntLink()); - if (IS_FLOAT(lval->etype) || IS_FLOAT(rval->etype)) - SPEC_NOUN(val->etype) = V_FLOAT ; - SPEC_SCLS(val->etype) = S_LITERAL ; - SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype)); - SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype)); - - if (IS_FLOAT(val->type)) - SPEC_CVAL(val->type).v_float = floatFromVal(lval) / floatFromVal(rval); - else { - if (SPEC_LONG(val->type)) { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) / - (unsigned long) floatFromVal(rval); - else - SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) / - (long) floatFromVal(rval); - } - else { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) / - (unsigned) floatFromVal(rval); + /* create a new value */ + val = newValue (); + val->type = val->etype = ((floatFromVal (lval) / floatFromVal (rval)) < 256 ? + newCharLink () : newIntLink ()); + if (IS_FLOAT (lval->etype) || IS_FLOAT (rval->etype)) + SPEC_NOUN (val->etype) = V_FLOAT; + SPEC_SCLS (val->etype) = S_LITERAL; + SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype)); + SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); + + if (IS_FLOAT (val->type)) + SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval); + else + { + if (SPEC_LONG (val->type)) + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) / + (unsigned long) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) / + (long) floatFromVal (rval); + } else - SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) / - (int) floatFromVal(rval); - } + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) / + (unsigned) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) / + (int) floatFromVal (rval); + } } - return val ; + return val; } /*------------------------------------------------------------------*/ /* valMod - Modulus constants */ /*------------------------------------------------------------------*/ -value *valMod (value *lval, value *rval) +value * +valMod (value * lval, value * rval) { - value *val ; - - /* create a new value */ - val = newValue(); - val->type = val->etype = newLink(); - val->type->class = SPECIFIER ; - SPEC_NOUN(val->type) = V_INT ; /* type is int */ - SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */ - SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype)); - SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype)); - - if (SPEC_LONG(val->type)) { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) % - (unsigned long) floatFromVal(rval); - else - SPEC_CVAL(val->type).v_long = (unsigned long) floatFromVal(lval) % - (unsigned long) floatFromVal(rval); + value *val; + + /* create a new value */ + val = newValue (); + val->type = val->etype = newLink (); + val->type->class = SPECIFIER; + SPEC_NOUN (val->type) = V_INT; /* type is int */ + SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ + SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype)); + SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); + + if (SPEC_LONG (val->type)) + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) % + (unsigned long) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_long = (unsigned long) floatFromVal (lval) % + (unsigned long) floatFromVal (rval); } - else { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) % - (unsigned) floatFromVal(rval); else - SPEC_CVAL(val->type).v_int = (unsigned) floatFromVal(lval) % - (unsigned) floatFromVal(rval); + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) % + (unsigned) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_int = (unsigned) floatFromVal (lval) % + (unsigned) floatFromVal (rval); } - return val ; + return val; } /*------------------------------------------------------------------*/ /* valPlus - Addition constants */ /*------------------------------------------------------------------*/ -value *valPlus (value *lval, value *rval) +value * +valPlus (value * lval, value * rval) { - value *val ; - - /* create a new value */ - val = newValue(); - val->type = val->etype = newLink(); - val->type->class = SPECIFIER ; - SPEC_NOUN(val->type) = (IS_FLOAT(lval->etype) || - IS_FLOAT(rval->etype) ? V_FLOAT : V_INT ); - SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */ - SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype)); - SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype)); - - if (IS_FLOAT(val->type)) - SPEC_CVAL(val->type).v_float = floatFromVal(lval) + floatFromVal(rval); - else { - if (SPEC_LONG(val->type)) { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) + - (unsigned long) floatFromVal(rval); - else - SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) + - (long) floatFromVal(rval); - } - else { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) + - (unsigned) floatFromVal(rval); + value *val; + + /* create a new value */ + val = newValue (); + val->type = val->etype = newLink (); + val->type->class = SPECIFIER; + SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) || + IS_FLOAT (rval->etype) ? V_FLOAT : V_INT); + SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ + SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype)); + SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); + + if (IS_FLOAT (val->type)) + SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval); + else + { + if (SPEC_LONG (val->type)) + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) + + (unsigned long) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) + + (long) floatFromVal (rval); + } else - SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) + - (int) floatFromVal(rval); - } + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) + + (unsigned) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) + + (int) floatFromVal (rval); + } } - return val ; + return val; } /*------------------------------------------------------------------*/ /* valMinus - Addition constants */ /*------------------------------------------------------------------*/ -value *valMinus (value *lval, value *rval) +value * +valMinus (value * lval, value * rval) { - value *val ; - - /* create a new value */ - val = newValue(); - val->type = val->etype = newLink(); - val->type->class = SPECIFIER ; - SPEC_NOUN(val->type) = (IS_FLOAT(lval->etype) || - IS_FLOAT(rval->etype) ? V_FLOAT : V_INT ); - SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */ - SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype)); - SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype)); - - if (IS_FLOAT(val->type)) - SPEC_CVAL(val->type).v_float = floatFromVal(lval) - floatFromVal(rval); - else { - if (SPEC_LONG(val->type)) { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) - - (unsigned long) floatFromVal(rval); - else - SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) - - (long) floatFromVal(rval); - } - else { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) - - (unsigned) floatFromVal(rval); + value *val; + + /* create a new value */ + val = newValue (); + val->type = val->etype = newLink (); + val->type->class = SPECIFIER; + SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) || + IS_FLOAT (rval->etype) ? V_FLOAT : V_INT); + SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ + SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype)); + SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); + + if (IS_FLOAT (val->type)) + SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval); + else + { + if (SPEC_LONG (val->type)) + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) - + (unsigned long) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) - + (long) floatFromVal (rval); + } else - SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) - (int) floatFromVal(rval); - } + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) - + (unsigned) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) - (int) floatFromVal (rval); + } } - return val ; + return val; } /*------------------------------------------------------------------*/ /* valShift - Shift left or right */ /*------------------------------------------------------------------*/ -value *valShift (value *lval, value *rval, int lr) +value * +valShift (value * lval, value * rval, int lr) { - value *val ; - - /* create a new value */ - val = newValue(); - val->type = val->etype = newLink(); - val->type->class = SPECIFIER ; - SPEC_NOUN(val->type) = V_INT ; /* type is int */ - SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */ - SPEC_USIGN(val->type) = (SPEC_USIGN(lval->etype) | SPEC_USIGN(rval->etype)); - SPEC_LONG(val->type) = (SPEC_LONG(lval->etype) | SPEC_LONG(rval->etype)); - - if (lr) { - if (SPEC_LONG(val->type)) { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) << - (unsigned long) floatFromVal(rval); - else - SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) << - (long) floatFromVal(rval); - } - else { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) << - (unsigned) floatFromVal(rval); - else - SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) << - (int) floatFromVal(rval); - } - } - else { - if (SPEC_LONG(val->type)) { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) >> - (unsigned long) floatFromVal(rval); - else - SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) >> - (long) floatFromVal(rval); - } - else { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) >> - (unsigned) floatFromVal(rval); - else - SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) >> - (int) floatFromVal(rval); - } - } - - return val ; + value *val; + + /* create a new value */ + val = newValue (); + val->type = val->etype = newLink (); + val->type->class = SPECIFIER; + SPEC_NOUN (val->type) = V_INT; /* type is int */ + SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ + SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype)); + SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); + + if (lr) + { + if (SPEC_LONG (val->type)) + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) << + (unsigned long) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) << + (long) floatFromVal (rval); + } + else + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) << + (unsigned) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) << + (int) floatFromVal (rval); + } + } + else + { + if (SPEC_LONG (val->type)) + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) >> + (unsigned long) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) >> + (long) floatFromVal (rval); + } + else + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) >> + (unsigned) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) >> + (int) floatFromVal (rval); + } + } + + return val; } /*------------------------------------------------------------------*/ /* valCompare- Compares two literal */ /*------------------------------------------------------------------*/ -value *valCompare (value *lval, value *rval, int ctype) +value * +valCompare (value * lval, value * rval, int ctype) { - value *val ; - - /* create a new value */ - val = newValue(); - val->type = val->etype = newCharLink(); - val->type->class = SPECIFIER ; - SPEC_NOUN(val->type) = V_INT ; /* type is int */ - SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */ - - switch (ctype) - { - case '<' : - SPEC_CVAL(val->type).v_int = floatFromVal(lval) < floatFromVal(rval); - break ; + value *val; + + /* create a new value */ + val = newValue (); + val->type = val->etype = newCharLink (); + val->type->class = SPECIFIER; + SPEC_NOUN (val->type) = V_INT; /* type is int */ + SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ + + switch (ctype) + { + case '<': + SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval); + break; - case '>' : - SPEC_CVAL(val->type).v_int = floatFromVal(lval) > floatFromVal(rval); - break ; + case '>': + SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval); + break; - case LE_OP : - SPEC_CVAL(val->type).v_int = floatFromVal(lval) <= floatFromVal(rval); - break ; + case LE_OP: + SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval); + break; - case GE_OP : - SPEC_CVAL(val->type).v_int = floatFromVal(lval) >= floatFromVal(rval); - break ; + case GE_OP: + SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval); + break; - case EQ_OP : - SPEC_CVAL(val->type).v_int = floatFromVal(lval) == floatFromVal(rval); - break ; + case EQ_OP: + SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval); + break; - case NE_OP : - SPEC_CVAL(val->type).v_int = floatFromVal(lval) != floatFromVal(rval); - break ; + case NE_OP: + SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval); + break; - } + } - return val ; + return val; } /*------------------------------------------------------------------*/ /* valBitwise - Bitwise operation */ /*------------------------------------------------------------------*/ -value *valBitwise (value *lval, value *rval, int op) +value * +valBitwise (value * lval, value * rval, int op) { - value *val ; - - /* create a new value */ - val = newValue(); - val->type = copyLinkChain (lval->type); - val->etype = getSpec(val->type); - - switch (op) - { - case '&' : - if (SPEC_LONG(val->type)) { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) & - (unsigned long) floatFromVal(rval); - else - SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) & - (long) floatFromVal(rval); - } - else { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) & - (unsigned) floatFromVal(rval); - else - SPEC_CVAL(val->type).v_int = (int) floatFromVal(lval) & (int) floatFromVal(rval); - } - break ; - - case '|' : - if (SPEC_LONG(val->type)) { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) | - (unsigned long) floatFromVal(rval); - else - SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) | - (long) floatFromVal(rval); - } - else { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) | - (unsigned) floatFromVal(rval); - else - SPEC_CVAL(val->type).v_int = - (int) floatFromVal(lval) | (int) floatFromVal(rval); - } - - break ; - - case '^' : - if (SPEC_LONG(val->type)) { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_ulong = (unsigned long) floatFromVal(lval) ^ - (unsigned long) floatFromVal(rval); - else - SPEC_CVAL(val->type).v_long = (long) floatFromVal(lval) ^ - (long) floatFromVal(rval); - } - else { - if (SPEC_USIGN(val->type)) - SPEC_CVAL(val->type).v_uint = (unsigned) floatFromVal(lval) ^ - (unsigned) floatFromVal(rval); - else - SPEC_CVAL(val->type).v_int = - (int) floatFromVal(lval) ^ (int) floatFromVal(rval); - } - break ; - } - - return val ; + value *val; + + /* create a new value */ + val = newValue (); + val->type = copyLinkChain (lval->type); + val->etype = getSpec (val->type); + + switch (op) + { + case '&': + if (SPEC_LONG (val->type)) + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) & + (unsigned long) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) & + (long) floatFromVal (rval); + } + else + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) & + (unsigned) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_int = (int) floatFromVal (lval) & (int) floatFromVal (rval); + } + break; + + case '|': + if (SPEC_LONG (val->type)) + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) | + (unsigned long) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) | + (long) floatFromVal (rval); + } + else + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) | + (unsigned) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_int = + (int) floatFromVal (lval) | (int) floatFromVal (rval); + } + + break; + + case '^': + if (SPEC_LONG (val->type)) + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_ulong = (unsigned long) floatFromVal (lval) ^ + (unsigned long) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_long = (long) floatFromVal (lval) ^ + (long) floatFromVal (rval); + } + else + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_uint = (unsigned) floatFromVal (lval) ^ + (unsigned) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_int = + (int) floatFromVal (lval) ^ (int) floatFromVal (rval); + } + break; + } + + return val; } /*------------------------------------------------------------------*/ /* valAndOr - Generates code for and / or operation */ /*------------------------------------------------------------------*/ -value *valLogicAndOr (value *lval, value *rval, int op) +value * +valLogicAndOr (value * lval, value * rval, int op) { - value *val ; - - /* create a new value */ - val = newValue(); - val->type = val->etype = newCharLink(); - val->type->class = SPECIFIER ; - SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */ - - switch (op) - { - case AND_OP : - SPEC_CVAL(val->type).v_int = floatFromVal(lval) && floatFromVal(rval); - break ; + value *val; + + /* create a new value */ + val = newValue (); + val->type = val->etype = newCharLink (); + val->type->class = SPECIFIER; + SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ + + switch (op) + { + case AND_OP: + SPEC_CVAL (val->type).v_int = floatFromVal (lval) && floatFromVal (rval); + break; - case OR_OP : - SPEC_CVAL(val->type).v_int = floatFromVal(lval) || floatFromVal(rval); - break ; - } + case OR_OP: + SPEC_CVAL (val->type).v_int = floatFromVal (lval) || floatFromVal (rval); + break; + } - return val ; + return val; } /*------------------------------------------------------------------*/ /* valCastLiteral - casts a literal value to another type */ /*------------------------------------------------------------------*/ -value *valCastLiteral (sym_link *dtype, double fval) +value * +valCastLiteral (sym_link * dtype, double fval) { - value *val ; - - if (!dtype) - return NULL ; - - val = newValue(); - val->etype = getSpec (val->type = copyLinkChain(dtype)); - SPEC_SCLS(val->etype) = S_LITERAL ; - /* if it is not a specifier then we can assume that */ - /* it will be an unsigned long */ - if (!IS_SPEC(val->type)) { - SPEC_CVAL(val->etype).v_ulong = (unsigned long) fval; - return val; + value *val; + + if (!dtype) + return NULL; + + val = newValue (); + val->etype = getSpec (val->type = copyLinkChain (dtype)); + SPEC_SCLS (val->etype) = S_LITERAL; + /* if it is not a specifier then we can assume that */ + /* it will be an unsigned long */ + if (!IS_SPEC (val->type)) + { + SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval; + return val; } - if (SPEC_NOUN(val->etype) == V_FLOAT ) - SPEC_CVAL(val->etype).v_float = fval; - else { - if (SPEC_LONG(val->etype)) { - if (SPEC_USIGN(val->etype)) - SPEC_CVAL(val->etype).v_ulong = (unsigned long) fval; - else - SPEC_CVAL(val->etype).v_long = (long) fval; - } - else { - if (SPEC_USIGN(val->etype)) - SPEC_CVAL(val->etype).v_uint = (unsigned int) fval; + if (SPEC_NOUN (val->etype) == V_FLOAT) + SPEC_CVAL (val->etype).v_float = fval; + else + { + if (SPEC_LONG (val->etype)) + { + if (SPEC_USIGN (val->etype)) + SPEC_CVAL (val->etype).v_ulong = (unsigned long) fval; + else + SPEC_CVAL (val->etype).v_long = (long) fval; + } else - SPEC_CVAL(val->etype).v_int = (int) fval; - } + { + if (SPEC_USIGN (val->etype)) + SPEC_CVAL (val->etype).v_uint = (unsigned int) fval; + else + SPEC_CVAL (val->etype).v_int = (int) fval; + } } - return val; + return val; } /*------------------------------------------------------------------*/ /* getNelements - determines # of elements from init list */ /*------------------------------------------------------------------*/ -int getNelements (sym_link *type,initList *ilist) +int +getNelements (sym_link * type, initList * ilist) { - sym_link *etype = getSpec(type); - int i; - - if (! ilist) - return 0; - - if (ilist->type == INIT_DEEP) - ilist = ilist->init.deep; - - /* if type is a character array and there is only one - initialiser then get the length of the string */ - if (IS_ARRAY(type) && IS_CHAR(etype) && !ilist->next) { - ast *iast = ilist->init.node; - value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL); - if (!v) { - werror(E_INIT_WRONG); - return 0; - } - if (!IS_ARRAY(v->type) || !IS_CHAR(v->etype)) { - werror(E_INIT_WRONG); - return 0; - } - return DCL_ELEM(v->type); + sym_link *etype = getSpec (type); + int i; + + if (!ilist) + return 0; + + if (ilist->type == INIT_DEEP) + ilist = ilist->init.deep; + + /* if type is a character array and there is only one + initialiser then get the length of the string */ + if (IS_ARRAY (type) && IS_CHAR (etype) && !ilist->next) + { + ast *iast = ilist->init.node; + value *v = (iast->type == EX_VALUE ? iast->opval.val : NULL); + if (!v) + { + werror (E_INIT_WRONG); + return 0; + } + if (!IS_ARRAY (v->type) || !IS_CHAR (v->etype)) + { + werror (E_INIT_WRONG); + return 0; + } + return DCL_ELEM (v->type); } - i = 0 ; - while (ilist) { - i++; - ilist = ilist->next; + i = 0; + while (ilist) + { + i++; + ilist = ilist->next; } - return i; + return i; } /*-----------------------------------------------------------------*/ /* valForArray - returns a value with name of array index */ /*-----------------------------------------------------------------*/ -value *valForArray (ast *arrExpr) +value * +valForArray (ast * arrExpr) { - value *val, *lval = NULL ; - char buffer[128]; - int size = getSize(arrExpr->left->ftype->next); - /* if the right or left is an array - resolve it first */ - if (IS_AST_OP(arrExpr->left)) { - if (arrExpr->left->opval.op == '[') - lval = valForArray(arrExpr->left); - else - if (arrExpr->left->opval.op == '.') - lval = valForStructElem(arrExpr->left->left, - arrExpr->left->right); + value *val, *lval = NULL; + char buffer[128]; + int size = getSize (arrExpr->left->ftype->next); + /* if the right or left is an array + resolve it first */ + if (IS_AST_OP (arrExpr->left)) + { + if (arrExpr->left->opval.op == '[') + lval = valForArray (arrExpr->left); + else if (arrExpr->left->opval.op == '.') + lval = valForStructElem (arrExpr->left->left, + arrExpr->left->right); + else if (arrExpr->left->opval.op == PTR_OP && + IS_ADDRESS_OF_OP (arrExpr->left->left)) + lval = valForStructElem (arrExpr->left->left->left, + arrExpr->left->right); else - if (arrExpr->left->opval.op == PTR_OP && - IS_ADDRESS_OF_OP(arrExpr->left->left)) - lval = valForStructElem(arrExpr->left->left->left, - arrExpr->left->right); - else - return NULL; - - } else - if (!IS_AST_SYM_VALUE(arrExpr->left)) - return NULL ; - - if (!IS_AST_LIT_VALUE(arrExpr->right)) - return NULL; - - val = newValue(); - if (!lval) - sprintf(buffer,"%s",AST_SYMBOL(arrExpr->left)->rname); - else - sprintf(buffer,"%s",lval->name); - - sprintf(val->name,"(%s + %d)",buffer, - (int)AST_LIT_VALUE(arrExpr->right)*size); - - val->type = newLink(); - if (SPEC_SCLS(arrExpr->left->etype) == S_CODE) { - DCL_TYPE(val->type) = CPOINTER ; - DCL_PTR_CONST(val->type) = port->mem.code_ro; + return NULL; + } - else - if (SPEC_SCLS(arrExpr->left->etype) == S_XDATA) - DCL_TYPE(val->type) = FPOINTER; + else if (!IS_AST_SYM_VALUE (arrExpr->left)) + return NULL; + + if (!IS_AST_LIT_VALUE (arrExpr->right)) + return NULL; + + val = newValue (); + if (!lval) + sprintf (buffer, "%s", AST_SYMBOL (arrExpr->left)->rname); else - if (SPEC_SCLS(arrExpr->left->etype) == S_XSTACK ) - DCL_TYPE(val->type) = PPOINTER ; - else - if (SPEC_SCLS(arrExpr->left->etype) == S_IDATA) - DCL_TYPE(val->type) = IPOINTER ; - else - if (SPEC_SCLS(arrExpr->left->etype) == S_EEPROM) - DCL_TYPE(val->type) = EEPPOINTER ; - else - DCL_TYPE(val->type) = POINTER ; - val->type->next = arrExpr->left->ftype; - val->etype = getSpec(val->type); - return val; + sprintf (buffer, "%s", lval->name); + + sprintf (val->name, "(%s + %d)", buffer, + (int) AST_LIT_VALUE (arrExpr->right) * size); + + val->type = newLink (); + if (SPEC_SCLS (arrExpr->left->etype) == S_CODE) + { + DCL_TYPE (val->type) = CPOINTER; + DCL_PTR_CONST (val->type) = port->mem.code_ro; + } + else if (SPEC_SCLS (arrExpr->left->etype) == S_XDATA) + DCL_TYPE (val->type) = FPOINTER; + else if (SPEC_SCLS (arrExpr->left->etype) == S_XSTACK) + DCL_TYPE (val->type) = PPOINTER; + else if (SPEC_SCLS (arrExpr->left->etype) == S_IDATA) + DCL_TYPE (val->type) = IPOINTER; + else if (SPEC_SCLS (arrExpr->left->etype) == S_EEPROM) + DCL_TYPE (val->type) = EEPPOINTER; + else + DCL_TYPE (val->type) = POINTER; + val->type->next = arrExpr->left->ftype; + val->etype = getSpec (val->type); + return val; } /*-----------------------------------------------------------------*/ /* valForStructElem - returns value with name of struct element */ /*-----------------------------------------------------------------*/ -value *valForStructElem(ast *structT, ast *elemT) +value * +valForStructElem (ast * structT, ast * elemT) { - value *val, *lval = NULL; - char buffer[128]; - symbol *sym; - - /* left could be furthur derefed */ - if (IS_AST_OP(structT)) { - if (structT->opval.op == '[') - lval = valForArray(structT); - else - if (structT->opval.op == '.') - lval = valForStructElem(structT->left,structT->right); + value *val, *lval = NULL; + char buffer[128]; + symbol *sym; + + /* left could be furthur derefed */ + if (IS_AST_OP (structT)) + { + if (structT->opval.op == '[') + lval = valForArray (structT); + else if (structT->opval.op == '.') + lval = valForStructElem (structT->left, structT->right); + else if (structT->opval.op == PTR_OP && + IS_ADDRESS_OF_OP (structT->left)) + lval = valForStructElem (structT->left->left, + structT->right); else - if (structT->opval.op == PTR_OP && - IS_ADDRESS_OF_OP(structT->left)) - lval = valForStructElem(structT->left->left, - structT->right); - else - return NULL; + return NULL; } - if (!IS_AST_SYM_VALUE(elemT)) - return NULL; + if (!IS_AST_SYM_VALUE (elemT)) + return NULL; - if (!IS_STRUCT(structT->etype)) - return NULL; + if (!IS_STRUCT (structT->etype)) + return NULL; - if ((sym = getStructElement(SPEC_STRUCT(structT->etype), - AST_SYMBOL(elemT))) == NULL) { - return NULL; + if ((sym = getStructElement (SPEC_STRUCT (structT->etype), + AST_SYMBOL (elemT))) == NULL) + { + return NULL; } - val = newValue(); - if (!lval) - sprintf(buffer,"%s",AST_SYMBOL(structT)->rname); - else - sprintf(buffer,"%s",lval->name); + val = newValue (); + if (!lval) + sprintf (buffer, "%s", AST_SYMBOL (structT)->rname); + else + sprintf (buffer, "%s", lval->name); - sprintf(val->name,"(%s + %d)",buffer, - (int)sym->offset); + sprintf (val->name, "(%s + %d)", buffer, + (int) sym->offset); - val->type = newLink(); - if (SPEC_SCLS(structT->etype) == S_CODE) { - DCL_TYPE(val->type) = CPOINTER ; - DCL_PTR_CONST(val->type) = port->mem.code_ro; + val->type = newLink (); + if (SPEC_SCLS (structT->etype) == S_CODE) + { + DCL_TYPE (val->type) = CPOINTER; + DCL_PTR_CONST (val->type) = port->mem.code_ro; } - else - if (SPEC_SCLS(structT->etype) == S_XDATA) - DCL_TYPE(val->type) = FPOINTER; + else if (SPEC_SCLS (structT->etype) == S_XDATA) + DCL_TYPE (val->type) = FPOINTER; + else if (SPEC_SCLS (structT->etype) == S_XSTACK) + DCL_TYPE (val->type) = PPOINTER; + else if (SPEC_SCLS (structT->etype) == S_IDATA) + DCL_TYPE (val->type) = IPOINTER; + else if (SPEC_SCLS (structT->etype) == S_EEPROM) + DCL_TYPE (val->type) = EEPPOINTER; else - if (SPEC_SCLS(structT->etype) == S_XSTACK ) - DCL_TYPE(val->type) = PPOINTER ; - else - if (SPEC_SCLS(structT->etype) == S_IDATA) - DCL_TYPE(val->type) = IPOINTER ; - else - if (SPEC_SCLS(structT->etype) == S_EEPROM) - DCL_TYPE(val->type) = EEPPOINTER ; - else - DCL_TYPE(val->type) = POINTER ; - val->type->next = sym->type; - val->etype = getSpec(val->type); - return val; + DCL_TYPE (val->type) = POINTER; + val->type->next = sym->type; + val->etype = getSpec (val->type); + return val; } /*-----------------------------------------------------------------*/ /* valForCastAggr - will return value for a cast of an aggregate */ /* plus minus a constant */ /*-----------------------------------------------------------------*/ -value *valForCastAggr (ast *aexpr, sym_link *type, ast *cnst, int op) +value * +valForCastAggr (ast * aexpr, sym_link * type, ast * cnst, int op) { - value *val; + value *val; - if (!IS_AST_SYM_VALUE(aexpr)) return NULL; - if (!IS_AST_LIT_VALUE(cnst)) return NULL; + if (!IS_AST_SYM_VALUE (aexpr)) + return NULL; + if (!IS_AST_LIT_VALUE (cnst)) + return NULL; - val = newValue(); + val = newValue (); - sprintf(val->name,"(%s %c %d)", - AST_SYMBOL(aexpr)->rname, op, - getSize(type->next)*(int)AST_LIT_VALUE(cnst)); + sprintf (val->name, "(%s %c %d)", + AST_SYMBOL (aexpr)->rname, op, + getSize (type->next) * (int) AST_LIT_VALUE (cnst)); - val->type = type; - val->etype = getSpec(val->type); - return val; + val->type = type; + val->etype = getSpec (val->type); + return val; } diff --git a/src/SDCCval.h b/src/SDCCval.h index 018213d4..77ea58cd 100644 --- a/src/SDCCval.h +++ b/src/SDCCval.h @@ -25,75 +25,82 @@ #define SDCCVAL_H /* value wrapper */ -typedef struct value { - char name[ SDCC_NAME_MAX + 1 ]; /* operand accessing this value */ - sym_link *type ; /* start of type chain */ - sym_link *etype; /* end of type chain */ - symbol *sym ; /* Original Symbol */ - struct value *next ; /* used in initializer list*/ - unsigned vArgs : 1 ; /* arg list ended with variable arg */ +typedef struct value + { + char name[SDCC_NAME_MAX + 1]; /* operand accessing this value */ + sym_link *type; /* start of type chain */ + sym_link *etype; /* end of type chain */ + symbol *sym; /* Original Symbol */ + struct value *next; /* used in initializer list */ + unsigned vArgs:1; /* arg list ended with variable arg */ -} value ; + } +value; -enum { - INIT_NODE , - INIT_DEEP , - INIT_HOLE -}; +enum + { + INIT_NODE, + INIT_DEEP, + INIT_HOLE + }; /* initializer lists use this structure */ -typedef struct initList { - int type ; - int lineno ; - union { - struct ast *node ; - struct initList *deep ; - } init ; - - struct initList *next ; -} initList ; +typedef struct initList + { + int type; + int lineno; + union + { + struct ast *node; + struct initList *deep; + } + init; + + struct initList *next; + } +initList; #define IS_VARG(x) (x->vArgs) /* forward definitions for the symbol table related functions */ -void initValue ( ); -value *newValue ( ); -value *constVal (char * ); -value *reverseVal (value * ); -value *reverseValWithType(value * ); -value *copyValue (value * ); -value *copyValueChain (value * ); -value *strVal (char * ); -value *charVal (char * ); -value *symbolVal (symbol * ); -void printVal (value * ); -double floatFromVal (value * ); -value *array2Ptr (value * ); -value *valUnaryPM (value * ); -value *valComplement (value * ); -value *valNot (value * ); -value *valMult (value *, value * ); -value *valDiv (value *, value * ); -value *valMod (value *, value * ); -value *valPlus (value *, value * ); -value *valMinus (value *, value * ); -value *valShift (value *, value *,int); -value *valCompare (value *, value *,int); -value *valBitwise (value *, value *,int); -value *valLogicAndOr (value *, value *,int); -value *valCastLiteral (sym_link *, double ); -value *valueFromLit (float ); -initList *newiList (int , void * ); -initList *revinit (initList * ); -initList *copyIlist (initList * ); -double list2int (initList * ); -value *list2val (initList * ); -struct ast *list2expr (initList * ); -void resolveIvalSym (initList * ); -value *valFromType (sym_link * ); -value *constFloatVal (char * ); -int getNelements (sym_link *, initList * ); -value *valForArray (struct ast * ); -value *valForStructElem (struct ast *, struct ast *); -value *valForCastAggr (struct ast *, sym_link *, struct ast *, int ) ; +void initValue (); +value *newValue (); +value *constVal (char *); +value *reverseVal (value *); +value *reverseValWithType (value *); +value *copyValue (value *); +value *copyValueChain (value *); +value *strVal (char *); +value *charVal (char *); +value *symbolVal (symbol *); +void printVal (value *); +double floatFromVal (value *); +value *array2Ptr (value *); +value *valUnaryPM (value *); +value *valComplement (value *); +value *valNot (value *); +value *valMult (value *, value *); +value *valDiv (value *, value *); +value *valMod (value *, value *); +value *valPlus (value *, value *); +value *valMinus (value *, value *); +value *valShift (value *, value *, int); +value *valCompare (value *, value *, int); +value *valBitwise (value *, value *, int); +value *valLogicAndOr (value *, value *, int); +value *valCastLiteral (sym_link *, double); +value *valueFromLit (float); +initList *newiList (int, void *); +initList *revinit (initList *); +initList *copyIlist (initList *); +double list2int (initList *); +value *list2val (initList *); +struct ast *list2expr (initList *); +void resolveIvalSym (initList *); +value *valFromType (sym_link *); +value *constFloatVal (char *); +int getNelements (sym_link *, initList *); +value *valForArray (struct ast *); +value *valForStructElem (struct ast *, struct ast *); +value *valForCastAggr (struct ast *, sym_link *, struct ast *, int); #endif diff --git a/src/altlex.c b/src/altlex.c index 6572164e..ea89db84 100644 --- a/src/altlex.c +++ b/src/altlex.c @@ -10,36 +10,36 @@ #define DUMP_OUTPUT 0 /* Right. What are the parts of the C stream? From SDCC.lex: - D = [0..9] digits - L = [a..z A..Z _] alphanumerics and _ - H = [a..f A..F 0-9] Hex digits - E = [eE+-0-9] Digits in a float - FS = [fFlL] Specifiers for a float - IS = [uUlL] Specifiers for a int - - L[LD]* A 'token' - cant think of a good name - Check tokens against the reserved words. - If match - return the token id. - else - If in the typedef table, do stuff... - Blah. See check_type() - 0[xX]{H}+ Hex number - PENDING: specifiers - 0{D}+ Octal number - PENDING: specifiers - {D}+ Decimal - PENDING: specifiers - Floats PENDING - + D = [0..9] digits + L = [a..z A..Z _] alphanumerics and _ + H = [a..f A..F 0-9] Hex digits + E = [eE+-0-9] Digits in a float + FS = [fFlL] Specifiers for a float + IS = [uUlL] Specifiers for a int + + L[LD]* A 'token' - cant think of a good name + Check tokens against the reserved words. + If match + return the token id. + else + If in the typedef table, do stuff... + Blah. See check_type() + 0[xX]{H}+ Hex number - PENDING: specifiers + 0{D}+ Octal number - PENDING: specifiers + {D}+ Decimal - PENDING: specifiers + Floats PENDING + Exceptions: - Comment start Strip until end of comment. - ... Ellipses + Comment start Strip until end of comment. + ... Ellipses So the inputs are: - Skip whitespace - switch class - L Try to read a token - D Try to read a number - Punct Try to read punct -*/ + Skip whitespace + switch class + L Try to read a token + D Try to read a number + Punct Try to read punct + */ extern int fatalError; extern int lineno; @@ -58,445 +58,548 @@ static int end_of_file; #ifdef __GNUC__ #define INLINE inline #else -#define INLINE +#define INLINE #endif #define ERRSINK stderr -static void error(const char *sz, ...) +static void +error (const char *sz,...) { - va_list ap; - fatalError++; - - if (filename && lineno) { - fprintf(ERRSINK, "%s(%d):",filename,lineno); + va_list ap; + fatalError++; + + if (filename && lineno) + { + fprintf (ERRSINK, "%s(%d):", filename, lineno); } - fprintf(ERRSINK, "error *** "); - va_start(ap, sz); - vfprintf(ERRSINK, sz, ap); - va_end(ap); - fprintf(ERRSINK, "\n"); - fflush(ERRSINK); + fprintf (ERRSINK, "error *** "); + va_start (ap, sz); + vfprintf (ERRSINK, sz, ap); + va_end (ap); + fprintf (ERRSINK, "\n"); + fflush (ERRSINK); } -static int underflow(void) +static int +underflow (void) { - linelen = fread(linebuf, 1, sizeof(linebuf), yyin); - if (linelen <= 0) - return EOF; - linepos = 0; - return linebuf[linepos++]; + linelen = fread (linebuf, 1, sizeof (linebuf), yyin); + if (linelen <= 0) + return EOF; + linepos = 0; + return linebuf[linepos++]; } -static int INLINE ygetc(void) +static int INLINE +ygetc (void) { - if (linepos < linelen) - return linebuf[linepos++]; - else - return underflow(); + if (linepos < linelen) + return linebuf[linepos++]; + else + return underflow (); }; -static int INLINE yungetc(int c) +static int INLINE +yungetc (int c) { - linebuf[--linepos] = c; - return 0; + linebuf[--linepos] = c; + return 0; } #define GETC() ygetc() #define UNGETC(_a) yungetc(_a) -//#define GETC() fgetc(yyin); -//#define UNGETC(_a) ungetc(_a, yyin) +//#define GETC() fgetc(yyin); +//#define UNGETC(_a) ungetc(_a, yyin) #define ISL(_a) (isalnum(_a) || _a == '_') #define ISALNUM(_a) isalnum(_a) #define ISHEX(_a) isxdigit(_a) -static char *stringLiteral (void) +static char * +stringLiteral (void) { - static char line[1000]; - int ch; - char *str = line; - - *str++ = '\"' ; - /* put into the buffer till we hit the */ - /* first \" */ - while (1) { - - ch = GETC(); - if (!ch) break ; /* end of input */ - /* if it is a \ then everything allowed */ - if (ch == '\\') { - *str++ = ch ; /* backslash in place */ - *str++ = GETC() ; /* following char in place */ - continue ; /* carry on */ + static char line[1000]; + int ch; + char *str = line; + + *str++ = '\"'; + /* put into the buffer till we hit the */ + /* first \" */ + while (1) + { + + ch = GETC (); + if (!ch) + break; /* end of input */ + /* if it is a \ then everything allowed */ + if (ch == '\\') + { + *str++ = ch; /* backslash in place */ + *str++ = GETC (); /* following char in place */ + continue; /* carry on */ } - - /* if new line we have a new line break */ - if (ch == '\n') break ; - - /* if this is a quote then we have work to do */ - /* find the next non whitespace character */ - /* if that is a double quote then carry on */ - if (ch == '\"') { - - while ((ch = GETC()) && isspace(ch)) ; - if (!ch) break ; - if (ch != '\"') { - UNGETC(ch) ; - break ; + + /* if new line we have a new line break */ + if (ch == '\n') + break; + + /* if this is a quote then we have work to do */ + /* find the next non whitespace character */ + /* if that is a double quote then carry on */ + if (ch == '\"') + { + + while ((ch = GETC ()) && isspace (ch)); + if (!ch) + break; + if (ch != '\"') + { + UNGETC (ch); + break; } - - continue ; - } - *str++ = ch; - } - *str++ = '\"' ; - *str = '\0'; - return line; + + continue; + } + *str++ = ch; + } + *str++ = '\"'; + *str = '\0'; + return line; } -static void discard_comments(int type) +static void +discard_comments (int type) { - int c; - if (type == '*') { - do { - c = GETC(); - if (c == '*') { - c = GETC(); - if (c == '/') - return; - } - else if (c == EOF) + int c; + if (type == '*') + { + do + { + c = GETC (); + if (c == '*') + { + c = GETC (); + if (c == '/') return; - } while (1); + } + else if (c == EOF) + return; + } + while (1); } - else if (type == '/') { - do { - c = GETC(); - } while (c != '\n' && c != EOF); + else if (type == '/') + { + do + { + c = GETC (); + } + while (c != '\n' && c != EOF); } - else { - assert(0); + else + { + assert (0); } } /* will return 1 if the string is a part of a target specific keyword */ -static INLINE int isTargetKeyword(const char *s) +static INLINE int +isTargetKeyword (const char *s) { - int i; - - if (port->keywords == NULL) - return 0; - for ( i = 0 ; port->keywords[i] ; i++ ) { - if (strcmp(port->keywords[i],s) == 0) - return 1; - } - + int i; + + if (port->keywords == NULL) return 0; + for (i = 0; port->keywords[i]; i++) + { + if (strcmp (port->keywords[i], s) == 0) + return 1; + } + + return 0; } -static INLINE int check_token(const char *sz) +static INLINE int +check_token (const char *sz) { - const struct reserved_words *p; - p = is_reserved_word(sz, strlen(sz)); - if (p) { - if (!p->is_special || isTargetKeyword(sz)) - return p->token; + const struct reserved_words *p; + p = is_reserved_word (sz, strlen (sz)); + if (p) + { + if (!p->is_special || isTargetKeyword (sz)) + return p->token; } - /* check if it is in the typedef table */ - if (findSym(TypedefTab,NULL,sz)) { - strcpy(yylval.yychar,sz); - return TYPE_NAME; + /* check if it is in the typedef table */ + if (findSym (TypedefTab, NULL, sz)) + { + strcpy (yylval.yychar, sz); + return TYPE_NAME; } - else { - strcpy (yylval.yychar,sz); - return IDENTIFIER; + else + { + strcpy (yylval.yychar, sz); + return IDENTIFIER; } } -static void handle_pragma(void) +static void +handle_pragma (void) { - char line[128], *p; - int c; - - c = GETC(); - while (c == '\t' || c == ' ') - c = GETC(); - p = line; - while (!isspace(c)) { - *p++ = c; - c = GETC(); + char line[128], *p; + int c; + + c = GETC (); + while (c == '\t' || c == ' ') + c = GETC (); + p = line; + while (!isspace (c)) + { + *p++ = c; + c = GETC (); } - *p = '\0'; - if (line[0] == '\0') - error("Missing argument to pragma"); - else { - /* First give the port a chance */ - if (port->process_pragma && !port->process_pragma(line)) - return; - /* PENDING: all the SDCC shared pragmas */ - /* Nothing handled it */ - error("Unrecognised #pragma %s", line); + *p = '\0'; + if (line[0] == '\0') + error ("Missing argument to pragma"); + else + { + /* First give the port a chance */ + if (port->process_pragma && !port->process_pragma (line)) + return; + /* PENDING: all the SDCC shared pragmas */ + /* Nothing handled it */ + error ("Unrecognised #pragma %s", line); } } -static void handle_line(void) +static void +handle_line (void) { - int c; - char line[128], *p; - - c = GETC(); - while (c == '\t' || c == ' ') - c = GETC(); - p = line; - while (isdigit(c)) { - *p++ = c; - c = GETC(); + int c; + char line[128], *p; + + c = GETC (); + while (c == '\t' || c == ' ') + c = GETC (); + p = line; + while (isdigit (c)) + { + *p++ = c; + c = GETC (); } - *p = '\0'; - if (line[0] == '\0') - error("Error in number in #line"); - /* This is weird but cpp seems to add an extra three to the line no */ - yylineno = atoi(line) - 3; - lineno = yylineno; - /* Fetch the filename if there is one */ - while (c == '\t' || c == ' ') - c = GETC(); - if (c == '\"') { - p = line; - c = GETC(); - while (c != '\"' && c != EOF && c != '\n') { - *p++ = c; - c = GETC(); + *p = '\0'; + if (line[0] == '\0') + error ("Error in number in #line"); + /* This is weird but cpp seems to add an extra three to the line no */ + yylineno = atoi (line) - 3; + lineno = yylineno; + /* Fetch the filename if there is one */ + while (c == '\t' || c == ' ') + c = GETC (); + if (c == '\"') + { + p = line; + c = GETC (); + while (c != '\"' && c != EOF && c != '\n') + { + *p++ = c; + c = GETC (); } - if (c == '\"') { - *p = '\0'; - currFname = gc_strdup(line); + if (c == '\"') + { + *p = '\0'; + currFname = gc_strdup (line); } - filename = currFname; + filename = currFname; } } -static INLINE void invalid_directive(void) +static INLINE void +invalid_directive (void) { - error("Invalid directive"); + error ("Invalid directive"); } -static INLINE int check_newline(void) +static INLINE int +check_newline (void) { - int c; - yylineno++; - lineno = yylineno; - - /* Skip any leading white space */ - c = GETC(); - while (c == '\t' || c == ' ') - c = GETC(); - /* Were only interested in #something */ - if (c != '#') - return c; - c = GETC(); - while (c == '\t' || c == ' ') - c = GETC(); - /* The text in the stream is the type of directive */ - switch (c) { + int c; + yylineno++; + lineno = yylineno; + + /* Skip any leading white space */ + c = GETC (); + while (c == '\t' || c == ' ') + c = GETC (); + /* Were only interested in #something */ + if (c != '#') + return c; + c = GETC (); + while (c == '\t' || c == ' ') + c = GETC (); + /* The text in the stream is the type of directive */ + switch (c) + { case 'l': - /* Start of line? */ - if (GETC() == 'i' && GETC() == 'n' && GETC() == 'e') { - c = GETC(); - if (c == '\t' || c == ' ') - handle_line(); - else - invalid_directive(); + /* Start of line? */ + if (GETC () == 'i' && GETC () == 'n' && GETC () == 'e') + { + c = GETC (); + if (c == '\t' || c == ' ') + handle_line (); + else + invalid_directive (); } - else - invalid_directive(); - break; + else + invalid_directive (); + break; case 'p': - /* Start of pragma? */ - if (GETC() == 'r' && GETC() == 'a' && GETC() == 'g' && - GETC() == 'm' && GETC() == 'a') { - c = GETC(); - if (c == '\t' || c == ' ') - handle_pragma(); - else - invalid_directive(); + /* Start of pragma? */ + if (GETC () == 'r' && GETC () == 'a' && GETC () == 'g' && + GETC () == 'm' && GETC () == 'a') + { + c = GETC (); + if (c == '\t' || c == ' ') + handle_pragma (); + else + invalid_directive (); } - else - invalid_directive(); - break; + else + invalid_directive (); + break; default: - invalid_directive(); + invalid_directive (); } - /* Discard from here until the start of the next line */ - while (c != '\n' && c != EOF) - c = GETC(); - return c; + /* Discard from here until the start of the next line */ + while (c != '\n' && c != EOF) + c = GETC (); + return c; } -static int skip_whitespace(int c) +static int +skip_whitespace (int c) { - while (1) { - switch (c) { + while (1) + { + switch (c) + { case ' ': case '\t': case '\f': case '\v': case '\b': case '\r': - c = GETC(); - break; + c = GETC (); + break; case '\n': - c = check_newline(); + c = check_newline (); default: - return c; + return c; } } } -void yyerror(const char *s) +void +yyerror (const char *s) { - if (end_of_file) - error("%s at end of of input", s); - else if (yytext[0] == '\0') - error("%s at null character", s); - else if (yytext[0] == '"') - error("%s before string constant", s); - else if (yytext[0] == '\'') - error("%s before character constant", s); - else - error("%s before %s", s, yytext); + if (end_of_file) + error ("%s at end of of input", s); + else if (yytext[0] == '\0') + error ("%s at null character", s); + else if (yytext[0] == '"') + error ("%s before string constant", s); + else if (yytext[0] == '\'') + error ("%s before character constant", s); + else + error ("%s before %s", s, yytext); } -static int _yylex(void) +static int +_yylex (void) { - int c; - static char line[128]; - char *p; + int c; + static char line[128]; + char *p; - yytext = line; + yytext = line; - c = GETC(); - while (1) { - switch (c) { + c = GETC (); + while (1) + { + switch (c) + { case ' ': case '\t': case '\f': case '\v': case '\b': - /* Skip whitespace */ - c = GETC(); - break; + /* Skip whitespace */ + c = GETC (); + break; case '\r': case '\n': - c = skip_whitespace(c); - break; + c = skip_whitespace (c); + break; case '#': - UNGETC(c); - c = check_newline(); - break; + UNGETC (c); + c = check_newline (); + break; default: - goto past_ws; + goto past_ws; } } - past_ws: - /* Handle comments first */ - if (c == '/') { - int c2 = GETC(); - if (c2 == '*' || c2 == '/') { - discard_comments(c2); - c = GETC(); +past_ws: + /* Handle comments first */ + if (c == '/') + { + int c2 = GETC (); + if (c2 == '*' || c2 == '/') + { + discard_comments (c2); + c = GETC (); } - else - UNGETC(c2); + else + UNGETC (c2); } - switch (c) { + switch (c) + { case EOF: - end_of_file = TRUE; - line[0] = '\0'; - return 0; - case 'a': case 'b': case 'c': case 'd': - case 'e': case 'f': case 'g': case 'h': - case 'i': case 'j': case 'k': case 'l': - case 'm': case 'n': case 'o': case 'p': - case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': - case 'y': case 'z': - case 'A': case 'B': case 'C': case 'D': - case 'E': case 'F': case 'G': case 'H': - case 'I': case 'J': case 'K': case 'L': - case 'M': case 'N': case 'O': case 'P': - case 'Q': case 'R': case 'S': case 'T': - case 'U': case 'V': case 'W': case 'X': - case 'Y': case 'Z': + end_of_file = TRUE; + line[0] = '\0'; + return 0; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': case '_': - /* Start of a token. Parse. */ - p = line; - *p++ = c; - c = GETC(); - while (ISL(c)) { - *p++ = c; - c = GETC(); + /* Start of a token. Parse. */ + p = line; + *p++ = c; + c = GETC (); + while (ISL (c)) + { + *p++ = c; + c = GETC (); } - *p = '\0'; - UNGETC(c); - return check_token(line); - case '0': case '1': - case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - p = line; - *p++ = c; - c = GETC(); - if (c == 'x' || c == 'X') { - *p++ = c; - c = GETC(); + *p = '\0'; + UNGETC (c); + return check_token (line); + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + p = line; + *p++ = c; + c = GETC (); + if (c == 'x' || c == 'X') + { + *p++ = c; + c = GETC (); } - while (ISHEX(c)) { - *p++ = c; - c = GETC(); + while (ISHEX (c)) + { + *p++ = c; + c = GETC (); } - if (c == 'U' || c == 'u' || c == 'L' || c == 'l') { - *p++ = c; - c = GETC(); + if (c == 'U' || c == 'u' || c == 'L' || c == 'l') + { + *p++ = c; + c = GETC (); } - if (c == 'U' || c == 'u' || c == 'L' || c == 'l') { - *p++ = c; - c = GETC(); + if (c == 'U' || c == 'u' || c == 'L' || c == 'l') + { + *p++ = c; + c = GETC (); } - *p = '\0'; - UNGETC(c); - yylval.val = constVal(line); - return CONSTANT; + *p = '\0'; + UNGETC (c); + yylval.val = constVal (line); + return CONSTANT; case '\"': - /* A string */ - p = stringLiteral(); - yylval.val = strVal(p); - return(STRING_LITERAL); + /* A string */ + p = stringLiteral (); + yylval.val = strVal (p); + return (STRING_LITERAL); case '\'': - /* Possible formats: - ['\n', '\\', '\'', '\"'...] - ['a'...] - */ - p = line; - *p++ = c; - c = GETC(); - if (c == '\\') { - *p++ = c; - c = GETC(); - /* Fall through */ + /* Possible formats: + ['\n', '\\', '\'', '\"'...] + ['a'...] + */ + p = line; + *p++ = c; + c = GETC (); + if (c == '\\') + { + *p++ = c; + c = GETC (); + /* Fall through */ } - *p++ = c; - c = GETC(); - *p++ = c; - *p = '\0'; - if (c != '\'') { - error("Unrecognised character constant %s", line); + *p++ = c; + c = GETC (); + *p++ = c; + *p = '\0'; + if (c != '\'') + { + error ("Unrecognised character constant %s", line); } - yylval.val = charVal(line); - return CONSTANT; + yylval.val = charVal (line); + return CONSTANT; case '=': case '&': case '!': @@ -508,7 +611,8 @@ static int _yylex(void) case '<': case '>': case '^': - case '|': { + case '|': + { /* Cases which can be compounds */ /* The types and classes of composites are: >>= <<= @@ -523,440 +627,591 @@ static int _yylex(void) 3. Followed by an equals 4. Be a '->' 5. Be by itself - */ - int next = GETC(); + */ + int next = GETC (); /* Class 1 and 2 */ - if (next == c) { - next = GETC(); + if (next == c) + { + next = GETC (); /* Class 1 */ - if (next == '=') { - switch (c) { - case '>': // >>= + if (next == '=') + { + switch (c) + { + case '>': // >>= + yylval.yyint = RIGHT_ASSIGN; return RIGHT_ASSIGN; - case '<': // <<= + case '<': // <<= + yylval.yyint = LEFT_ASSIGN; return LEFT_ASSIGN; - default: - error("Unrecognised token %c%c=", c, c); - } - } - else { + default: + error ("Unrecognised token %c%c=", c, c); + } + } + else + { /* Push the next char back on and find the class */ - UNGETC(next); + UNGETC (next); /* Case 2 */ - switch (c) { - case '>': // >> + switch (c) + { + case '>': // >> + return RIGHT_OP; - case '<': // << + case '<': // << + return LEFT_OP; - case '+': + case '+': return INC_OP; - case '-': + case '-': return DEC_OP; - case '&': + case '&': return AND_OP; - case '|': + case '|': return OR_OP; - case '=': + case '=': return EQ_OP; - default: - error("Unrecognised token %c%c", c, c); - } - } - } + default: + error ("Unrecognised token %c%c", c, c); + } + } + } /* Case 3 */ - else if (next == '=') { + else if (next == '=') + { int result = 0; - switch (c) { - case '+': - result = ADD_ASSIGN; break; - case '-': - result = SUB_ASSIGN; break; - case '*': - result = MUL_ASSIGN; break; - case '/': - result = DIV_ASSIGN; break; - case '%': - result = MOD_ASSIGN; break; - case '&': - result = AND_ASSIGN; break; - case '^': - result = XOR_ASSIGN; break; - case '|': - result = OR_ASSIGN; break; - case '<': - result = LE_OP; break; - case '>': - result = GE_OP; break; - case '!': - result = NE_OP; break; - default: - error("Unrecognised token %c=", c); - } - if (result) { + switch (c) + { + case '+': + result = ADD_ASSIGN; + break; + case '-': + result = SUB_ASSIGN; + break; + case '*': + result = MUL_ASSIGN; + break; + case '/': + result = DIV_ASSIGN; + break; + case '%': + result = MOD_ASSIGN; + break; + case '&': + result = AND_ASSIGN; + break; + case '^': + result = XOR_ASSIGN; + break; + case '|': + result = OR_ASSIGN; + break; + case '<': + result = LE_OP; + break; + case '>': + result = GE_OP; + break; + case '!': + result = NE_OP; + break; + default: + error ("Unrecognised token %c=", c); + } + if (result) + { yylval.yyint = result; return result; - } - } + } + } /* Case 4 */ - else if (c == '-' && next == '>') { + else if (c == '-' && next == '>') + { return PTR_OP; - } + } /* Case 5 */ - else { - UNGETC(next); + else + { + UNGETC (next); return c; - } + } break; - } + } case '{': - NestLevel++; - return c; + NestLevel++; + return c; case '}': - NestLevel--; - return c; + NestLevel--; + return c; case '.': - c = GETC(); - if (c == '.') { - c = GETC(); - if (c == '.') { - return VAR_ARGS; + c = GETC (); + if (c == '.') + { + c = GETC (); + if (c == '.') + { + return VAR_ARGS; } } - UNGETC(c); - return '.'; - case '[': case ']': - return c; + UNGETC (c); + return '.'; + case '[': + case ']': + return c; case ',': case ':': - case '(': case ')': + case '(': + case ')': case '~': case '?': case ';': - /* Special characters that cant be part of a composite */ - return c; + /* Special characters that cant be part of a composite */ + return c; default: - error("Unhandled character %c", c); + error ("Unhandled character %c", c); } - return 0; + return 0; } #define ENTRY(_a) case (_a): printf(#_a); break; -int yylex(void) +int +yylex (void) { - int ret = _yylex(); + int ret = _yylex (); #if DUMP_OUTPUT - static int lastpos = 0; - char tmp; - - printf("Returning "); - switch (ret) { - /* Wrapper */ - ENTRY(IDENTIFIER); - ENTRY(TYPE_NAME); - ENTRY(CONSTANT); - ENTRY(STRING_LITERAL); - ENTRY(SIZEOF); - ENTRY(PTR_OP); - ENTRY(INC_OP); - ENTRY(DEC_OP); - ENTRY(LEFT_OP); - ENTRY(RIGHT_OP); - ENTRY(LE_OP); - ENTRY(GE_OP); - ENTRY(EQ_OP); - ENTRY(NE_OP); - ENTRY(AND_OP); - ENTRY(OR_OP); - ENTRY(MUL_ASSIGN); - ENTRY(DIV_ASSIGN); - ENTRY(MOD_ASSIGN); - ENTRY(ADD_ASSIGN); - ENTRY(SUB_ASSIGN); - ENTRY(LEFT_ASSIGN); - ENTRY(RIGHT_ASSIGN); - ENTRY(AND_ASSIGN); - ENTRY(XOR_ASSIGN); - ENTRY(OR_ASSIGN); - ENTRY(TYPEDEF); - ENTRY(EXTERN); - ENTRY(STATIC); - ENTRY(AUTO); - ENTRY(REGISTER); - ENTRY(CODE); - ENTRY(EEPROM); - ENTRY(INTERRUPT); - ENTRY(SFR); - ENTRY(AT); - ENTRY(SBIT); - ENTRY(REENTRANT); - ENTRY(USING); - ENTRY(XDATA); - ENTRY(DATA); - ENTRY(IDATA); - ENTRY(PDATA); - ENTRY(VAR_ARGS); - ENTRY(CRITICAL); - ENTRY(NONBANKED); - ENTRY(BANKED); - ENTRY(CHAR); - ENTRY(SHORT); - ENTRY(INT); - ENTRY(LONG); - ENTRY(SIGNED); - ENTRY(UNSIGNED); - ENTRY(FLOAT); - ENTRY(DOUBLE); - ENTRY(CONST); - ENTRY(VOLATILE); - ENTRY(VOID); - ENTRY(BIT); - ENTRY(STRUCT); - ENTRY(UNION); - ENTRY(ENUM); - ENTRY(ELIPSIS); - ENTRY(RANGE); - ENTRY(FAR); - ENTRY(_XDATA); - ENTRY(_CODE); - ENTRY(_GENERIC); - ENTRY(_NEAR); - ENTRY(_PDATA); - ENTRY(_IDATA); - ENTRY(_EEPROM); - ENTRY(CASE); - ENTRY(DEFAULT); - ENTRY(IF); - ENTRY(ELSE); - ENTRY(SWITCH); - ENTRY(WHILE); - ENTRY(DO); - ENTRY(FOR); - ENTRY(GOTO); - ENTRY(CONTINUE); - ENTRY(BREAK); - ENTRY(RETURN); - ENTRY(INLINEASM); - ENTRY(IFX); - ENTRY(ADDRESS_OF); - ENTRY(GET_VALUE_AT_ADDRESS); - ENTRY(SPIL); - ENTRY(UNSPIL); - ENTRY(GETHBIT); - ENTRY(BITWISEAND); - ENTRY(UNARYMINUS); - ENTRY(IPUSH); - ENTRY(IPOP); - ENTRY(PCALL); - ENTRY(ENDFUNCTION); - ENTRY(JUMPTABLE); - ENTRY(RRC); - ENTRY(RLC); - ENTRY(CAST); - ENTRY(CALL); - ENTRY(PARAM); - ENTRY(NULLOP); - ENTRY(BLOCK); - ENTRY(LABEL); - ENTRY(RECEIVE); - ENTRY(SEND); + static int lastpos = 0; + char tmp; + + printf ("Returning "); + switch (ret) + { + /* Wrapper */ + ENTRY (IDENTIFIER); + ENTRY (TYPE_NAME); + ENTRY (CONSTANT); + ENTRY (STRING_LITERAL); + ENTRY (SIZEOF); + ENTRY (PTR_OP); + ENTRY (INC_OP); + ENTRY (DEC_OP); + ENTRY (LEFT_OP); + ENTRY (RIGHT_OP); + ENTRY (LE_OP); + ENTRY (GE_OP); + ENTRY (EQ_OP); + ENTRY (NE_OP); + ENTRY (AND_OP); + ENTRY (OR_OP); + ENTRY (MUL_ASSIGN); + ENTRY (DIV_ASSIGN); + ENTRY (MOD_ASSIGN); + ENTRY (ADD_ASSIGN); + ENTRY (SUB_ASSIGN); + ENTRY (LEFT_ASSIGN); + ENTRY (RIGHT_ASSIGN); + ENTRY (AND_ASSIGN); + ENTRY (XOR_ASSIGN); + ENTRY (OR_ASSIGN); + ENTRY (TYPEDEF); + ENTRY (EXTERN); + ENTRY (STATIC); + ENTRY (AUTO); + ENTRY (REGISTER); + ENTRY (CODE); + ENTRY (EEPROM); + ENTRY (INTERRUPT); + ENTRY (SFR); + ENTRY (AT); + ENTRY (SBIT); + ENTRY (REENTRANT); + ENTRY (USING); + ENTRY (XDATA); + ENTRY (DATA); + ENTRY (IDATA); + ENTRY (PDATA); + ENTRY (VAR_ARGS); + ENTRY (CRITICAL); + ENTRY (NONBANKED); + ENTRY (BANKED); + ENTRY (CHAR); + ENTRY (SHORT); + ENTRY (INT); + ENTRY (LONG); + ENTRY (SIGNED); + ENTRY (UNSIGNED); + ENTRY (FLOAT); + ENTRY (DOUBLE); + ENTRY (CONST); + ENTRY (VOLATILE); + ENTRY (VOID); + ENTRY (BIT); + ENTRY (STRUCT); + ENTRY (UNION); + ENTRY (ENUM); + ENTRY (ELIPSIS); + ENTRY (RANGE); + ENTRY (FAR); + ENTRY (_XDATA); + ENTRY (_CODE); + ENTRY (_GENERIC); + ENTRY (_NEAR); + ENTRY (_PDATA); + ENTRY (_IDATA); + ENTRY (_EEPROM); + ENTRY (CASE); + ENTRY (DEFAULT); + ENTRY (IF); + ENTRY (ELSE); + ENTRY (SWITCH); + ENTRY (WHILE); + ENTRY (DO); + ENTRY (FOR); + ENTRY (GOTO); + ENTRY (CONTINUE); + ENTRY (BREAK); + ENTRY (RETURN); + ENTRY (INLINEASM); + ENTRY (IFX); + ENTRY (ADDRESS_OF); + ENTRY (GET_VALUE_AT_ADDRESS); + ENTRY (SPIL); + ENTRY (UNSPIL); + ENTRY (GETHBIT); + ENTRY (BITWISEAND); + ENTRY (UNARYMINUS); + ENTRY (IPUSH); + ENTRY (IPOP); + ENTRY (PCALL); + ENTRY (ENDFUNCTION); + ENTRY (JUMPTABLE); + ENTRY (RRC); + ENTRY (RLC); + ENTRY (CAST); + ENTRY (CALL); + ENTRY (PARAM); + ENTRY (NULLOP); + ENTRY (BLOCK); + ENTRY (LABEL); + ENTRY (RECEIVE); + ENTRY (SEND); default: - printf("default: %c", ret); + printf ("default: %c", ret); } - tmp = linebuf[linepos]; - linebuf[linepos] = '\0'; - printf(" for %s (%u bytes)\n", linebuf + lastpos, linepos - lastpos); - linebuf[linepos] = tmp; - lastpos = linepos; - fflush(stdout); + tmp = linebuf[linepos]; + linebuf[linepos] = '\0'; + printf (" for %s (%u bytes)\n", linebuf + lastpos, linepos - lastpos); + linebuf[linepos] = tmp; + lastpos = linepos; + fflush (stdout); #endif - return ret; + return ret; } #define TEST(_a) (_a) ? (void)0 : printf("Test %s failed\n", #_a); -int altlex_testparse(const char *input) +int +altlex_testparse (const char *input) { - /* Fiddle with the read-ahead buffer to insert ourselves */ - strcpy(linebuf, input); - linelen = strlen(linebuf)+1; - linepos = 0; - - return yylex(); + /* Fiddle with the read-ahead buffer to insert ourselves */ + strcpy (linebuf, input); + linelen = strlen (linebuf) + 1; + linepos = 0; + + return yylex (); } -int altlex_testchar(const char *input) +int +altlex_testchar (const char *input) { - value *val; - if (altlex_testparse(input) != CONSTANT) - return -2; - val = yylval.val; - if (val->type->class != SPECIFIER) - return -3; - if (SPEC_NOUN(val->type) != V_CHAR) - return -4; - if (SPEC_SCLS(val->type) != S_LITERAL) - return -5; - return SPEC_CVAL(val->type).v_int; + value *val; + if (altlex_testparse (input) != CONSTANT) + return -2; + val = yylval.val; + if (val->type->class != SPECIFIER) + return -3; + if (SPEC_NOUN (val->type) != V_CHAR) + return -4; + if (SPEC_SCLS (val->type) != S_LITERAL) + return -5; + return SPEC_CVAL (val->type).v_int; } -int altlex_testnum(const char *input) +int +altlex_testnum (const char *input) { - value *val; - if (altlex_testparse(input) != CONSTANT) - return -2; - val = yylval.val; - if (val->type->class != SPECIFIER) - return -3; - if (SPEC_NOUN(val->type) != V_INT) - return -4; - if (SPEC_SCLS(val->type) != S_LITERAL) - return -5; - if (SPEC_USIGN(val->type)) - return SPEC_CVAL(val->type).v_uint; - else - return SPEC_CVAL(val->type).v_int; + value *val; + if (altlex_testparse (input) != CONSTANT) + return -2; + val = yylval.val; + if (val->type->class != SPECIFIER) + return -3; + if (SPEC_NOUN (val->type) != V_INT) + return -4; + if (SPEC_SCLS (val->type) != S_LITERAL) + return -5; + if (SPEC_USIGN (val->type)) + return SPEC_CVAL (val->type).v_uint; + else + return SPEC_CVAL (val->type).v_int; } -int altlex_runtests(void) +int +altlex_runtests (void) { - /* These conditions are ripped directly from SDCC.lex */ - /* First check the parsing of the basic tokens */ - TEST(altlex_testparse(">>=") == RIGHT_ASSIGN); - TEST(altlex_testparse("<<=") == LEFT_ASSIGN); - TEST(altlex_testparse("+=") == ADD_ASSIGN); - TEST(altlex_testparse("-=") == SUB_ASSIGN); - TEST(altlex_testparse("*=") == MUL_ASSIGN); - TEST(altlex_testparse("/=") == DIV_ASSIGN); - TEST(altlex_testparse("%=") == MOD_ASSIGN); - TEST(altlex_testparse("&=") == AND_ASSIGN); - TEST(altlex_testparse("^=") == XOR_ASSIGN); - TEST(altlex_testparse("|=") == OR_ASSIGN); - TEST(altlex_testparse(">>") == RIGHT_OP); - TEST(altlex_testparse("<<") == LEFT_OP); - TEST(altlex_testparse("++") == INC_OP); - TEST(altlex_testparse("--") == DEC_OP); - TEST(altlex_testparse("->") == PTR_OP); - TEST(altlex_testparse("&&") == AND_OP); - TEST(altlex_testparse("||") == OR_OP); - TEST(altlex_testparse("<=") == LE_OP); - TEST(altlex_testparse(">=") == GE_OP); - TEST(altlex_testparse("==") == EQ_OP); - TEST(altlex_testparse("!=") == NE_OP); - TEST(altlex_testparse(";") == ';'); - TEST(altlex_testparse("{") == '{'); - TEST(altlex_testparse("}") == '}'); - TEST(altlex_testparse(",") == ','); - TEST(altlex_testparse(":") == ':'); - TEST(altlex_testparse("=") == '='); - TEST(altlex_testparse("(") == '('); - TEST(altlex_testparse(")") == ')'); - TEST(altlex_testparse("[") == '['); - TEST(altlex_testparse("]") == ']'); - TEST(altlex_testparse(".") == '.'); - TEST(altlex_testparse("&") == '&'); - TEST(altlex_testparse("!") == '!'); - TEST(altlex_testparse("~") == '~'); - TEST(altlex_testparse("-") == '-'); - TEST(altlex_testparse("+") == '+'); - TEST(altlex_testparse("*") == '*'); - TEST(altlex_testparse("/") == '/'); - TEST(altlex_testparse("%") == '%'); - TEST(altlex_testparse("<") == '<'); - TEST(altlex_testparse(">") == '>'); - TEST(altlex_testparse("^") == '^'); - TEST(altlex_testparse("|") == '|'); - TEST(altlex_testparse("?") == '?'); - - /* Now some character constants */ - TEST(altlex_testchar("'1'") == '1'); - TEST(altlex_testchar("'a'") == 'a'); - TEST(altlex_testchar("'A'") == 'A'); - TEST(altlex_testchar("'z'") == 'z'); - TEST(altlex_testchar("'Z'") == 'Z'); - TEST(altlex_testchar("'\n'") == '\n'); - TEST(altlex_testchar("'\\\\'") == '\\'); - TEST(altlex_testchar("'\\''") == '\''); - - /* And some numbers */ - TEST(altlex_testnum("0") == 0); - TEST(altlex_testnum("1") == 1); - TEST(altlex_testnum("075") == 075); - TEST(altlex_testnum("0xfeed") == 0xfeed); - TEST(altlex_testnum("0xFEED") == 0xFEED); - TEST(altlex_testnum("0x00005678") == 0x5678); - - /* Keywords */ - TEST(altlex_testparse("auto") == AUTO); - TEST(altlex_testparse("break") == BREAK); - TEST(altlex_testparse("case") == CASE); - TEST(altlex_testparse("char") == CHAR); - TEST(altlex_testparse("const") == CONST); - TEST(altlex_testparse("continue") == CONTINUE); - TEST(altlex_testparse("default") == DEFAULT); - TEST(altlex_testparse("do") == DO); - /* Prints a warning */ - // TEST(altlex_testparse("double") == FLOAT); - TEST(altlex_testparse("else") == ELSE); - TEST(altlex_testparse("enum") == ENUM); - TEST(altlex_testparse("extern") == EXTERN); - TEST(altlex_testparse("float") == FLOAT); - TEST(altlex_testparse("for") == FOR); - TEST(altlex_testparse("goto") == GOTO); - TEST(altlex_testparse("if") == IF); - TEST(altlex_testparse("int") == INT); - TEST(altlex_testparse("interrupt") == INTERRUPT); - TEST(altlex_testparse("long") == LONG); - TEST(altlex_testparse("register") == REGISTER); - TEST(altlex_testparse("return") == RETURN); - TEST(altlex_testparse("short") == SHORT); - TEST(altlex_testparse("signed") == SIGNED); - TEST(altlex_testparse("sizeof") == SIZEOF); - TEST(altlex_testparse("static") == STATIC); - TEST(altlex_testparse("struct") == STRUCT); - TEST(altlex_testparse("switch") == SWITCH); - TEST(altlex_testparse("typedef") == TYPEDEF); - TEST(altlex_testparse("union") == UNION); - TEST(altlex_testparse("unsigned") == UNSIGNED); - TEST(altlex_testparse("void") == VOID); - TEST(altlex_testparse("volatile") == VOLATILE); - TEST(altlex_testparse("while") == WHILE); - TEST(altlex_testparse("...") == VAR_ARGS); + /* These conditions are ripped directly from SDCC.lex */ + /* First check the parsing of the basic tokens */ + TEST (altlex_testparse (">>=") == RIGHT_ASSIGN); + TEST (altlex_testparse ("<<=") == LEFT_ASSIGN); + TEST (altlex_testparse ("+=") == ADD_ASSIGN); + TEST (altlex_testparse ("-=") == SUB_ASSIGN); + TEST (altlex_testparse ("*=") == MUL_ASSIGN); + TEST (altlex_testparse ("/=") == DIV_ASSIGN); + TEST (altlex_testparse ("%=") == MOD_ASSIGN); + TEST (altlex_testparse ("&=") == AND_ASSIGN); + TEST (altlex_testparse ("^=") == XOR_ASSIGN); + TEST (altlex_testparse ("|=") == OR_ASSIGN); + TEST (altlex_testparse (">>") == RIGHT_OP); + TEST (altlex_testparse ("<<") == LEFT_OP); + TEST (altlex_testparse ("++") == INC_OP); + TEST (altlex_testparse ("--") == DEC_OP); + TEST (altlex_testparse ("->") == PTR_OP); + TEST (altlex_testparse ("&&") == AND_OP); + TEST (altlex_testparse ("||") == OR_OP); + TEST (altlex_testparse ("<=") == LE_OP); + TEST (altlex_testparse (">=") == GE_OP); + TEST (altlex_testparse ("==") == EQ_OP); + TEST (altlex_testparse ("!=") == NE_OP); + TEST (altlex_testparse (";") == ';'); + TEST (altlex_testparse ("{") == '{'); + TEST (altlex_testparse ("}") == '}'); + TEST (altlex_testparse (",") == ','); + TEST (altlex_testparse (":") == ':'); + TEST (altlex_testparse ("=") == '='); + TEST (altlex_testparse ("(") == '('); + TEST (altlex_testparse (")") == ')'); + TEST (altlex_testparse ("[") == '['); + TEST (altlex_testparse ("]") == ']'); + TEST (altlex_testparse (".") == '.'); + TEST (altlex_testparse ("&") == '&'); + TEST (altlex_testparse ("!") == '!'); + TEST (altlex_testparse ("~") == '~'); + TEST (altlex_testparse ("-") == '-'); + TEST (altlex_testparse ("+") == '+'); + TEST (altlex_testparse ("*") == '*'); + TEST (altlex_testparse ("/") == '/'); + TEST (altlex_testparse ("%") == '%'); + TEST (altlex_testparse ("<") == '<'); + TEST (altlex_testparse (">") == '>'); + TEST (altlex_testparse ("^") == '^'); + TEST (altlex_testparse ("|") == '|'); + TEST (altlex_testparse ("?") == '?'); + + /* Now some character constants */ + TEST (altlex_testchar ("'1'") == '1'); + TEST (altlex_testchar ("'a'") == 'a'); + TEST (altlex_testchar ("'A'") == 'A'); + TEST (altlex_testchar ("'z'") == 'z'); + TEST (altlex_testchar ("'Z'") == 'Z'); + TEST (altlex_testchar ("'\n'") == '\n'); + TEST (altlex_testchar ("'\\\\'") == '\\'); + TEST (altlex_testchar ("'\\''") == '\''); + + /* And some numbers */ + TEST (altlex_testnum ("0") == 0); + TEST (altlex_testnum ("1") == 1); + TEST (altlex_testnum ("075") == 075); + TEST (altlex_testnum ("0xfeed") == 0xfeed); + TEST (altlex_testnum ("0xFEED") == 0xFEED); + TEST (altlex_testnum ("0x00005678") == 0x5678); + + /* Keywords */ + TEST (altlex_testparse ("auto") == AUTO); + TEST (altlex_testparse ("break") == BREAK); + TEST (altlex_testparse ("case") == CASE); + TEST (altlex_testparse ("char") == CHAR); + TEST (altlex_testparse ("const") == CONST); + TEST (altlex_testparse ("continue") == CONTINUE); + TEST (altlex_testparse ("default") == DEFAULT); + TEST (altlex_testparse ("do") == DO); + /* Prints a warning */ + // TEST(altlex_testparse("double") == FLOAT); + TEST (altlex_testparse ("else") == ELSE); + TEST (altlex_testparse ("enum") == ENUM); + TEST (altlex_testparse ("extern") == EXTERN); + TEST (altlex_testparse ("float") == FLOAT); + TEST (altlex_testparse ("for") == FOR); + TEST (altlex_testparse ("goto") == GOTO); + TEST (altlex_testparse ("if") == IF); + TEST (altlex_testparse ("int") == INT); + TEST (altlex_testparse ("interrupt") == INTERRUPT); + TEST (altlex_testparse ("long") == LONG); + TEST (altlex_testparse ("register") == REGISTER); + TEST (altlex_testparse ("return") == RETURN); + TEST (altlex_testparse ("short") == SHORT); + TEST (altlex_testparse ("signed") == SIGNED); + TEST (altlex_testparse ("sizeof") == SIZEOF); + TEST (altlex_testparse ("static") == STATIC); + TEST (altlex_testparse ("struct") == STRUCT); + TEST (altlex_testparse ("switch") == SWITCH); + TEST (altlex_testparse ("typedef") == TYPEDEF); + TEST (altlex_testparse ("union") == UNION); + TEST (altlex_testparse ("unsigned") == UNSIGNED); + TEST (altlex_testparse ("void") == VOID); + TEST (altlex_testparse ("volatile") == VOLATILE); + TEST (altlex_testparse ("while") == WHILE); + TEST (altlex_testparse ("...") == VAR_ARGS); #if 0 - /* Platform specific keywords */ - TEST(altlex_testparse("sram") ==) { count(); TKEYWORD(XDATA);} - TEST(altlex_testparse("using") ==) { count(); TKEYWORD(USING); } - TEST(altlex_testparse("near") ==) { count(); TKEYWORD(DATA);} - TEST(altlex_testparse("at") ==) { count(); TKEYWORD(AT) ; } - TEST(altlex_testparse("bit") ==) { count(); TKEYWORD(BIT) ; } - TEST(altlex_testparse("code") ==) { count(); TKEYWORD(CODE); } - TEST(altlex_testparse("critical") ==) { count(); TKEYWORD(CRITICAL); } - TEST(altlex_testparse("data") ==) { count(); TKEYWORD(DATA); } - TEST(altlex_testparse("far") ==) { count(); TKEYWORD(XDATA); } - TEST(altlex_testparse("eeprom") ==) { count(); TKEYWORD(EEPROM); } - TEST(altlex_testparse("flash") ==) { count(); TKEYWORD(CODE);} - TEST(altlex_testparse("idata") ==) { count(); TKEYWORD(IDATA);} - TEST(altlex_testparse("nonbanked") ==) { count(); TKEYWORD(NONBANKED);} - TEST(altlex_testparse("banked") ==) { count(); TKEYWORD(BANKED);} - TEST(altlex_testparse("pdata") ==) { count(); TKEYWORD(PDATA); } - TEST(altlex_testparse("reentrant") ==) { count(); TKEYWORD(REENTRANT);} - TEST(altlex_testparse("sfr") ==) { count(); TKEYWORD(SFR) ; } - TEST(altlex_testparse("sbit") ==) { count(); TKEYWORD(SBIT) ; } - TEST(altlex_testparse("xdata") ==) { count(); TKEYWORD(XDATA); } - TEST(altlex_testparse("_data") ==) { count(); TKEYWORD(_NEAR); } - TEST(altlex_testparse("_code") ==) { count(); TKEYWORD(_CODE); } - TEST(altlex_testparse("_eeprom") ==) { count(); TKEYWORD(_EEPROM); } - TEST(altlex_testparse("_flash") ==) { count(); TKEYWORD(_CODE); } - TEST(altlex_testparse("_generic") ==) { count(); TKEYWORD(_GENERIC); } - TEST(altlex_testparse("_near") ==) { count(); TKEYWORD(_NEAR); } - TEST(altlex_testparse("_sram") ==) { count(); TKEYWORD(_XDATA);} - TEST(altlex_testparse("_xdata") ==) { count(); TKEYWORD(_XDATA);} - TEST(altlex_testparse("_pdata") ==) { count(); TKEYWORD(_PDATA); } - TEST(altlex_testparse("_idata") ==) { count(); TKEYWORD(_IDATA); } + /* Platform specific keywords */ + TEST (altlex_testparse ("sram") ==) + { + count (); + TKEYWORD (XDATA); + } + TEST (altlex_testparse ("using") ==) + { + count (); + TKEYWORD (USING); + } + TEST (altlex_testparse ("near") ==) + { + count (); + TKEYWORD (DATA); + } + TEST (altlex_testparse ("at") ==) + { + count (); + TKEYWORD (AT); + } + TEST (altlex_testparse ("bit") ==) + { + count (); + TKEYWORD (BIT); + } + TEST (altlex_testparse ("code") ==) + { + count (); + TKEYWORD (CODE); + } + TEST (altlex_testparse ("critical") ==) + { + count (); + TKEYWORD (CRITICAL); + } + TEST (altlex_testparse ("data") ==) + { + count (); + TKEYWORD (DATA); + } + TEST (altlex_testparse ("far") ==) + { + count (); + TKEYWORD (XDATA); + } + TEST (altlex_testparse ("eeprom") ==) + { + count (); + TKEYWORD (EEPROM); + } + TEST (altlex_testparse ("flash") ==) + { + count (); + TKEYWORD (CODE); + } + TEST (altlex_testparse ("idata") ==) + { + count (); + TKEYWORD (IDATA); + } + TEST (altlex_testparse ("nonbanked") ==) + { + count (); + TKEYWORD (NONBANKED); + } + TEST (altlex_testparse ("banked") ==) + { + count (); + TKEYWORD (BANKED); + } + TEST (altlex_testparse ("pdata") ==) + { + count (); + TKEYWORD (PDATA); + } + TEST (altlex_testparse ("reentrant") ==) + { + count (); + TKEYWORD (REENTRANT); + } + TEST (altlex_testparse ("sfr") ==) + { + count (); + TKEYWORD (SFR); + } + TEST (altlex_testparse ("sbit") ==) + { + count (); + TKEYWORD (SBIT); + } + TEST (altlex_testparse ("xdata") ==) + { + count (); + TKEYWORD (XDATA); + } + TEST (altlex_testparse ("_data") ==) + { + count (); + TKEYWORD (_NEAR); + } + TEST (altlex_testparse ("_code") ==) + { + count (); + TKEYWORD (_CODE); + } + TEST (altlex_testparse ("_eeprom") ==) + { + count (); + TKEYWORD (_EEPROM); + } + TEST (altlex_testparse ("_flash") ==) + { + count (); + TKEYWORD (_CODE); + } + TEST (altlex_testparse ("_generic") ==) + { + count (); + TKEYWORD (_GENERIC); + } + TEST (altlex_testparse ("_near") ==) + { + count (); + TKEYWORD (_NEAR); + } + TEST (altlex_testparse ("_sram") ==) + { + count (); + TKEYWORD (_XDATA); + } + TEST (altlex_testparse ("_xdata") ==) + { + count (); + TKEYWORD (_XDATA); + } + TEST (altlex_testparse ("_pdata") ==) + { + count (); + TKEYWORD (_PDATA); + } + TEST (altlex_testparse ("_idata") ==) + { + count (); + TKEYWORD (_IDATA); + } #endif - return 0; + return 0; } diff --git a/src/asm.c b/src/asm.c index e18a60c4..8d92b377 100644 --- a/src/asm.c +++ b/src/asm.c @@ -15,288 +15,323 @@ static hTab *_h; -char * FileBaseName(char * fileFullName) +char * +FileBaseName (char *fileFullName) { - char * p = fileFullName; + char *p = fileFullName; - while (*fileFullName) { - if((*fileFullName=='/')||(*fileFullName=='\\')||(*fileFullName==':')) { - p = fileFullName; - p++; - } - fileFullName++; + while (*fileFullName) + { + if ((*fileFullName == '/') || (*fileFullName == '\\') || (*fileFullName == ':')) + { + p = fileFullName; + p++; } - return p; + fileFullName++; + } + return p; } -static const char *_findMapping(const char *szKey) +static const char * +_findMapping (const char *szKey) { - return shash_find(_h, szKey); + return shash_find (_h, szKey); } #if 0 -static void _iprintf(char *pInto, const char *sz, va_list *pap) +static void +_iprintf (char *pInto, const char *sz, va_list * pap) { - char format[MAX_TOKEN_LEN]; - char *pStart = pInto; - static int count; + char format[MAX_TOKEN_LEN]; + char *pStart = pInto; + static int count; - while (*sz) { - if (*sz == '%') { - switch (*++sz) { - /* See if it's a special emitter */ + while (*sz) + { + if (*sz == '%') + { + switch (*++sz) + { + /* See if it's a special emitter */ case 'r': - wassert(0); - break; - /* Name of the code segment */ + wassert (0); + break; + /* Name of the code segment */ case 'C': - strcpy(pInto, CODE_NAME); - pInto = pStart + strlen(pStart); - sz++; - break; + strcpy (pInto, CODE_NAME); + pInto = pStart + strlen (pStart); + sz++; + break; case 'F': - strcpy(pInto, srcFileName); - pInto = pStart + strlen(pStart); - sz++; - break; + strcpy (pInto, srcFileName); + pInto = pStart + strlen (pStart); + sz++; + break; case 'I': - sprintf(pInto, "%u", ++count); - pInto = pStart + strlen(pStart); - sz++; - break; + sprintf (pInto, "%u", ++count); + pInto = pStart + strlen (pStart); + sz++; + break; default: - { - /* Scan out the arg and pass it on to sprintf */ - char *p = format; - *p++ = '%'; - while (isdigit(*sz)) - *p++ = *sz++; - *p++ = *sz++; - *p = '\0'; - vsprintf(pInto, format, *pap); - /* PENDING: Assume that the arg length was an int */ - (void)va_arg(*pap, int); - } + { + /* Scan out the arg and pass it on to sprintf */ + char *p = format; + *p++ = '%'; + while (isdigit (*sz)) + *p++ = *sz++; + *p++ = *sz++; + *p = '\0'; + vsprintf (pInto, format, *pap); + /* PENDING: Assume that the arg length was an int */ + (void) va_arg (*pap, int); + } } - pInto = pStart + strlen(pStart); + pInto = pStart + strlen (pStart); } - else { - *pInto++ = *sz++; + else + { + *pInto++ = *sz++; } } - *pInto = '\0'; + *pInto = '\0'; } -void tvsprintf(char *buffer, const char *sz, va_list ap) +void +tvsprintf (char *buffer, const char *sz, va_list ap) { - char *pInto = buffer; - char *p; - char token[MAX_TOKEN_LEN]; + char *pInto = buffer; + char *p; + char token[MAX_TOKEN_LEN]; - buffer[0] = '\0'; - - while (*sz) { - if (*sz == '!') { - /* Start of a token. Search until the first - [non alplha, *] and call it a token. */ - const char *t; - p = token; - sz++; - while (isalpha(*sz) || *sz == '*') { - *p++ = *sz++; + buffer[0] = '\0'; + + while (*sz) + { + if (*sz == '!') + { + /* Start of a token. Search until the first + [non alplha, *] and call it a token. */ + const char *t; + p = token; + sz++; + while (isalpha (*sz) || *sz == '*') + { + *p++ = *sz++; } - *p = '\0'; - /* Now find the token in the token list */ - if ((t = _findMapping(token))) { - printf("tvsprintf: found token \"%s\" to \"%s\"\n", token, t); - _iprintf(pInto, t, &ap); - pInto = buffer + strlen(buffer); + *p = '\0'; + /* Now find the token in the token list */ + if ((t = _findMapping (token))) + { + printf ("tvsprintf: found token \"%s\" to \"%s\"\n", token, t); + _iprintf (pInto, t, &ap); + pInto = buffer + strlen (buffer); } - else { - fprintf(stderr, "Cant find token \"%s\"\n", token); - wassert(0); + else + { + fprintf (stderr, "Cant find token \"%s\"\n", token); + wassert (0); } } - else if (*sz == '%') { - p = token; - *p++ = *sz++; - while (!isalpha(*sz)) { - *p++ = *sz++; + else if (*sz == '%') + { + p = token; + *p++ = *sz++; + while (!isalpha (*sz)) + { + *p++ = *sz++; } - *p++ = *sz++; - *p = '\0'; - vsprintf(pInto, token, ap); - pInto = buffer + strlen(buffer); - (void)va_arg(ap, int); + *p++ = *sz++; + *p = '\0'; + vsprintf (pInto, token, ap); + pInto = buffer + strlen (buffer); + (void) va_arg (ap, int); } - else { - *pInto++ = *sz++; + else + { + *pInto++ = *sz++; } } - *pInto = '\0'; + *pInto = '\0'; } #else // Append a string onto another, and update the pointer to the end of // the new string. -static char *_appendAt(char *at, char *onto, const char *sz) +static char * +_appendAt (char *at, char *onto, const char *sz) { - wassert(at && onto && sz); - strcpy(at, sz); - return at + strlen(sz); + wassert (at && onto && sz); + strcpy (at, sz); + return at + strlen (sz); } -void tvsprintf(char *buffer, const char *format, va_list ap) +void +tvsprintf (char *buffer, const char *format, va_list ap) { - // Under Linux PPC va_list is a structure instead of a primitive type, - // and doesnt like being passed around. This version turns everything - // into one function. - - // Supports: - // !tokens - // %[CIF] - special formats with no argument (ie list isnt touched) - // All of the system formats + // Under Linux PPC va_list is a structure instead of a primitive type, + // and doesnt like being passed around. This version turns everything + // into one function. - // This is acheived by expanding the tokens and zero arg formats into - // one big format string, which is passed to the native printf. - static int count; - char newformat[MAX_INLINEASM]; - char *pInto = newformat; - char *p; - char token[MAX_TOKEN_LEN]; - const char *sz = format; + // Supports: + // !tokens + // %[CIF] - special formats with no argument (ie list isnt touched) + // All of the system formats - // NULL terminate it to let strlen work. - *pInto = '\0'; - - while (*sz) { - if (*sz == '!') { - /* Start of a token. Search until the first - [non alpha, *] and call it a token. */ - const char *t; - p = token; - sz++; - while (isalpha(*sz) || *sz == '*') { - *p++ = *sz++; + // This is acheived by expanding the tokens and zero arg formats into + // one big format string, which is passed to the native printf. + static int count; + char newformat[MAX_INLINEASM]; + char *pInto = newformat; + char *p; + char token[MAX_TOKEN_LEN]; + const char *sz = format; + + // NULL terminate it to let strlen work. + *pInto = '\0'; + + while (*sz) + { + if (*sz == '!') + { + /* Start of a token. Search until the first + [non alpha, *] and call it a token. */ + const char *t; + p = token; + sz++; + while (isalpha (*sz) || *sz == '*') + { + *p++ = *sz++; } - *p = '\0'; - /* Now find the token in the token list */ - if ((t = _findMapping(token))) { - pInto = _appendAt(pInto, newformat, t); + *p = '\0'; + /* Now find the token in the token list */ + if ((t = _findMapping (token))) + { + pInto = _appendAt (pInto, newformat, t); } - else { - fprintf(stderr, "Cant find token \"%s\"\n", token); - wassert(0); + else + { + fprintf (stderr, "Cant find token \"%s\"\n", token); + wassert (0); } } - else if (*sz == '%') { - // See if its one that we handle. - sz++; - switch (*sz) { + else if (*sz == '%') + { + // See if its one that we handle. + sz++; + switch (*sz) + { case 'C': - // Code segment name. - pInto = _appendAt(pInto, newformat, CODE_NAME); - break; + // Code segment name. + pInto = _appendAt (pInto, newformat, CODE_NAME); + break; case 'F': - // Source file name. - pInto = _appendAt(pInto, newformat, srcFileName); - break; - case 'I': { + // Source file name. + pInto = _appendAt (pInto, newformat, srcFileName); + break; + case 'I': + { // Unique ID. char id[20]; - sprintf(id, "%u", ++count); - pInto = _appendAt(pInto, newformat, id); + sprintf (id, "%u", ++count); + pInto = _appendAt (pInto, newformat, id); break; - } + } default: - // Not one of ours. Copy until the end. - *pInto++ = '%'; - while (!isalpha(*sz)) { - *pInto++ = *sz++; + // Not one of ours. Copy until the end. + *pInto++ = '%'; + while (!isalpha (*sz)) + { + *pInto++ = *sz++; } - *pInto++ = *sz++; + *pInto++ = *sz++; } } - else { - *pInto++ = *sz++; + else + { + *pInto++ = *sz++; } } - *pInto = '\0'; - - // Now do the actual printing - vsprintf(buffer, newformat, ap); + *pInto = '\0'; + + // Now do the actual printing + vsprintf (buffer, newformat, ap); } #endif -void tfprintf(FILE *fp, const char *szFormat, ...) +void +tfprintf (FILE * fp, const char *szFormat,...) { - va_list ap; - char buffer[MAX_INLINEASM]; + va_list ap; + char buffer[MAX_INLINEASM]; - va_start(ap, szFormat); - tvsprintf(buffer, szFormat, ap); - fputs(buffer, fp); + va_start (ap, szFormat); + tvsprintf (buffer, szFormat, ap); + fputs (buffer, fp); } -void tsprintf(char *buffer, const char *szFormat, ...) +void +tsprintf (char *buffer, const char *szFormat,...) { - va_list ap; - va_start(ap, szFormat); - tvsprintf(buffer, szFormat, ap); + va_list ap; + va_start (ap, szFormat); + tvsprintf (buffer, szFormat, ap); } -void asm_addTree(const ASM_MAPPINGS *pMappings) +void +asm_addTree (const ASM_MAPPINGS * pMappings) { - const ASM_MAPPING *pMap; - /* Traverse down first */ - if (pMappings->pParent) - asm_addTree(pMappings->pParent); - pMap = pMappings->pMappings; - while (pMap->szKey && pMap->szValue) { - shash_add(&_h, pMap->szKey, pMap->szValue); - pMap++; + const ASM_MAPPING *pMap; + /* Traverse down first */ + if (pMappings->pParent) + asm_addTree (pMappings->pParent); + pMap = pMappings->pMappings; + while (pMap->szKey && pMap->szValue) + { + shash_add (&_h, pMap->szKey, pMap->szValue); + pMap++; } } -static const ASM_MAPPING _asxxxx_mapping[] = { - { "labeldef", "%s::" }, - { "slabeldef", "%s:" }, - { "tlabeldef", "%05d$:" }, - { "tlabel", "%05d$" }, - { "immed", "#" }, - { "zero", "#0x00" }, - { "one", "#0x01" }, - { "area", ".area %s" }, - { "areacode", ".area %s" }, - { "areadata", ".area %s" }, - { "areahome", ".area %s" }, - { "ascii", ".ascii \"%s\"" }, - { "ds", ".ds %d" }, - { "db", ".db" }, - { "dbs", ".db %s" }, - { "dw", ".dw" }, - { "dws", ".dw %s" }, - { "constbyte", "0x%02X" }, - { "constword", "0x%04X" }, - { "immedword", "#0x%04X" }, - { "immedbyte", "#0x%02X" }, - { "hashedstr", "#%s" }, - { "lsbimmeds", "#<%s" }, - { "msbimmeds", "#>%s" }, - { "module", ".module %s" }, - { "global", ".globl %s" }, - { "fileprelude", "" }, - { "functionheader", - "; ---------------------------------\n" - "; Function %s\n" - "; ---------------------------------" - }, - { "functionlabeldef", "%s:" }, - { "bankimmeds", "0 ; PENDING: bank support" }, - { NULL, NULL } +static const ASM_MAPPING _asxxxx_mapping[] = +{ + {"labeldef", "%s::"}, + {"slabeldef", "%s:"}, + {"tlabeldef", "%05d$:"}, + {"tlabel", "%05d$"}, + {"immed", "#"}, + {"zero", "#0x00"}, + {"one", "#0x01"}, + {"area", ".area %s"}, + {"areacode", ".area %s"}, + {"areadata", ".area %s"}, + {"areahome", ".area %s"}, + {"ascii", ".ascii \"%s\""}, + {"ds", ".ds %d"}, + {"db", ".db"}, + {"dbs", ".db %s"}, + {"dw", ".dw"}, + {"dws", ".dw %s"}, + {"constbyte", "0x%02X"}, + {"constword", "0x%04X"}, + {"immedword", "#0x%04X"}, + {"immedbyte", "#0x%02X"}, + {"hashedstr", "#%s"}, + {"lsbimmeds", "#<%s"}, + {"msbimmeds", "#>%s"}, + {"module", ".module %s"}, + {"global", ".globl %s"}, + {"fileprelude", ""}, + {"functionheader", + "; ---------------------------------\n" + "; Function %s\n" + "; ---------------------------------" + }, + {"functionlabeldef", "%s:"}, + {"bankimmeds", "0 ; PENDING: bank support"}, + {NULL, NULL} }; -const ASM_MAPPINGS asm_asxxxx_mapping = { - NULL, - _asxxxx_mapping +const ASM_MAPPINGS asm_asxxxx_mapping = +{ + NULL, + _asxxxx_mapping }; - diff --git a/src/asm.h b/src/asm.h index 5e773280..7a0431d4 100644 --- a/src/asm.h +++ b/src/asm.h @@ -1,23 +1,26 @@ #ifndef ASM_PORT_INCLUDE #define ASM_PORT_INCLUDE -void tfprintf(FILE *fp, const char *szFormat, ...); -void tsprintf(char *buffer, const char *szFormat, ...); -void tvsprintf(char *buffer, const char *szFormat, va_list ap); +void tfprintf (FILE * fp, const char *szFormat,...); +void tsprintf (char *buffer, const char *szFormat,...); +void tvsprintf (char *buffer, const char *szFormat, va_list ap); -typedef struct { +typedef struct + { const char *szKey; const char *szValue; -} ASM_MAPPING; + } +ASM_MAPPING; typedef struct _ASM_MAPPINGS ASM_MAPPINGS; /* PENDING: could include the peephole rules here as well. -*/ -struct _ASM_MAPPINGS { + */ +struct _ASM_MAPPINGS + { const ASM_MAPPINGS *pParent; const ASM_MAPPING *pMappings; -}; + }; /* The default asxxxx token mapping. */ @@ -25,8 +28,8 @@ extern const ASM_MAPPINGS asm_asxxxx_mapping; /** Last entry has szKey = NULL. */ -void asm_addTree(const ASM_MAPPINGS *pMappings); +void asm_addTree (const ASM_MAPPINGS * pMappings); -char * FileBaseName(char * fileFullName); +char *FileBaseName (char *fileFullName); #endif diff --git a/src/port.h b/src/port.h index b9aa3b6f..57aebe82 100644 --- a/src/port.h +++ b/src/port.h @@ -6,14 +6,16 @@ #define PORT_INCLUDE /* Processor specific names */ -typedef struct { - /** Target name used for -m */ +typedef struct + { +/** Target name used for -m */ const char *target; - /** Target name string, used for --help */ +/** Target name string, used for --help */ const char *target_name; - struct { + struct + { /** TRUE if all types of glue functions should be inseted into the file that also defines main. We dont want this in cases like the z80 where the startup @@ -23,37 +25,45 @@ typedef struct { /* OR of MODEL_* */ int supported_models; int default_model; - } general; + } + general; /* assembler related information */ - struct { - /** Command to run and arguments (eg as-z80) */ + struct + { +/** Command to run and arguments (eg as-z80) */ const char **cmd; - /** Arguments for debug mode. PENDING: ignored */ +/** Arguments for debug mode. PENDING: ignored */ const char *debug_opts; - /** Arguments for normal assembly mode. PENDING: ignored */ +/** Arguments for normal assembly mode. PENDING: ignored */ const char *plain_opts; /* print externs as global */ int externGlobal; - } assembler; + } + assembler; /* linker related info */ - struct { - /** Command to run (eg link-z80) */ + struct + { +/** Command to run (eg link-z80) */ const char **cmd; - /** If non-null will be used to execute the link. */ - void (*do_link)(void); - /** Extention for object files (.rel, .obj, ...) */ +/** If non-null will be used to execute the link. */ + void (*do_link) (void); +/** Extention for object files (.rel, .obj, ...) */ const char *rel_ext; - } linker; + } + linker; - struct { - /** Default peephole rules */ + struct + { +/** Default peephole rules */ char *default_rules; - } peep; + } + peep; - /** Basic type sizes */ - struct { +/** Basic type sizes */ + struct + { int char_size; int short_size; int int_size; @@ -64,10 +74,12 @@ typedef struct { int bit_size; int float_size; int max_base_size; - } s; + } + s; - /** memory regions related stuff */ - struct { +/** memory regions related stuff */ + struct + { const char *xstack_name; const char *istack_name; const char *code_name; @@ -80,29 +92,33 @@ typedef struct { const char *overlay_name; const char *post_static_name; const char *home_name; - struct memmap *default_local_map ; /* default location for auto vars */ - struct memmap *default_globl_map ; /* default location for globl vars*/ - int code_ro; /* code space read-only 1=yes */ - } mem; - + struct memmap *default_local_map; /* default location for auto vars */ + struct memmap *default_globl_map; /* default location for globl vars */ + int code_ro; /* code space read-only 1=yes */ + } + mem; + /* stack related information */ - struct { - /** -1 for grows down (z80), +1 for grows up (mcs51) */ + struct + { +/** -1 for grows down (z80), +1 for grows up (mcs51) */ int direction; - /** Extra overhead when calling between banks */ +/** Extra overhead when calling between banks */ int bank_overhead; - /** Extra overhead when the function is an ISR */ +/** Extra overhead when the function is an ISR */ int isr_overhead; - /** Standard overhead for a function call */ +/** Standard overhead for a function call */ int call_overhead; - /** Re-enterant space */ +/** Re-enterant space */ int reent_overhead; /** 'banked' call overhead. Mild overlap with bank_overhead */ int banked_overhead; - } stack; + } + stack; - struct { + struct + { /** One more than the smallest mul/div operation the processor can do nativley Eg if the processor has an 8 bit mul, nativebelow is 2 */ @@ -111,69 +127,71 @@ typedef struct { for sizeof(param) < log2(force_reg) i.e. Use 2 for WORD and BYTE, 0 for none. */ int force_reg_param_below; - } muldiv; + } + muldiv; - /** Prefix to add to a C function (eg "_") */ +/** Prefix to add to a C function (eg "_") */ const char *fun_prefix; /** Called once the processor target has been selected. First chance to initalise and set any port specific varibles. 'port' is set before calling this. May be NULL. */ - void (*init)(void); - /** Parses one option + its arguments */ - bool (*parseOption)(int *pargc, char **argv, int *i); - /** Called after all the options have been parsed. */ - void (*finaliseOptions)(void); + void (*init) (void); +/** Parses one option + its arguments */ + bool (*parseOption) (int *pargc, char **argv, int *i); +/** Called after all the options have been parsed. */ + void (*finaliseOptions) (void); /** Called after the port has been selected but before any options are parsed. */ - void (*setDefaultOptions)(void); - /** Does the dirty work. */ - void (*assignRegisters)(struct eBBlock **, int); - + void (*setDefaultOptions) (void); +/** Does the dirty work. */ + void (*assignRegisters) (struct eBBlock **, int); + /** Returns the register name of a symbol. Used so that 'regs' can be an incomplete type. */ - const char *(*getRegName)(struct regs *reg); + const char *(*getRegName) (struct regs * reg); /* list of keywords that are used by this target (used by lexer) */ - char **keywords; - + char **keywords; + /* Write any port specific assembler output. */ - void (*genAssemblerPreamble)(FILE *of); - + void (*genAssemblerPreamble) (FILE * of); + /* Write the port specific IVT. If genIVT is NULL or if * it returns zero, default (8051) IVT generation code * will be used. */ - int (*genIVT)(FILE *of, symbol **intTable, int intCount); + int (*genIVT) (FILE * of, symbol ** intTable, int intCount); /* parameter passing in register related functions */ - void (*reset_regparms)(); /* reset the register count */ - int (*reg_parm)(struct sym_link *); /* will return 1 if can be passed in register */ + void (*reset_regparms) (); /* reset the register count */ + int (*reg_parm) (struct sym_link *); /* will return 1 if can be passed in register */ /** Process the pragma string 'sz'. Returns 0 if recognised and processed, 1 otherwise. May be NULL. */ - int (*process_pragma)(const char *sz); + int (*process_pragma) (const char *sz); /** If TRUE, then tprintf and !dw will be used for some initalisers */ bool use_dw_for_init; /* condition transformations */ - bool lt_nge ; /* transform (a < b) to !(a >= b) */ - bool gt_nle ; /* transform (a > b) to !(a <= b) */ - bool le_ngt ; /* transform (a <= b) to !(a > b) */ - bool ge_nlt ; /* transform (a >= b) to !(a < b) */ - bool ne_neq ; /* transform a != b --> ! (a == b) */ - bool eq_nne ; /* transform a == b --> ! (a != b) */ + bool lt_nge; /* transform (a < b) to !(a >= b) */ + bool gt_nle; /* transform (a > b) to !(a <= b) */ + bool le_ngt; /* transform (a <= b) to !(a > b) */ + bool ge_nlt; /* transform (a >= b) to !(a < b) */ + bool ne_neq; /* transform a != b --> ! (a == b) */ + bool eq_nne; /* transform a == b --> ! (a != b) */ #define PORT_MAGIC 0xAC32 - /** Used at runtime to detect if this structure has been completly filled in. */ +/** Used at runtime to detect if this structure has been completly filled in. */ int magic; -} PORT; + } +PORT; extern PORT *port; diff --git a/src/spawn.c b/src/spawn.c index e7c27168..3c85169e 100644 --- a/src/spawn.c +++ b/src/spawn.c @@ -26,20 +26,21 @@ sequence which doesn't work for djgpp. ***************************************************************************/ -int spawnv(int mode, const char *path, char *const argv[]) +int +spawnv (int mode, const char *path, char *const argv[]) { - int pStatus; + int pStatus; - if (mode==P_OVERLAY) - return execv(path,argv); - if (!fork()) - { - if (execv(path,argv)) - return -1; - } - if (mode==P_WAIT) - wait(&pStatus); - return 0; + if (mode == P_OVERLAY) + return execv (path, argv); + if (!fork ()) + { + if (execv (path, argv)) + return -1; + } + if (mode == P_WAIT) + wait (&pStatus); + return 0; } /**[txh]******************************************************************** @@ -49,20 +50,21 @@ int spawnv(int mode, const char *path, char *const argv[]) ***************************************************************************/ -int spawnvp(int mode, const char *path, char *const argv[]) +int +spawnvp (int mode, const char *path, char *const argv[]) { - int pStatus; + int pStatus; - if (mode==P_OVERLAY) - return execv(path,argv); - if (!fork()) - { - if (execvp(path,argv)) - return -1; - } - if (mode==P_WAIT) - wait(&pStatus); - return 0; + if (mode == P_OVERLAY) + return execv (path, argv); + if (!fork ()) + { + if (execvp (path, argv)) + return -1; + } + if (mode == P_WAIT) + wait (&pStatus); + return 0; } #endif #endif diff --git a/src/spawn.h b/src/spawn.h index 4d0be572..3e700dc5 100644 --- a/src/spawn.h +++ b/src/spawn.h @@ -3,11 +3,11 @@ #include #else /* Specially defined for UNIX and Cygwin */ -int spawnv(int mode, const char *path, char *const argv[]); -int spawnvp(int mode, const char *path, char *const argv[]); +int spawnv (int mode, const char *path, char *const argv[]); +int spawnvp (int mode, const char *path, char *const argv[]); #define P_WAIT 1 -#define P_NOWAIT 2 /* always generates error for DJGPP! */ +#define P_NOWAIT 2 /* always generates error for DJGPP! */ #define P_OVERLAY 3 #endif -- 2.30.2