From d60dda202f1d848e447f70c4a3935280b38f9431 Mon Sep 17 00:00:00 2001 From: borutr Date: Sun, 30 Dec 2007 22:56:15 +0000 Subject: [PATCH] * src/pic16/gen.c: fixed implementation of bitwise operations for pic16targer * support/regression/tests/bitwise.c: added test cases git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4990 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- src/pic16/gen.c | 1259 +++++++++++++++------------- support/regression/tests/bitwise.c | 310 ++++++- 2 files changed, 972 insertions(+), 597 deletions(-) diff --git a/src/pic16/gen.c b/src/pic16/gen.c index 6f7eb251..290d7b33 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -8,6 +8,7 @@ PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002) - Vangelis Rokas (2003-2006) Bug Fixes - Raphael Neider (2004,2005) + Bug Fixes - Borut Razem (2007) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -7599,47 +7600,50 @@ static void jmpTrueOrFalse (iCode *ic, symbol *tlbl) static void genAnd (iCode *ic, iCode *ifx) { operand *left, *right, *result; - int size, offset=0; + int size, offset = 0; unsigned long lit = 0L; - int bytelit = 0; resolvedIfx rIfx; - FENTRY; + FENTRY; - pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE); - pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE); - pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE); + pic16_aopOp ((left = IC_LEFT (ic)), ic, FALSE); + pic16_aopOp ((right = IC_RIGHT (ic)), ic, FALSE); + pic16_aopOp ((result = IC_RESULT (ic)), ic, TRUE); - resolveIfx(&rIfx,ifx); + resolveIfx (&rIfx, ifx); /* if left is a literal & right is not then exchange them */ - if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) || - AOP_NEEDSACC(left)) { - operand *tmp = right ; - right = left; - left = tmp; - } + if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) || + AOP_NEEDSACC (left)) + { + operand *tmp = right; + right = left; + left = tmp; + } /* if result = right then exchange them */ - if(pic16_sameRegs(AOP(result),AOP(right))){ - operand *tmp = right ; - right = left; - left = tmp; - } + if (pic16_sameRegs (AOP (result), AOP (right))) + { + operand *tmp = right; + right = left; + left = tmp; + } /* if right is bit then exchange them */ - if (AOP_TYPE(right) == AOP_CRY && - AOP_TYPE(left) != AOP_CRY){ - operand *tmp = right ; - right = left; - left = tmp; - } - if(AOP_TYPE(right) == AOP_LIT) - lit = ulFromVal (AOP(right)->aopu.aop_lit); + if (AOP_TYPE (right) == AOP_CRY && + AOP_TYPE (left) != AOP_CRY) + { + operand *tmp = right; + right = left; + left = tmp; + } - size = AOP_SIZE(result); + if (AOP_TYPE (right) == AOP_LIT) + lit = ulFromVal (AOP (right)->aopu.aop_lit); - DEBUGpic16_pic16_AopType(__LINE__,left,right,result); + size = AOP_SIZE (result); + + DEBUGpic16_pic16_AopType (__LINE__, left, right, result); // if(bit & yy) // result = bit & yy; @@ -7686,124 +7690,112 @@ static void genAnd (iCode *ic, iCode *ifx) goto release ; } - // if(val & 0xZZ) - size = 0, ifx != FALSE - + // if (val & 0xZZ) - size = 0, ifx != FALSE - // bit = val & 0xZZ - size = 1, ifx = FALSE - - if((AOP_TYPE(right) == AOP_LIT) && - (AOP_TYPE(result) == AOP_CRY) && - (AOP_TYPE(left) != AOP_CRY)){ - int posbit = isLiteralBit(lit); - /* left & 2^n */ - if(posbit){ - posbit--; - //MOVA(pic16_aopGet(AOP(left),posbit>>3,FALSE,FALSE)); - // bit = left & 2^n - if(size) - pic16_emitcode("mov","c,acc.%d",posbit&0x07); - // if(left & 2^n) - else{ - if(ifx){ -/* - if(IC_TRUE(ifx)) { - pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0)); - pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key)); - } else { - pic16_emitpcode(POC_BTFSS,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0)); - pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key)); - } -*/ - DEBUGpic16_emitcode("***", "%d %s", __LINE__, __FUNCTION__); - size = AOP_SIZE(left); - - { - int bp = posbit, ofs=0; - - while(bp > 7) { - bp -= 8; - ofs++; - } - - pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS), - pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0, PO_GPR_REGISTER)); + if ((AOP_TYPE (right) == AOP_LIT) && + (AOP_TYPE (result) == AOP_CRY) && + (AOP_TYPE (left) != AOP_CRY)) + { + symbol *tlbl = newiTempLabel (NULL); + int sizel = AOP_SIZE (left); + int nonnull = 0; + char emitBra; - } -/* - pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS), - pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0)); -*/ - pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key)); + if (size) + emitSETC; - ifx->generated = 1; + /* get number of non null bytes in literal */ + while (sizel--) + { + if (lit & (0xff << (sizel * 8))) + ++nonnull; } - goto release; - } - } else { - symbol *tlbl = newiTempLabel(NULL); - int sizel = AOP_SIZE(left); - - if(size) - emitSETC; - while(sizel--) { - if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L) { + emitBra = nonnull || rIfx.condition; - /* patch provided by Aaron Colwell */ - if((posbit = isLiteralBit(bytelit)) != 0) { - pic16_emitpcode(((rIfx.condition) ? POC_BTFSS : POC_BTFSC ), - pic16_newpCodeOpBit(pic16_aopGet(AOP(left), offset,FALSE,FALSE), - (posbit-1),0, PO_GPR_REGISTER)); + for (sizel = AOP_SIZE (left); sizel--; ++offset, lit >>= 8) + { + unsigned char bytelit = lit; - pic16_emitpcode(POC_BRA, pic16_popGetLabel(tlbl->key)); -// pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key)); - } else { - if (bytelit == 0xff) { - /* Aaron had a MOVF instruction here, changed to MOVFW cause - * a peephole could optimize it out -- VR */ - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset)); - } else { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset)); - pic16_emitpcode(POC_ANDLW, pic16_popGetLit(bytelit)); - } + if (bytelit != 0) + { + int posbit; - pic16_emitpcode(((rIfx.condition) ? POC_BZ : POC_BNZ), - pic16_popGetLabel(tlbl->key)); - } + --nonnull; -#if 0 - /* old code, left here for reference -- VR 09/2004 */ - MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE)); - // byte == 2^n ? - if((posbit = isLiteralBit(bytelit)) != 0) - pic16_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100); - else{ - if(bytelit != 0x0FFL) - pic16_emitcode("anl","a,%s", - pic16_aopGet(AOP(right),offset,FALSE,TRUE)); - pic16_emitcode("jnz","%05d_DS_",tlbl->key+100); - } -#endif + /* patch provided by Aaron Colwell */ + if ((posbit = isLiteralBit (bytelit)) != 0) + { + if (nonnull) + { + pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet (AOP (left), offset, FALSE, FALSE), posbit - 1, 0, PO_GPR_REGISTER)); + pic16_emitpcode (POC_BRA, pic16_popGetLabel (rIfx.condition ? rIfx.lbl->key : tlbl->key)); + } + else + { + pic16_emitpcode (rIfx.condition ? POC_BTFSC :POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet (AOP (left), offset, FALSE, FALSE), posbit - 1, 0, PO_GPR_REGISTER)); + } + } + else + { + if (bytelit == 0xff) + { + /* Aaron had a MOVF instruction here, changed to MOVFW cause + * a peephole could optimize it out -- VR */ + pic16_emitpcode (POC_MOVFW, pic16_popGet (AOP (left), offset)); + } + else + { + pic16_emitpcode (POC_MOVFW, pic16_popGet (AOP (left), offset)); + pic16_emitpcode (POC_ANDLW, pic16_popGetLit (bytelit)); + } + if (nonnull) + { + if (rIfx.condition) + { + emitSKPZ; + pic16_emitpcode (POC_BRA, pic16_popGetLabel (rIfx.lbl->key)); /* to false */ + } + else + { + pic16_emitpcode (POC_BNZ, pic16_popGetLabel (tlbl->key)); /* to true */ + } + } + else + { + /* last non null byte */ + if (rIfx.condition) + emitSKPZ; + else + emitSKPNZ; + } + } + } } - offset++; - } + // bit = left & literal - if(size) { - emitCLRC; - pic16_emitpLabel(tlbl->key); - } + if (size) + { + emitCLRC; + pic16_emitpLabel (tlbl->key); + } + // if(left & literal) - else { - if(ifx) { - pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key)); - ifx->generated = 1; + else + { + if (ifx) + { + if (emitBra) + pic16_emitpcode (POC_BRA, pic16_popGetLabel (rIfx.lbl->key)); + ifx->generated = 1; + } + pic16_emitpLabel (tlbl->key); + goto release; } - pic16_emitpLabel(tlbl->key); - goto release; - } + pic16_outBitC (result); + goto release; } - pic16_outBitC(result); - goto release ; - } - /* if left is same as result */ if(pic16_sameRegs(AOP(result),AOP(left))){ int know_W = -1; @@ -7921,8 +7913,8 @@ static void genAnd (iCode *ic, iCode *ifx) } } - release : - pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); +release : + pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); pic16_freeAsmop(result,NULL,ic,TRUE); } @@ -7932,272 +7924,260 @@ static void genAnd (iCode *ic, iCode *ifx) /*-----------------------------------------------------------------*/ static void genOr (iCode *ic, iCode *ifx) { - operand *left, *right, *result; - int size, offset=0; - unsigned long lit = 0L; + operand *left, *right, *result; + int size, offset = 0; + unsigned long lit = 0L; + resolvedIfx rIfx; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - FENTRY; + FENTRY; - pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE); - pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE); - pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE); + pic16_aopOp ((left = IC_LEFT (ic)), ic, FALSE); + pic16_aopOp ((right= IC_RIGHT (ic)), ic, FALSE); + pic16_aopOp ((result=IC_RESULT (ic)), ic, TRUE); - DEBUGpic16_pic16_AopType(__LINE__,left,right,result); + resolveIfx (&rIfx, ifx); - /* if left is a literal & right is not then exchange them */ - if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) || - AOP_NEEDSACC(left)) { - operand *tmp = right ; - right = left; - left = tmp; + /* if left is a literal & right is not then exchange them */ + if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) || + AOP_NEEDSACC (left)) + { + operand *tmp = right; + right = left; + left = tmp; } - /* if result = right then exchange them */ - if(pic16_sameRegs(AOP(result),AOP(right))){ - operand *tmp = right ; - right = left; - left = tmp; + /* if result = right then exchange them */ + if (pic16_sameRegs (AOP (result), AOP (right))) + { + operand *tmp = right; + right = left; + left = tmp; } - /* if right is bit then exchange them */ - if (AOP_TYPE(right) == AOP_CRY && - AOP_TYPE(left) != AOP_CRY){ - operand *tmp = right ; - right = left; - left = tmp; + /* if right is bit then exchange them */ + if (AOP_TYPE (right) == AOP_CRY && + AOP_TYPE (left) != AOP_CRY) + { + operand *tmp = right; + right = left; + left = tmp; } - DEBUGpic16_pic16_AopType(__LINE__,left,right,result); + DEBUGpic16_pic16_AopType (__LINE__, left, right, result); - if(AOP_TYPE(right) == AOP_LIT) - lit = ulFromVal (AOP(right)->aopu.aop_lit); + if (AOP_TYPE (right) == AOP_LIT) + lit = ulFromVal (AOP (right)->aopu.aop_lit); - size = AOP_SIZE(result); + size = AOP_SIZE (result); - // if(bit | yy) - // xx = bit | yy; - if (AOP_TYPE(left) == AOP_CRY){ - if(AOP_TYPE(right) == AOP_LIT){ - // c = bit & literal; - if(lit){ - // lit != 0 => result = 1 - if(AOP_TYPE(result) == AOP_CRY){ - if(size) - pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0)); - //pic16_emitcode("bsf","(%s >> 3), (%s & 7)", - // AOP(result)->aopu.aop_dir, - // AOP(result)->aopu.aop_dir); - else if(ifx) - continueIfTrue(ifx); - goto release; - } + // if(bit | yy) + // xx = bit | yy; + if (AOP_TYPE(left) == AOP_CRY){ + if(AOP_TYPE(right) == AOP_LIT){ + // c = bit & literal; + if(lit){ + // lit != 0 => result = 1 + if(AOP_TYPE(result) == AOP_CRY){ + if(size) + pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0)); + //pic16_emitcode("bsf","(%s >> 3), (%s & 7)", + // AOP(result)->aopu.aop_dir, + // AOP(result)->aopu.aop_dir); + else if(ifx) + continueIfTrue(ifx); + goto release; + } + } else { + // lit == 0 => result = left + if(size && pic16_sameRegs(AOP(result),AOP(left))) + goto release; + pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__); + } + } else { + if (AOP_TYPE(right) == AOP_CRY){ + if(pic16_sameRegs(AOP(result),AOP(left))){ + // c = bit | bit; + pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0)); + + pic16_emitcode("bcf","(%s >> 3), (%s & 7)", + AOP(result)->aopu.aop_dir, + AOP(result)->aopu.aop_dir); + pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", + AOP(right)->aopu.aop_dir, + AOP(right)->aopu.aop_dir); + pic16_emitcode("bsf","(%s >> 3), (%s & 7)", + AOP(result)->aopu.aop_dir, + AOP(result)->aopu.aop_dir); } else { - // lit == 0 => result = left - if(size && pic16_sameRegs(AOP(result),AOP(left))) - goto release; - pic16_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__); - } - } else { - if (AOP_TYPE(right) == AOP_CRY){ - if(pic16_sameRegs(AOP(result),AOP(left))){ - // c = bit | bit; + if( AOP_TYPE(result) == AOP_ACC) { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0)); + pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0)); + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1)); + + } else { + pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0)); pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0)); pic16_emitcode("bcf","(%s >> 3), (%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); + AOP(result)->aopu.aop_dir, + AOP(result)->aopu.aop_dir); + pic16_emitcode("btfss","(%s >> 3), (%s & 7)", + AOP(right)->aopu.aop_dir, + AOP(right)->aopu.aop_dir); pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(right)->aopu.aop_dir, - AOP(right)->aopu.aop_dir); + AOP(left)->aopu.aop_dir, + AOP(left)->aopu.aop_dir); pic16_emitcode("bsf","(%s >> 3), (%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); - } else { - if( AOP_TYPE(result) == AOP_ACC) { - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0)); - pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0)); - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(1)); - - } else { - - pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0)); - pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0)); - - pic16_emitcode("bcf","(%s >> 3), (%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); - pic16_emitcode("btfss","(%s >> 3), (%s & 7)", - AOP(right)->aopu.aop_dir, - AOP(right)->aopu.aop_dir); - pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(left)->aopu.aop_dir, - AOP(left)->aopu.aop_dir); - pic16_emitcode("bsf","(%s >> 3), (%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); - } + AOP(result)->aopu.aop_dir, + AOP(result)->aopu.aop_dir); } - } else { - // c = bit | val; - symbol *tlbl = newiTempLabel(NULL); - pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); + } + } else { + // c = bit | val; + symbol *tlbl = newiTempLabel(NULL); + pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); - pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0)); - if( AOP_TYPE(right) == AOP_ACC) { - pic16_emitpcode(POC_IORLW, pic16_popGetLit(0)); - emitSKPNZ; - pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0)); - pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0)); - } + pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0)); + if( AOP_TYPE(right) == AOP_ACC) { + pic16_emitpcode(POC_IORLW, pic16_popGetLit(0)); + emitSKPNZ; + pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(left),0)); + pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0)); + } - if(!((AOP_TYPE(result) == AOP_CRY) && ifx)) - pic16_emitcode(";XXX setb","c"); - pic16_emitcode(";XXX jb","%s,%05d_DS_", - AOP(left)->aopu.aop_dir,tlbl->key+100); - pic16_toBoolean(right); - pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); - if((AOP_TYPE(result) == AOP_CRY) && ifx){ - jmpTrueOrFalse(ifx, tlbl); - goto release; - } else { - CLRC; - pic16_emitcode("","%05d_DS_:",tlbl->key+100); - } - } - } - // bit = c - // val = c - if(size) - pic16_outBitC(result); - // if(bit | ...) - else if((AOP_TYPE(result) == AOP_CRY) && ifx) - genIfxJump(ifx, "c"); - goto release ; - } + if(!((AOP_TYPE(result) == AOP_CRY) && ifx)) + pic16_emitcode(";XXX setb","c"); + pic16_emitcode(";XXX jb","%s,%05d_DS_", + AOP(left)->aopu.aop_dir,tlbl->key+100); + pic16_toBoolean(right); + pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); + if((AOP_TYPE(result) == AOP_CRY) && ifx){ + jmpTrueOrFalse(ifx, tlbl); + goto release; + } else { + CLRC; + pic16_emitcode("","%05d_DS_:",tlbl->key+100); + } + } + } + // bit = c + // val = c + if(size) + pic16_outBitC(result); + // if(bit | ...) + else if((AOP_TYPE(result) == AOP_CRY) && ifx) + genIfxJump(ifx, "c"); + goto release ; + } - // if(val | 0xZZ) - size = 0, ifx != FALSE - - // bit = val | 0xZZ - size = 1, ifx = FALSE - - if((AOP_TYPE(right) == AOP_LIT) && - (AOP_TYPE(result) == AOP_CRY) && - (AOP_TYPE(left) != AOP_CRY)){ - if(lit){ - pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); - // result = 1 - if(size) - pic16_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir); - else - continueIfTrue(ifx); - goto release; - } else { - pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); - // lit = 0, result = boolean(left) - if(size) - pic16_emitcode(";XXX setb","c"); - pic16_toBoolean(right); - if(size){ - symbol *tlbl = newiTempLabel(NULL); - pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); - CLRC; - pic16_emitcode("","%05d_DS_:",tlbl->key+100); - } else { - genIfxJump (ifx,"a"); - goto release; - } + // if(val | 0xZZ) - size = 0, ifx != FALSE - + // bit = val | 0xZZ - size = 1, ifx = FALSE - + if ((AOP_TYPE (right) == AOP_LIT) && + (AOP_TYPE (result) == AOP_CRY) && + (AOP_TYPE (left) != AOP_CRY)) + { + if (lit) + { + if (rIfx.condition) + pic16_emitpcode (POC_BRA, pic16_popGetLabel (rIfx.lbl->key)); /* to false */ + ifx->generated = 1; } - pic16_outBitC(result); - goto release ; - } + else + wassert (0); - /* if left is same as result */ - if(pic16_sameRegs(AOP(result),AOP(left))){ - int know_W = -1; - for(;size--; offset++,lit>>=8) { - if(AOP_TYPE(right) == AOP_LIT){ - if((lit & 0xff) == 0) - /* or'ing with 0 has no effect */ - continue; - else { - int p = pic16_my_powof2(lit & 0xff); - if(p>=0) { - /* only one bit is set in the literal, so use a bsf instruction */ - pic16_emitpcode(POC_BSF, - pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER)); - } else { - if(know_W != (lit & 0xff)) - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff)); - know_W = lit & 0xff; - pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset)); - } + goto release; + } + /* if left is same as result */ + if(pic16_sameRegs(AOP(result),AOP(left))){ + int know_W = -1; + for(;size--; offset++,lit>>=8) { + if(AOP_TYPE(right) == AOP_LIT){ + if((lit & 0xff) == 0) + /* or'ing with 0 has no effect */ + continue; + else { + int p = pic16_my_powof2(lit & 0xff); + if(p>=0) { + /* only one bit is set in the literal, so use a bsf instruction */ + pic16_emitpcode(POC_BSF, + pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER)); + } else { + if(know_W != (lit & 0xff)) + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff)); + know_W = lit & 0xff; + pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset)); } - } else { - if (AOP_TYPE(left) == AOP_ACC) { - pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset)); + + } + } else { + if (AOP_TYPE(left) == AOP_ACC) { + pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset)); // pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); - } else { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); - pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset)); + } else { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); + pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset)); // pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); // pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE)); - } } } - } else { - // left & result in different registers - if(AOP_TYPE(result) == AOP_CRY){ - // result = bit - // if(size), result in bit - // if(!size && ifx), conditional oper: if(left | right) - symbol *tlbl = newiTempLabel(NULL); - int sizer = max(AOP_SIZE(left),AOP_SIZE(right)); - pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); - - - if(size) - pic16_emitcode(";XXX setb","c"); - while(sizer--){ - MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE)); - pic16_emitcode(";XXX orl","a,%s", - pic16_aopGet(AOP(left),offset,FALSE,FALSE)); - pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); - offset++; - } - if(size){ - CLRC; - pic16_emitcode("","%05d_DS_:",tlbl->key+100); - pic16_outBitC(result); - } else if(ifx) - jmpTrueOrFalse(ifx, tlbl); - } else for(;(size--);offset++){ - // normal case - // result = left & right - if(AOP_TYPE(right) == AOP_LIT){ - int t = (lit >> (offset*8)) & 0x0FFL; - switch(t) { - case 0x00: - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); + } + } else { + // left & result in different registers + if(AOP_TYPE(result) == AOP_CRY){ + // result = bit + // if(size), result in bit + // if(!size && ifx), conditional oper: if(left | right) + symbol *tlbl = newiTempLabel(NULL); + int sizer = max(AOP_SIZE(left),AOP_SIZE(right)); + pic16_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); + + + if(size) + pic16_emitcode(";XXX setb","c"); + while(sizer--){ + MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE)); + pic16_emitcode(";XXX orl","a,%s", + pic16_aopGet(AOP(left),offset,FALSE,FALSE)); + pic16_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); + offset++; + } + if(size){ + CLRC; + pic16_emitcode("","%05d_DS_:",tlbl->key+100); + pic16_outBitC(result); + } else if(ifx) + jmpTrueOrFalse(ifx, tlbl); + } else for(;(size--);offset++){ + // normal case + // result = left & right + if(AOP_TYPE(right) == AOP_LIT){ + int t = (lit >> (offset*8)) & 0x0FFL; + switch(t) { + case 0x00: + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pic16_emitcode("movf","%s,w", // pic16_aopGet(AOP(left),offset,FALSE,FALSE)); // pic16_emitcode("movwf","%s", // pic16_aopGet(AOP(result),offset,FALSE,FALSE)); - break; - default: - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t)); - pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); + break; + default: + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t)); + pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pic16_emitcode("movlw","0x%x",t); // pic16_emitcode("iorwf","%s,w", @@ -8205,32 +8185,32 @@ static void genOr (iCode *ic, iCode *ifx) // pic16_emitcode("movwf","%s", // pic16_aopGet(AOP(result),offset,FALSE,FALSE)); - } - continue; } + continue; + } - // faster than result <- left, anl result,right - // and better if result is SFR - if (AOP_TYPE(left) == AOP_ACC) { - pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset)); + // faster than result <- left, anl result,right + // and better if result is SFR + if (AOP_TYPE(left) == AOP_ACC) { + pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset)); // pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); - } else { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); - pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset)); + } else { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); + pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset)); // pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); // pic16_emitcode("iorwf","%s,w", // pic16_aopGet(AOP(left),offset,FALSE,FALSE)); - } - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); -// pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE)); } - } + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); +// pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE)); + } + } release : - pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - pic16_freeAsmop(result,NULL,ic,TRUE); + pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -8239,240 +8219,362 @@ release : static void genXor (iCode *ic, iCode *ifx) { operand *left, *right, *result; - int size, offset=0; + int size, offset = 0; unsigned long lit = 0L; + resolvedIfx rIfx; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); FENTRY; - pic16_aopOp((left = IC_LEFT(ic)),ic,FALSE); - pic16_aopOp((right= IC_RIGHT(ic)),ic,FALSE); - pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE); + pic16_aopOp ((left = IC_LEFT (ic)), ic, FALSE); + pic16_aopOp ((right = IC_RIGHT (ic)), ic, FALSE); + pic16_aopOp ((result = IC_RESULT (ic)), ic, TRUE); + + resolveIfx (&rIfx,ifx); /* if left is a literal & right is not || if left needs acc & right does not */ - if ((AOP_TYPE(left) == AOP_LIT && AOP_TYPE(right) != AOP_LIT) || - (AOP_NEEDSACC(left) && !AOP_NEEDSACC(right))) { - operand *tmp = right ; - right = left; - left = tmp; - } + if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) || + (AOP_NEEDSACC (left) && !AOP_NEEDSACC (right))) + { + operand *tmp = right; + right = left; + left = tmp; + } /* if result = right then exchange them */ - if(pic16_sameRegs(AOP(result),AOP(right))){ - operand *tmp = right ; - right = left; - left = tmp; - } + if (pic16_sameRegs (AOP (result), AOP (right))) + { + operand *tmp = right ; + right = left; + left = tmp; + } /* if right is bit then exchange them */ - if (AOP_TYPE(right) == AOP_CRY && - AOP_TYPE(left) != AOP_CRY){ - operand *tmp = right ; - right = left; - left = tmp; - } - if(AOP_TYPE(right) == AOP_LIT) - lit = ulFromVal (AOP(right)->aopu.aop_lit); + if (AOP_TYPE (right) == AOP_CRY && + AOP_TYPE (left) != AOP_CRY) + { + operand *tmp = right ; + right = left; + left = tmp; + } - size = AOP_SIZE(result); + if (AOP_TYPE (right) == AOP_LIT) + lit = ulFromVal (AOP (right)->aopu.aop_lit); + + size = AOP_SIZE (result); // if(bit ^ yy) // xx = bit ^ yy; - if (AOP_TYPE(left) == AOP_CRY){ - if(AOP_TYPE(right) == AOP_LIT){ - // c = bit & literal; - if(lit>>1){ - // lit>>1 != 0 => result = 1 - if(AOP_TYPE(result) == AOP_CRY){ - if(size) - {pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),offset)); - pic16_emitcode("setb","%s",AOP(result)->aopu.aop_dir);} - else if(ifx) - continueIfTrue(ifx); - goto release; + if (AOP_TYPE(left) == AOP_CRY) + { + if (AOP_TYPE(right) == AOP_LIT) + { + // c = bit & literal; + if (lit >> 1) + { + // lit>>1 != 0 => result = 1 + if (AOP_TYPE(result) == AOP_CRY) + { + if (size) + { + pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result), offset)); + pic16_emitcode("setb", "%s", AOP(result)->aopu.aop_dir); + } + else if (ifx) + continueIfTrue(ifx); + goto release; + } + pic16_emitcode("setb", "c"); + } + else + { + // lit == (0 or 1) + if (lit == 0) + { + // lit == 0, result = left + if (size && pic16_sameRegs(AOP(result), AOP(left))) + goto release; + pic16_emitcode("mov", "c,%s", AOP(left)->aopu.aop_dir); + } + else + { + // lit == 1, result = not(left) + if (size && pic16_sameRegs(AOP(result), AOP(left))) + { + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result), offset)); + pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result), offset)); + pic16_emitcode("cpl", "%s", AOP(result)->aopu.aop_dir); + goto release; + } + else + { + pic16_emitcode("mov", "c,%s", AOP(left)->aopu.aop_dir); + pic16_emitcode("cpl", "c"); + } + } + } } - pic16_emitcode("setb","c"); - } else{ - // lit == (0 or 1) - if(lit == 0){ - // lit == 0, result = left - if(size && pic16_sameRegs(AOP(result),AOP(left))) - goto release; - pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - } else{ - // lit == 1, result = not(left) - if(size && pic16_sameRegs(AOP(result),AOP(left))){ - pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(result),offset)); - pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offset)); - pic16_emitcode("cpl","%s",AOP(result)->aopu.aop_dir); - goto release; - } else { - pic16_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - pic16_emitcode("cpl","c"); - } + else + { + // right != literal + symbol *tlbl = newiTempLabel(NULL); + if (AOP_TYPE(right) == AOP_CRY) + { + // c = bit ^ bit; + pic16_emitcode("mov", "c,%s", AOP(right)->aopu.aop_dir); + } + else + { + int sizer = AOP_SIZE(right); + // c = bit ^ val + // if val>>1 != 0, result = 1 + pic16_emitcode("setb", "c"); + while (sizer) + { + MOVA(pic16_aopGet(AOP(right), sizer - 1, FALSE, FALSE)); + if (sizer == 1) + // test the msb of the lsb + pic16_emitcode("anl", "a,#0xfe"); + pic16_emitcode("jnz", "%05d_DS_", tlbl->key+100); + sizer--; + } + // val = (0,1) + pic16_emitcode("rrc", "a"); + } + pic16_emitcode("jnb", "%s,%05d_DS_", AOP(left)->aopu.aop_dir, (tlbl->key + 100)); + pic16_emitcode("cpl", "c"); + pic16_emitcode("", "%05d_DS_:", (tlbl->key + 100)); } - } - - } else { - // right != literal - symbol *tlbl = newiTempLabel(NULL); - if (AOP_TYPE(right) == AOP_CRY){ - // c = bit ^ bit; - pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); - } - else{ - int sizer = AOP_SIZE(right); - // c = bit ^ val - // if val>>1 != 0, result = 1 - pic16_emitcode("setb","c"); - while(sizer){ - MOVA(pic16_aopGet(AOP(right),sizer-1,FALSE,FALSE)); - if(sizer == 1) - // test the msb of the lsb - pic16_emitcode("anl","a,#0xfe"); - pic16_emitcode("jnz","%05d_DS_",tlbl->key+100); - sizer--; - } - // val = (0,1) - pic16_emitcode("rrc","a"); - } - pic16_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100)); - pic16_emitcode("cpl","c"); - pic16_emitcode("","%05d_DS_:",(tlbl->key+100)); + // bit = c + // val = c + if (size) + pic16_outBitC(result); + // if(bit | ...) + else if ((AOP_TYPE(result) == AOP_CRY) && ifx) + genIfxJump(ifx, "c"); + goto release; } - // bit = c - // val = c - if(size) - pic16_outBitC(result); - // if(bit | ...) - else if((AOP_TYPE(result) == AOP_CRY) && ifx) - genIfxJump(ifx, "c"); - goto release ; - } - if(pic16_sameRegs(AOP(result),AOP(left))){ - /* if left is same as result */ - for(;size--; offset++) { - if(AOP_TYPE(right) == AOP_LIT){ - int t = (lit >> (offset*8)) & 0x0FFL; - if(t == 0x00L) - continue; - else - if (IS_AOP_PREG(left)) { - MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE)); - pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE)); - pic16_aopPut(AOP(result),"a",offset); - } else { - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t)); - pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset)); - pic16_emitcode("xrl","%s,%s", - pic16_aopGet(AOP(left),offset,FALSE,TRUE), - pic16_aopGet(AOP(right),offset,FALSE,FALSE)); - } - } else { - if (AOP_TYPE(left) == AOP_ACC) - pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); - else { - pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset)); - pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(left),offset)); -/* - if (IS_AOP_PREG(left)) { - pic16_emitcode("xrl","a,%s",pic16_aopGet(AOP(left),offset,FALSE,TRUE)); - pic16_aopPut(AOP(result),"a",offset); - } else - pic16_emitcode("xrl","%s,a", - pic16_aopGet(AOP(left),offset,FALSE,TRUE)); -*/ + // if(val ^ 0xZZ) - size = 0, ifx != FALSE - + // bit = val ^ 0xZZ - size = 1, ifx = FALSE - + if ((AOP_TYPE (right) == AOP_LIT) && + (AOP_TYPE (result) == AOP_CRY) && + (AOP_TYPE (left) != AOP_CRY)) + { + symbol *tlbl = newiTempLabel (NULL); + int sizel; + + if (size) + emitSETC; + + for (sizel = AOP_SIZE(left); sizel--; ++offset, lit >>= 8) + { + unsigned char bytelit = lit; + + switch (bytelit) + { + case 0xff: + pic16_emitpcode (POC_COMFW, pic16_popGet (AOP (left), offset)); + break; + + case 0x00: + pic16_emitpcode (POC_MOVFW, pic16_popGet (AOP (left), offset)); + break; + + default: + pic16_emitpcode (POC_MOVLW, pic16_popGetLit (bytelit)); + pic16_emitpcode (POC_XORFW, pic16_popGet (AOP (left), offset)); + break; + } + if (sizel) + { + if (rIfx.condition) + { + emitSKPZ; + pic16_emitpcode (POC_BRA, pic16_popGetLabel (rIfx.lbl->key)); /* to false */ + } + else + { + pic16_emitpcode (POC_BNZ, pic16_popGetLabel (tlbl->key)); /* to true */ + } + } + else + { + /* last non null byte */ + if (rIfx.condition) + emitSKPZ; + else + emitSKPNZ; + } } - } - } - } else { - // left & result in different registers - if(AOP_TYPE(result) == AOP_CRY){ - // result = bit - // if(size), result in bit - // if(!size && ifx), conditional oper: if(left ^ right) - symbol *tlbl = newiTempLabel(NULL); - int sizer = max(AOP_SIZE(left),AOP_SIZE(right)); - if(size) - pic16_emitcode("setb","c"); - while(sizer--){ - if((AOP_TYPE(right) == AOP_LIT) && - (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){ - MOVA(pic16_aopGet(AOP(left),offset,FALSE,FALSE)); - } else { - MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE)); - pic16_emitcode("xrl","a,%s", - pic16_aopGet(AOP(left),offset,FALSE,FALSE)); + + // bit = left ^ literal + if (size) + { + emitCLRC; + pic16_emitpLabel (tlbl->key); } - pic16_emitcode("jnz","%05d_DS_",tlbl->key+100); - offset++; - } - if(size){ - CLRC; - pic16_emitcode("","%05d_DS_:",tlbl->key+100); - pic16_outBitC(result); - } else if(ifx) - jmpTrueOrFalse(ifx, tlbl); - } else for(;(size--);offset++){ - // normal case - // result = left & right - if(AOP_TYPE(right) == AOP_LIT){ - int t = (lit >> (offset*8)) & 0x0FFL; - switch(t) { - case 0x00: - pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset)); - pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset)); - pic16_emitcode("movf","%s,w", - pic16_aopGet(AOP(left),offset,FALSE,FALSE)); - pic16_emitcode("movwf","%s", - pic16_aopGet(AOP(result),offset,FALSE,FALSE)); - break; - case 0xff: - pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(left),offset)); - pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset)); - pic16_emitcode("comf","%s,w", - pic16_aopGet(AOP(left),offset,FALSE,FALSE)); - pic16_emitcode("movwf","%s", - pic16_aopGet(AOP(result),offset,FALSE,FALSE)); - break; - default: - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t)); - pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset)); - pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset)); - pic16_emitcode("movlw","0x%x",t); - pic16_emitcode("xorwf","%s,w", - pic16_aopGet(AOP(left),offset,FALSE,FALSE)); - pic16_emitcode("movwf","%s", - pic16_aopGet(AOP(result),offset,FALSE,FALSE)); + // if (left ^ literal) + else + { + if (ifx) + { + pic16_emitpcode (POC_BRA, pic16_popGetLabel (rIfx.lbl->key)); + ifx->generated = 1; + } + pic16_emitpLabel (tlbl->key); + goto release; + } + + pic16_outBitC (result); + goto release; + } + if (pic16_sameRegs(AOP(result), AOP(left))) + { + /* if left is same as result */ + for (; size--; offset++) + { + if (AOP_TYPE(right) == AOP_LIT) + { + int t = (lit >> (offset * 8)) & 0x0FFL; + if (t == 0x00L) + continue; + else + if (IS_AOP_PREG(left)) + { + MOVA(pic16_aopGet(AOP(right), offset, FALSE, FALSE)); + pic16_emitcode("xrl", "a,%s", pic16_aopGet(AOP(left), offset, FALSE, TRUE)); + pic16_aopPut(AOP(result), "a", offset); + } + else + { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t)); + pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(left), offset)); + pic16_emitcode("xrl", "%s,%s", + pic16_aopGet(AOP(left), offset, FALSE, TRUE), + pic16_aopGet(AOP(right), offset, FALSE, FALSE)); + } + } + else + { + if (AOP_TYPE(left) == AOP_ACC) + pic16_emitcode("xrl", "a,%s", pic16_aopGet(AOP(right), offset, FALSE, FALSE)); + else + { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset)); + pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(left), offset)); + } + } } - continue; + } + else + { + // left ^ result in different registers + if (AOP_TYPE(result) == AOP_CRY) + { + // result = bit + // if(size), result in bit + // if(!size && ifx), conditional oper: if(left ^ right) + symbol *tlbl = newiTempLabel(NULL); + int sizer = max(AOP_SIZE(left), AOP_SIZE(right)); + if (size) + pic16_emitcode("setb", "c"); + while (sizer--) + { + if ((AOP_TYPE(right) == AOP_LIT) && + (((lit >> (offset*8)) & 0x0FFL) == 0x00L)) + { + MOVA(pic16_aopGet(AOP(left), offset, FALSE, FALSE)); + } + else + { + MOVA(pic16_aopGet(AOP(right), offset, FALSE, FALSE)); + pic16_emitcode("xrl", "a,%s", + pic16_aopGet(AOP(left), offset, FALSE, FALSE)); + } + pic16_emitcode("jnz", "%05d_DS_", tlbl->key + 100); + offset++; + } + if (size) + { + CLRC; + pic16_emitcode("", "%05d_DS_:", tlbl->key + 100); + pic16_outBitC(result); + } + else if (ifx) + jmpTrueOrFalse(ifx, tlbl); } + else + { + for (; (size--); offset++) + { + // normal case + // result = left ^ right + if (AOP_TYPE(right) == AOP_LIT) + { + int t = (lit >> (offset * 8)) & 0x0FFL; + switch(t) + { + case 0x00: + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset)); + pic16_emitcode("movf", "%s,w", + pic16_aopGet(AOP(left), offset, FALSE, FALSE)); + pic16_emitcode("movwf", "%s", + pic16_aopGet(AOP(result), offset, FALSE, FALSE)); + break; + + case 0xff: + pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(left), offset)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset)); + pic16_emitcode("comf", "%s,w", + pic16_aopGet(AOP(left), offset, FALSE, FALSE)); + pic16_emitcode("movwf", "%s", + pic16_aopGet(AOP(result), offset, FALSE, FALSE)); + break; + + default: + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t)); + pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left), offset)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset)); + pic16_emitcode("movlw", "0x%x", t); + pic16_emitcode("xorwf", "%s,w", + pic16_aopGet(AOP(left), offset, FALSE, FALSE)); + pic16_emitcode("movwf", "%s", + pic16_aopGet(AOP(result), offset, FALSE, FALSE)); - // faster than result <- left, anl result,right - // and better if result is SFR - if (AOP_TYPE(left) == AOP_ACC) { - pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset)); - pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); - } else { - pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset)); - pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(left),offset)); - pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); - pic16_emitcode("xorwf","%s,w",pic16_aopGet(AOP(left),offset,FALSE,FALSE)); - } - if ( AOP_TYPE(result) != AOP_ACC){ - pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset)); - pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE)); + } + continue; + } + + // faster than result <- left, anl result,right + // and better if result is SFR + if (AOP_TYPE(left) == AOP_ACC) + { + pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right), offset)); + pic16_emitcode("xorwf", "%s,w", pic16_aopGet(AOP(right), offset, FALSE, FALSE)); + } + else + { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset)); + pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left), offset)); + pic16_emitcode("movf", "%s,w", pic16_aopGet(AOP(right), offset, FALSE, FALSE)); + pic16_emitcode("xorwf", "%s,w", pic16_aopGet(AOP(left), offset, FALSE, FALSE)); + } + if ( AOP_TYPE(result) != AOP_ACC) + { + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset)); + pic16_emitcode("movwf", "%s", pic16_aopGet(AOP(result), offset, FALSE, FALSE)); + } + } } - } } - release : - pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - pic16_freeAsmop(result,NULL,ic,TRUE); +release : + pic16_freeAsmop(left, NULL, ic, (RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(right, NULL, ic, (RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(result, NULL, ic, TRUE); } /*-----------------------------------------------------------------*/ @@ -13863,4 +13965,3 @@ void genpic16Code (iCode *lic) return; } - diff --git a/support/regression/tests/bitwise.c b/support/regression/tests/bitwise.c index 7982be71..4ee3a7fc 100644 --- a/support/regression/tests/bitwise.c +++ b/support/regression/tests/bitwise.c @@ -9,34 +9,308 @@ static void testTwoOpBitwise(void) { - {storage} {attr} {type} left, right; + {storage} {attr} {type} left, right; - left = ({type})0x3df7; - right = ({type})0xc1ec; + left = ({type})0x3df7; + right = ({type})0xc1ec; - ASSERT(({type})(left & right) == ({type})0x1E4); - ASSERT(({type})(right & left) == ({type})0x1E4); - ASSERT(({type})(left & 0xc1ec) == ({type})0x1E4); - ASSERT(({type})(0x3df7 & right) == ({type})0x1E4); + ASSERT(({type})(left & right) == ({type})0x1E4); + ASSERT(({type})(right & left) == ({type})0x1E4); + ASSERT(({type})(left & 0xc1ec) == ({type})0x1E4); + ASSERT(({type})(0x3df7 & right) == ({type})0x1E4); - ASSERT(({type})(left | right) == ({type})0xFDFF); - ASSERT(({type})(right | left) == ({type})0xFDFF); - ASSERT(({type})(left | 0xc1ec) == ({type})0xFDFF); - ASSERT(({type})(0x3df7 | right) == ({type})0xFDFF); + ASSERT(({type})(left | right) == ({type})0xFDFF); + ASSERT(({type})(right | left) == ({type})0xFDFF); + ASSERT(({type})(left | 0xc1ec) == ({type})0xFDFF); + ASSERT(({type})(0x3df7 | right) == ({type})0xFDFF); - ASSERT(({type})(left ^ right) == ({type})0xFC1B); - ASSERT(({type})(right ^ left) == ({type})0xFC1B); - ASSERT(({type})(left ^ 0xc1ec) == ({type})0xFC1B); - ASSERT(({type})(0x3df7 ^ right) == ({type})0xFC1B); + ASSERT(({type})(left ^ right) == ({type})0xFC1B); + ASSERT(({type})(right ^ left) == ({type})0xFC1B); + ASSERT(({type})(left ^ 0xc1ec) == ({type})0xFC1B); + ASSERT(({type})(0x3df7 ^ right) == ({type})0xFC1B); #if defined (__alpha__) || defined (__x86_64__) - /* long is 64 bits on 64 bit machines */ - ASSERT(({type})(~left) == ({type})0xFFFFFFFFFFFFC208); + /* long is 64 bits on 64 bit machines */ + ASSERT(({type})(~left) == ({type})0xFFFFFFFFFFFFC208); #else - ASSERT(({type})(~left) == ({type})0xFFFFC208); + ASSERT(({type})(~left) == ({type})0xFFFFC208); #endif } +void +testAnd(void) +{ + char res; + {attr} int a; + + /* always false if right literal == 0 */ +#if 0 + // fails on pic16 + if (a & 0) + res = 1; + else + res = 0; + ASSERT(res = 0); + + a = 0x1234; + + if (a & 0) + res = 1; + else + res = 0; + ASSERT(res = 0); +#endif + + /* + * result: if, left: var, right: literal + */ + a = 0x1234; + + if (a & 0x4321) + res = 1; + else + res = 0; + ASSERT(res == 1); + + if (a & 0x4321) + /* nothing for true */ + ; + else + res = 0; + ASSERT(res == 1); + + if (!(a & 0x4321)) + res = 1; + else + res = 0; + ASSERT(res == 0); + + if (!(a & 0x4321)) + /* nothing for true */ + ; + else + res = 0; + ASSERT(res == 0); + + /* bitmask literal */ + a = 0xffff; + + if (a & 0x1004) + res = 1; + else + res = 0; + ASSERT(res == 1); + + if (!(a & 0x1004)) + res = 1; + else + res = 0; + ASSERT(res == 0); + + a = 0x0000; + + if (a & 0x1004) + res = 1; + else + res = 0; + ASSERT(res == 0); + + if (!(a & 0x1004)) + res = 1; + else + res = 0; + ASSERT(res == 1); + + a = 0x00ff; + + if (a & 0x1004) + res = 1; + else + res = 0; + ASSERT(res == 1); + + if (!(a & 0x1004)) + res = 1; + else + res = 0; + ASSERT(res == 0); + + a = 0xff00; + + if (a & 0x1004) + res = 1; + else + res = 0; + ASSERT(res == 1); + + if (!(a & 0x1004)) + res = 1; + else + res = 0; + ASSERT(res == 0); + + /* literal with zero bytes */ + a = 0x1234; + + if (a & 0x4300) + res = 1; + else + res = 0; + ASSERT(res == 1); + + if (a & 0x0012) + res = 1; + else + res = 0; + ASSERT(res == 1); + + if (!(a & 0x4300)) + res = 1; + else + res = 0; + ASSERT(res == 0); + + if (!(a & 0x0012)) + res = 1; + else + res = 0; + ASSERT(res == 0); + + /* + * result: bit, left: var, right: literal + */ +} + +void +testOr(void) +{ + char res; + {attr} int a = 0x1234; + + /* + * result: if, left: var, right: literal + */ + res = 1; + if (a | 0x4321) + /* nothing for true */ + ; + else + res = 0; + ASSERT(res == 1); + + if (!(a | 0x4321)) + /* nothing for true */ + ; + else + res = 0; + ASSERT(res == 0); + + if (a | 0x4321) + res = 1; + else + res = 0; + ASSERT(res == 1); + + if (!(a | 0x4321)) + res = 1; + else + res = 0; + ASSERT(res == 0); + + /* or with zero: result is left */ + res = 1; + + if (a | 0) + /* nothing for true */ + ; + else + res = 0; + ASSERT(res == 1); + + res = 1; + + if (!(a | 0)) + /* nothing for true */ + ; + else + res = 0; + ASSERT(res == 0); + + if (a | 0) + res = 1; + else + res = 0; + ASSERT(res == 1); + + if (!(a | 0)) + res = 1; + else + res = 0; + ASSERT(res == 0); +} + +void +testXor(void) +{ + char res; + {attr} int a = 0x1234; + + /* + * result: if, left: var, right: literal + */ + if (a ^ 0x4321) + res = 1; + else + res = 0; + ASSERT(res == 1); + + if (a ^ 0x4321) + /* nothing for true */ + ; + else + res = 0; + ASSERT(res == 1); + + if (!(a ^ 0x4321)) + res = 1; + else + res = 0; + ASSERT(res == 0); + + if (!(a ^ 0x4321)) + /* nothing for true */ + ; + else + res = 0; + ASSERT(res == 0); + + /* literal with 0xff bytes */ + if (a ^ 0xff04) + res = 1; + else + res = 0; + ASSERT(res == 1); + + if (!(a ^ 0xff04)) + res = 1; + else + res = 0; + ASSERT(res == 0); + + /* literal with zero bytes */ + if (a ^ 0x0004) + res = 1; + else + res = 0; + ASSERT(res == 1); + + if (!(a ^ 0x0004)) + res = 1; + else + res = 0; + ASSERT(res == 0); +} + static void testBug_1777758(void) { -- 2.30.2