From c2669053120ee399168b6a7c44e7087abb0115b7 Mon Sep 17 00:00:00 2001 From: sdattalo Date: Fri, 31 May 2002 04:14:11 +0000 Subject: [PATCH] PIC Port - fixed pointer/array accesses. Stream line comparisons. Started function inlining. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2019 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- src/pic/gen.c | 1111 ++++++++++++++++++++---------------- src/pic/genarith.c | 5 +- src/pic/glue.c | 10 +- src/pic/pcode.c | 499 +++++++++++----- src/pic/pcode.h | 33 +- src/pic/pcodepeep.c | 186 ++++-- src/regression/compare10.c | 34 ++ src/regression/compare7.c | 36 ++ src/regression/compare8.c | 35 ++ src/regression/compare9.c | 34 ++ src/regression/pointer1.c | 63 ++ 11 files changed, 1352 insertions(+), 694 deletions(-) diff --git a/src/pic/gen.c b/src/pic/gen.c index 8b4c6d57..71f087db 100644 --- a/src/pic/gen.c +++ b/src/pic/gen.c @@ -587,33 +587,35 @@ static asmop *aopForRemat (operand *op) // x symbol *sym) ic = sym->rematiCode; - DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__); - - for (;;) { - if (ic->op == '+') { - val += (int) operandLitValue(IC_RIGHT(ic)); - } else if (ic->op == '-') { - val -= (int) operandLitValue(IC_RIGHT(ic)); - } else - break; + DEBUGpic14_emitcode(";","%s %d",__FUNCTION__,__LINE__); + if(IS_OP_POINTER(op)) { + DEBUGpic14_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__); + } + for (;;) { + if (ic->op == '+') { + val += (int) operandLitValue(IC_RIGHT(ic)); + } else if (ic->op == '-') { + val -= (int) operandLitValue(IC_RIGHT(ic)); + } else + break; - ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode; - } + ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode; + } - offset = OP_SYMBOL(IC_LEFT(ic))->offset; - aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val); - PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op)); - PCOI(aop->aopu.pcop)->index = val; + offset = OP_SYMBOL(IC_LEFT(ic))->offset; + aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val); + PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op)); + PCOI(aop->aopu.pcop)->index = val; - DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d", - OP_SYMBOL(IC_LEFT(ic))->rname, - val, IS_PTR_CONST(operandType(op))); + DEBUGpic14_emitcode(";"," rname %s, val %d, const = %d", + OP_SYMBOL(IC_LEFT(ic))->rname, + val, IS_PTR_CONST(operandType(op))); - // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic)))); + // DEBUGpic14_emitcode(";","aop type %s",AopType(AOP_TYPE(IC_LEFT(ic)))); - allocDirReg (IC_LEFT(ic)); + allocDirReg (IC_LEFT(ic)); - return aop; + return aop; } int aopIdx (asmop *aop, int offset) @@ -2340,7 +2342,6 @@ static void genCall (iCode *ic) aopOp(IC_LEFT(sic),sic,FALSE); size = AOP_SIZE(IC_LEFT(sic)); - while (size--) { DEBUGpic14_emitcode ("; ","%d left %s",__LINE__, AopType(AOP_TYPE(IC_LEFT(sic)))); @@ -3583,12 +3584,12 @@ static void genSkipc(resolvedIfx *rifx) /*-----------------------------------------------------------------*/ /* genSkipz2 */ /*-----------------------------------------------------------------*/ -static void genSkipz2(resolvedIfx *rifx) +static void genSkipz2(resolvedIfx *rifx, int invert_condition) { if(!rifx) return; - if(rifx->condition) + if( (rifx->condition ^ invert_condition) & 1) emitSKPZ; else emitSKPNZ; @@ -3681,13 +3682,36 @@ static void genCmp (operand *left,operand *right, symbol *truelbl; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(ifx) { - DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true")); - DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true")); + DEBUGpic14_emitcode ("; ***","true ifx is %s",((IC_TRUE(ifx) == NULL) ? "false" : "true")); + DEBUGpic14_emitcode ("; ***","false ifx is %s",((IC_FALSE(ifx) == NULL) ? "false" : "true")); } resolveIfx(&rFalseIfx,ifx); truelbl = newiTempLabel(NULL); + size = max(AOP_SIZE(left),AOP_SIZE(right)); + +#define _swapp + + /* if literal is on the right then swap with left */ + if ((AOP_TYPE(right) == AOP_LIT)) { + operand *tmp = right ; + unsigned long mask = (0x100 << (8*(size-1))) - 1; + lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); +#ifdef _swapp + DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x",__LINE__,lit); + lit = (lit - 1) & mask; + DEBUGpic14_emitcode ("; ***","%d swapping left&right, lit =0x%x, mask 0x%x",__LINE__,lit,mask); + + right = left; + left = tmp; + rFalseIfx.condition ^= 1; +#endif + + } else if ((AOP_TYPE(left) == AOP_LIT)) { + lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit); + } + //if(IC_TRUE(ifx) == NULL) /* if left & right are bit variables */ @@ -3699,526 +3723,590 @@ static void genCmp (operand *left,operand *right, /* subtract right from left if at the end the carry flag is set then we know that left is greater than right */ - size = max(AOP_SIZE(left),AOP_SIZE(right)); - /* if unsigned char cmp with lit, do cjne left,#right,zz */ - //if((size == 1) && !sign && - // (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR )){ - // symbol *lbl = newiTempLabel(NULL); - // pic14_emitcode("cjne","%s,%s,%05d_DS_", - // aopGet(AOP(left),offset,FALSE,FALSE), - // aopGet(AOP(right),offset,FALSE,FALSE), - // lbl->key+100); - //pic14_emitcode("","%05d_DS_:",lbl->key+100); - //} else - { + // { - symbol *lbl = newiTempLabel(NULL); + symbol *lbl = newiTempLabel(NULL); - if(AOP_TYPE(right) == AOP_LIT) { +#ifndef _swapp + if(AOP_TYPE(right) == AOP_LIT) { - lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); + //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign); + DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign); - /* special cases */ + /* special cases */ - if(lit == 0) { + if(lit == 0) { - if(sign != 0) - genSkipCond(&rFalseIfx,left,size-1,7); - else - /* no need to compare to 0...*/ - /* NOTE: this is a de-generate compare that most certainly - * creates some dead code. */ - emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key)); + if(sign != 0) + genSkipCond(&rFalseIfx,left,size-1,7); + else + /* no need to compare to 0...*/ + /* NOTE: this is a de-generate compare that most certainly + * creates some dead code. */ + emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key)); - if(ifx) ifx->generated = 1; - return; + if(ifx) ifx->generated = 1; + return; - } - size--; + } + size--; - if(size == 0) { - //i = (lit >> (size*8)) & 0xff; - DEBUGpic14_emitcode(";right lit","line = %d",__LINE__); + if(size == 0) { + //i = (lit >> (size*8)) & 0xff; + DEBUGpic14_emitcode(";right lit","line = %d",__LINE__); - emitpcode(POC_MOVFW, popGet(AOP(left),size)); - - i = ((0-lit) & 0xff); - if(sign) { - if( i == 0x81) { - /* lit is 0x7f, all signed chars are less than - * this except for 0x7f itself */ - emitpcode(POC_XORLW, popGetLit(0x7f)); - genSkipz2(&rFalseIfx); - } else { - emitpcode(POC_ADDLW, popGetLit(0x80)); - emitpcode(POC_ADDLW, popGetLit(i^0x80)); - genSkipc(&rFalseIfx); - } + emitpcode(POC_MOVFW, popGet(AOP(left),size)); + i = ((0-lit) & 0xff); + if(sign) { + if( i == 0x81) { + /* lit is 0x7f, all signed chars are less than + * this except for 0x7f itself */ + emitpcode(POC_XORLW, popGetLit(0x7f)); + genSkipz2(&rFalseIfx,0); } else { - emitpcode(POC_ADDLW, popGetLit(i)); + emitpcode(POC_ADDLW, popGetLit(0x80)); + emitpcode(POC_ADDLW, popGetLit(i^0x80)); genSkipc(&rFalseIfx); + } + } else { + if(lit == 1) { + genSkipz2(&rFalseIfx,1); + } else { + emitpcode(POC_ADDLW, popGetLit(i)); + genSkipc(&rFalseIfx); } + } + + if(ifx) ifx->generated = 1; + return; + } + + /* chars are out of the way. now do ints and longs */ + + DEBUGpic14_emitcode(";right lit","line = %d",__LINE__); + + /* special cases */ + + if(sign) { + + if(lit == 0) { + genSkipCond(&rFalseIfx,left,size,7); if(ifx) ifx->generated = 1; return; } - /* chars are out of the way. now do ints and longs */ + if(lit <0x100) { + DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); + //rFalseIfx.condition ^= 1; + //genSkipCond(&rFalseIfx,left,size,7); + //rFalseIfx.condition ^= 1; - DEBUGpic14_emitcode(";right lit","line = %d",__LINE__); - - /* special cases */ + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0)); + if(rFalseIfx.condition) + emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); + else + emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - if(sign) { + emitpcode(POC_MOVLW, popGetLit(0x100-lit)); + emitpcode(POC_ADDFW, popGet(AOP(left),0)); + emitpcode(POC_MOVFW, popGet(AOP(left),1)); - if(lit == 0) { - genSkipCond(&rFalseIfx,left,size,7); - if(ifx) ifx->generated = 1; - return; - } + while(size > 1) + emitpcode(POC_IORFW, popGet(AOP(left),size--)); - if(lit <0x100) { - DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); + if(rFalseIfx.condition) { + emitSKPZ; + emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - //rFalseIfx.condition ^= 1; - //genSkipCond(&rFalseIfx,left,size,7); - //rFalseIfx.condition ^= 1; + } else { + emitSKPNZ; + } - emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0)); - if(rFalseIfx.condition) - emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); - else - emitpcode(POC_GOTO, popGetLabel(truelbl->key)); + genSkipc(&rFalseIfx); + emitpLabel(truelbl->key); + if(ifx) ifx->generated = 1; + return; - emitpcode(POC_MOVLW, popGetLit(0x100-lit)); - emitpcode(POC_ADDFW, popGet(AOP(left),0)); - emitpcode(POC_MOVFW, popGet(AOP(left),1)); + } - while(size > 1) - emitpcode(POC_IORFW, popGet(AOP(left),size--)); + if(size == 1) { - if(rFalseIfx.condition) { - emitSKPZ; - emitpcode(POC_GOTO, popGetLabel(truelbl->key)); + if( (lit & 0xff) == 0) { + /* lower byte is zero */ + DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); + i = ((lit >> 8) & 0xff) ^0x80; + emitpcode(POC_MOVFW, popGet(AOP(left),size)); + emitpcode(POC_ADDLW, popGetLit( 0x80)); + emitpcode(POC_ADDLW, popGetLit(0x100-i)); + genSkipc(&rFalseIfx); - } else { - emitSKPNZ; - } - genSkipc(&rFalseIfx); - emitpLabel(truelbl->key); if(ifx) ifx->generated = 1; return; } + } else { + /* Special cases for signed longs */ + if( (lit & 0xffffff) == 0) { + /* lower byte is zero */ + DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); + i = ((lit >> 8*3) & 0xff) ^0x80; + emitpcode(POC_MOVFW, popGet(AOP(left),size)); + emitpcode(POC_ADDLW, popGetLit( 0x80)); + emitpcode(POC_ADDLW, popGetLit(0x100-i)); + genSkipc(&rFalseIfx); - if(size == 1) { - if( (lit & 0xff) == 0) { - /* lower byte is zero */ - DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); - i = ((lit >> 8) & 0xff) ^0x80; - emitpcode(POC_MOVFW, popGet(AOP(left),size)); - emitpcode(POC_ADDLW, popGetLit( 0x80)); - emitpcode(POC_ADDLW, popGetLit(0x100-i)); - genSkipc(&rFalseIfx); + if(ifx) ifx->generated = 1; + return; + } - if(ifx) ifx->generated = 1; - return; + } - } - } else { - /* Special cases for signed longs */ - if( (lit & 0xffffff) == 0) { - /* lower byte is zero */ - DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); - i = ((lit >> 8*3) & 0xff) ^0x80; - emitpcode(POC_MOVFW, popGet(AOP(left),size)); - emitpcode(POC_ADDLW, popGetLit( 0x80)); - emitpcode(POC_ADDLW, popGetLit(0x100-i)); - genSkipc(&rFalseIfx); + if(lit & (0x80 << (size*8))) { + /* lit is negative */ + DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); - if(ifx) ifx->generated = 1; - return; + //genSkipCond(&rFalseIfx,left,size,7); - } + emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0)); - } + if(rFalseIfx.condition) + emitpcode(POC_GOTO, popGetLabel(truelbl->key)); + else + emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); - if(lit & (0x80 << (size*8))) { - /* lit is negative */ - DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); + } else { + /* lit is positive */ + DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0)); + if(rFalseIfx.condition) + emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); + else + emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - //genSkipCond(&rFalseIfx,left,size,7); + } - emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0)); + /* + This works, but is only good for ints. + It also requires a "known zero" register. + emitpcode(POC_MOVLW, popGetLit(mlit & 0xff)); + emitpcode(POC_ADDFW, popGet(AOP(left),0)); + emitpcode(POC_RLFW, popCopyReg(&pc_kzero)); + emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff))); + emitpcode(POC_ADDFW, popGet(AOP(left),1)); + genSkipc(&rFalseIfx); - if(rFalseIfx.condition) - emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - else - emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); + emitpLabel(truelbl->key); + if(ifx) ifx->generated = 1; + return; + **/ + + /* There are no more special cases, so perform a general compare */ + + emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff)); + emitpcode(POC_SUBFW, popGet(AOP(left),size)); + while(size--) { - } else { - /* lit is positive */ - DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); - emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0)); - if(rFalseIfx.condition) - emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); - else - emitpcode(POC_GOTO, popGetLabel(truelbl->key)); + emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff)); + emitSKPNZ; + emitpcode(POC_SUBFW, popGet(AOP(left),size)); + } + //rFalseIfx.condition ^= 1; + genSkipc(&rFalseIfx); - //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0)); - //emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - //rFalseIfx.condition ^= 1; - //genSkipCond(&rFalseIfx,left,size,7); - //rFalseIfx.condition ^= 1; - } + emitpLabel(truelbl->key); - /* - This works, but is only good for ints. - It also requires a "known zero" register. - emitpcode(POC_MOVLW, popGetLit(mlit & 0xff)); - emitpcode(POC_ADDFW, popGet(AOP(left),0)); - emitpcode(POC_RLFW, popCopyReg(&pc_kzero)); - emitpcode(POC_ADDLW, popGetLit( ((mlit>>8) & 0xff))); - emitpcode(POC_ADDFW, popGet(AOP(left),1)); - genSkipc(&rFalseIfx); + if(ifx) ifx->generated = 1; + return; - emitpLabel(truelbl->key); - if(ifx) ifx->generated = 1; - return; - **/ - - /* There are no more special cases, so perform a general compare */ - - emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff)); - emitpcode(POC_SUBFW, popGet(AOP(left),size)); - while(size--) { + } - emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff)); - emitSKPNZ; - emitpcode(POC_SUBFW, popGet(AOP(left),size)); - } - //rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); - emitpLabel(truelbl->key); + /* sign is out of the way. So now do an unsigned compare */ + DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit); - if(ifx) ifx->generated = 1; - return; + /* General case - compare to an unsigned literal on the right.*/ + i = (lit >> (size*8)) & 0xff; + emitpcode(POC_MOVLW, popGetLit(i)); + emitpcode(POC_SUBFW, popGet(AOP(left),size)); + while(size--) { + i = (lit >> (size*8)) & 0xff; + + if(i) { + emitpcode(POC_MOVLW, popGetLit(i)); + emitSKPNZ; + emitpcode(POC_SUBFW, popGet(AOP(left),size)); + } else { + /* this byte of the lit is zero, + *if it's not the last then OR in the variable */ + if(size) + emitpcode(POC_IORFW, popGet(AOP(left),size)); } + } - /* sign is out of the way. So now do an unsigned compare */ - DEBUGpic14_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit); + emitpLabel(lbl->key); + //if(emitFinalCheck) + genSkipc(&rFalseIfx); + if(sign) + emitpLabel(truelbl->key); + if(ifx) ifx->generated = 1; + return; - //genChkZeroes(left) - /* General case - compare to an unsigned literal on the right.*/ + } +#endif + if(AOP_TYPE(left) == AOP_LIT) { + //symbol *lbl = newiTempLabel(NULL); - i = (lit >> (size*8)) & 0xff; - emitpcode(POC_MOVLW, popGetLit(i)); - emitpcode(POC_SUBFW, popGet(AOP(left),size)); - while(size--) { - i = (lit >> (size*8)) & 0xff; + //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit)); - if(i) { - emitpcode(POC_MOVLW, popGetLit(i)); - emitSKPNZ; - emitpcode(POC_SUBFW, popGet(AOP(left),size)); - } else { - /* this byte of the lit is zero, - *if it's not the last then OR in the variable */ - if(size) - emitpcode(POC_IORFW, popGet(AOP(left),size)); - } - } + DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign); - emitpLabel(lbl->key); - //if(emitFinalCheck) - genSkipc(&rFalseIfx); - if(sign) - emitpLabel(truelbl->key); + /* Special cases */ + if((lit == 0) && (sign == 0)){ + size--; + emitpcode(POC_MOVFW, popGet(AOP(right),size)); + while(size) + emitpcode(POC_IORFW, popGet(AOP(right),--size)); + + genSkipz2(&rFalseIfx,0); if(ifx) ifx->generated = 1; return; + } + if(size==1) { + /* Special cases */ + lit &= 0xff; + if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) { + /* degenerate compare can never be true */ + if(rFalseIfx.condition == 0) + emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key)); - } + if(ifx) ifx->generated = 1; + return; + } - if(AOP_TYPE(left) == AOP_LIT) { - //symbol *lbl = newiTempLabel(NULL); + if(sign) { + /* signed comparisons to a literal byte */ - lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit)); + int lp1 = (lit+1) & 0xff; + DEBUGpic14_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit); + switch (lp1) { + case 0: + rFalseIfx.condition ^= 1; + genSkipCond(&rFalseIfx,right,0,7); + break; + case 0x7f: + emitpcode(POC_MOVFW, popGet(AOP(right),0)); + emitpcode(POC_XORLW, popGetLit(0x7f)); + genSkipz2(&rFalseIfx,1); + break; + default: + emitpcode(POC_MOVFW, popGet(AOP(right),0)); + emitpcode(POC_ADDLW, popGetLit(0x80)); + emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80)); + rFalseIfx.condition ^= 1; + genSkipc(&rFalseIfx); + break; + } + } else { + /* unsigned comparisons to a literal byte */ - DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign); + switch(lit & 0xff ) { + case 0: + emitpcode(POC_MOVFW, popGet(AOP(right),0)); + genSkipz2(&rFalseIfx,0); + break; + case 0x7f: + rFalseIfx.condition ^= 1; + genSkipCond(&rFalseIfx,right,0,7); + break; - /* Special cases */ - if((lit == 0) && (sign == 0)){ + default: + emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff)); + emitpcode(POC_SUBFW, popGet(AOP(right),0)); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + rFalseIfx.condition ^= 1; + genSkipc(&rFalseIfx); + break; + } + } + + if(ifx) ifx->generated = 1; + return; + + } else { + + /* Size is greater than 1 */ + + if(sign) { + int lp1 = lit+1; size--; - emitpcode(POC_MOVFW, popGet(AOP(right),size)); - while(size) - emitpcode(POC_IORFW, popGet(AOP(right),--size)); - //rFalseIfx.condition ^= 1; - genSkipz2(&rFalseIfx); - if(ifx) ifx->generated = 1; - return; - } + if(lp1 == 0) { + /* this means lit = 0xffffffff, or -1 */ - if(size==1) { - /* Special cases */ - lit &= 0xff; - if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) { - /* degenerate compare can never be true */ - if(rFalseIfx.condition == 0) - emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key)); + DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__); + rFalseIfx.condition ^= 1; + genSkipCond(&rFalseIfx,right,size,7); if(ifx) ifx->generated = 1; return; } - if(sign) { - if((lit+1)&0xff) { - emitpcode(POC_MOVFW, popGet(AOP(right),0)); - emitpcode(POC_ADDLW, popGetLit(0x80)); - emitpcode(POC_ADDLW, popGetLit(((-(lit+1)) & 0xff) ^ 0x80)); - rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); - } else { - rFalseIfx.condition ^= 1; - genSkipCond(&rFalseIfx,right,0,7); + if(lit == 0) { + int s = size; + + if(rFalseIfx.condition) { + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0)); + emitpcode(POC_GOTO, popGetLabel(truelbl->key)); } - - } else { - if(lit & 0xff) { - emitpcode(POC_MOVLW, popGetLit((lit+1) & 0xff)); - emitpcode(POC_SUBFW, popGet(AOP(right),0)); - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + emitpcode(POC_MOVFW, popGet(AOP(right),size)); + while(size--) + emitpcode(POC_IORFW, popGet(AOP(right),size)); + + + emitSKPZ; + if(rFalseIfx.condition) { + emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); + emitpLabel(truelbl->key); + }else { rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); - } else { - emitpcode(POC_MOVFW, popGet(AOP(right),0)); - genSkipz2(&rFalseIfx); + genSkipCond(&rFalseIfx,right,s,7); } + + if(ifx) ifx->generated = 1; + return; } - if(ifx) ifx->generated = 1; - return; + if((size == 1) && (0 == (lp1&0xff))) { + /* lower byte of signed word is zero */ + DEBUGpic14_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit); + i = ((lp1 >> 8) & 0xff) ^0x80; + emitpcode(POC_MOVFW, popGet(AOP(right),size)); + emitpcode(POC_ADDLW, popGetLit( 0x80)); + emitpcode(POC_ADDLW, popGetLit(0x100-i)); + rFalseIfx.condition ^= 1; + genSkipc(&rFalseIfx); - } else { - /* Size is greater than 1 */ + if(ifx) ifx->generated = 1; + return; + } + if(lit & (0x80 << (size*8))) { + /* Lit is less than zero */ + DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit); + //rFalseIfx.condition ^= 1; + //genSkipCond(&rFalseIfx,left,size,7); + //rFalseIfx.condition ^= 1; + emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0)); + //emitpcode(POC_GOTO, popGetLabel(truelbl->key)); + if(rFalseIfx.condition) + emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); + else + emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - if(sign) { - int lp1 = lit+1; - size--; + } else { + /* Lit is greater than or equal to zero */ + DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit); + //rFalseIfx.condition ^= 1; + //genSkipCond(&rFalseIfx,right,size,7); + //rFalseIfx.condition ^= 1; - if(lp1 == 0) { - /* this means lit = 0xffffffff, or -1 */ + //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0)); + //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0)); + if(rFalseIfx.condition) + emitpcode(POC_GOTO, popGetLabel(truelbl->key)); + else + emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); - DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__); - rFalseIfx.condition ^= 1; - genSkipCond(&rFalseIfx,right,size,7); - if(ifx) ifx->generated = 1; - return; - } + } - if(lit == 0) { - int s = size; - if(rFalseIfx.condition) { - emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0)); - emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - } + emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff)); + emitpcode(POC_SUBFW, popGet(AOP(right),size)); - emitpcode(POC_MOVFW, popGet(AOP(right),size)); - while(size--) - emitpcode(POC_IORFW, popGet(AOP(right),size)); + while(size--) { + emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff)); + emitSKPNZ; + emitpcode(POC_SUBFW, popGet(AOP(right),size)); + } + rFalseIfx.condition ^= 1; + //rFalseIfx.condition = 1; + genSkipc(&rFalseIfx); - emitSKPZ; - if(rFalseIfx.condition) { - emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); - emitpLabel(truelbl->key); - }else { - rFalseIfx.condition ^= 1; - genSkipCond(&rFalseIfx,right,s,7); - } + emitpLabel(truelbl->key); - if(ifx) ifx->generated = 1; - return; - } + if(ifx) ifx->generated = 1; + return; + // end of if (sign) + } else { + /* compare word or long to an unsigned literal on the right.*/ - if(lit & (0x80 << (size*8))) { - /* Lit is less than zero */ - DEBUGpic14_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit); - //rFalseIfx.condition ^= 1; - //genSkipCond(&rFalseIfx,left,size,7); - //rFalseIfx.condition ^= 1; - emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0)); - //emitpcode(POC_GOTO, popGetLabel(truelbl->key)); + size--; + if(lit < 0xff) { + DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit); + switch (lit) { + case 0: + break; /* handled above */ +/* + case 0xff: + emitpcode(POC_MOVFW, popGet(AOP(right),size)); + while(size--) + emitpcode(POC_IORFW, popGet(AOP(right),size)); + genSkipz2(&rFalseIfx,0); + break; +*/ + default: + emitpcode(POC_MOVFW, popGet(AOP(right),size)); + while(--size) + emitpcode(POC_IORFW, popGet(AOP(right),size)); + + emitSKPZ; if(rFalseIfx.condition) emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); else emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - } else { - /* Lit is greater than or equal to zero */ - DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit); - //rFalseIfx.condition ^= 1; - //genSkipCond(&rFalseIfx,right,size,7); - //rFalseIfx.condition ^= 1; - - //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0)); - //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); - - emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0)); - if(rFalseIfx.condition) - emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - else - emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); - - } - emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff)); - emitpcode(POC_SUBFW, popGet(AOP(right),size)); - - while(size--) { + emitpcode(POC_MOVLW, popGetLit(lit+1)); + emitpcode(POC_SUBFW, popGet(AOP(right),0)); - emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff)); - emitSKPNZ; - emitpcode(POC_SUBFW, popGet(AOP(right),size)); + rFalseIfx.condition ^= 1; + genSkipc(&rFalseIfx); } - rFalseIfx.condition ^= 1; - //rFalseIfx.condition = 1; - genSkipc(&rFalseIfx); emitpLabel(truelbl->key); if(ifx) ifx->generated = 1; return; + } - } else { - /* Unsigned compare for sizes greater than 1 */ - while(size--) { - i = (lit >> (size*8)) & 0xff; + lit++; + DEBUGpic14_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit); + i = (lit >> (size*8)) & 0xff; + emitpcode(POC_MOVLW, popGetLit(i)); + emitpcode(POC_SUBFW, popGet(AOP(right),size)); - if(size) { - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - emitpcode(POC_MOVLW, popGetLit(i&0xff)); - emitpcode(POC_SUBFW, popGet(AOP(right),size)); - emitSKPZ; - emitpcode(POC_GOTO, popGetLabel(lbl->key)); - } else { - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - emitpcode(POC_MOVLW, popGetLit((i+1)&0xff)); - emitpcode(POC_SUBFW, popGet(AOP(right),size)); + while(size--) { + i = (lit >> (size*8)) & 0xff; - } + if(i) { + emitpcode(POC_MOVLW, popGetLit(i)); + emitSKPNZ; + emitpcode(POC_SUBFW, popGet(AOP(right),size)); + } else { + /* this byte of the lit is zero, + *if it's not the last then OR in the variable */ + if(size) + emitpcode(POC_IORFW, popGet(AOP(right),size)); } + } - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - emitpLabel(lbl->key); + emitpLabel(lbl->key); - rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); + rFalseIfx.condition ^= 1; + genSkipc(&rFalseIfx); + } - } if(sign) emitpLabel(truelbl->key); if(ifx) ifx->generated = 1; return; - } } - /* Compare two variables */ - - DEBUGpic14_emitcode(";sign","%d",sign); + } + /* Compare two variables */ - size--; - if(sign) { - /* Sigh. thus sucks... */ - if(size) { - emitpcode(POC_MOVFW, popGet(AOP(left),size)); - emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr)); - emitpcode(POC_MOVLW, popGetLit(0x80)); - emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr)); - emitpcode(POC_XORFW, popGet(AOP(right),size)); - emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr)); - } else { - /* Signed char comparison */ - /* Special thanks to Nikolai Golovchenko for this snippet */ - emitpcode(POC_MOVFW, popGet(AOP(right),0)); - emitpcode(POC_SUBFW, popGet(AOP(left),0)); - emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */ - emitpcode(POC_XORFW, popGet(AOP(left),0)); - emitpcode(POC_XORFW, popGet(AOP(right),0)); - emitpcode(POC_ADDLW, popGetLit(0x80)); - - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - genSkipc(&rFalseIfx); - - if(ifx) ifx->generated = 1; - return; - } + DEBUGpic14_emitcode(";sign","%d",sign); + size--; + if(sign) { + /* Sigh. thus sucks... */ + if(size) { + emitpcode(POC_MOVFW, popGet(AOP(left),size)); + emitpcode(POC_MOVWF, popRegFromIdx(Gstack_base_addr)); + emitpcode(POC_MOVLW, popGetLit(0x80)); + emitpcode(POC_XORWF, popRegFromIdx(Gstack_base_addr)); + emitpcode(POC_XORFW, popGet(AOP(right),size)); + emitpcode(POC_SUBFW, popRegFromIdx(Gstack_base_addr)); } else { + /* Signed char comparison */ + /* Special thanks to Nikolai Golovchenko for this snippet */ + emitpcode(POC_MOVFW, popGet(AOP(right),0)); + emitpcode(POC_SUBFW, popGet(AOP(left),0)); + emitpcode(POC_RRFW, popGet(AOP(left),0)); /* could be any register */ + emitpcode(POC_XORFW, popGet(AOP(left),0)); + emitpcode(POC_XORFW, popGet(AOP(right),0)); + emitpcode(POC_ADDLW, popGetLit(0x80)); - emitpcode(POC_MOVFW, popGet(AOP(right),size)); - emitpcode(POC_SUBFW, popGet(AOP(left),size)); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + genSkipc(&rFalseIfx); + + if(ifx) ifx->generated = 1; + return; } + } else { - /* The rest of the bytes of a multi-byte compare */ - while (size) { - - emitSKPZ; - emitpcode(POC_GOTO, popGetLabel(lbl->key)); - size--; + emitpcode(POC_MOVFW, popGet(AOP(right),size)); + emitpcode(POC_SUBFW, popGet(AOP(left),size)); + } - emitpcode(POC_MOVFW, popGet(AOP(right),size)); - emitpcode(POC_SUBFW, popGet(AOP(left),size)); + /* The rest of the bytes of a multi-byte compare */ + while (size) { - } + emitSKPZ; + emitpcode(POC_GOTO, popGetLabel(lbl->key)); + size--; - emitpLabel(lbl->key); + emitpcode(POC_MOVFW, popGet(AOP(right),size)); + emitpcode(POC_SUBFW, popGet(AOP(left),size)); - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - genSkipc(&rFalseIfx); - if(ifx) ifx->generated = 1; - return; } + + emitpLabel(lbl->key); + + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + genSkipc(&rFalseIfx); + if(ifx) ifx->generated = 1; + return; + } - //release: if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) { pic14_outBitC(result); } else { @@ -4607,7 +4695,7 @@ static void genCmpEq (iCode *ic, iCode *ifx) emitpcode(POC_ANDFW,popGet(AOP(left),0)); emitpcode(POC_BTFSC,popGet(AOP(right),0)); emitpcode(POC_ANDLW,popGet(AOP(left),0)); - genSkipz2(&rIfx); + genSkipz2(&rIfx,0); } } else { @@ -7807,16 +7895,18 @@ static void genNearPointerGet (operand *left, if (!AOP_INPREG(AOP(left))) { /* otherwise get a free pointer register */ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); +/* aop = newAsmop(0); preg = getFreePtr(ic,&aop,FALSE); pic14_emitcode("mov","%s,%s", preg->name, aopGet(AOP(left),0,FALSE,TRUE)); rname = preg->name ; +*/ + rname ="BAD"; } else rname = aopGet(AOP(left),0,FALSE,FALSE); - freeAsmop(left,NULL,ic,TRUE); aopOp (result,ic,FALSE); /* if bitfield then unpack the bits */ @@ -7824,10 +7914,20 @@ static void genNearPointerGet (operand *left, genUnpackBits (result,rname,POINTER); else { /* we have can just get the values */ - int size = AOP_SIZE(result); - int offset = 0 ; + int size = AOP_SIZE(result); + int offset = 0 ; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + emitpcode(POC_MOVFW,popGet(AOP(left),0)); + emitpcode(POC_MOVWF,popCopyReg(&pc_fsr)); + while(size--) { + emitpcode(POC_MOVFW,popCopyReg(&pc_indf)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset++)); + if(size) + emitpcode(POC_INCF,popCopyReg(&pc_fsr)); + } +/* while (size--) { if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) { @@ -7841,6 +7941,7 @@ static void genNearPointerGet (operand *left, if (size) pic14_emitcode("inc","%s",rname); } +*/ } /* now some housekeeping stuff */ @@ -7866,6 +7967,7 @@ static void genNearPointerGet (operand *left, } /* done */ + freeAsmop(left,NULL,ic,TRUE); freeAsmop(result,NULL,ic,TRUE); } @@ -8457,117 +8559,124 @@ static void genNearPointerSet (operand *right, operand *result, iCode *ic) { - asmop *aop = NULL; - char *l; - sym_link *retype; - sym_link *ptype = operandType(result); + asmop *aop = NULL; + char *l; + sym_link *retype; + sym_link *ptype = operandType(result); - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - retype= getSpec(operandType(right)); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + retype= getSpec(operandType(right)); + + aopOp(result,ic,FALSE); - aopOp(result,ic,FALSE); - /* if the result is rematerializable & - in data space & not a bit variable */ - //if (AOP_TYPE(result) == AOP_IMMD && - if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD && - DCL_TYPE(ptype) == POINTER && - !IS_BITVAR(retype)) { - genDataPointerSet (right,result,ic); - return; - } + /* if the result is rematerializable & + in data space & not a bit variable */ + //if (AOP_TYPE(result) == AOP_IMMD && + if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD && + DCL_TYPE(ptype) == POINTER && + !IS_BITVAR(retype)) { + genDataPointerSet (right,result,ic); + freeAsmop(result,NULL,ic,TRUE); + return; + } + + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + aopOp(right,ic,FALSE); + DEBUGpic14_AopType(__LINE__,NULL,right,result); + /* if the value is already in a pointer register + then don't need anything more */ + if (!AOP_INPREG(AOP(result))) { + /* otherwise get a free pointer register */ + //aop = newAsmop(0); + //preg = getFreePtr(ic,&aop,FALSE); DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + //pic14_emitcode("mov","%s,%s", + // preg->name, + // aopGet(AOP(result),0,FALSE,TRUE)); + //rname = preg->name ; + //pic14_emitcode("movwf","fsr"); + emitpcode(POC_MOVFW, popGet(AOP(result),0)); + emitpcode(POC_MOVWF, popCopyReg(&pc_fsr)); + emitpcode(POC_MOVFW, popGet(AOP(right),0)); + emitpcode(POC_MOVWF, popCopyReg(&pc_indf)); + goto release; - /* if the value is already in a pointer register - then don't need anything more */ - if (!AOP_INPREG(AOP(result))) { - /* otherwise get a free pointer register */ - //aop = newAsmop(0); - //preg = getFreePtr(ic,&aop,FALSE); - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - //pic14_emitcode("mov","%s,%s", - // preg->name, - // aopGet(AOP(result),0,FALSE,TRUE)); - //rname = preg->name ; - pic14_emitcode("movwf","fsr"); - }// else - // rname = aopGet(AOP(result),0,FALSE,FALSE); + }// else + // rname = aopGet(AOP(result),0,FALSE,FALSE); - freeAsmop(result,NULL,ic,TRUE); - aopOp (right,ic,FALSE); - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if bitfield then unpack the bits */ - if (IS_BITVAR(retype)) { - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - "The programmer is obviously confused"); - //genPackBits (retype,right,rname,POINTER); - exit(1); - } - else { - /* we have can just get the values */ - int size = AOP_SIZE(right); - int offset = 0 ; + /* if bitfield then unpack the bits */ + if (IS_BITVAR(retype)) { + werror(E_INTERNAL_ERROR,__FILE__,__LINE__, + "The programmer is obviously confused"); + //genPackBits (retype,right,rname,POINTER); + exit(1); + } + else { + /* we have can just get the values */ + int size = AOP_SIZE(right); + int offset = 0 ; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - while (size--) { - l = aopGet(AOP(right),offset,FALSE,TRUE); - if (*l == '@' ) { - //MOVA(l); - //pic14_emitcode("mov","@%s,a",rname); - pic14_emitcode("movf","indf,w ;1"); - } else { + while (size--) { + l = aopGet(AOP(right),offset,FALSE,TRUE); + if (*l == '@' ) { + //MOVA(l); + //pic14_emitcode("mov","@%s,a",rname); + pic14_emitcode("movf","indf,w ;1"); + } else { - if (AOP_TYPE(right) == AOP_LIT) { - unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); - if(lit) { - pic14_emitcode("movlw","%s",l); - pic14_emitcode("movwf","indf ;2"); - } else - pic14_emitcode("clrf","indf"); - }else { - pic14_emitcode("movf","%s,w",l); - pic14_emitcode("movwf","indf ;2"); - } - //pic14_emitcode("mov","@%s,%s",rname,l); - } - if (size) - pic14_emitcode("incf","fsr,f ;3"); - //pic14_emitcode("inc","%s",rname); - offset++; - } + if (AOP_TYPE(right) == AOP_LIT) { + unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); + if(lit) { + pic14_emitcode("movlw","%s",l); + pic14_emitcode("movwf","indf ;2"); + } else + pic14_emitcode("clrf","indf"); + }else { + pic14_emitcode("movf","%s,w",l); + pic14_emitcode("movwf","indf ;2"); + } + //pic14_emitcode("mov","@%s,%s",rname,l); + } + if (size) + pic14_emitcode("incf","fsr,f ;3"); + //pic14_emitcode("inc","%s",rname); + offset++; } + } + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* now some housekeeping stuff */ + if (aop) { + /* we had to allocate for this iCode */ + freeAsmop(NULL,aop,ic,TRUE); + } else { + /* we did not allocate which means left + already in a pointer register, then + if size > 0 && this could be used again + we have to point it back to where it + belongs */ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* now some housekeeping stuff */ - if (aop) { - /* we had to allocate for this iCode */ - freeAsmop(NULL,aop,ic,TRUE); - } else { - /* we did not allocate which means left - already in a pointer register, then - if size > 0 && this could be used again - we have to point it back to where it - belongs */ - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (AOP_SIZE(right) > 1 && - !OP_SYMBOL(result)->remat && - ( OP_SYMBOL(result)->liveTo > ic->seq || - ic->depth )) { - int size = AOP_SIZE(right) - 1; - while (size--) - pic14_emitcode("decf","fsr,f"); - //pic14_emitcode("dec","%s",rname); - } + if (AOP_SIZE(right) > 1 && + !OP_SYMBOL(result)->remat && + ( OP_SYMBOL(result)->liveTo > ic->seq || + ic->depth )) { + int size = AOP_SIZE(right) - 1; + while (size--) + pic14_emitcode("decf","fsr,f"); + //pic14_emitcode("dec","%s",rname); } + } - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* done */ - freeAsmop(right,NULL,ic,TRUE); - - + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* done */ + release: + freeAsmop(right,NULL,ic,TRUE); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -9426,14 +9535,22 @@ static void genCast (iCode *ic) } /* the first two bytes are known */ + DEBUGpic14_emitcode("; ***","%s %d - pointer cast2",__FUNCTION__,__LINE__); size = GPTRSIZE - 1; offset = 0 ; while (size--) { - if(offset < AOP_SIZE(right)) - aopPut(AOP(result), - aopGet(AOP(right),offset,FALSE,FALSE), - offset); - else + if(offset < AOP_SIZE(right)) { + DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__); + if ((AOP_TYPE(right) == AOP_PCODE) && + AOP(right)->aopu.pcop->type == PO_IMMEDIATE) { + emitpcode(POC_MOVLW, popGet(AOP(right),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); + } else { + aopPut(AOP(result), + aopGet(AOP(right),offset,FALSE,FALSE), + offset); + } + } else emitpcode(POC_CLRF,popGet(AOP(result),offset)); offset++; } @@ -9682,9 +9799,15 @@ void genpic14Code (iCode *lic) ic->level,ic->block); _G.debugLine = 0; } - pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno); - pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, - printCLine(ic->filename, ic->lineno)); + /* + pic14_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno); + pic14_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, + printCLine(ic->filename, ic->lineno)); + */ + addpCode2pBlock(pb, + newpCodeCSource(ic->lineno, + ic->filename, + printCLine(ic->filename, ic->lineno))); cln = ic->lineno ; } diff --git a/src/pic/genarith.c b/src/pic/genarith.c index da50b903..de312a50 100644 --- a/src/pic/genarith.c +++ b/src/pic/genarith.c @@ -906,13 +906,14 @@ void genPlus (iCode *ic) emitpcode(POC_ADDWF, popGet(AOP(IC_LEFT(ic)),0)); else { if( (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) || + (AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) || (AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ) { emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),0)); } else { emitpcode(POC_ADDFW, popGet(AOP(IC_LEFT(ic)),0)); - if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) - emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0)); } + if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) + emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0)); } } } diff --git a/src/pic/glue.c b/src/pic/glue.c index c49dfcb3..e41cd3df 100644 --- a/src/pic/glue.c +++ b/src/pic/glue.c @@ -57,7 +57,7 @@ extern DEFSETFUNC (rmTmpFiles); extern void AnalyzeBanking (void); extern void copyFile (FILE * dest, FILE * src); - +extern void InlinepCode(void); extern void writeUsedRegs(FILE *); extern void initialComments (FILE * afile); @@ -813,12 +813,16 @@ picglue () pic14emitOverlay(ovrFile); - AnalyzepCode('*'); //code->dbName); + AnalyzepCode('*'); //#ifdef PCODE_DEBUG - // printCallTree(stderr); + //printCallTree(stderr); //#endif +/* + InlinepCode(); + AnalyzepCode('*'); +*/ pcode_test(); diff --git a/src/pic/pcode.c b/src/pic/pcode.c index 9249f813..c330f6f3 100644 --- a/src/pic/pcode.c +++ b/src/pic/pcode.c @@ -70,7 +70,7 @@ static hTab *pic14pCodePeepCommandsHash = NULL; static pFile *the_pFile = NULL; -static int peepOptimizing = 0; +static int peepOptimizing = 1; static int GpCodeSequenceNumber = 1; static int GpcFlowSeq = 1; @@ -120,6 +120,7 @@ pCodeInstruction pciADDWF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip @@ -140,6 +141,7 @@ pCodeInstruction pciADDFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -160,6 +162,7 @@ pCodeInstruction pciADDLW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -180,6 +183,7 @@ pCodeInstruction pciANDLW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -200,6 +204,7 @@ pCodeInstruction pciANDWF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip @@ -220,6 +225,7 @@ pCodeInstruction pciANDFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -240,6 +246,7 @@ pCodeInstruction pciBCF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,1, // dest, bit instruction 0,0, // branch, skip @@ -260,6 +267,7 @@ pCodeInstruction pciBSF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,1, // dest, bit instruction 0,0, // branch, skip @@ -280,6 +288,7 @@ pCodeInstruction pciBTFSC = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,1, // dest, bit instruction 1,1, // branch, skip @@ -300,6 +309,7 @@ pCodeInstruction pciBTFSS = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,1, // dest, bit instruction 1,1, // branch, skip @@ -320,6 +330,7 @@ pCodeInstruction pciCALL = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 1, // num ops 0,0, // dest, bit instruction 1,0, // branch, skip @@ -340,6 +351,7 @@ pCodeInstruction pciCOMF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip @@ -360,6 +372,7 @@ pCodeInstruction pciCOMFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -380,6 +393,7 @@ pCodeInstruction pciCLRF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -400,6 +414,7 @@ pCodeInstruction pciCLRW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 0, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -420,6 +435,7 @@ pCodeInstruction pciDECF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip @@ -440,6 +456,7 @@ pCodeInstruction pciDECFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -460,6 +477,7 @@ pCodeInstruction pciDECFSZ = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 1,1, // branch, skip @@ -480,6 +498,7 @@ pCodeInstruction pciDECFSZW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 1,1, // branch, skip @@ -500,6 +519,7 @@ pCodeInstruction pciGOTO = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 1, // num ops 0,0, // dest, bit instruction 1,0, // branch, skip @@ -520,6 +540,7 @@ pCodeInstruction pciINCF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip @@ -540,6 +561,7 @@ pCodeInstruction pciINCFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -560,6 +582,7 @@ pCodeInstruction pciINCFSZ = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 1,1, // branch, skip @@ -580,6 +603,7 @@ pCodeInstruction pciINCFSZW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 1,1, // branch, skip @@ -600,6 +624,7 @@ pCodeInstruction pciIORWF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip @@ -620,6 +645,7 @@ pCodeInstruction pciIORFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -640,6 +666,7 @@ pCodeInstruction pciIORLW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -660,6 +687,7 @@ pCodeInstruction pciMOVF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip @@ -680,6 +708,7 @@ pCodeInstruction pciMOVFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -700,6 +729,7 @@ pCodeInstruction pciMOVWF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -720,6 +750,7 @@ pCodeInstruction pciMOVLW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -739,6 +770,7 @@ pCodeInstruction pciNOP = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 0, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -759,6 +791,7 @@ pCodeInstruction pciRETFIE = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 0, // num ops 0,0, // dest, bit instruction 1,0, // branch, skip @@ -779,6 +812,7 @@ pCodeInstruction pciRETLW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 1, // num ops 0,0, // dest, bit instruction 1,0, // branch, skip @@ -799,6 +833,7 @@ pCodeInstruction pciRETURN = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 0, // num ops 0,0, // dest, bit instruction 1,0, // branch, skip @@ -819,6 +854,7 @@ pCodeInstruction pciRLF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip @@ -839,6 +875,7 @@ pCodeInstruction pciRLFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -859,6 +896,7 @@ pCodeInstruction pciRRF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip @@ -879,6 +917,7 @@ pCodeInstruction pciRRFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -899,6 +938,7 @@ pCodeInstruction pciSUBWF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip @@ -919,6 +959,7 @@ pCodeInstruction pciSUBFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -939,6 +980,7 @@ pCodeInstruction pciSUBLW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -959,6 +1001,7 @@ pCodeInstruction pciSWAPF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip @@ -979,6 +1022,7 @@ pCodeInstruction pciSWAPFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -999,6 +1043,7 @@ pCodeInstruction pciTRIS = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -1019,6 +1064,7 @@ pCodeInstruction pciXORWF = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 1,0, // dest, bit instruction 0,0, // branch, skip @@ -1039,6 +1085,7 @@ pCodeInstruction pciXORFW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 2, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -1059,6 +1106,7 @@ pCodeInstruction pciXORLW = { NULL, // label NULL, // operand NULL, // flow block + NULL, // C source 1, // num ops 0,0, // dest, bit instruction 0,0, // branch, skip @@ -1148,7 +1196,7 @@ extern void init_pic(char *); void pCodeInitRegisters(void) { - initStack(0x38, 8); + initStack(0xfff, 8); init_pic(port->processor); pc_status.r = allocProcessorRegister(IDX_STATUS,"STATUS", PO_STATUS, 0x80); @@ -1672,6 +1720,8 @@ pCode *newpCodeFunction(char *mod,char *f) pcf->pc.destruct = genericDestruct; pcf->pc.print = pCodePrintFunction; + pcf->ncalled = 0; + if(mod) { //_ALLOC_ATOMIC(pcf->modname,strlen(mod)+1); pcf->modname = Safe_calloc(1,strlen(mod)+1); @@ -1726,6 +1776,38 @@ pCode *newpCodeFlow(void ) } +/*-----------------------------------------------------------------*/ +/* newpCodeCSource - create a new pCode Source Symbol */ +/*-----------------------------------------------------------------*/ + +pCode *newpCodeCSource(int ln, char *f, char *l) +{ + + pCodeCSource *pccs; + + pccs = Safe_calloc(1,sizeof(pCodeCSource)); + + pccs->pc.type = PC_CSOURCE; + pccs->pc.prev = pccs->pc.next = NULL; + pccs->pc.pb = NULL; + + pccs->pc.destruct = genericDestruct; + pccs->pc.print = genericPrint; + + pccs->line_number = ln; + if(l) + pccs->line = Safe_strdup(l); + else + pccs->line = NULL; + + if(f) + pccs->file_name = Safe_strdup(f); + else + pccs->file_name = NULL; + + return ( (pCode *)pccs); + +} /*-----------------------------------------------------------------*/ /* pCodeLabelDestruct - free memory used by a label. */ /*-----------------------------------------------------------------*/ @@ -2113,6 +2195,43 @@ void addpBlock(pBlock *pb) the_pFile->pbTail = pb; } +/*-----------------------------------------------------------------*/ +/* removepBlock - remove a pBlock from the pFile */ +/*-----------------------------------------------------------------*/ +void removepBlock(pBlock *pb) +{ + pBlock *pbs; + + if(!the_pFile) + return; + + + //fprintf(stderr," Removing pBlock: dbName =%c\n",getpBlock_dbName(pb)); + + for(pbs = the_pFile->pbHead; pbs; pbs = pbs->next) { + if(pbs == pb) { + + if(pbs == the_pFile->pbHead) + the_pFile->pbHead = pbs->next; + + if (pbs == the_pFile->pbTail) + the_pFile->pbTail = pbs->prev; + + if(pbs->next) + pbs->next->prev = pbs->prev; + + if(pbs->prev) + pbs->prev->next = pbs->next; + + return; + + } + } + + fprintf(stderr, "Warning: call to %s:%s didn't find pBlock\n",__FILE__,__FUNCTION__); + +} + /*-----------------------------------------------------------------*/ /* printpCode - write the contents of a pCode to a file */ /*-----------------------------------------------------------------*/ @@ -2161,6 +2280,10 @@ static void unlinkPC(pCode *pc) if(pc) { +#ifdef PCODE_DEBUG + fprintf(stderr,"Unlinking: "); + printpCode(stderr, pc); +#endif if(pc->prev) pc->prev->next = pc->next; if(pc->next) @@ -2285,9 +2408,11 @@ static char *get_op_from_instruction( pCodeInstruction *pcc) static void pCodeOpPrint(FILE *of, pCodeOp *pcop) { - fprintf(of,"pcodeopprint\n"); + fprintf(of,"pcodeopprint- not implemented\n"); } +/*-----------------------------------------------------------------*/ +/*-----------------------------------------------------------------*/ char *pCode2str(char *str, int size, pCode *pc) { char *s = str; @@ -2355,6 +2480,10 @@ char *pCode2str(char *str, int size, pCode *pc) case PC_FLOW: SAFE_snprintf(&s,&size,";\t--FLOW change\n"); break; + case PC_CSOURCE: + SAFE_snprintf(&s,&size,";#CSRC\t%s %d\n; %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line); + break; + } return str; @@ -2390,6 +2519,8 @@ static void genericPrint(FILE *of, pCode *pc) } } + if(PCI(pc)->cline) + genericPrint(of,PCODE(PCI(pc)->cline)); { char str[256]; @@ -2446,6 +2577,9 @@ static void genericPrint(FILE *of, pCode *pc) fprintf(of,";Start of new flow, seq=%d\n",pc->seq); break; + case PC_CSOURCE: + fprintf(of,";#CSRC\t%s %d\n; %s\n", PCCS(pc)->file_name, PCCS(pc)->line_number, PCCS(pc)->line); + break; case PC_LABEL: default: fprintf(of,"unknown pCode type %d\n",pc->type); @@ -2796,12 +2930,14 @@ pCode * findPrevpCode(pCode *pc, PC_TYPE pct) /* findNextInstruction - given a pCode, find the next instruction */ /* in the linked list */ /*-----------------------------------------------------------------*/ -pCode * findNextInstruction(pCode *pc) +pCode * findNextInstruction(pCode *pci) { + pCode *pc = pci; while(pc) { if((pc->type == PC_OPCODE) || (pc->type == PC_WILD)) return pc; + #ifdef PCODE_DEBUG fprintf(stderr,"findNextInstruction: "); printpCode(stderr, pc); @@ -2813,9 +2949,18 @@ pCode * findNextInstruction(pCode *pc) return NULL; } +/*-----------------------------------------------------------------*/ +/* findNextInstruction - given a pCode, find the next instruction */ +/* in the linked list */ +/*-----------------------------------------------------------------*/ +pCode * findPrevInstruction(pCode *pci) +{ + return findPrevpCode(pci, PC_OPCODE); +} + /*-----------------------------------------------------------------*/ /* findFunctionEnd - given a pCode find the end of the function */ -/* that contains it t */ +/* that contains it */ /*-----------------------------------------------------------------*/ pCode * findFunctionEnd(pCode *pc) { @@ -3231,15 +3376,35 @@ void LinkFlow(pBlock *pb) /*-----------------------------------------------------------------*/ int OptimizepBlock(pBlock *pb) { - pCode *pc; + pCode *pc, *pcprev; int matches =0; if(!pb || !peepOptimizing) return 0; DFPRINTF((stderr," Optimizing pBlock: %c\n",getpBlock_dbName(pb))); +/* for(pc = pb->pcHead; pc; pc = pc->next) matches += pCodePeepMatchRule(pc); +*/ + + pc = findNextInstruction(pb->pcHead); + pcprev = pc->prev; + do { + + + if(pCodePeepMatchRule(pc)) { + + matches++; + + if(pcprev) + pc = findNextInstruction(pcprev->next); + else + pc = findNextInstruction(pb->pcHead); + } else + pc = findNextInstruction(pc->next); + } while(pc); + if(matches) DFPRINTF((stderr," Optimizing pBlock: %c - matches=%d\n",getpBlock_dbName(pb),matches)); return matches; @@ -3293,8 +3458,7 @@ void pBlockRemoveUnusedLabels(pBlock *pb) * So, unlink the pCode label from it's pCode chain * and destroy the label */ - DFPRINTF((stderr," !!! REMOVED A LABEL !!! key = %d\n", pcl->key)); - + DFPRINTF((stderr," !!! REMOVED A LABEL !!! key = %d, %s\n", pcl->key,pcl->label)); if(pc->type == PC_LABEL) { unlinkPC(pc); pCodeLabelDestruct(pc); @@ -3333,30 +3497,51 @@ void pBlockMergeLabels(pBlock *pb) for(pc = pb->pcHead; pc; pc = pc->next) { if(pc->type == PC_LABEL) { + + //fprintf(stderr," checking merging label %s\n",PCL(pc)->label); //fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key); - if( !(pcnext = findNextInstruction(pc)) ) - return; // Couldn't find an instruction associated with this label - - // Unlink the pCode label from it's pCode chain - unlinkPC(pc); - - //fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key); - // And link it into the instruction's pBranch labels. (Note, since - // it's possible to have multiple labels associated with one instruction - // we must provide a means to accomodate the additional labels. Thus - // the labels are placed into the singly-linked list "label" as - // opposed to being a single member of the pCodeInstruction.) - - //_ALLOC(pbr,sizeof(pBranch)); - pbr = Safe_calloc(1,sizeof(pBranch)); - pbr->pc = pc; - pbr->next = NULL; - - PCI(pcnext)->label = pBranchAppend(PCI(pcnext)->label,pbr); - if(pcnext->prev) - pc = pcnext->prev; - else - pc = pcnext; + if((pcnext = findNextInstruction(pc) )) { + + pCode *pcn = pc->next; + + // Unlink the pCode label from it's pCode chain + unlinkPC(pc); + + //fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key); + // And link it into the instruction's pBranch labels. (Note, since + // it's possible to have multiple labels associated with one instruction + // we must provide a means to accomodate the additional labels. Thus + // the labels are placed into the singly-linked list "label" as + // opposed to being a single member of the pCodeInstruction.) + + //_ALLOC(pbr,sizeof(pBranch)); + pbr = Safe_calloc(1,sizeof(pBranch)); + pbr->pc = pc; + pbr->next = NULL; + + + PCI(pcnext)->label = pBranchAppend(PCI(pcnext)->label,pbr); + + pc = pcn; + + } else { + fprintf(stderr, "WARNING: couldn't associate label %s with an instruction\n",PCL(pc)->label); + } + } else if(pc->type == PC_CSOURCE) { + + /* merge the source line symbolic info into the next instruction */ + if((pcnext = findNextInstruction(pc) )) { + + pCode *pcn = pc->next; + + // Unlink the pCode label from it's pCode chain + unlinkPC(pc); + PCI(pcnext)->cline = PCCS(pc); + //fprintf(stderr, "merging CSRC\n"); + //genericPrint(stderr,pcnext); + pc = pcn; + } + } } @@ -3366,7 +3551,7 @@ void pBlockMergeLabels(pBlock *pb) /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ -void OptimizepCode(char dbName) +int OptimizepCode(char dbName) { #define MAX_PASSES 4 @@ -3375,11 +3560,12 @@ void OptimizepCode(char dbName) pBlock *pb; if(!the_pFile) - return; + return 0; DFPRINTF((stderr," Optimizing pCode\n")); do { + matches = 0; for(pb = the_pFile->pbHead; pb; pb = pb->next) { if('*' == dbName || getpBlock_dbName(pb) == dbName) matches += OptimizepBlock(pb); @@ -3387,6 +3573,7 @@ void OptimizepCode(char dbName) } while(matches && ++passes < MAX_PASSES); + return matches; } /*-----------------------------------------------------------------*/ @@ -3663,7 +3850,7 @@ void buildCallTree(void ) for(pb = the_pFile->pbHead; pb; pb = pb->next) { pCode *pc_fstart=NULL; for(pc = pb->pcHead; pc; pc = pc->next) { - if(isPCF(pc)) { //pc->type == PC_FUNCTION) { + if(isPCF(pc)) { if (PCF(pc)->fname) { if(STRCASECMP(PCF(pc)->fname, "_main") == 0) { @@ -3672,7 +3859,6 @@ void buildCallTree(void ) pb->dbName = 'M'; } - //_ALLOC(pbr,sizeof(pBranch)); pbr = Safe_calloc(1,sizeof(pBranch)); pbr->pc = pc_fstart = pc; pbr->next = NULL; @@ -3690,7 +3876,7 @@ void buildCallTree(void ) addSet(&pb->function_exits, pc); } - } else if(isCALL(pc)) {// if(pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL) { + } else if(isCALL(pc)) { addSet(&pb->function_calls,pc); } } @@ -3748,19 +3934,15 @@ void AnalyzepCode(char dbName) if('*' == dbName || getpBlock_dbName(pb) == dbName) { DFPRINTF((stderr," analyze and merging block %c\n",dbName)); - //fprintf(stderr," analyze and merging block %c\n",getpBlock_dbName(pb)); pBlockMergeLabels(pb); AnalyzepBlock(pb); + } else { + DFPRINTF((stderr," skipping block analysis dbName=%c blockname=%c\n",dbName,getpBlock_dbName)); } } - changes = 0; + changes = OptimizepCode(dbName); - for(pb = the_pFile->pbHead; pb; pb = pb->next) { - if('*' == dbName || getpBlock_dbName(pb) == dbName) - changes += OptimizepBlock(pb); - } - } while(changes && (i++ < MAX_PASSES)); buildCallTree(); @@ -4006,10 +4188,10 @@ void pct2(FILE *of,pBlock *pb,int indent) // set *registersInCallPath = NULL; if(!of) - return;// registers; + return; if(indent > 10) - return; // registers; //recursion ? + return; //recursion ? pc = setFirstItem(pb->function_entries); @@ -4044,77 +4226,6 @@ void pct2(FILE *of,pBlock *pb,int indent) } -#if 0 - fprintf(stderr,"pBlock before register optim.\n"); - pBlockStats(stderr,pb); // debug - - if(registersInCallPath) { - /* registers were used in the functions this pBlock has called */ - /* so now, we need to see if these collide with the ones we are using here */ - - regs *r1,*r2, *newreg; - - fprintf(stderr,"comparing registers\n"); - - r1 = setFirstItem(registersInCallPath); - while(r1) { - - r2 = setFirstItem(pb->registers); - - while(r2) { - - if(r2->rIdx == r1->rIdx) { - newreg = pic14_findFreeReg(); - - - if(!newreg) { - fprintf(stderr,"Bummer, no more registers.\n"); - exit(1); - } - - fprintf(stderr,"Cool found register collision nIdx=%d moving to %d\n", - r1->rIdx, newreg->rIdx); - r2->rIdx = newreg->rIdx; - //if(r2->name) free(r2->name); - if(newreg->name) - r2->name = Safe_strdup(newreg->name); - else - r2->name = NULL; - newreg->isFree = 0; - newreg->wasUsed = 1; - } - r2 = setNextItem(pb->registers); - } - - r1 = setNextItem(registersInCallPath); - } - - /* Collisions have been resolved. Now free the registers in the call path */ - r1 = setFirstItem(registersInCallPath); - while(r1) { - newreg = pic14_regWithIdx(r1->rIdx); - newreg->isFree = 1; - r1 = setNextItem(registersInCallPath); - } - - } else - MarkUsedRegisters(pb->registers); - - registers = unionSets(pb->registers, registersInCallPath, THROW_NONE); - - if(registers) - fprintf(stderr,"returning regs\n"); - else - fprintf(stderr,"not returning regs\n"); - - fprintf(stderr,"pBlock after register optim.\n"); - pBlockStats(stderr,pb); // debug - - - return registers; - -#endif - /*-----------------------------------------------------------------*/ /* printCallTree - writes the call tree to a file */ @@ -4161,17 +4272,6 @@ void printCallTree(FILE *of) } - /* Re-allocate the registers so that there are no collisions - * between local variables when one function call another */ -#if 0 - pic14_deallocateAllRegs(); - - for(pb = the_pFile->pbHead; pb; pb = pb->next) { - if(!pb->visited) - register_usage(pb); - } -#endif - fprintf(of,"\n**************\n\na better call tree\n"); for(pb = the_pFile->pbHead; pb; pb = pb->next) { if(pb->visited) @@ -4182,3 +4282,148 @@ void printCallTree(FILE *of) fprintf(of,"block dbname: %c\n", getpBlock_dbName(pb)); } } + + + +/*-----------------------------------------------------------------*/ +/* */ +/*-----------------------------------------------------------------*/ + +void InlineFunction(pBlock *pb) +{ + pCode *pc; + pCode *pc_call; + + if(!pb) + return; + + pc = setFirstItem(pb->function_calls); + + for( ; pc; pc = setNextItem(pb->function_calls)) { + + if(isCALL(pc)) { + pCode *pcn = findFunction(get_op_from_instruction(PCI(pc))); + pCode *pct; + pCode *pce; + + pBranch *pbr; + + if(pcn && isPCF(pcn) && (PCF(pcn)->ncalled == 1)) { + + //fprintf(stderr,"Cool can inline:\n"); + //pcn->print(stderr,pcn); + + //fprintf(stderr,"recursive call Inline\n"); + InlineFunction(pcn->pb); + //fprintf(stderr,"return from recursive call Inline\n"); + + /* + At this point, *pc points to a CALL mnemonic, and + *pcn points to the function that is being called. + + To in-line this call, we need to remove the CALL + and RETURN(s), and link the function pCode in with + the CALLee pCode. + + */ + + + /* Remove the CALL */ + pc_call = pc; + pc = pc->prev; + + /* remove callee pBlock from the pBlock linked list */ + removepBlock(pcn->pb); + + pce = pcn; + while(pce) { + pce->pb = pb; + pce = pce->next; + } + + /* Remove the Function pCode */ + pct = findNextInstruction(pcn->next); + + /* Link the function with the callee */ + pc->next = pcn->next; + pcn->next->prev = pc; + + /* Convert the function name into a label */ + + pbr = Safe_calloc(1,sizeof(pBranch)); + pbr->pc = newpCodeLabel(PCF(pcn)->fname, -1); + pbr->next = NULL; + PCI(pct)->label = pBranchAppend(PCI(pct)->label,pbr); + PCI(pct)->label = pBranchAppend(PCI(pct)->label,PCI(pc_call)->label); + + /* turn all of the return's except the last into goto's */ + /* check case for 2 instruction pBlocks */ + pce = findNextInstruction(pcn->next); + while(pce) { + pCode *pce_next = findNextInstruction(pce->next); + + if(pce_next == NULL) { + /* found the last return */ + pCode *pc_call_next = findNextInstruction(pc_call->next); + + //fprintf(stderr,"found last return\n"); + //pce->print(stderr,pce); + pce->prev->next = pc_call->next; + pc_call->next->prev = pce->prev; + PCI(pc_call_next)->label = pBranchAppend(PCI(pc_call_next)->label, + PCI(pce)->label); + } + + pce = pce_next; + } + + + } + } else + fprintf(stderr,"BUG? pCode isn't a POC_CALL %d\n",__LINE__); + + } + +} + +/*-----------------------------------------------------------------*/ +/* */ +/*-----------------------------------------------------------------*/ + +void InlinepCode(void) +{ + + pBlock *pb; + pCode *pc; + + if(!the_pFile) + return; + + + /* Loop through all of the function definitions and count the + * number of times each one is called */ + + for(pb = the_pFile->pbHead; pb; pb = pb->next) { + + pc = setFirstItem(pb->function_calls); + + for( ; pc; pc = setNextItem(pb->function_calls)) { + + if(isCALL(pc)) { + pCode *pcn = findFunction(get_op_from_instruction(PCI(pc))); + if(pcn && isPCF(pcn)) { + PCF(pcn)->ncalled++; + } + } else + fprintf(stderr,"BUG? pCode isn't a POC_CALL %d\n",__LINE__); + + } + } + + + /* Now, Loop through the function definitions again, but this + * time inline those functions that have only been called once. */ + + InlineFunction(the_pFile->pbHead); + +} diff --git a/src/pic/pcode.h b/src/pic/pcode.h index 55a5e744..f3c05fd5 100644 --- a/src/pic/pcode.h +++ b/src/pic/pcode.h @@ -233,8 +233,9 @@ typedef enum PC_LABEL, /* assembly label */ PC_FLOW, /* flow analysis */ PC_FUNCTION, /* Function start or end */ - PC_WILD /* wildcard - an opcode place holder used + PC_WILD, /* wildcard - an opcode place holder used * in the pCode peep hole optimizer */ + PC_CSOURCE /* C-Source Line */ } PC_TYPE; /************************************************/ @@ -397,6 +398,22 @@ typedef struct pCodeComment } pCodeComment; +/************************************************* + pCodeComment +**************************************************/ + +typedef struct pCodeCSource +{ + + pCode pc; + + int line_number; + char *line; + char *file_name; + +} pCodeCSource; + + /************************************************* pCodeFlow @@ -451,9 +468,9 @@ typedef struct pCodeInstruction pBranch *to; // pCodes that execute after pBranch *label; // pCode instructions that have labels - pCodeOp *pcop; /* Operand, if this instruction has one */ - - pCodeFlow *pcflow; /* flow block to which this instruction belongs */ + pCodeOp *pcop; /* Operand, if this instruction has one */ + pCodeFlow *pcflow; /* flow block to which this instruction belongs */ + pCodeCSource *cline; /* C Source from which this instruction was derived */ unsigned int num_ops; /* Number of operands (0,1,2 for mid range pics) */ unsigned int isModReg: 1; /* If destination is W or F, then 1==F */ @@ -501,6 +518,8 @@ typedef struct pCodeFunction pBranch *to; // pCodes that execute after pBranch *label; // pCode instructions that have labels + int ncalled; /* Number of times function is called */ + } pCodeFunction; @@ -673,8 +692,9 @@ typedef struct peepCommand { #define PCI(x) ((pCodeInstruction *)(x)) #define PCL(x) ((pCodeLabel *)(x)) #define PCF(x) ((pCodeFunction *)(x)) -#define PCFL(x) ((pCodeFlow *)(x)) +#define PCFL(x) ((pCodeFlow *)(x)) #define PCW(x) ((pCodeWild *)(x)) +#define PCCS(x) ((pCodeCSource *)(x)) #define PCOP(x) ((pCodeOp *)(x)) //#define PCOB(x) ((pCodeOpBit *)(x)) @@ -698,6 +718,7 @@ pCode *newpCodeCharP(char *cP); // Create a new pCode given a char pCode *newpCodeInlineP(char *cP); // Create a new pCode given a char * pCode *newpCodeFunction(char *g, char *f); // Create a new function pCode *newpCodeLabel(char *name,int key); // Create a new label given a key +pCode *newpCodeCSource(int ln, char *f, char *l); // Create a new symbol line pBlock *newpCodeChain(memmap *cm,char c, pCode *pc); // Create a new pBlock void printpBlock(FILE *of, pBlock *pb); // Write a pBlock to a file void printpCode(FILE *of, pCode *pc); // Write a pCode to a file @@ -706,7 +727,7 @@ void addpBlock(pBlock *pb); // Add a pBlock to a pFile void copypCode(FILE *of, char dbName); // Write all pBlocks with dbName to *of void movepBlock2Head(char dbName); // move pBlocks around void AnalyzepCode(char dbName); -void OptimizepCode(char dbName); +int OptimizepCode(char dbName); void printCallTree(FILE *of); void pCodePeepInit(void); void pBlockConvert2ISR(pBlock *pb); diff --git a/src/pic/pcodepeep.c b/src/pic/pcodepeep.c index 3352e97c..6963f5fb 100644 --- a/src/pic/pcodepeep.c +++ b/src/pic/pcodepeep.c @@ -23,8 +23,7 @@ #include "common.h" // Include everything in the SDCC src directory #include "newalloc.h" - - +//#define PCODE_DEBUG #include "pcode.h" #include "pcodeflow.h" #include "ralloc.h" @@ -1157,13 +1156,13 @@ void postinit_pCodeWildBlock(pCodeWildBlock *pcwb) if(!pcwb) return; - pcwb->nvars++; + pcwb->nvars+=2; pcwb->nops = pcwb->nvars; pcwb->vars = Safe_calloc(pcwb->nvars, sizeof(char *)); pcwb->wildpCodeOps = Safe_calloc(pcwb->nvars, sizeof(pCodeOp *)); - pcwb->nwildpCodes++; + pcwb->nwildpCodes+=2; pcwb->wildpCodes = Safe_calloc(pcwb->nwildpCodes, sizeof(pCode *)); } @@ -1221,19 +1220,6 @@ void peepRules2pCode(peepRule *rules) pcps = Safe_calloc(1,sizeof(pCodePeepSnippets)); peepSnippets = DLL_append((_DLL*)peepSnippets,(_DLL*)pcps); -/* - curPeep = pcps->peep = Safe_calloc(1,sizeof(pCodePeep)); - - curPeep->vars = NULL; - curPeep->wildpCodes = NULL; curPeep->wildpCodeOps = NULL; - curPeep->postFalseCond = PCC_NONE; - curPeep->postTrueCond = PCC_NONE; - - - curPeep->target = curBlock = newpCodeChain(NULL, 'W', NULL); - sMaxWildVar = 0; - sMaxWildMnem = 0; -*/ currentRule = pcps->peep = Safe_calloc(1,sizeof(pCodePeep)); initpCodePeep(currentRule); @@ -1254,8 +1240,6 @@ void peepRules2pCode(peepRule *rules) //DFPRINTF((stderr,"\nReplaced by:\n")); - //curPeep->replace = curBlock = newpCodeChain(NULL, 'W', NULL); - /* Convert the replace block */ peepRuleBlock2pCodeBlock(pr->replace, ¤tRule->replace); @@ -1263,7 +1247,7 @@ void peepRules2pCode(peepRule *rules) //printpBlock(stderr, curBlock); //DFPRINTF((stderr,"replace with labels merged:\n")); - //pBlockMergeLabels(curBlock); + pBlockMergeLabels(currentRule->replace.pb); //printpBlock(stderr, currentRule->replace.pb); @@ -1272,18 +1256,8 @@ void peepRules2pCode(peepRule *rules) /* The rule has been converted to pCode. Now allocate * space for the wildcards */ -/* - ++sMaxWildVar; - curPeep->nvars = sMaxWildVar; - curPeep->vars = Safe_calloc(sMaxWildVar, sizeof(char *)); - - curPeep->nops = sMaxWildVar; - curPeep->wildpCodeOps = Safe_calloc(sMaxWildVar, sizeof(pCodeOp *)); - - curPeep->nwildpCodes = ++sMaxWildMnem; - curPeep->wildpCodes = Safe_calloc(sMaxWildMnem, sizeof(char *)); -*/ postinit_pCodeWildBlock(¤tRule->target); + postinit_pCodeWildBlock(¤tRule->replace); //return; // debug ... don't want to go through all the rules yet } @@ -1455,31 +1429,49 @@ int pCodePeepMatchLabels(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) /* Check for a label associated with this wild pCode */ // If the wild card has a label, make sure the source code does too. if(PCI(pcd)->label) { - pCode *pcl; + pCode *pcl = PCI(pcd)->label->pc; + +#ifdef PCODE_DEBUG + int li = -PCL(pcl)->key; + + if(peepBlock->target.vars[li] == NULL) { + if(PCI(pcs)->label) { + DFPRINTF((stderr,"first time for a label: %d %s\n",li,PCL(PCI(pcs)->label->pc)->label)); + } + } else { + // DFPRINTF((stderr,"label id = %d \n",PCL(PCI(pcd)->label->pc)->key)); + DFPRINTF((stderr," label id: %d %s\n",li,peepBlock->target.vars[li])); + if(PCI(pcs)->label) { + DFPRINTF((stderr," src %s\n",PCL(PCI(pcs)->label->pc)->label)); + } + } +#endif + if(!PCI(pcs)->label) return 0; - pcl = PCI(pcd)->label->pc; - labindex = -PCL(pcl)->key; - //DFPRINTF((stderr,"label id = %d (labindex = %d)\n",PCL(pcl)->key,labindex)); if(peepBlock->target.vars[labindex] == NULL) { // First time to encounter this label peepBlock->target.vars[labindex] = PCL(PCI(pcs)->label->pc)->label; - //DFPRINTF((stderr,"first time for a label: %d %s\n",labindex, peepBlock->vars[labindex])); + DFPRINTF((stderr,"first time for a label: %d %s\n",labindex,PCL(PCI(pcs)->label->pc)->label)); + } else { if(strcmp(peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label) != 0) { - // DFPRINTF((stderr,"labels don't match\n")); + DFPRINTF((stderr,"labels don't match dest %s != src %s\n",peepBlock->target.vars[labindex],PCL(PCI(pcs)->label->pc)->label)); return 0; } - //DFPRINTF((stderr,"matched a label\n")); + DFPRINTF((stderr,"matched a label %d %s -hey\n",labindex,peepBlock->target.vars[labindex])); } } else { - // DFPRINTF((stderr,"destination doesn't have a label\n")); + //DFPRINTF((stderr,"destination doesn't have a label\n")); if(PCI(pcs)->label) return 0; + + //DFPRINTF((stderr,"neither src nor dest have labels\n")); + } return 1; @@ -1520,6 +1512,12 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) /* one-for-one match. Here the source and destination opcodes * are not wild. However, there may be a label or a wild operand */ + if(pcs) { + if(PCI(pcs)->label) { + DFPRINTF((stderr,"Match line source label: %s\n",PCL(PCI(pcs)->label->pc)->label)); + } + } + if(pcs->type == pcd->type) { if(pcs->type == PC_OPCODE) { @@ -1528,11 +1526,11 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) if(PCI(pcs)->op != PCI(pcd)->op) return 0; - /* +#ifdef PCODE_DEBUG DFPRINTF((stderr,"%s comparing\n",__FUNCTION__)); pcs->print(stderr,pcs); pcd->print(stderr,pcd); - */ +#endif if(!pCodePeepMatchLabels(peepBlock, pcs, pcd)) return 0; @@ -1586,7 +1584,7 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) if(peepBlock->target.vars[index]) return (strcmp(peepBlock->target.vars[index],n) == 0); else { - // DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n)); + DFPRINTF((stderr,"first time for a variable: %d, %s\n",index,n)); peepBlock->target.vars[index] = n; return 1; } @@ -1607,19 +1605,21 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) index = PCW(pcd)->id; - - // DFPRINTF((stderr,"%s comparing wild cards\n",__FUNCTION__)); - //pcs->print(stderr,pcs); - //pcd->print(stderr,pcd); - +#ifdef PCODE_DEBUG + DFPRINTF((stderr,"%s comparing wild cards\n",__FUNCTION__)); + pcs->print(stderr,pcs); + pcd->print(stderr,pcd); +#endif peepBlock->target.wildpCodes[PCW(pcd)->id] = pcs; - if(!pCodePeepMatchLabels(peepBlock, pcs, pcd)) + if(!pCodePeepMatchLabels(peepBlock, pcs, pcd)) { + DFPRINTF((stderr," Failing because labels don't match\n")); return 0; + } if(PCW(pcd)->mustBeBitSkipInst & !(PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) { // doesn't match because the wild pcode must be a bit skip - //fprintf(stderr," Failing match because bit skip is req:\n"); + DFPRINTF((stderr," Failing match because bit skip is req\n")); //pcd->print(stderr,pcd); //pcs->print(stderr,pcs); return 0; @@ -1627,7 +1627,7 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) if(PCW(pcd)->mustNotBeBitSkipInst & (PCI(pcs)->isBitInst && PCI(pcs)->isSkip)) { // doesn't match because the wild pcode must *not* be a bit skip - //fprintf(stderr," Failing match because don't want skip :\n"); + DFPRINTF((stderr," Failing match because shouldn't be bit skip\n")); //pcd->print(stderr,pcd); //pcs->print(stderr,pcs); return 0; @@ -1637,18 +1637,20 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) PCOW(PCI(pcd)->pcop)->matched = PCI(pcs)->pcop; if(peepBlock->target.vars[index]) { int i = (strcmp(peepBlock->target.vars[index],PCI(pcs)->pcop->name) == 0); - /* +#ifdef PCODE_DEBUG + if(i) DFPRINTF((stderr," (matched)\n")); else { DFPRINTF((stderr," (no match: wild card operand mismatch\n")); - DFPRINTF((stderr," peepblock= %s, pcodeop= %s\n"), - peepBlock->vars[index], - PCI(pcs)->pcop->name); + DFPRINTF((stderr," peepblock= %s, pcodeop= %s\n", + peepBlock->target.vars[index], + PCI(pcs)->pcop->name)); } - */ +#endif return i; } else { + DFPRINTF((stderr," (matched %s\n",PCI(pcs)->pcop->name)); peepBlock->target.vars[index] = PCI(pcs)->pcop->name; return 1; } @@ -1678,10 +1680,27 @@ void pCodePeepClrVars(pCodePeep *pcp) if(!pcp) return; - for(i=0;itarget.nvars; i++) { + DFPRINTF((stderr," Clearing peep rule vars\n")); + DFPRINTF((stderr," %d %d %d %d %d %d\n", + pcp->target.nvars,pcp->target.nops,pcp->target.nwildpCodes, + pcp->replace.nvars,pcp->replace.nops,pcp->replace.nwildpCodes)); + + for(i=0;itarget.nvars; i++) pcp->target.vars[i] = NULL; + for(i=0;itarget.nops; i++) pcp->target.wildpCodeOps[i] = NULL; - } + for(i=0;itarget.nwildpCodes; i++) + pcp->target.wildpCodes[i] = NULL; + + for(i=0;ireplace.nvars; i++) + pcp->replace.vars[i] = NULL; + for(i=0;ireplace.nops; i++) + pcp->replace.wildpCodeOps[i] = NULL; + for(i=0;ireplace.nwildpCodes; i++) + pcp->replace.wildpCodes[i] = NULL; + + + } /*-----------------------------------------------------------------*/ @@ -1857,6 +1876,7 @@ int pCodePeepMatchRule(pCode *pc) { pCodePeep *peepBlock; pCode *pct, *pcin; + pCodeCSource *pc_cline=NULL; _DLL *peeprules; int matched; @@ -1871,12 +1891,20 @@ int pCodePeepMatchRule(pCode *pc) } pCodePeepClrVars(peepBlock); - +/* pcin = pc; if(IS_PCCOMMENT(pcin)) pc = pcin = findNextInstruction(pcin->next); +*/ + pcin = pc = findNextInstruction(pc); pct = peepBlock->target.pb->pcHead; +#ifdef PCODE_DEBUG + { + pCode *pcr = peepBlock->replace.pb->pcHead; + if(pcr) pct->print(stderr,pcr); + } +#endif matched = 0; while(pct && pcin) { @@ -1891,8 +1919,9 @@ int pCodePeepMatchRule(pCode *pc) DFPRINTF((stderr," partial match... no more code\n")); matched = 0; } - if(!pct) + if(!pct) { DFPRINTF((stderr," end of rule\n")); + } } if(matched) { @@ -1924,11 +1953,12 @@ int pCodePeepMatchRule(pCode *pc) printpCodeString(stderr,peepBlock->target.pb->pcHead,10); DFPRINTF((stderr,"first thing matched\n")); pc->print(stderr,pc); -#endif if(pcin) { DFPRINTF((stderr,"last thing matched\n")); pcin->print(stderr,pcin); } +#endif + /* Unlink the original code */ pcprev = pc->prev; @@ -1936,21 +1966,38 @@ int pCodePeepMatchRule(pCode *pc) if(pcin) pcin->prev = pc->prev; + + { /* DEBUG */ /* Converted the deleted pCodes into comments */ char buf[256]; + pCodeCSource *pc_cline2=NULL; buf[0] = ';'; buf[1] = '#'; while(pc && pc!=pcin) { + + if(pc->type == PC_OPCODE && PCI(pc)->cline) { + if(pc_cline) { + pc_cline2->pc.next = PCODE(PCI(pc)->cline); + pc_cline2 = PCCS(pc_cline2->pc.next); + } else { + pc_cline = pc_cline2 = PCI(pc)->cline; + pc_cline->pc.seq = pc->seq; + } + } + pCode2str(&buf[2], 254, pc); pCodeInsertAfter(pcprev, newpCodeCharP(buf)); pcprev = pcprev->next; pc = pc->next; + } + if(pc_cline2) + pc_cline2->pc.next = NULL; } if(pcin) @@ -1961,6 +2008,7 @@ int pCodePeepMatchRule(pCode *pc) pcr = peepBlock->replace.pb->pcHead; // This is the replacement code while (pcr) { pCodeOp *pcop=NULL; + /* If the replace pcode is an instruction with an operand, */ /* then duplicate the operand (and expand wild cards in the process). */ if(pcr->type == PC_OPCODE) { @@ -1991,16 +2039,30 @@ int pCodePeepMatchRule(pCode *pc) pc = pc->next; - //if(pc) - // pc->print(stderr,pc); +#ifdef PCODE_DEBUG + DFPRINTF((stderr," NEW Code:")); + if(pc) pc->print(stderr,pc); +#endif pcr = pcr->next; } + /* We have just replaced the inefficient code with the rule. + * Now, we need to re-add the C-source symbols if there are any */ + pc = pcprev; + while(pc_cline ) { + + pc = findNextInstruction(pc->next); + PCI(pc)->cline = pc_cline; + pc_cline = PCCS(pc_cline->pc.next); + + } + return 1; } next_rule: peeprules = peeprules->next; } + DFPRINTF((stderr," no rule matched\n")); return 0; } diff --git a/src/regression/compare10.c b/src/regression/compare10.c index f8f045c3..6582aad6 100644 --- a/src/regression/compare10.c +++ b/src/regression/compare10.c @@ -21,6 +21,40 @@ signed char char1 = 0; char long0 = 0; char long1 = 0; +/* copied from 16f877.inc file supplied with gpasm */ + +#define _CP_ALL 0x0FCF +#define _CP_HALF 0x1FDF +#define _CP_UPPER_256 0x2FEF +#define _CP_OFF 0x3FFF +#define _DEBUG_ON 0x37FF +#define _DEBUG_OFF 0x3FFF +#define _WRT_ENABLE_ON 0x3FFF +#define _WRT_ENABLE_OFF 0x3DFF +#define _CPD_ON 0x3EFF +#define _CPD_OFF 0x3FFF +#define _LVP_ON 0x3FFF +#define _LVP_OFF 0x3F7F +#define _BODEN_ON 0x3FFF +#define _BODEN_OFF 0x3FBF +#define _PWRTE_OFF 0x3FFF +#define _PWRTE_ON 0x3FF7 +#define _WDT_ON 0x3FFF +#define _WDT_OFF 0x3FFB +#define _LP_OSC 0x3FFC +#define _XT_OSC 0x3FFD +#define _HS_OSC 0x3FFE +#define _RC_OSC 0x3FFF + +/* *** NOTE *** This particular test takes quite a while to run + * ~ 10,000,000 instruction cycles. (2.5 seconds on a 20Mhz PIC). + * The WDT will reset the CPU if it's enabled. So disable it... +*/ + +typedef unsigned int word; + +word at 0x2007 CONFIG = _WDT_OFF & _PWRTE_ON; + void done () { diff --git a/src/regression/compare7.c b/src/regression/compare7.c index fb665c7e..30fa333d 100644 --- a/src/regression/compare7.c +++ b/src/regression/compare7.c @@ -19,6 +19,41 @@ signed char char1 = 0; char long0 = 0; char long1 = 0; + +/* copied from 16f877.inc file supplied with gpasm */ + +#define _CP_ALL 0x0FCF +#define _CP_HALF 0x1FDF +#define _CP_UPPER_256 0x2FEF +#define _CP_OFF 0x3FFF +#define _DEBUG_ON 0x37FF +#define _DEBUG_OFF 0x3FFF +#define _WRT_ENABLE_ON 0x3FFF +#define _WRT_ENABLE_OFF 0x3DFF +#define _CPD_ON 0x3EFF +#define _CPD_OFF 0x3FFF +#define _LVP_ON 0x3FFF +#define _LVP_OFF 0x3F7F +#define _BODEN_ON 0x3FFF +#define _BODEN_OFF 0x3FBF +#define _PWRTE_OFF 0x3FFF +#define _PWRTE_ON 0x3FF7 +#define _WDT_ON 0x3FFF +#define _WDT_OFF 0x3FFB +#define _LP_OSC 0x3FFC +#define _XT_OSC 0x3FFD +#define _HS_OSC 0x3FFE +#define _RC_OSC 0x3FFF + +/* *** NOTE *** This particular test takes quite a while to run + * ~ 10,000,000 instruction cycles. (2.5 seconds on a 20Mhz PIC). + * The WDT will reset the CPU if it's enabled. So disable it... +*/ + +typedef unsigned int word; + +word at 0x2007 CONFIG = _WDT_OFF & _PWRTE_ON; + void done () { @@ -188,6 +223,7 @@ void int_compare1(void) for(int0 = 0x201; int0 != 0x7fff; int0++) c_int_lt_lit1(0); + } diff --git a/src/regression/compare8.c b/src/regression/compare8.c index 838d16bc..e7191684 100644 --- a/src/regression/compare8.c +++ b/src/regression/compare8.c @@ -21,6 +21,41 @@ signed char char1 = 0; char long0 = 0; char long1 = 0; + +/* copied from 16f877.inc file supplied with gpasm */ + +#define _CP_ALL 0x0FCF +#define _CP_HALF 0x1FDF +#define _CP_UPPER_256 0x2FEF +#define _CP_OFF 0x3FFF +#define _DEBUG_ON 0x37FF +#define _DEBUG_OFF 0x3FFF +#define _WRT_ENABLE_ON 0x3FFF +#define _WRT_ENABLE_OFF 0x3DFF +#define _CPD_ON 0x3EFF +#define _CPD_OFF 0x3FFF +#define _LVP_ON 0x3FFF +#define _LVP_OFF 0x3F7F +#define _BODEN_ON 0x3FFF +#define _BODEN_OFF 0x3FBF +#define _PWRTE_OFF 0x3FFF +#define _PWRTE_ON 0x3FF7 +#define _WDT_ON 0x3FFF +#define _WDT_OFF 0x3FFB +#define _LP_OSC 0x3FFC +#define _XT_OSC 0x3FFD +#define _HS_OSC 0x3FFE +#define _RC_OSC 0x3FFF + +/* *** NOTE *** This particular test takes quite a while to run + * ~ 10,000,000 instruction cycles. (2.5 seconds on a 20Mhz PIC). + * The WDT will reset the CPU if it's enabled. So disable it... +*/ + +typedef unsigned int word; + +word at 0x2007 CONFIG = _WDT_OFF & _PWRTE_ON; + void done () { diff --git a/src/regression/compare9.c b/src/regression/compare9.c index 6e4fa3c5..6f79bc16 100644 --- a/src/regression/compare9.c +++ b/src/regression/compare9.c @@ -16,6 +16,40 @@ int int1 = 0; signed char char0 = 0; signed char char1 = 0; +/* copied from 16f877.inc file supplied with gpasm */ + +#define _CP_ALL 0x0FCF +#define _CP_HALF 0x1FDF +#define _CP_UPPER_256 0x2FEF +#define _CP_OFF 0x3FFF +#define _DEBUG_ON 0x37FF +#define _DEBUG_OFF 0x3FFF +#define _WRT_ENABLE_ON 0x3FFF +#define _WRT_ENABLE_OFF 0x3DFF +#define _CPD_ON 0x3EFF +#define _CPD_OFF 0x3FFF +#define _LVP_ON 0x3FFF +#define _LVP_OFF 0x3F7F +#define _BODEN_ON 0x3FFF +#define _BODEN_OFF 0x3FBF +#define _PWRTE_OFF 0x3FFF +#define _PWRTE_ON 0x3FF7 +#define _WDT_ON 0x3FFF +#define _WDT_OFF 0x3FFB +#define _LP_OSC 0x3FFC +#define _XT_OSC 0x3FFD +#define _HS_OSC 0x3FFE +#define _RC_OSC 0x3FFF + +/* *** NOTE *** This particular test takes quite a while to run + * ~ 10,000,000 instruction cycles. (2.5 seconds on a 20Mhz PIC). + * The WDT will reset the CPU if it's enabled. So disable it... +*/ + +typedef unsigned int word; + +word at 0x2007 CONFIG = _WDT_OFF & _PWRTE_ON; + void done () { diff --git a/src/regression/pointer1.c b/src/regression/pointer1.c index 435b778d..6b738ee0 100644 --- a/src/regression/pointer1.c +++ b/src/regression/pointer1.c @@ -12,6 +12,8 @@ unsigned char achar0 = 0; unsigned char achar1 = 0; unsigned char *acharP = 0; +char buff[10]; + void done () { @@ -56,9 +58,67 @@ f3 (void) return &achar0; } +void f4(unsigned char *ucP, unsigned char uc) +{ + + if(!ucP) { + failures++; + return; + } + + if(*ucP != uc) + failures++; + +} + +void init_array(char start_value) +{ + unsigned char c; + + for(c=0; c