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)
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))));
/*-----------------------------------------------------------------*/
/* 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;
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 */
/* 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 {
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 {
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 */
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 ) {
if (size)
pic14_emitcode("inc","%s",rname);
}
+*/
}
/* now some housekeeping stuff */
}
/* done */
+ freeAsmop(left,NULL,ic,TRUE);
freeAsmop(result,NULL,ic,TRUE);
}
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);
}
/*-----------------------------------------------------------------*/
}
/* 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++;
}
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 ;
}
static pFile *the_pFile = NULL;
-static int peepOptimizing = 0;
+static int peepOptimizing = 1;
static int GpCodeSequenceNumber = 1;
static int GpcFlowSeq = 1;
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
1,1, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
1,1, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
0,1, // dest, bit instruction
1,1, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
0,1, // dest, bit instruction
1,1, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
1, // num ops
0,0, // dest, bit instruction
1,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
0, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
1,0, // dest, bit instruction
1,1, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
0,0, // dest, bit instruction
1,1, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
1, // num ops
0,0, // dest, bit instruction
1,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
1,0, // dest, bit instruction
1,1, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
0,0, // dest, bit instruction
1,1, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
0, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
0, // num ops
0,0, // dest, bit instruction
1,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
1, // num ops
0,0, // dest, bit instruction
1,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
0, // num ops
0,0, // dest, bit instruction
1,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
1,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
2, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
NULL, // label
NULL, // operand
NULL, // flow block
+ NULL, // C source
1, // num ops
0,0, // dest, bit instruction
0,0, // branch, skip
void pCodeInitRegisters(void)
{
- initStack(0x38, 8);
+ initStack(0xfff, 8);
init_pic(port->processor);
pc_status.r = allocProcessorRegister(IDX_STATUS,"STATUS", PO_STATUS, 0x80);
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);
}
+/*-----------------------------------------------------------------*/
+/* 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. */
/*-----------------------------------------------------------------*/
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 */
/*-----------------------------------------------------------------*/
if(pc) {
+#ifdef PCODE_DEBUG
+ fprintf(stderr,"Unlinking: ");
+ printpCode(stderr, pc);
+#endif
if(pc->prev)
pc->prev->next = pc->next;
if(pc->next)
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;
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;
}
}
+ if(PCI(pc)->cline)
+ genericPrint(of,PCODE(PCI(pc)->cline));
{
char str[256];
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);
/* 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);
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)
{
/*-----------------------------------------------------------------*/
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;
* 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);
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;
+ }
+
}
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
-void OptimizepCode(char dbName)
+int OptimizepCode(char dbName)
{
#define MAX_PASSES 4
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);
}
while(matches && ++passes < MAX_PASSES);
+ return matches;
}
/*-----------------------------------------------------------------*/
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) {
pb->dbName = 'M';
}
- //_ALLOC(pbr,sizeof(pBranch));
pbr = Safe_calloc(1,sizeof(pBranch));
pbr->pc = pc_fstart = pc;
pbr->next = NULL;
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);
}
}
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();
// set *registersInCallPath = NULL;
if(!of)
- return;// registers;
+ return;
if(indent > 10)
- return; // registers; //recursion ?
+ return; //recursion ?
pc = setFirstItem(pb->function_entries);
}
-#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 */
}
- /* 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)
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);
+
+}
#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"
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 *));
}
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);
//DFPRINTF((stderr,"\nReplaced by:\n"));
- //curPeep->replace = curBlock = newpCodeChain(NULL, 'W', NULL);
-
/* Convert the replace block */
peepRuleBlock2pCodeBlock(pr->replace, ¤tRule->replace);
//printpBlock(stderr, curBlock);
//DFPRINTF((stderr,"replace with labels merged:\n"));
- //pBlockMergeLabels(curBlock);
+
pBlockMergeLabels(currentRule->replace.pb);
//printpBlock(stderr, currentRule->replace.pb);
/* 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
}
/* 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;
/* 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) {
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;
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;
}
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;
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;
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;
}
if(!pcp)
return;
- for(i=0;i<pcp->target.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;i<pcp->target.nvars; i++)
pcp->target.vars[i] = NULL;
+ for(i=0;i<pcp->target.nops; i++)
pcp->target.wildpCodeOps[i] = NULL;
- }
+ for(i=0;i<pcp->target.nwildpCodes; i++)
+ pcp->target.wildpCodes[i] = NULL;
+
+ for(i=0;i<pcp->replace.nvars; i++)
+ pcp->replace.vars[i] = NULL;
+ for(i=0;i<pcp->replace.nops; i++)
+ pcp->replace.wildpCodeOps[i] = NULL;
+ for(i=0;i<pcp->replace.nwildpCodes; i++)
+ pcp->replace.wildpCodes[i] = NULL;
+
+
+
}
/*-----------------------------------------------------------------*/
{
pCodePeep *peepBlock;
pCode *pct, *pcin;
+ pCodeCSource *pc_cline=NULL;
_DLL *peeprules;
int matched;
}
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) {
DFPRINTF((stderr," partial match... no more code\n"));
matched = 0;
}
- if(!pct)
+ if(!pct) {
DFPRINTF((stderr," end of rule\n"));
+ }
}
if(matched) {
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;
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)
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) {
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;
}