{
newic = newiCode (IPUSH, right, NULL);
newic->parmPush = 1;
- bytesPushed+=4;
+ //bytesPushed+=4;
+ bytesPushed += getSize(operandType(right));
}
addiCodeToeBBlock (ebp, newic, ip);
{
newic = newiCode (IPUSH, left, NULL);
newic->parmPush = 1;
- bytesPushed+=4;
+ //bytesPushed+=4;
+ bytesPushed += getSize(operandType(left));
}
addiCodeToeBBlock (ebp, newic, ip);
newic->lineno = lineno;
sym_link *type = operandType (IC_RIGHT (ic));
int linenno = ic->lineno;
int bwd, su;
+ int bytesPushed=0;
ip = ic->next;
/* remove it from the iCode */
{
newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
newic->parmPush = 1;
+ bytesPushed += getSize(operandType(IC_RIGHT(ic)));
}
addiCodeToeBBlock (ebp, newic, ip);
newic->lineno = linenno;
/* make the call */
newic = newiCode (CALL, operandFromSymbol (func), NULL);
IC_RESULT (newic) = IC_RESULT (ic);
+ newic->parmBytes+=bytesPushed;
addiCodeToeBBlock (ebp, newic, ip);
newic->lineno = linenno;
sym_link *type = operandType (IC_LEFT (ic));
int lineno = ic->lineno;
int bwd, su;
+ int bytesPushed=0;
ip = ic->next;
/* remove it from the iCode */
{
newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
newic->parmPush = 1;
+ bytesPushed += getSize(operandType(IC_RIGHT(ic)));
}
addiCodeToeBBlock (ebp, newic, ip);
newic->lineno = lineno;
/* make the call */
newic = newiCode (CALL, operandFromSymbol (func), NULL);
IC_RESULT (newic) = IC_RESULT (ic);
+ newic->parmBytes+=bytesPushed;
addiCodeToeBBlock (ebp, newic, ip);
newic->lineno = lineno;
}
+extern operand *geniCodeRValue (operand *, bool);
+
/*-----------------------------------------------------------------*/
/* convilong - converts int or long mults or divs to fcalls */
/*-----------------------------------------------------------------*/
int su;
int bytesPushed=0;
- remiCodeFromeBBlock (ebp, ic);
-
+ // Easy special case which avoids function call: modulo by a literal power
+ // of two can be replaced by a bitwise AND.
+ if (op == '%' && isOperandLiteral(IC_RIGHT(ic)))
+ {
+ unsigned litVal = (unsigned)(operandLitValue(IC_RIGHT(ic)));
+
+ // See if literal value is a power of 2.
+ while (litVal && !(litVal & 1))
+ {
+ litVal >>= 1;
+ }
+ if (litVal)
+ {
+ // discard first high bit set.
+ litVal >>= 1;
+ }
+
+ if (!litVal)
+ {
+ ic->op = BITWISEAND;
+ IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) - 1);
+ return;
+ }
+ }
+
+ remiCodeFromeBBlock (ebp, ic);
+
+
/* depending on the type */
for (bwd = 0; bwd < 3; bwd++)
{
if (SKIP_IC (ic) ||
ic->op == IFX ||
- ic->op == RETURN)
+ ic->op == RETURN ||
+ ic->op == DUMMY_READ_VOLATILE ||
+ ic->op == CRITICAL ||
+ ic->op == ENDCRITICAL)
continue;
/* if the result is volatile then continue */
/* if the result is a temp & isaddr then skip */
if (IC_RESULT (ic) && POINTER_SET (ic))
continue;
+
+ if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next))
+ continue;
/* if the result is used in the remainder of the */
/* block then skip */
continue;
kill = 1;
- }
+ }
kill:
/* kill this one if required */
dumpEbbsToFileExt (DUMP_RAW1, ebbs, count);
/* do common subexpression elimination for each block */
- change = cseAllBlocks (ebbs, saveCount);
+ change = cseAllBlocks (ebbs, saveCount, FALSE);
/* dumpraw if asked for */
if (options.dump_raw)
/* global common subexpression elimination */
if (optimize.global_cse)
{
- change += cseAllBlocks (ebbs, saveCount);
+ change += cseAllBlocks (ebbs, saveCount, FALSE);
if (options.dump_gcse)
dumpEbbsToFileExt (DUMP_GCSE, ebbs, saveCount);
}
+ else
+ {
+ // compute the dataflow only
+ assert(cseAllBlocks (ebbs, saveCount, TRUE)==0);
+ }
/* kill dead code */
kchange = killDeadCode (ebbs, saveCount);
if (lchange || kchange)
{
computeDataFlow (ebbs, saveCount);
- change += cseAllBlocks (ebbs, saveCount);
+ change += cseAllBlocks (ebbs, saveCount, FALSE);
if (options.dump_loop)
dumpEbbsToFileExt (DUMP_LOOPG, ebbs, count);
}
- // this is a good place to check missing return values
- if (currFunc) {
- if (!IS_VOID(currFunc->type->next)) {
- eBBlock *bp;
- // make sure all predecessors of the last block end in a return
- for (bp=setFirstItem(ebbs[saveCount-1]->predList);
- bp;
- bp=setNextItem(ebbs[saveCount-1]->predList)) {
- if (bp->ech->op != RETURN) {
- werror (W_VOID_FUNC, currFunc->name);
+ /* sort it back by block number */
+ qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare);
+
+ if (!options.lessPedantic) {
+ // this is a good place to check missing return values
+ if (currFunc) {
+ // the user is on his own with naked functions...
+ if (!IS_VOID(currFunc->etype)
+ && !FUNC_ISNAKED(currFunc->type)) {
+ eBBlock *bp;
+ // make sure all predecessors of the last block end in a return
+ for (bp=setFirstItem(ebbs[saveCount-1]->predList);
+ bp;
+ bp=setNextItem(ebbs[saveCount-1]->predList)) {
+ if (bp->ech->op != RETURN) {
+ werror (W_VOID_FUNC, currFunc->name);
+ }
}
}
}
}
- /* sort it back by block number */
- qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare);
-
/* if cyclomatic info requested then print it */
if (options.cyclomatic)
printCyclomatic (ebbs, saveCount);
port->assignRegisters (ebbs, count);
/* throw away blocks */
- setToNull ((void **) &graphEdges);
+ setToNull ((void *) &graphEdges);
ebbs = NULL;
- currFunc=NULL;
-
return NULL;
}