From 19693155e102bd3284ecc3c8a7fe7cf7332b60b4 Mon Sep 17 00:00:00 2001 From: sdattalo Date: Tue, 11 Dec 2001 15:20:51 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1673 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- src/pic/gen.c | 432 +++++++++++++++++++++++++++++--------- src/pic/genarith.c | 52 ++++- src/pic/pcode.c | 30 ++- src/pic/pcode.h | 1 + src/pic/ralloc.c | 37 +++- src/pic/ralloc.h | 6 + src/regression/compare7.c | 298 ++++++++++++++++++++++++++ src/regression/compare8.c | 311 +++++++++++++++++++++++++++ 8 files changed, 1060 insertions(+), 107 deletions(-) create mode 100644 src/regression/compare7.c create mode 100644 src/regression/compare8.c diff --git a/src/pic/gen.c b/src/pic/gen.c index 50f5c867..f34f6277 100644 --- a/src/pic/gen.c +++ b/src/pic/gen.c @@ -3481,6 +3481,34 @@ static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit) emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key)); rifx->generated = 1; } + +/*-----------------------------------------------------------------*/ +/* genChkZeroes :- greater or less than comparison */ +/* For each byte in a literal that is zero, inclusive or the */ +/* the corresponding byte in the operand with W */ +/* returns true if any of the bytes are zero */ +/*-----------------------------------------------------------------*/ +static int genChkZeroes(operand *op, int lit, int size) +{ + + int i; + int flag =1; + + while(size--) { + i = (lit >> (size*8)) & 0xff; + + if(i==0) { + if(flag) + emitpcode(POC_MOVFW, popGet(AOP(op),size)); + else + emitpcode(POC_IORFW, popGet(AOP(op),size)); + flag = 0; + } + } + + return (flag==0); +} + /*-----------------------------------------------------------------*/ /* genCmp :- greater or less than comparison */ /*-----------------------------------------------------------------*/ @@ -3523,6 +3551,7 @@ static void genCmp (operand *left,operand *right, symbol *lbl = newiTempLabel(NULL); int flag; + int emitFinalCheck=1; symbol *truelbl = newiTempLabel(NULL); @@ -3532,10 +3561,18 @@ static void genCmp (operand *left,operand *right, DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign); + /* special cases */ + if(lit == 0) { + + if(sign != 0) + genSkipCond(&rIfx,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(rIfx.lbl->key)); - if(lit == 0 && sign == 0) { - /* no need to compare to 0...*/ if(ifx) ifx->generated = 1; return; @@ -3543,63 +3580,215 @@ static void genCmp (operand *left,operand *right, size--; if(size == 0) { - i = (lit >> (size*8)) & 0xff; + //i = (lit >> (size*8)) & 0xff; DEBUGpic14_emitcode(";right lit","line = %d",__LINE__); - switch(i) { - case 0: - if(sign) - genSkipCond(&rIfx,left,0,7); - break; - default: - emitpcode(POC_MOVFW, popGet(AOP(left),size)); + emitpcode(POC_MOVFW, popGet(AOP(left),size)); - i = ((0-i) & 0xff); - if(sign) { + 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(&rIfx); + } else { emitpcode(POC_ADDLW, popGetLit(0x80)); emitpcode(POC_ADDLW, popGetLit(i^0x80)); - } else { - emitpcode(POC_ADDLW, popGetLit(i)); + genSkipc(&rIfx); } + + } else { + emitpcode(POC_ADDLW, popGetLit(i)); genSkipc(&rIfx); + } if(ifx) ifx->generated = 1; return; } - + /* chars are out of the way. now do ints and longs */ DEBUGpic14_emitcode(";right lit","line = %d",__LINE__); - flag=1; - size++; - while(size--) { - i = (lit >> (size*8)) & 0xff; - if(sign && flag) { - /* handle the first byte differently in signed compares */ + /* special cases */ + + if(sign) { + unsigned int mlit = -lit; + + if(lit == 0) { + genSkipCond(&rIfx,left,size,7); + if(ifx) ifx->generated = 1; + return; + } + if(lit <0x100) { + 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)); + emitpcode(POC_GOTO, popGetLabel(truelbl->key)); + 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--)); + + emitSKPNZ; + + genSkipc(&rIfx); + emitpLabel(truelbl->key); + if(ifx) ifx->generated = 1; + return; + + } + + 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(((-i)&0xff) ^ 0x80)); + emitpcode(POC_ADDLW, popGetLit( 0x80)); + emitpcode(POC_ADDLW, popGetLit(0x100-i)); genSkipc(&rIfx); - emitSKPZ; + + + 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(&rIfx); + + + if(ifx) ifx->generated = 1; + return; + + } + +#if 0 + if( lit < 0x10000) { + /* upper word is zero */ + 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)); emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - flag=0; + emitpcode(POC_MOVLW, popGetLit((lit >> (1*8)) & 0xff)); + emitpcode(POC_SUBFW, popGet(AOP(left),1)); + emitpcode(POC_MOVLW, popGetLit((lit & 0xff)); + emitSKPNZ; + emitpcode(POC_SUBFW, popGet(AOP(left),0)); + + emitpcode(POC_IORFW, popGet(AOP(left),2)); + emitpcode(POC_IORFW, popGet(AOP(left),3)); + + emitSKPNZ; + + genSkipc(&rIfx); + emitpLabel(truelbl->key); + if(ifx) ifx->generated = 1; + return; + + } +#endif + + } + + + if(lit & (0x80 << (size*8))) { + /* lit is negative */ + DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); + + genSkipCond(&rIfx,left,size,7); } 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)); + emitpcode(POC_GOTO, popGetLabel(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(&rIfx); + + 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)); + } + + genSkipc(&rIfx); + + emitpLabel(truelbl->key); + + if(ifx) ifx->generated = 1; + return; + + + } + + + /* 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); + + + //genChkZeroes(left) + + /* 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)); - if(size) { - emitSKPZ; - emitpcode(POC_GOTO, popGetLabel(lbl->key)); - } + } 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)); } } + + emitpLabel(lbl->key); - genSkipc(&rIfx); + if(emitFinalCheck) + genSkipc(&rIfx); if(sign) emitpLabel(truelbl->key); @@ -3611,24 +3800,36 @@ static void genCmp (operand *left,operand *right, if(AOP_TYPE(left) == AOP_LIT) { //symbol *lbl = newiTempLabel(NULL); - + unsigned long mlit; lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit)); + mlit = -lit; DEBUGpic14_emitcode(";left lit","lit = %d,sign=%d",lit,sign); /* Special cases */ - if((lit == 0)&& (sign==0)) { + if((lit == 0) && (sign == 0)){ size--; emitpcode(POC_MOVFW, popGet(AOP(right),size)); while(size) emitpcode(POC_IORFW, popGet(AOP(right),--size)); + + //rIfx.condition ^= 1; genSkipz2(&rIfx); 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 */ + emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key)); + if(ifx) ifx->generated = 1; + return; + } + if(sign) { if((lit+1)&0xff) { emitpcode(POC_MOVFW, popGet(AOP(right),0)); @@ -3637,6 +3838,7 @@ static void genCmp (operand *left,operand *right, rIfx.condition ^= 1; genSkipc(&rIfx); } else { + rIfx.condition ^= 1; genSkipCond(&rIfx,right,0,7); } @@ -3652,33 +3854,84 @@ static void genCmp (operand *left,operand *right, genSkipz2(&rIfx); } } + + if(ifx) ifx->generated = 1; + return; + } else { - flag = 1; - while(size--) { - i = (lit >> (size*8)) & 0xff; + /* Size is greater than 1 */ - if(flag && sign) { - /* Handle first byte of compare differently */ - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(i) { - emitpcode(POC_MOVFW, popGet(AOP(right),size)); - emitpcode(POC_ADDLW, popGetLit(0x80)); - emitpcode(POC_SUBLW, popGetLit( (i & 0xff) ^ 0x80)); - //rIfx.condition ^= 1; - genSkipc(&rIfx); - emitSKPZ; - emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - } else { - rIfx.condition ^= 1; - genSkipCond(&rIfx,right,size,7); - rIfx.condition ^= 1; - } + if(sign) { + int mlit = -lit; + int lp1 = lit+1; + + size--; + + if(lp1 == 0) { + /* this means lit = 0xffffffff, or -1 */ + + + DEBUGpic14_emitcode(";left lit = -1","line = %d ",__LINE__); + rIfx.condition ^= 1; + genSkipCond(&rIfx,right,size,7); + if(ifx) ifx->generated = 1; + return; + } + + if(lit == 0) { + int s = size; + emitpcode(POC_MOVFW, popGet(AOP(right),size)); + while(size--) + emitpcode(POC_IORFW, popGet(AOP(right),size)); + + emitSKPZ; + rIfx.condition ^= 1; + genSkipCond(&rIfx,right,s,7); + 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); + emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0)); + emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - flag = 0; } else { + /* Lit is greater than or equal to zero */ + DEBUGpic14_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit); + rIfx.condition ^= 1; + genSkipCond(&rIfx,right,size,7); + rIfx.condition ^= 1; + + } + emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff)); + emitpcode(POC_SUBFW, popGet(AOP(right),size)); + + while(size--) { + + emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff)); + emitSKPNZ; + emitpcode(POC_SUBFW, popGet(AOP(right),size)); + } + rIfx.condition ^= 1; + genSkipc(&rIfx); + + emitpLabel(truelbl->key); + + if(ifx) ifx->generated = 1; + return; + + } else { + /* Unsigned compare for sizes greater than 1 */ + + while(size--) { + i = (lit >> (size*8)) & 0xff; + if(size) { DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -3687,28 +3940,27 @@ static void genCmp (operand *left,operand *right, emitSKPZ; emitpcode(POC_GOTO, popGetLabel(lbl->key)); } else { - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); emitpcode(POC_MOVLW, popGetLit((i+1)&0xff)); emitpcode(POC_SUBFW, popGet(AOP(right),size)); } } - } - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - emitpLabel(lbl->key); + emitpLabel(lbl->key); - rIfx.condition ^= 1; - genSkipc(&rIfx); + rIfx.condition ^= 1; + genSkipc(&rIfx); - } + } if(sign) emitpLabel(truelbl->key); if(ifx) ifx->generated = 1; return; + } } - /* Compare two variables */ DEBUGpic14_emitcode(";sign","%d",sign); @@ -4108,18 +4360,19 @@ static void genCmpEq (iCode *ic, iCode *ifx) is not */ if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) { - operand *t = IC_RIGHT(ic); - IC_RIGHT(ic) = IC_LEFT(ic); - IC_LEFT(ic) = t; + operand *tmp = right ; + right = left; + left = tmp; } + if(ifx && !AOP_SIZE(result)){ symbol *tlbl; /* if they are both bit variables */ if (AOP_TYPE(left) == AOP_CRY && ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) { if(AOP_TYPE(right) == AOP_LIT){ - unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); + unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); if(lit == 0L){ pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); pic14_emitcode("cpl","c"); @@ -4153,7 +4406,6 @@ static void genCmpEq (iCode *ic, iCode *ifx) if(AOP_TYPE(right) == AOP_LIT) { lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - switch(size) { case 1: @@ -4294,7 +4546,7 @@ static void genCmpEq (iCode *ic, iCode *ifx) if (AOP_TYPE(left) == AOP_CRY && ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) { if(AOP_TYPE(right) == AOP_LIT){ - unsigned long lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); + unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); if(lit == 0L){ pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); pic14_emitcode("cpl","c"); @@ -8715,10 +8967,6 @@ static void genCast (iCode *ic) size = AOP_SIZE(right); offset = 0 ; while (size--) { - pic14_emitcode(";","%d",__LINE__); - /* aopPut(AOP(result), - aopGet(AOP(right),offset,FALSE,FALSE), - offset); */ emitpcode(POC_MOVFW, popGet(AOP(right),offset)); emitpcode(POC_MOVWF, popGet(AOP(result),offset)); offset++; @@ -8728,39 +8976,31 @@ static void genCast (iCode *ic) size = AOP_SIZE(result) - AOP_SIZE(right); /* if unsigned or not an integral type */ if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) { - while (size--) { - emitpcode(POC_CLRF, popGet(AOP(result),offset)); - pic14_emitcode("clrf","%s ;%d",aopGet(AOP(result),offset,FALSE,FALSE),__LINE__); - offset++; - } + while (size--) + emitpcode(POC_CLRF, popGet(AOP(result),offset++)); } else { /* we need to extend the sign :{ */ - emitpcodeNULLop(POC_CLRW); - - if(offset) - emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0)); - else - emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0)); - - emitpcode(POC_MOVLW, popGetLit(0xff)); + if(size == 1) { + /* Save one instruction of casting char to int */ + emitpcode(POC_CLRF, popGet(AOP(result),offset)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0)); + emitpcode(POC_DECF, popGet(AOP(result),offset)); + } else { + emitpcodeNULLop(POC_CLRW); - pic14_emitcode("clrw",""); - pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(right)->aopu.aop_dir, - AOP(right)->aopu.aop_dir); - pic14_emitcode("movlw","0xff"); - while (size--) { - emitpcode(POC_MOVWF, popGet(AOP(result),offset)); - pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE)); - offset++; - // aopPut(AOP(result),"a",offset++); - } + if(offset) + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset-1,FALSE,FALSE),7,0)); + else + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),offset,FALSE,FALSE),7,0)); + + emitpcode(POC_MOVLW, popGetLit(0xff)); + while (size--) + emitpcode(POC_MOVWF, popGet(AOP(result),offset++)); + } } - /* we are done hurray !!!! */ - release: freeAsmop(right,NULL,ic,TRUE); freeAsmop(result,NULL,ic,TRUE); diff --git a/src/pic/genarith.c b/src/pic/genarith.c index a35f5589..a4e501bb 100644 --- a/src/pic/genarith.c +++ b/src/pic/genarith.c @@ -65,6 +65,7 @@ #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff) +void DEBUGpic14_AopType(int line_no, operand *left, operand *right, operand *result); const char *AopType(short type) { @@ -727,6 +728,8 @@ void genPlus (iCode *ic) aopOp (IC_RIGHT(ic),ic,FALSE); aopOp (IC_RESULT(ic),ic,TRUE); + DEBUGpic14_AopType(__LINE__,IC_LEFT(ic),IC_RIGHT(ic),IC_RESULT(ic)); + /* if literal, literal on the right or if left requires ACC or right is already in ACC */ @@ -879,6 +882,9 @@ void genPlus (iCode *ic) } else { DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + /* Add the first bytes */ + if(strcmp(aopGet(AOP(IC_LEFT(ic)),0,FALSE,FALSE),"a") == 0 ) { emitpcode(POC_ADDFW, popGet(AOP(IC_RIGHT(ic)),0)); emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0)); @@ -907,8 +913,9 @@ void genPlus (iCode *ic) } } + size = min( AOP_SIZE(IC_RESULT(ic)), AOP_SIZE(IC_RIGHT(ic))) - 1; offset = 1; - size--; + while(size--){ if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { @@ -936,6 +943,49 @@ void genPlus (iCode *ic) } + if (AOP_SIZE(IC_RESULT(ic)) > AOP_SIZE(IC_RIGHT(ic))) { + int sign = !(SPEC_USIGN(getSpec(operandType(IC_LEFT(ic)))) | + SPEC_USIGN(getSpec(operandType(IC_RIGHT(ic)))) ); + + + /* Need to extend result to higher bytes */ + size = AOP_SIZE(IC_RESULT(ic)) - AOP_SIZE(IC_RIGHT(ic)) - 1; + + /* First grab the carry from the lower bytes */ + emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset)); + emitpcode(POC_RLF, popGet(AOP(IC_RESULT(ic)),offset)); + + + if(sign) { + /* Now this is really horrid. Gotta check the sign of the addends and propogate + * to the result */ + + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_LEFT(ic)),offset-1,FALSE,FALSE),7,0)); + emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RIGHT(ic)),offset-1,FALSE,FALSE),7,0)); + emitpcode(POC_DECF, popGet(AOP(IC_RESULT(ic)),offset)); + + /* if chars or ints or being signed extended to longs: */ + if(size) { + emitpcode(POC_MOVLW, popGetLit(0)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(IC_RESULT(ic)),offset,FALSE,FALSE),7,0)); + emitpcode(POC_MOVLW, popGetLit(0xff)); + } + } + + offset++; + while(size--) { + + if(sign) + emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); + else + emitpcode(POC_CLRF, popGet(AOP(IC_RESULT(ic)),offset)); + + offset++; + } + } + + //adjustArithmeticResult(ic); release: diff --git a/src/pic/pcode.c b/src/pic/pcode.c index 04744116..884ff12e 100644 --- a/src/pic/pcode.c +++ b/src/pic/pcode.c @@ -40,6 +40,8 @@ pCodeOpReg pc_fsr = {{PO_FSR, "FSR"}, -1, NULL,NULL}; pCodeOpReg pc_pcl = {{PO_PCL, "PCL"}, -1, NULL,NULL}; pCodeOpReg pc_pclath = {{PO_PCLATH, "PCLATH"}, -1, NULL,NULL}; +pCodeOpReg pc_kzero = {{PO_GPR_REGISTER, "KZ"}, -1, NULL,NULL}; + static int mnemonics_initialized = 0; @@ -773,11 +775,14 @@ void SAFE_snprintf(char **str, size_t *size, const char *format, ...) void pCodeInitRegisters(void) { - pc_fsr.rIdx = 4; - pc_fsr.r = pic14_regWithIdx(4); + pc_fsr.rIdx = IDX_FSR; + pc_fsr.r = pic14_regWithIdx(IDX_FSR); + + pc_indf.rIdx = IDX_INDF; + pc_indf.r = pic14_regWithIdx(IDX_INDF); - pc_indf.rIdx = 0; - pc_indf.r = pic14_regWithIdx(0); + pc_kzero.rIdx = IDX_KZ; + pc_kzero.r = pic14_regWithIdx(IDX_KZ); } @@ -2076,8 +2081,8 @@ void AnalyzepBlock(pBlock *pb) /* Find all of the registers used in this pBlock */ for(pc = pb->pcHead; pc; pc = pc->next) { - if(pc->type == PC_OPCODE) { - if(PCI(pc)->pcop && PCI(pc)->pcop->type == PO_GPR_TEMP) { + if(pc->type == PC_OPCODE && PCI(pc)->pcop) { + if(PCI(pc)->pcop->type == PO_GPR_TEMP) { /* Loop through all of the registers declared so far in this block and see if we find this one there */ @@ -2102,7 +2107,20 @@ void AnalyzepBlock(pBlock *pb) } else fprintf(stderr,"found register in pblock: reg %d\n",r->rIdx); } + if(PCI(pc)->pcop->type == PO_GPR_REGISTER) { + if(PCOR(PCI(pc)->pcop)->r) { + pic14_allocWithIdx (PCOR(PCI(pc)->pcop)->r->rIdx); + fprintf(stderr,"found register in pblock: reg 0x%x\n",PCOR(PCI(pc)->pcop)->r->rIdx); + } else { + if(PCI(pc)->pcop->name) + fprintf(stderr,"ERROR: %s is a NULL register\n",PCI(pc)->pcop->name ); + else + fprintf(stderr,"ERROR: NULL register\n"); + } + } } + + } } diff --git a/src/pic/pcode.h b/src/pic/pcode.h index 1d5961eb..ed230e74 100644 --- a/src/pic/pcode.h +++ b/src/pic/pcode.h @@ -607,6 +607,7 @@ extern pCodeOpReg pc_indf; extern pCodeOpReg pc_fsr; extern pCodeOpReg pc_pcl; extern pCodeOpReg pc_pclath; +extern pCodeOpReg pc_kzero; //////////////////// DELETE THIS /////////////////// diff --git a/src/pic/ralloc.c b/src/pic/ralloc.c index 5135db54..08b72f92 100644 --- a/src/pic/ralloc.c +++ b/src/pic/ralloc.c @@ -134,8 +134,12 @@ regs regspic14[] = {REG_STK, PO_GPR_TEMP, 0x46, "r0x46", "r0x46", 0x46, 1, 0}, {REG_STK, PO_GPR_TEMP, 0x47, "r0x47", "r0x47", 0x47, 1, 0}, - {REG_STK, PO_FSR, 4, "FSR", "FSR", 4, 1, 0}, - {REG_STK, PO_INDF, 0, "INDF", "INDF", 0, 1, 0}, + {REG_SFR, PO_GPR_REGISTER, IDX_KZ, "KZ", "KZ", IDX_KZ, 1, 0}, /* Known zero */ + + + {REG_STK, PO_FSR, IDX_FSR, "FSR", "FSR", IDX_FSR, 1, 0}, + {REG_STK, PO_INDF, IDX_INDF, "INDF", "INDF", IDX_INDF, 1, 0}, + }; @@ -532,6 +536,29 @@ pic14_regWithIdx (int idx) exit (1); } +/*-----------------------------------------------------------------*/ +/* pic14_regWithIdx - returns pointer to register wit index number */ +/*-----------------------------------------------------------------*/ +regs * +pic14_allocWithIdx (int idx) +{ + int i; + + debugLog ("%s - allocating with index = 0x%x\n", __FUNCTION__,idx); + + for (i = 0; i < pic14_nRegs; i++) + if (regspic14[i].rIdx == idx){ + debugLog ("%s - alloc fount index = 0x%x\n", __FUNCTION__,idx); + regspic14[i].wasUsed = 1; + regspic14[i].isFree = 0; + return ®spic14[i]; + } + //return ®spic14[0]; + fprintf(stderr,"%s %d - requested register: 0x%x\n",__FUNCTION__,__LINE__,idx); + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "regWithIdx not found"); + exit (1); +} /*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/ regs * @@ -2001,8 +2028,10 @@ pic14_deallocateAllRegs () debugLog ("%s\n", __FUNCTION__); for (i = 0; i < pic14_nRegs; i++) { - regspic14[i].isFree = 1; - regspic14[i].wasUsed = 0; + if(regspic14[i].pc_type == PO_GPR_TEMP) { + regspic14[i].isFree = 1; + regspic14[i].wasUsed = 0; + } } } diff --git a/src/pic/ralloc.h b/src/pic/ralloc.h index c0801c28..b99341b8 100644 --- a/src/pic/ralloc.h +++ b/src/pic/ralloc.h @@ -71,5 +71,11 @@ regs *pic14_regWithIdx (int); void pic14_freeAllRegs (); void pic14_deallocateAllRegs (); regs *pic14_findFreeReg(short type); +regs *pic14_allocWithIdx (int idx); + +/* Define register address that are constant across PIC family */ +#define IDX_INDF 0 +#define IDX_FSR 4 +#define IDX_KZ 0x7fff /* Known zero - actually just a general purpose reg. */ #endif diff --git a/src/regression/compare7.c b/src/regression/compare7.c new file mode 100644 index 00000000..3ea4bd6d --- /dev/null +++ b/src/regression/compare7.c @@ -0,0 +1,298 @@ +// Signed comparisons of the form: (variableLIT) +// +// This regression test exercises all of the boundary +// conditions in literal less than comparisons. There +// are numerous opportunities to optimize these comparison +// and each one has an astonishing capability of failing +// a boundary condition. + +unsigned char success = 0; +unsigned char failures = 0; +unsigned char dummy = 0; +unsigned char result = 0; + +//bit bit0 = 0; +long int0 = 0; +long int1 = 0; +unsigned char uchar0 = 0; +unsigned char uchar1 = 0; +signed char char0 = 0; +signed char char1 = 0; +char long0 = 0; +char long1 = 0; + +void +done () +{ + dummy++; +} + + +void c_char_gt_lit1(unsigned char expected_result) +{ + result = 0; + + if(char0 > -0x7f) + result |= 1; + + + if(char0 > -1) + result |= 2; + + if(char0 > 0) + result |= 4; + + if(char0 > 1) + result |= 8; + + if(char0 > 0x7e) + result |= 0x10; + + if(char0 > 0x7f) + result |= 0x20; + + if(result != expected_result) + failures++; +} + + +void char_compare(void) +{ + char0 = 0x7f; + c_char_gt_lit1(0x1f); + + char0 = 0x7e; + c_char_gt_lit1(0x0f); + + char0 = 0x40; + c_char_gt_lit1(0x0f); + + char0 = 0x2; + c_char_gt_lit1(0x0f); + + char0 = 0x1; + c_char_gt_lit1(0x07); + + char0 = 0; + c_char_gt_lit1(0x03); + + char0 = -1; + c_char_gt_lit1(0x01); + + char0 = -2; + c_char_gt_lit1(0x01); + + char0 = -0x40; + c_char_gt_lit1(0x01); + + char0 = -0x7e; + c_char_gt_lit1(0x01); + + char0 = -0x7f; + c_char_gt_lit1(0x00); + + char0 = 0x80; + c_char_gt_lit1(0x00); + + + /* Now test entire range */ + + for(char0=2; char0 != 0x7f; char0++) + c_char_gt_lit1(0x0f); + + + for(char0=-0x7e; char0 != -1; char0++) + c_char_gt_lit1(0x01); + + +} + + +void c_int_gt_lit1(unsigned char expected_result) +{ + result = 0; + + if(int0 > 0) + result |= 1; + + if(int0 > 1) + result |= 2; + + + if(int0 > 0xff) + result |= 4; + + if(int0 > 0x100) + result |= 8; + + if(int0 > 0x0101) + result |= 0x10; + + if(int0 > 0x01ff) + result |= 0x20; + + if(int0 > 0x0200) + result |= 0x40; + + if(int0 > 0x0201) + result |= 0x80; + + if(result != expected_result) + failures=1; + +} + + +void int_compare1(void) +{ + int0 = -1; + c_int_gt_lit1(0x00); + + int0 = 0; + c_int_gt_lit1(0x00); + + int0 = 1; + c_int_gt_lit1(0x01); + + int0 = 2; + c_int_gt_lit1(0x03); + + int0 = 0xfe; + c_int_gt_lit1(0x03); + + int0 = 0xff; + c_int_gt_lit1(0x03); + + int0 = 0x100; + c_int_gt_lit1(0x07); + + int0 = 0x101; + c_int_gt_lit1(0x0f); + + int0 = 0x102; + c_int_gt_lit1(0x1f); + + int0 = 0x1fe; + c_int_gt_lit1(0x1f); + + int0 = 0x1ff; + c_int_gt_lit1(0x1f); + + int0 = 0x200; + c_int_gt_lit1(0x3f); + + int0 = 0x201; + c_int_gt_lit1(0x7f); + + int0 = 0x7f00; + c_int_gt_lit1(0xff); + + /* now check contiguous ranges */ + + for(int0 = -0x7fff; int0 != -1; int0++) + c_int_gt_lit1(0x00); + + for(int0 = 2; int0 != 0xff; int0++) + c_int_gt_lit1(0x03); + + for(int0 = 0x202; int0 != 0x7fff; int0++) + c_int_gt_lit1(0xff); + +} + + +void c_int_gt_lit2(unsigned char expected_result) +{ + result = 0; + + if(int0 > -0x7fff) + result |= 1; + + if(int0 > -0x7f00) + result |= 2; + + if(int0 > -0x7eff) + result |= 4; + + if(int0 > -0x7e00) + result |= 8; + + if(int0 > -0x0101) + result |= 0x10; + + if(int0 > -0x0100) + result |= 0x20; + + if(int0 > -0xff) + result |= 0x40; + + if(int0 > -1) + result |= 0x80; + + if(result != expected_result) + failures=1; +} + +void int_compare2(void) +{ + int0 = -0x7fff; + c_int_gt_lit2(0x00); + + int0 = -0x7f00; + c_int_gt_lit2(0x01); + + int0 = -0x7eff; + c_int_gt_lit2(0x03); + + int0 = -0x7e00; + c_int_gt_lit2(0x07); + + int0 = -0x7dff; + c_int_gt_lit2(0x0f); + + int0 = -0x4567; + c_int_gt_lit2(0x0f); + + int0 = -0x200; + c_int_gt_lit2(0x0f); + + int0 = -0x102; + c_int_gt_lit2(0x0f); + + int0 = -0x101; + c_int_gt_lit2(0x0f); + + int0 = -0x100; + c_int_gt_lit2(0x1f); + + int0 = -0xff; + c_int_gt_lit2(0x3f); + + int0 = -0x02; + c_int_gt_lit2(0x7f); + + int0 = -0x01; + c_int_gt_lit2(0x7f); + + int0 = 0; + c_int_gt_lit2(0xff); + + int0 = 1; + c_int_gt_lit2(0xff); + + int0 = 0x7fff; + c_int_gt_lit2(0xff); + + /* now check contiguous ranges */ + + for(int0 = -0x7ffe; int0 != -0x7f01; int0++) + c_int_gt_lit2(0x01); + + for(int0 = -0x7dff; int0 != -0x101; int0++) + c_int_gt_lit2(0x0f); + + for(int0 = 0; int0 != 0x7fff; int0++) + c_int_gt_lit2(0xff); + +} + + + + +void +main (void) +{ + char_compare(); + int_compare1(); + int_compare2(); + + success = failures; + done (); +} -- 2.39.5