X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic%2Fgen.c;h=a2482345d8cf644255cb770a7ffb6c44b8de79f4;hb=455a1bc2a169f6caf0e3c5d3bfd5be0b23b99846;hp=507d386d9b8b50f7010d3ebc788e71f48bb52399;hpb=ac9ebda6996416faaf1f6ac189024acb7efbf991;p=fw%2Fsdcc diff --git a/src/pic/gen.c b/src/pic/gen.c index 507d386d..a2482345 100644 --- a/src/pic/gen.c +++ b/src/pic/gen.c @@ -218,11 +218,6 @@ void emitpComment (const char *fmt, ...) Safe_vsnprintf (buffer, 4096, fmt, va); //fprintf (stderr, "%s\n" ,buffer); addpCode2pBlock (pb, newpCodeCharP (buffer)); -#if 0 - } else { - Safe_vsnprintf (buffer, 4096, fmt, va); - fprintf (stderr, "No current pBlock -- discarding comment [%s]\n", buffer); -#endif } va_end (va); } @@ -252,12 +247,9 @@ void emitpcode_real(PIC_OPCODE poc, pCodeOp *pcop) static void emitpcodeNULLop(PIC_OPCODE poc) { - addpCode2pBlock(pb,newpCode(poc,NULL)); - } - /*-----------------------------------------------------------------*/ /* pic14_emitcode - writes the code into a file : for now it is simple */ /*-----------------------------------------------------------------*/ @@ -334,10 +326,6 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx) if(!ifx) { resIfx->lbl = NULL; /* this is wrong: newiTempLabel(NULL); / * oops, there is no ifx. so create a label */ - /* - DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d", - __FUNCTION__,__LINE__,resIfx->lbl->key); - */ } else { if(IC_TRUE(ifx)) { resIfx->lbl = IC_TRUE(ifx); @@ -345,28 +333,11 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx) resIfx->lbl = IC_FALSE(ifx); resIfx->condition = 0; } - /* - if(IC_TRUE(ifx)) - DEBUGpic14_emitcode("; ***","ifx true is non-null"); - if(IC_FALSE(ifx)) - DEBUGpic14_emitcode("; ***","ifx false is non-null"); - */ } // DEBUGpic14_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset); } -/*-----------------------------------------------------------------*/ -/* pointerCode - returns the code for a pointer type */ -/*-----------------------------------------------------------------*/ -#if 0 -static int pointerCode (sym_link *etype) -{ - - return PTR_TYPE(SPEC_OCLS(etype)); - -} -#endif /*-----------------------------------------------------------------*/ /* aopForSym - for a true symbol */ @@ -400,12 +371,6 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) PCOI(aop->aopu.pcop)->_function = 1; PCOI(aop->aopu.pcop)->index = 0; aop->size = FPTRSIZE; - /* - sym->aop = aop = newAsmop(AOP_IMMD); - aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1); - strcpy(aop->aopu.aop_immd,sym->rname); - aop->size = FPTRSIZE; - */ DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname); return aop; } @@ -499,6 +464,7 @@ static int aopIdx (asmop *aop, int offset) return aop->aopu.aop_reg[offset]->rIdx; } + /*-----------------------------------------------------------------*/ /* regsInCommon - two operands have some registers in common */ /*-----------------------------------------------------------------*/ @@ -916,7 +882,6 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname) exit(0); } - /*-----------------------------------------------------------------*/ /* popGetTempReg - create a new temporary pCodeOp */ /*-----------------------------------------------------------------*/ @@ -944,6 +909,7 @@ static void popReleaseTempReg(pCodeOp *pcop) PCOR(pcop)->r->isFree = 1; } + /*-----------------------------------------------------------------*/ /* popGetLabel - create a new pCodeOp of type PO_LABEL */ /*-----------------------------------------------------------------*/ @@ -1124,24 +1090,6 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname) case AOP_DIR: return popRegFromString(aop->aopu.aop_dir, aop->size, offset); -#if 0 - pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); - pcop->type = PO_DIR; - - pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1); - strcpy(pcop->name,aop->aopu.aop_dir); - PCOR(pcop)->r = dirregWithName(aop->aopu.aop_dir); - if(PCOR(pcop)->r == NULL) { - //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size); - PCOR(pcop)->r = allocRegByName (aop->aopu.aop_dir,aop->size); - DEBUGpic14_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset); - } else { - DEBUGpic14_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset); - } - PCOR(pcop)->instance = offset; - - return pcop; -#endif case AOP_REG: { @@ -1175,15 +1123,6 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname) case AOP_STR: DEBUGpic14_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]); return newpCodeOpRegFromStr(aop->aopu.aop_str[offset]); - /* - pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); - PCOR(pcop)->r = allocRegByName(aop->aopu.aop_str[offset]); - PCOR(pcop)->rIdx = PCOR(pcop)->r->rIdx; - pcop->type = PCOR(pcop)->r->pc_type; - pcop->name = PCOR(pcop)->r->name; - - return pcop; - */ case AOP_PCODE: pcop = NULL; @@ -1296,21 +1235,6 @@ void aopPut (asmop *aop, char *s, int offset) case AOP_REG: if (strcmp(aop->aopu.aop_reg[offset]->name,s) != 0) { - /* - if (*s == '@' || - strcmp(s,"r0") == 0 || - strcmp(s,"r1") == 0 || - strcmp(s,"r2") == 0 || - strcmp(s,"r3") == 0 || - strcmp(s,"r4") == 0 || - strcmp(s,"r5") == 0 || - strcmp(s,"r6") == 0 || - strcmp(s,"r7") == 0 ) - pic14_emitcode("mov","%s,%s ; %d", - aop->aopu.aop_reg[offset]->dname,s,__LINE__); - else - */ - if(strcmp(s,"W")==0 ) pic14_emitcode("movf","%s,w ; %d",s,__LINE__); @@ -1693,30 +1617,27 @@ release: /*-----------------------------------------------------------------*/ /* genUminusFloat - unary minus for floating points */ /*-----------------------------------------------------------------*/ -static void genUminusFloat(operand *op,operand *result) +static void +genUminusFloat(operand *op, operand *result) { - int size ,offset =0 ; - char *l; - - FENTRY; + int size; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* for this we just need to flip the - first it then copy the rest in place */ - size = AOP_SIZE(op) - 1; - l = aopGet(AOP(op),3,FALSE,FALSE); + FENTRY; - MOVA(l); + DEBUGpic14_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__); + /* for this we just need to flip the + first it then copy the rest in place */ + size = AOP_SIZE(op) - 1; - pic14_emitcode("cpl","acc.7"); - aopPut(AOP(result),"a",3); + mov2w_op(op, size); + emitpcode(POC_XORLW, popGetLit(0x80)); + movwf(AOP(result), size); - while(size--) { - aopPut(AOP(result), - aopGet(AOP(op),offset,FALSE,FALSE), - offset); - offset++; - } + while (size--) + { + mov2w_op(op, size); + movwf(AOP(result), size); + } // while } /*-----------------------------------------------------------------*/ @@ -2348,29 +2269,6 @@ static int resultRemat (iCode *ic) return 0; } -#if 0 -/*-----------------------------------------------------------------*/ -/* inExcludeList - return 1 if the string is in exclude Reg list */ -/*-----------------------------------------------------------------*/ -static bool inExcludeList(char *s) -{ - DEBUGpic14_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__); - int i =0; - - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (options.excludeRegs[i] && - STRCASECMP(options.excludeRegs[i],"none") == 0) - return FALSE ; - - for ( i = 0 ; options.excludeRegs[i]; i++) { - if (options.excludeRegs[i] && - STRCASECMP(s,options.excludeRegs[i]) == 0) - return TRUE; - } - return FALSE ; -} -#endif - /*-----------------------------------------------------------------*/ /* genFunction - generated code for function entry */ /*-----------------------------------------------------------------*/ @@ -3164,59 +3062,6 @@ static void genIfxJump (iCode *ic, char *jval) ic->generated = 1; } -#if 0 -/*-----------------------------------------------------------------*/ -/* genSkip */ -/*-----------------------------------------------------------------*/ -static void genSkip(iCode *ifx,int status_bit) -{ - FENTRY; - if(!ifx) - return; - - if ( IC_TRUE(ifx) ) { - switch(status_bit) { - case 'z': - emitSKPNZ; - break; - - case 'c': - emitSKPNC; - break; - - case 'd': - emitSKPDC; - break; - - } - - emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key)); - pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); - - } else { - - switch(status_bit) { - - case 'z': - emitSKPZ; - break; - - case 'c': - emitSKPC; - break; - - case 'd': - emitSKPDC; - break; - } - emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key)); - pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); - - } - -} -#endif - /*-----------------------------------------------------------------*/ /* genSkipc */ /*-----------------------------------------------------------------*/ @@ -3236,104 +3081,6 @@ static void genSkipc(resolvedIfx *rifx) rifx->generated = 1; } -#if 0 -/*-----------------------------------------------------------------*/ -/* genSkipz2 */ -/*-----------------------------------------------------------------*/ -static void genSkipz2(resolvedIfx *rifx, int invert_condition) -{ - FENTRY; - if(!rifx) - return; - - if( (rifx->condition ^ invert_condition) & 1) - emitSKPZ; - else - emitSKPNZ; - - emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key)); - rifx->generated = 1; -} -#endif - -#if 0 -/*-----------------------------------------------------------------*/ -/* genSkipz */ -/*-----------------------------------------------------------------*/ -static void genSkipz(iCode *ifx, int condition) -{ - FENTRY; - assert (ifx != NULL); - - if(condition) - emitSKPNZ; - else - emitSKPZ; - - if ( IC_TRUE(ifx) ) - emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key)); - else - emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ifx)->key)); - - if ( IC_TRUE(ifx) ) - pic14_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); - else - pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); - -} -#endif - -#if 0 -/*-----------------------------------------------------------------*/ -/* genSkipCond */ -/*-----------------------------------------------------------------*/ -static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit) -{ - FENTRY; - if(!rifx) - return; - - if(rifx->condition) - emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0)); - else - emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(op),offset,FALSE,FALSE),bit,0)); - - - emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key)); - rifx->generated = 1; -} -#endif - -#if 0 -/*-----------------------------------------------------------------*/ -/* 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); -} -#endif - - #define isAOP_REGlike(x) (AOP_TYPE(x) == AOP_REG || AOP_TYPE(x) == AOP_DIR || AOP_TYPE(x) == AOP_PCODE) #define isAOP_LIT(x) (AOP_TYPE(x) == AOP_LIT) #define DEBUGpc emitpComment @@ -3565,3155 +3312,1621 @@ correct_result_in_carry: } // if } - -#if 0 -/* OLD VERSION -- BUGGY, DO NOT USE */ - /*-----------------------------------------------------------------*/ -/* genCmp :- greater or less than comparison */ +/* genCmpGt :- greater than comparison */ /*-----------------------------------------------------------------*/ -static void genCmp (operand *left,operand *right, - operand *result, iCode *ifx, int sign) +static void genCmpGt (iCode *ic, iCode *ifx) { - int size; //, offset = 0 ; - unsigned long lit = 0L,i = 0; - resolvedIfx rFalseIfx; - // resolvedIfx rTrueIfx; - symbol *truelbl; + operand *left, *right, *result; + sym_link *letype , *retype; + int sign ; FENTRY; 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")); - } - */ - - resolveIfx(&rFalseIfx,ifx); - truelbl = newiTempLabel(NULL); - size = max(AOP_SIZE(left),AOP_SIZE(right)); - - DEBUGpic14_AopType(__LINE__,left,right,result); + left = IC_LEFT(ic); + right= IC_RIGHT(ic); + result = IC_RESULT(ic); -#define _swapp + letype = getSpec(operandType(left)); + retype =getSpec(operandType(right)); + sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype)); + /* assign the amsops */ + aopOp (left,ic,FALSE); + aopOp (right,ic,FALSE); + aopOp (result,ic,TRUE); - /* 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 = ulFromVal(AOP(right)->aopu.aop_lit); -#ifdef _swapp + genCmp(right, left, result, ifx, sign); - lit = (lit - 1) & mask; - right = left; - left = tmp; - rFalseIfx.condition ^= 1; -#endif + freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); +} - } else if ((AOP_TYPE(left) == AOP_LIT)) { - lit = ulFromVal(AOP(left)->aopu.aop_lit); - } +/*-----------------------------------------------------------------*/ +/* genCmpLt - less than comparisons */ +/*-----------------------------------------------------------------*/ +static void genCmpLt (iCode *ic, iCode *ifx) +{ + operand *left, *right, *result; + sym_link *letype , *retype; + int sign ; + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + left = IC_LEFT(ic); + right= IC_RIGHT(ic); + result = IC_RESULT(ic); - //if(IC_TRUE(ifx) == NULL) - /* if left & right are bit variables */ - if (AOP_TYPE(left) == AOP_CRY && - AOP_TYPE(right) == AOP_CRY ) { - pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); - pic14_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir); - } else { - /* subtract right from left if at the - end the carry flag is set then we know that - left is greater than right */ + letype = getSpec(operandType(left)); + retype =getSpec(operandType(right)); + sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype)); - symbol *lbl = newiTempLabel(NULL); + /* assign the amsops */ + aopOp (left,ic,FALSE); + aopOp (right,ic,FALSE); + aopOp (result,ic,TRUE); -#ifndef _swapp - if(AOP_TYPE(right) == AOP_LIT) { + genCmp(left, right, result, ifx, sign); - //lit = ulFromVal(AOP(right)->aopu.aop_lit); + freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); +} - DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign); +/*-----------------------------------------------------------------*/ +/* genCmpEq - generates code for equal to */ +/*-----------------------------------------------------------------*/ +static void genCmpEq (iCode *ic, iCode *ifx) +{ + operand *left, *right, *result; + int size; + symbol *false_label; - /* special cases */ + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(lit == 0) { + if(ifx) + DEBUGpic14_emitcode ("; ifx is non-null",""); + else + DEBUGpic14_emitcode ("; ifx is null",""); - 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)); + aopOp((left=IC_LEFT(ic)),ic,FALSE); + aopOp((right=IC_RIGHT(ic)),ic,FALSE); + aopOp((result=IC_RESULT(ic)),ic,TRUE); - if(ifx) ifx->generated = 1; - return; + DEBUGpic14_AopType(__LINE__,left,right,result); - } - size--; + /* if literal, move literal to right */ + if (op_isLitLike (IC_LEFT(ic))) { + operand *tmp = right ; + right = left; + left = tmp; + } - 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,0); - } else { - emitpcode(POC_ADDLW, popGetLit(0x80)); - emitpcode(POC_ADDLW, popGetLit(i^0x80)); - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); - } - - } else { - if(lit == 1) { - genSkipz2(&rFalseIfx,1); - } else { - emitpcode(POC_ADDLW, popGetLit(i)); - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); - } - } - - 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 */ + false_label = NULL; + if (ifx && !IC_TRUE(ifx)) + { + assert (IC_FALSE(ifx)); + false_label = IC_FALSE(ifx); + } - if(sign) { + size = min(AOP_SIZE(left),AOP_SIZE(right)); + assert(!pic14_sameRegs(AOP(result),AOP(left))); + assert(!pic14_sameRegs(AOP(result),AOP(right))); - if(lit == 0) { - genSkipCond(&rFalseIfx,left,size,7); - if(ifx) ifx->generated = 1; - return; - } + /* assume left != right */ + { + int i; + for (i=0; i < AOP_SIZE(result); i++) + { + emitpcode(POC_CLRF, popGet(AOP(result),i)); + } + } - if(lit <0x100) { - DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); + if (AOP_TYPE(right) == AOP_LIT) + { + unsigned long lit = ulFromVal (AOP(right)->aopu.aop_lit); + int i; + size = AOP_SIZE(left); + assert(!op_isLitLike(left)); - //rFalseIfx.condition ^= 1; - //genSkipCond(&rFalseIfx,left,size,7); - //rFalseIfx.condition ^= 1; + switch (lit) + { + case 0: + mov2w(AOP(left), 0); + for (i=1; i < size; i++) + emitpcode(POC_IORFW,popGet(AOP(left),i)); + /* now Z is set iff `left == right' */ + emitSKPZ; + if (!false_label) false_label = newiTempLabel(NULL); + emitpcode(POC_GOTO, popGetLabel(false_label->key)); + break; - 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)); + default: + for (i=0; i < size; i++) + { + mov2w(AOP(left),i); + emitpcode(POC_XORLW, popGetLit(lit >> (8*i))); + /* now Z is cleared if `left != right' */ + emitSKPZ; + if (!false_label) false_label = newiTempLabel(NULL); + emitpcode(POC_GOTO, popGetLabel(false_label->key)); + } // for i + break; + } // switch (lit) + } + else + { + /* right is no literal */ + int i; - emitpcode(POC_MOVLW, popGetLit(0x100-lit)); - emitpcode(POC_ADDFW, popGet(AOP(left),0)); - emitpcode(POC_MOVFW, popGet(AOP(left),1)); + for (i=0; i < size; i++) + { + mov2w(AOP(right),i); + emitpcode(POC_XORFW,popGet(AOP(left),i)); + /* now Z is cleared if `left != right' */ + emitSKPZ; + if (!false_label) false_label = newiTempLabel(NULL); + emitpcode(POC_GOTO, popGetLabel(false_label->key)); + } // for i + } - while(size > 1) - emitpcode(POC_IORFW, popGet(AOP(left),size--)); + /* if we reach here, left == right */ - if(rFalseIfx.condition) { - emitSKPZ; - emitpcode(POC_GOTO, popGetLabel(truelbl->key)); + if (AOP_SIZE(result) > 0) + { + emitpcode(POC_INCF, popGet(AOP(result),0)); + } - } else { - emitSKPNZ; - } + if (ifx && IC_TRUE(ifx)) + { + emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key)); + } - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); - emitpLabel(truelbl->key); - if(ifx) ifx->generated = 1; - return; + if (false_label && (!ifx || IC_TRUE(ifx))) + emitpLabel(false_label->key); - } + if (ifx) ifx->generated = 1; - if(size == 1) { + freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); +} - 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); assert ( !"genSkipc should have inverse logic" ); +/*-----------------------------------------------------------------*/ +/* ifxForOp - returns the icode containing the ifx for operand */ +/*-----------------------------------------------------------------*/ +static iCode *ifxForOp ( operand *op, iCode *ic ) +{ + FENTRY; + /* if true symbol then needs to be assigned */ + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if (IS_TRUE_SYMOP(op)) + return NULL ; + /* if this has register type condition and + the next instruction is ifx with the same operand + and live to of the operand is upto the ifx only then */ + if (ic->next && + ic->next->op == IFX && + IC_COND(ic->next)->key == op->key && + OP_SYMBOL(op)->liveTo <= ic->next->seq ) + return ic->next; - if(ifx) ifx->generated = 1; - return; + if (ic->next && + ic->next->op == IFX && + IC_COND(ic->next)->key == op->key) { + DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__); + return ic->next; + } - } - } 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); assert ( !"genSkipc should have inverse logic" ); + DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__); + if (ic->next && + ic->next->op == IFX) + DEBUGpic14_emitcode ("; ic-next"," is an IFX"); + if (ic->next && + ic->next->op == IFX && + IC_COND(ic->next)->key == op->key) { + DEBUGpic14_emitcode ("; "," key is okay"); + DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d", + OP_SYMBOL(op)->liveTo, + ic->next->seq); + } - if(ifx) ifx->generated = 1; - return; - } + return NULL; +} +/*-----------------------------------------------------------------*/ +/* genAndOp - for && operation */ +/*-----------------------------------------------------------------*/ +static void genAndOp (iCode *ic) +{ + operand *left,*right, *result; + /* symbol *tlbl; */ - } + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* note here that && operations that are in an + if statement are taken away by backPatchLabels + only those used in arthmetic operations remain */ + aopOp((left=IC_LEFT(ic)),ic,FALSE); + aopOp((right=IC_RIGHT(ic)),ic,FALSE); + aopOp((result=IC_RESULT(ic)),ic,FALSE); + DEBUGpic14_AopType(__LINE__,left,right,result); - if(lit & (0x80 << (size*8))) { - /* lit is negative */ - DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); + emitpcode(POC_MOVFW,popGet(AOP(left),0)); + emitpcode(POC_ANDFW,popGet(AOP(right),0)); + emitpcode(POC_MOVWF,popGet(AOP(result),0)); - //genSkipCond(&rFalseIfx,left,size,7); + /* if both are bit variables */ + /* if (AOP_TYPE(left) == AOP_CRY && */ + /* AOP_TYPE(right) == AOP_CRY ) { */ + /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */ + /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */ + /* pic14_outBitC(result); */ + /* } else { */ + /* tlbl = newiTempLabel(NULL); */ + /* pic14_toBoolean(left); */ + /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */ + /* pic14_toBoolean(right); */ + /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */ + /* pic14_outBitAcc(result); */ + /* } */ - emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0)); + freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); +} - if(rFalseIfx.condition) - emitpcode(POC_GOTO, popGetLabel(truelbl->key)); - else - emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); +/*-----------------------------------------------------------------*/ +/* genOrOp - for || operation */ +/*-----------------------------------------------------------------*/ +/* +tsd pic port - +modified this code, but it doesn't appear to ever get called +*/ - } 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)); +static void genOrOp (iCode *ic) +{ + operand *left,*right, *result; + symbol *tlbl; + int i; - } + /* note here that || operations that are in an + if statement are taken away by backPatchLabels + only those used in arthmetic operations remain */ + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + aopOp((left=IC_LEFT(ic)),ic,FALSE); + aopOp((right=IC_RIGHT(ic)),ic,FALSE); + aopOp((result=IC_RESULT(ic)),ic,FALSE); - /* There are no more special cases, so perform a general compare */ + DEBUGpic14_AopType(__LINE__,left,right,result); - emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff)); - emitpcode(POC_SUBFW, popGet(AOP(left),size)); + for (i=0; i < AOP_SIZE(result); i++) + { + emitpcode(POC_CLRF, popGet(AOP(result), i)); + } // for i - while(size--) { + tlbl = newiTempLabel(NULL); + pic14_toBoolean(left); + emitSKPZ; + emitpcode(POC_GOTO, popGetLabel(tlbl->key)); + pic14_toBoolean(right); + emitpLabel(tlbl->key); + /* here Z is clear IFF `left || right' */ + emitSKPZ; + emitpcode(POC_INCF, popGet(AOP(result), 0)); - emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff)); - emitSKPNZ; - emitpcode(POC_SUBFW, popGet(AOP(left),size)); - } - //rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); + freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); +} - emitpLabel(truelbl->key); +/*-----------------------------------------------------------------*/ +/* isLiteralBit - test if lit == 2^n */ +/*-----------------------------------------------------------------*/ +static int isLiteralBit(unsigned long lit) +{ + unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L, + 0x100L,0x200L,0x400L,0x800L, + 0x1000L,0x2000L,0x4000L,0x8000L, + 0x10000L,0x20000L,0x40000L,0x80000L, + 0x100000L,0x200000L,0x400000L,0x800000L, + 0x1000000L,0x2000000L,0x4000000L,0x8000000L, + 0x10000000L,0x20000000L,0x40000000L,0x80000000L}; + int idx; - if(ifx) ifx->generated = 1; - return; + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + for(idx = 0; idx < 32; idx++) + if(lit == pw[idx]) + return idx+1; + return 0; +} +/*-----------------------------------------------------------------*/ +/* continueIfTrue - */ +/*-----------------------------------------------------------------*/ +static void continueIfTrue (iCode *ic) +{ + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if(IC_TRUE(ic)) + { + // Why +100?!? + emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key+100)); + pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100); + } + ic->generated = 1; +} - } - +/*-----------------------------------------------------------------*/ +/* jmpIfTrue - */ +/*-----------------------------------------------------------------*/ +static void jumpIfTrue (iCode *ic) +{ + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if(!IC_TRUE(ic)) + { + // Why +100?!? + emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key+100)); + pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100); + } + ic->generated = 1; +} - /* 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); +/*-----------------------------------------------------------------*/ +/* jmpTrueOrFalse - */ +/*-----------------------------------------------------------------*/ +static void jmpTrueOrFalse (iCode *ic, symbol *tlbl) +{ + FENTRY; + // ugly but optimized by peephole + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if(IC_TRUE(ic)){ + symbol *nlbl = newiTempLabel(NULL); + pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100); + pic14_emitcode("","%05d_DS_:",nlbl->key+100); + } + else{ + pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + } + ic->generated = 1; +} +/*-----------------------------------------------------------------*/ +/* genAnd - code for and */ +/*-----------------------------------------------------------------*/ +static void genAnd (iCode *ic, iCode *ifx) +{ + operand *left, *right, *result; + int size, offset=0; + unsigned long lit = 0L; + int bytelit = 0; + resolvedIfx rIfx; - /* General case - compare to an unsigned literal on the right.*/ + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + aopOp((left = IC_LEFT(ic)),ic,FALSE); + aopOp((right= IC_RIGHT(ic)),ic,FALSE); + aopOp((result=IC_RESULT(ic)),ic,TRUE); - i = (lit >> (size*8)) & 0xff; - emitpcode(POC_MOVLW, popGetLit(i)); - emitpcode(POC_SUBFW, popGet(AOP(left),size)); - while(size--) { - i = (lit >> (size*8)) & 0xff; + resolveIfx(&rIfx,ifx); - 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)); - } - } + /* 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(pic14_sameRegs(AOP(result),AOP(right))){ + operand *tmp = right ; + right = left; + left = tmp; + } - emitpLabel(lbl->key); - //if(emitFinalCheck) - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); - if(sign) - emitpLabel(truelbl->key); + /* 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(ifx) ifx->generated = 1; - return; + size = AOP_SIZE(result); + DEBUGpic14_AopType(__LINE__,left,right,result); + // if(bit & yy) + // result = bit & yy; + if (AOP_TYPE(left) == AOP_CRY){ + // c = bit & literal; + if(AOP_TYPE(right) == AOP_LIT){ + if(lit & 1) { + if(size && pic14_sameRegs(AOP(result),AOP(left))) + // no change + goto release; + pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); + } else { + // bit(result) = 0; + if(size && (AOP_TYPE(result) == AOP_CRY)){ + pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir); + goto release; + } + if((AOP_TYPE(result) == AOP_CRY) && ifx){ + jumpIfTrue(ifx); + goto release; + } + pic14_emitcode("clr","c"); + } + } else { + if (AOP_TYPE(right) == AOP_CRY){ + // c = bit & bit; + pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); + pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir); + } else { + // c = bit & val; + MOVA(aopGet(AOP(right),0,FALSE,FALSE)); + // c = lsb + pic14_emitcode("rrc","a"); + pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir); + } } -#endif // _swapp - - if(AOP_TYPE(left) == AOP_LIT) { - //symbol *lbl = newiTempLabel(NULL); - - //EXPERIMENTAL lit = ulFromVal(AOP(left)->aopu.aop_lit); - - - DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign); - - /* Special cases */ - if((lit == 0) && (sign == 0)){ + // bit = c + // val = c + if(size) + pic14_outBitC(result); + // if(bit & ...) + else if((AOP_TYPE(result) == AOP_CRY) && ifx) + genIfxJump(ifx, "c"); + goto release ; + } - size--; - emitpcode(POC_MOVFW, popGet(AOP(right),size)); - while(size) - emitpcode(POC_IORFW, popGet(AOP(right),--size)); + // 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(aopGet(AOP(left),posbit>>3,FALSE,FALSE)); + // bit = left & 2^n + if(size) + pic14_emitcode("mov","c,acc.%d",posbit&0x07); + // if(left & 2^n) + else{ + if(ifx){ + int offset = 0; + while (posbit > 7) { + posbit -= 8; + offset++; + } + emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS), + newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0)); + emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key)); - genSkipz2(&rFalseIfx,0); - if(ifx) ifx->generated = 1; - return; + ifx->generated = 1; + } + goto release; } + } else { + symbol *tlbl = newiTempLabel(NULL); + int sizel = AOP_SIZE(left); + if(size) + pic14_emitcode("setb","c"); + while(sizel--){ + if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){ + mov2w( AOP(left), offset); + // byte == 2^n ? + if((posbit = isLiteralBit(bytelit)) != 0) { + emitpcode(rIfx.condition ? POC_BTFSC : POC_BTFSS, // XXX: or the other way round? + newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit - 1, 0)); + pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100); + } + else{ + emitpcode(POC_ANDLW, newpCodeOpLit(bytelit & 0x0ff)); + if (rIfx.condition) emitSKPZ; + else emitSKPNZ; - 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(bytelit != 0x0FFL) + { + pic14_emitcode("anl","a,%s", + aopGet(AOP(right),offset,FALSE,TRUE)); + } + pic14_emitcode("jnz","%05d_DS_",tlbl->key+100); + } - if(sign) { - /* signed comparisons to a literal byte */ + emitpcode(POC_GOTO, popGetLabel(rIfx.lbl->key)); + ifx->generated = 1; - int lp1 = (lit+1) & 0xff; + } + offset++; + } + // bit = left & literal + if(size){ + pic14_emitcode("clr","c"); + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + } + // if(left & literal) + else{ + if(ifx) + jmpTrueOrFalse(ifx, tlbl); + goto release ; + } + } + pic14_outBitC(result); + goto release ; + } - 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(((0-(lit+1)) & 0xff) ^ 0x80)); - rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); - break; - } - if(ifx) ifx->generated = 1; - } else { - /* unsigned comparisons to a literal byte */ + /* if left is same as result */ + if(pic14_sameRegs(AOP(result),AOP(left))){ + int know_W = -1; + for(;size--; offset++,lit>>=8) { + if(AOP_TYPE(right) == AOP_LIT){ + switch(lit & 0xff) { + case 0x00: + /* and'ing with 0 has clears the result */ + emitpcode(POC_CLRF,popGet(AOP(result),offset)); + break; + case 0xff: + /* and'ing with 0xff is a nop when the result and left are the same */ + break; - switch(lit & 0xff ) { - case 0: - emitpcode(POC_MOVFW, popGet(AOP(right),0)); - genSkipz2(&rFalseIfx,0); - if(ifx) ifx->generated = 1; - break; - case 0x7f: - genSkipCond(&rFalseIfx,right,0,7); - if(ifx) ifx->generated = 1; - break; + default: + { + int p = my_powof2( (~lit) & 0xff ); + if(p>=0) { + /* only one bit is set in the literal, so use a bcf instruction */ + emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,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; - if (AOP_TYPE(result) == AOP_CRY) { - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); - if(ifx) ifx->generated = 1; } else { - DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition); - emitpcode(POC_CLRF, popGet(AOP(result),0)); - emitpcode(POC_RLF, popGet(AOP(result),0)); - emitpcode(POC_MOVLW, popGetLit(0x01)); - emitpcode(POC_XORWF, popGet(AOP(result),0)); + if(know_W != (int)(lit&0xff)) + emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); + know_W = lit &0xff; + emitpcode(POC_ANDWF,popGet(AOP(left),offset)); } - break; } } - - //goto check_carry; - return; - } else { + emitpcode(POC_MOVFW,popGet(AOP(right),offset)); + emitpcode(POC_ANDWF,popGet(AOP(left),offset)); + } + } - /* Size is greater than 1 */ - - if(sign) { - int lp1 = lit+1; - - size--; - - if(lp1 == 0) { - /* this means lit = 0xffffffff, or -1 */ - - - 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_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; - genSkipCond(&rFalseIfx,right,s,7); - } - - if(ifx) ifx->generated = 1; - return; + } 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 = min(AOP_SIZE(left),AOP_SIZE(right)); + if(size) + pic14_emitcode("setb","c"); + while(sizer--){ + MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); + pic14_emitcode("anl","a,%s", + aopGet(AOP(left),offset,FALSE,FALSE)); + pic14_emitcode("jnz","%05d_DS_",tlbl->key+100); + offset++; + } + if(size){ + CLRC; + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + pic14_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: + emitpcode(POC_CLRF,popGet(AOP(result),offset)); + break; + case 0xff: + emitpcode(POC_MOVFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); + break; + default: + emitpcode(POC_MOVLW, popGetLit(t)); + emitpcode(POC_ANDFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); } + continue; + } - 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); assert ( !"genSkipc should have inverse logic" ); - - - if(ifx) ifx->generated = 1; - return; - } + emitpcode(POC_MOVFW,popGet(AOP(right),offset)); + emitpcode(POC_ANDFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); + } + } + } - 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)); +release : + freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); +} - if(rFalseIfx.condition) - emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); - else - emitpcode(POC_GOTO, popGetLabel(truelbl->key)); +/*-----------------------------------------------------------------*/ +/* genOr - code for or */ +/*-----------------------------------------------------------------*/ +static void genOr (iCode *ic, iCode *ifx) +{ + operand *left, *right, *result; + int size, offset=0; + unsigned long lit = 0L; + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - } 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; + aopOp((left = IC_LEFT(ic)),ic,FALSE); + aopOp((right= IC_RIGHT(ic)),ic,FALSE); + aopOp((result=IC_RESULT(ic)),ic,TRUE); - //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0)); - //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key)); + DEBUGpic14_AopType(__LINE__,left,right,result); - 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)); + /* 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(pic14_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; + } - emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff)); - emitpcode(POC_SUBFW, popGet(AOP(right),size)); + DEBUGpic14_AopType(__LINE__,left,right,result); - while(size--) { + if(AOP_TYPE(right) == AOP_LIT) + lit = ulFromVal (AOP(right)->aopu.aop_lit); - emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff)); - emitSKPNZ; - emitpcode(POC_SUBFW, popGet(AOP(right),size)); - } - rFalseIfx.condition ^= 1; - //rFalseIfx.condition = 1; - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); + size = AOP_SIZE(result); - emitpLabel(truelbl->key); + // 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) + emitpcode(POC_BSF, popGet(AOP(result),0)); + //pic14_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 && pic14_sameRegs(AOP(result),AOP(left))) + goto release; + pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__); + } + } else { + if (AOP_TYPE(right) == AOP_CRY){ + if(pic14_sameRegs(AOP(result),AOP(left))){ + // c = bit | bit; + emitpcode(POC_BCF, popGet(AOP(result),0)); + emitpcode(POC_BTFSC, popGet(AOP(right),0)); + emitpcode(POC_BSF, popGet(AOP(result),0)); - if(ifx) ifx->generated = 1; - return; - // end of if (sign) + pic14_emitcode("bcf","(%s >> 3), (%s & 7)", + AOP(result)->aopu.aop_dir, + AOP(result)->aopu.aop_dir); + pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", + AOP(right)->aopu.aop_dir, + AOP(right)->aopu.aop_dir); + pic14_emitcode("bsf","(%s >> 3), (%s & 7)", + AOP(result)->aopu.aop_dir, + AOP(result)->aopu.aop_dir); } else { - - /* compare word or long to an unsigned literal on the right.*/ - - - 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)); - - - emitpcode(POC_MOVLW, popGetLit(lit+1)); - emitpcode(POC_SUBFW, popGet(AOP(right),0)); - - rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); - } - - emitpLabel(truelbl->key); - - if(ifx) ifx->generated = 1; - return; - } - - - 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)); - - 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)); - } - } + emitpcode(POC_BCF, popGet(AOP(result),0)); + emitpcode(POC_BTFSS, popGet(AOP(right),0)); + emitpcode(POC_BTFSC, popGet(AOP(left),0)); + emitpcode(POC_BSF, popGet(AOP(result),0)); + } + } else { + // c = bit | val; + symbol *tlbl = newiTempLabel(NULL); + pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); - emitpLabel(lbl->key); + emitpcode(POC_BCF, popGet(AOP(result),0)); - rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); + if(!((AOP_TYPE(result) == AOP_CRY) && ifx)) + pic14_emitcode(";XXX setb","c"); + pic14_emitcode(";XXX jb","%s,%05d_DS_", + AOP(left)->aopu.aop_dir,tlbl->key+100); + pic14_toBoolean(right); + pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); + if((AOP_TYPE(result) == AOP_CRY) && ifx){ + jmpTrueOrFalse(ifx, tlbl); + goto release; + } else { + CLRC; + pic14_emitcode("","%05d_DS_:",tlbl->key+100); } - - if(sign) - emitpLabel(truelbl->key); - if(ifx) ifx->generated = 1; - return; } } - /* Compare two variables */ - - DEBUGpic14_emitcode(";sign","%d",sign); + // bit = c + // val = c + if(size) + pic14_outBitC(result); + // if(bit | ...) + else if((AOP_TYPE(result) == AOP_CRY) && ifx) + genIfxJump(ifx, "c"); + goto release ; + } - 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)); + // 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){ + pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); + // result = 1 + if(size) + pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir); + else + continueIfTrue(ifx); + goto release; + } else { + pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); + // lit = 0, result = boolean(left) + if(size) + pic14_emitcode(";XXX setb","c"); + pic14_toBoolean(right); + if(size){ + symbol *tlbl = newiTempLabel(NULL); + pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); + CLRC; + pic14_emitcode("","%05d_DS_:",tlbl->key+100); } 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); assert ( !"genSkipc should have inverse logic" ); - - if(ifx) ifx->generated = 1; - return; + genIfxJump (ifx,"a"); + goto release; } + } + pic14_outBitC(result); + goto release ; + } - } else { + /* if left is same as result */ + if(pic14_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 = my_powof2(lit & 0xff); + if(p>=0) { + /* only one bit is set in the literal, so use a bsf instruction */ + emitpcode(POC_BSF, + newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0)); + } else { + if(know_W != (int)(lit & 0xff)) + emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); + know_W = lit & 0xff; + emitpcode(POC_IORWF, popGet(AOP(left),offset)); + } - emitpcode(POC_MOVFW, popGet(AOP(right),size)); - emitpcode(POC_SUBFW, popGet(AOP(left),size)); + } + } else { + emitpcode(POC_MOVFW, popGet(AOP(right),offset)); + emitpcode(POC_IORWF, popGet(AOP(left),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)); + pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); - /* 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)); - - - } + if(size) + pic14_emitcode(";XXX setb","c"); + while(sizer--){ + MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); + pic14_emitcode(";XXX orl","a,%s", + aopGet(AOP(left),offset,FALSE,FALSE)); + pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); + offset++; + } + if(size){ + CLRC; + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + pic14_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: + emitpcode(POC_MOVFW, popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); - emitpLabel(lbl->key); + break; + default: + emitpcode(POC_MOVLW, popGetLit(t)); + emitpcode(POC_IORFW, popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); + } + continue; + } - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || - (AOP_TYPE(result) == AOP_REG)) { - emitpcode(POC_CLRF, popGet(AOP(result),0)); - emitpcode(POC_RLF, popGet(AOP(result),0)); - } else { - genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); + // faster than result <- left, anl result,right + // and better if result is SFR + emitpcode(POC_MOVFW,popGet(AOP(right),offset)); + emitpcode(POC_IORFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); } - //genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" ); - if(ifx) ifx->generated = 1; - - return; - - } - - // check_carry: - if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) { - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic14_outBitC(result); - } else { - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if the result is used in the next - ifx conditional branch then generate - code a little differently */ - if (ifx ) - genIfxJump (ifx,"c"); - else - pic14_outBitC(result); - /* leave the result in acc */ } -} -#endif - -/*-----------------------------------------------------------------*/ -/* genCmpGt :- greater than comparison */ -/*-----------------------------------------------------------------*/ -static void genCmpGt (iCode *ic, iCode *ifx) -{ - operand *left, *right, *result; - sym_link *letype , *retype; - int sign ; - - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - left = IC_LEFT(ic); - right= IC_RIGHT(ic); - result = IC_RESULT(ic); - - letype = getSpec(operandType(left)); - retype =getSpec(operandType(right)); - sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype)); - /* assign the amsops */ - aopOp (left,ic,FALSE); - aopOp (right,ic,FALSE); - aopOp (result,ic,TRUE); - - genCmp(right, left, result, ifx, sign); - +release : freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ -/* genCmpLt - less than comparisons */ +/* genXor - code for xclusive or */ /*-----------------------------------------------------------------*/ -static void genCmpLt (iCode *ic, iCode *ifx) +static void genXor (iCode *ic, iCode *ifx) { operand *left, *right, *result; - sym_link *letype , *retype; - int sign ; + int size, offset=0; + unsigned long lit = 0L; FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - left = IC_LEFT(ic); - right= IC_RIGHT(ic); - result = IC_RESULT(ic); - - letype = getSpec(operandType(left)); - retype =getSpec(operandType(right)); - sign = !(SPEC_USIGN(letype) | SPEC_USIGN(retype)); - - /* assign the amsops */ - aopOp (left,ic,FALSE); - aopOp (right,ic,FALSE); - aopOp (result,ic,TRUE); - - genCmp(left, right, result, ifx, sign); - - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genCmpEq - generates code for equal to */ -/*-----------------------------------------------------------------*/ -static void genCmpEq (iCode *ic, iCode *ifx) -{ - operand *left, *right, *result; - int size; - symbol *false_label; - - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(ifx) - DEBUGpic14_emitcode ("; ifx is non-null",""); - else - DEBUGpic14_emitcode ("; ifx is null",""); + aopOp((left = IC_LEFT(ic)),ic,FALSE); + aopOp((right= IC_RIGHT(ic)),ic,FALSE); + aopOp((result=IC_RESULT(ic)),ic,TRUE); - aopOp((left=IC_LEFT(ic)),ic,FALSE); - aopOp((right=IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,TRUE); + /* 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; + } - DEBUGpic14_AopType(__LINE__,left,right,result); + /* if result = right then exchange them */ + if(pic14_sameRegs(AOP(result),AOP(right))){ + operand *tmp = right ; + right = left; + left = tmp; + } - /* if literal, move literal to right */ - if (op_isLitLike (IC_LEFT(ic))) { - 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); - false_label = NULL; - if (ifx && !IC_TRUE(ifx)) - { - assert (IC_FALSE(ifx)); - false_label = IC_FALSE(ifx); - } + size = AOP_SIZE(result); - size = min(AOP_SIZE(left),AOP_SIZE(right)); - assert(!pic14_sameRegs(AOP(result),AOP(left))); - assert(!pic14_sameRegs(AOP(result),AOP(right))); + // 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) + {emitpcode(POC_BSF, popGet(AOP(result),offset)); + pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);} + else if(ifx) + continueIfTrue(ifx); + goto release; + } + pic14_emitcode("setb","c"); + } else{ + // lit == (0 or 1) + if(lit == 0){ + // lit == 0, result = left + if(size && pic14_sameRegs(AOP(result),AOP(left))) + goto release; + pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); + } else{ + // lit == 1, result = not(left) + if(size && pic14_sameRegs(AOP(result),AOP(left))){ + emitpcode(POC_MOVLW, popGet(AOP(result),offset)); + emitpcode(POC_XORWF, popGet(AOP(result),offset)); + pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir); + goto release; + } else { + assert ( !"incomplete genXor" ); + pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); + pic14_emitcode("cpl","c"); + } + } + } - /* assume left != right */ - { - int i; - for (i=0; i < AOP_SIZE(result); i++) - { - emitpcode(POC_CLRF, popGet(AOP(result),i)); + } else { + // right != literal + symbol *tlbl = newiTempLabel(NULL); + if (AOP_TYPE(right) == AOP_CRY){ + // c = bit ^ bit; + pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); + } + else{ + int sizer = AOP_SIZE(right); + // c = bit ^ val + // if val>>1 != 0, result = 1 + pic14_emitcode("setb","c"); + while(sizer){ + MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE)); + if(sizer == 1) + // test the msb of the lsb + pic14_emitcode("anl","a,#0xfe"); + pic14_emitcode("jnz","%05d_DS_",tlbl->key+100); + sizer--; + } + // val = (0,1) + pic14_emitcode("rrc","a"); + } + pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100)); + pic14_emitcode("cpl","c"); + pic14_emitcode("","%05d_DS_:",(tlbl->key+100)); + } + // bit = c + // val = c + if(size) + pic14_outBitC(result); + // if(bit | ...) + else if((AOP_TYPE(result) == AOP_CRY) && ifx) + genIfxJump(ifx, "c"); + goto release ; } - } - if (AOP_TYPE(right) == AOP_LIT) - { - unsigned long lit = ulFromVal (AOP(right)->aopu.aop_lit); - int i; - size = AOP_SIZE(left); - assert(!op_isLitLike(left)); - - switch (lit) - { - case 0: - mov2w(AOP(left), 0); - for (i=1; i < size; i++) - emitpcode(POC_IORFW,popGet(AOP(left),i)); - /* now Z is set iff `left == right' */ - emitSKPZ; - if (!false_label) false_label = newiTempLabel(NULL); - emitpcode(POC_GOTO, popGetLabel(false_label->key)); - break; - - default: - for (i=0; i < size; i++) - { - mov2w(AOP(left),i); - emitpcode(POC_XORLW, popGetLit(lit >> (8*i))); - /* now Z is cleared if `left != right' */ - emitSKPZ; - if (!false_label) false_label = newiTempLabel(NULL); - emitpcode(POC_GOTO, popGetLabel(false_label->key)); - } // for i - break; - } // switch (lit) - } - else - { - /* right is no literal */ - int i; - - for (i=0; i < size; i++) - { - mov2w(AOP(right),i); - emitpcode(POC_XORFW,popGet(AOP(left),i)); - /* now Z is cleared if `left != right' */ - emitSKPZ; - if (!false_label) false_label = newiTempLabel(NULL); - emitpcode(POC_GOTO, popGetLabel(false_label->key)); - } // for i - } - - /* if we reach here, left == right */ - - if (AOP_SIZE(result) > 0) - { - emitpcode(POC_INCF, popGet(AOP(result),0)); - } - - if (ifx && IC_TRUE(ifx)) - { - emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ifx)->key)); - } - - if (false_label && (!ifx || IC_TRUE(ifx))) - emitpLabel(false_label->key); - - if (ifx) ifx->generated = 1; - - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* ifxForOp - returns the icode containing the ifx for operand */ -/*-----------------------------------------------------------------*/ -static iCode *ifxForOp ( operand *op, iCode *ic ) -{ - FENTRY; - /* if true symbol then needs to be assigned */ - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (IS_TRUE_SYMOP(op)) - return NULL ; - - /* if this has register type condition and - the next instruction is ifx with the same operand - and live to of the operand is upto the ifx only then */ - if (ic->next && - ic->next->op == IFX && - IC_COND(ic->next)->key == op->key && - OP_SYMBOL(op)->liveTo <= ic->next->seq ) - return ic->next; - - if (ic->next && - ic->next->op == IFX && - IC_COND(ic->next)->key == op->key) { - DEBUGpic14_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__); - return ic->next; - } - - DEBUGpic14_emitcode ("; NULL :(","%d",__LINE__); - if (ic->next && - ic->next->op == IFX) - DEBUGpic14_emitcode ("; ic-next"," is an IFX"); - - if (ic->next && - ic->next->op == IFX && - IC_COND(ic->next)->key == op->key) { - DEBUGpic14_emitcode ("; "," key is okay"); - DEBUGpic14_emitcode ("; "," key liveTo %d, next->seq = %d", - OP_SYMBOL(op)->liveTo, - ic->next->seq); - } - - - return NULL; -} -/*-----------------------------------------------------------------*/ -/* genAndOp - for && operation */ -/*-----------------------------------------------------------------*/ -static void genAndOp (iCode *ic) -{ - operand *left,*right, *result; - /* symbol *tlbl; */ - - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* note here that && operations that are in an - if statement are taken away by backPatchLabels - only those used in arthmetic operations remain */ - aopOp((left=IC_LEFT(ic)),ic,FALSE); - aopOp((right=IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,FALSE); - - DEBUGpic14_AopType(__LINE__,left,right,result); - - emitpcode(POC_MOVFW,popGet(AOP(left),0)); - emitpcode(POC_ANDFW,popGet(AOP(right),0)); - emitpcode(POC_MOVWF,popGet(AOP(result),0)); - - /* if both are bit variables */ - /* if (AOP_TYPE(left) == AOP_CRY && */ - /* AOP_TYPE(right) == AOP_CRY ) { */ - /* pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); */ - /* pic14_emitcode("anl","c,%s",AOP(right)->aopu.aop_dir); */ - /* pic14_outBitC(result); */ - /* } else { */ - /* tlbl = newiTempLabel(NULL); */ - /* pic14_toBoolean(left); */ - /* pic14_emitcode("jz","%05d_DS_",tlbl->key+100); */ - /* pic14_toBoolean(right); */ - /* pic14_emitcode("","%05d_DS_:",tlbl->key+100); */ - /* pic14_outBitAcc(result); */ - /* } */ - - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - - -/*-----------------------------------------------------------------*/ -/* genOrOp - for || operation */ -/*-----------------------------------------------------------------*/ -/* -tsd pic port - -modified this code, but it doesn't appear to ever get called -*/ - -static void genOrOp (iCode *ic) -{ - operand *left,*right, *result; - symbol *tlbl; - int i; - - /* note here that || operations that are in an - if statement are taken away by backPatchLabels - only those used in arthmetic operations remain */ - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - aopOp((left=IC_LEFT(ic)),ic,FALSE); - aopOp((right=IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,FALSE); - - DEBUGpic14_AopType(__LINE__,left,right,result); - - for (i=0; i < AOP_SIZE(result); i++) - { - emitpcode(POC_CLRF, popGet(AOP(result), i)); - } // for i - - tlbl = newiTempLabel(NULL); - pic14_toBoolean(left); - emitSKPZ; - emitpcode(POC_GOTO, popGetLabel(tlbl->key)); - pic14_toBoolean(right); - emitpLabel(tlbl->key); - /* here Z is clear IFF `left || right' */ - emitSKPZ; - emitpcode(POC_INCF, popGet(AOP(result), 0)); - - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* isLiteralBit - test if lit == 2^n */ -/*-----------------------------------------------------------------*/ -static int isLiteralBit(unsigned long lit) -{ - unsigned long pw[32] = {1L,2L,4L,8L,16L,32L,64L,128L, - 0x100L,0x200L,0x400L,0x800L, - 0x1000L,0x2000L,0x4000L,0x8000L, - 0x10000L,0x20000L,0x40000L,0x80000L, - 0x100000L,0x200000L,0x400000L,0x800000L, - 0x1000000L,0x2000000L,0x4000000L,0x8000000L, - 0x10000000L,0x20000000L,0x40000000L,0x80000000L}; - int idx; - - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - for(idx = 0; idx < 32; idx++) - if(lit == pw[idx]) - return idx+1; - return 0; -} - -/*-----------------------------------------------------------------*/ -/* continueIfTrue - */ -/*-----------------------------------------------------------------*/ -static void continueIfTrue (iCode *ic) -{ - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(IC_TRUE(ic)) - { - // Why +100?!? - emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key+100)); - pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100); - } - ic->generated = 1; -} - -/*-----------------------------------------------------------------*/ -/* jmpIfTrue - */ -/*-----------------------------------------------------------------*/ -static void jumpIfTrue (iCode *ic) -{ - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(!IC_TRUE(ic)) - { - // Why +100?!? - emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key+100)); - pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100); - } - ic->generated = 1; -} - -/*-----------------------------------------------------------------*/ -/* jmpTrueOrFalse - */ -/*-----------------------------------------------------------------*/ -static void jmpTrueOrFalse (iCode *ic, symbol *tlbl) -{ - FENTRY; - // ugly but optimized by peephole - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(IC_TRUE(ic)){ - symbol *nlbl = newiTempLabel(NULL); - pic14_emitcode("sjmp","%05d_DS_",nlbl->key+100); - pic14_emitcode("","%05d_DS_:",tlbl->key+100); - pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100); - pic14_emitcode("","%05d_DS_:",nlbl->key+100); - } - else{ - pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100); - pic14_emitcode("","%05d_DS_:",tlbl->key+100); - } - ic->generated = 1; -} - -/*-----------------------------------------------------------------*/ -/* genAnd - code for and */ -/*-----------------------------------------------------------------*/ -static void genAnd (iCode *ic, iCode *ifx) -{ - operand *left, *right, *result; - int size, offset=0; - unsigned long lit = 0L; - int bytelit = 0; - resolvedIfx rIfx; - - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - aopOp((left = IC_LEFT(ic)),ic,FALSE); - aopOp((right= IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,TRUE); - - 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 result = right then exchange them */ - if(pic14_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); - - size = AOP_SIZE(result); - - DEBUGpic14_AopType(__LINE__,left,right,result); - - // if(bit & yy) - // result = bit & yy; - if (AOP_TYPE(left) == AOP_CRY){ - // c = bit & literal; - if(AOP_TYPE(right) == AOP_LIT){ - if(lit & 1) { - if(size && pic14_sameRegs(AOP(result),AOP(left))) - // no change - goto release; - pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - } else { - // bit(result) = 0; - if(size && (AOP_TYPE(result) == AOP_CRY)){ - pic14_emitcode("clr","%s",AOP(result)->aopu.aop_dir); - goto release; - } - if((AOP_TYPE(result) == AOP_CRY) && ifx){ - jumpIfTrue(ifx); - goto release; - } - pic14_emitcode("clr","c"); - } - } else { - if (AOP_TYPE(right) == AOP_CRY){ - // c = bit & bit; - pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); - pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir); - } else { - // c = bit & val; - MOVA(aopGet(AOP(right),0,FALSE,FALSE)); - // c = lsb - pic14_emitcode("rrc","a"); - pic14_emitcode("anl","c,%s",AOP(left)->aopu.aop_dir); - } - } - // bit = c - // val = c - if(size) - pic14_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)){ - int posbit = isLiteralBit(lit); - /* left & 2^n */ - if(posbit){ - posbit--; - //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE)); - // bit = left & 2^n - if(size) - pic14_emitcode("mov","c,acc.%d",posbit&0x07); - // if(left & 2^n) - else{ - if(ifx){ - int offset = 0; - while (posbit > 7) { - posbit -= 8; - offset++; - } - emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS), - newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit,0)); - emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key)); - - ifx->generated = 1; - } - goto release; - } - } else { - symbol *tlbl = newiTempLabel(NULL); - int sizel = AOP_SIZE(left); - if(size) - pic14_emitcode("setb","c"); - while(sizel--){ - if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){ - mov2w( AOP(left), offset); - // byte == 2^n ? - if((posbit = isLiteralBit(bytelit)) != 0) { - emitpcode(rIfx.condition ? POC_BTFSC : POC_BTFSS, // XXX: or the other way round? - newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit - 1, 0)); - pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100); - } - else{ - emitpcode(POC_ANDLW, newpCodeOpLit(bytelit & 0x0ff)); - if (rIfx.condition) emitSKPZ; - else emitSKPNZ; - - if(bytelit != 0x0FFL) - { - pic14_emitcode("anl","a,%s", - aopGet(AOP(right),offset,FALSE,TRUE)); - } - pic14_emitcode("jnz","%05d_DS_",tlbl->key+100); - } - - emitpcode(POC_GOTO, popGetLabel(rIfx.lbl->key)); - ifx->generated = 1; - - } - offset++; - } - // bit = left & literal - if(size){ - pic14_emitcode("clr","c"); - pic14_emitcode("","%05d_DS_:",tlbl->key+100); - } - // if(left & literal) - else{ - if(ifx) - jmpTrueOrFalse(ifx, tlbl); - goto release ; - } - } - pic14_outBitC(result); - goto release ; - } - - /* if left is same as result */ - if(pic14_sameRegs(AOP(result),AOP(left))){ - int know_W = -1; - for(;size--; offset++,lit>>=8) { - if(AOP_TYPE(right) == AOP_LIT){ - switch(lit & 0xff) { - case 0x00: - /* and'ing with 0 has clears the result */ - emitpcode(POC_CLRF,popGet(AOP(result),offset)); - break; - case 0xff: - /* and'ing with 0xff is a nop when the result and left are the same */ - break; - - default: - { - int p = my_powof2( (~lit) & 0xff ); - if(p>=0) { - /* only one bit is set in the literal, so use a bcf instruction */ - emitpcode(POC_BCF,newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0)); - - } else { - if(know_W != (int)(lit&0xff)) - emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); - know_W = lit &0xff; - emitpcode(POC_ANDWF,popGet(AOP(left),offset)); - } - } - } - } else { - emitpcode(POC_MOVFW,popGet(AOP(right),offset)); - emitpcode(POC_ANDWF,popGet(AOP(left),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 = min(AOP_SIZE(left),AOP_SIZE(right)); - if(size) - pic14_emitcode("setb","c"); - while(sizer--){ - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - pic14_emitcode("anl","a,%s", - aopGet(AOP(left),offset,FALSE,FALSE)); - pic14_emitcode("jnz","%05d_DS_",tlbl->key+100); - offset++; - } - if(size){ - CLRC; - pic14_emitcode("","%05d_DS_:",tlbl->key+100); - pic14_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: - emitpcode(POC_CLRF,popGet(AOP(result),offset)); - break; - case 0xff: - emitpcode(POC_MOVFW,popGet(AOP(left),offset)); - emitpcode(POC_MOVWF,popGet(AOP(result),offset)); - break; - default: - emitpcode(POC_MOVLW, popGetLit(t)); - emitpcode(POC_ANDFW,popGet(AOP(left),offset)); - emitpcode(POC_MOVWF,popGet(AOP(result),offset)); - } - continue; - } - - emitpcode(POC_MOVFW,popGet(AOP(right),offset)); - emitpcode(POC_ANDFW,popGet(AOP(left),offset)); - emitpcode(POC_MOVWF,popGet(AOP(result),offset)); - } - } - } - -release : - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genOr - code for or */ -/*-----------------------------------------------------------------*/ -static void genOr (iCode *ic, iCode *ifx) -{ - operand *left, *right, *result; - int size, offset=0; - unsigned long lit = 0L; - - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - aopOp((left = IC_LEFT(ic)),ic,FALSE); - aopOp((right= IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,TRUE); - - DEBUGpic14_AopType(__LINE__,left,right,result); - - /* 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(pic14_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; - } - - DEBUGpic14_AopType(__LINE__,left,right,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){ - // lit != 0 => result = 1 - if(AOP_TYPE(result) == AOP_CRY){ - if(size) - emitpcode(POC_BSF, popGet(AOP(result),0)); - //pic14_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 && pic14_sameRegs(AOP(result),AOP(left))) - goto release; - pic14_emitcode(";XXX mov","c,%s %s,%d",AOP(left)->aopu.aop_dir,__FILE__,__LINE__); - } - } else { - if (AOP_TYPE(right) == AOP_CRY){ - if(pic14_sameRegs(AOP(result),AOP(left))){ - // c = bit | bit; - emitpcode(POC_BCF, popGet(AOP(result),0)); - emitpcode(POC_BTFSC, popGet(AOP(right),0)); - emitpcode(POC_BSF, popGet(AOP(result),0)); - - pic14_emitcode("bcf","(%s >> 3), (%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); - pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(right)->aopu.aop_dir, - AOP(right)->aopu.aop_dir); - pic14_emitcode("bsf","(%s >> 3), (%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); - } else { - emitpcode(POC_BCF, popGet(AOP(result),0)); - emitpcode(POC_BTFSS, popGet(AOP(right),0)); - emitpcode(POC_BTFSC, popGet(AOP(left),0)); - emitpcode(POC_BSF, popGet(AOP(result),0)); - } - } else { - // c = bit | val; - symbol *tlbl = newiTempLabel(NULL); - pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); - - - emitpcode(POC_BCF, popGet(AOP(result),0)); - - if(!((AOP_TYPE(result) == AOP_CRY) && ifx)) - pic14_emitcode(";XXX setb","c"); - pic14_emitcode(";XXX jb","%s,%05d_DS_", - AOP(left)->aopu.aop_dir,tlbl->key+100); - pic14_toBoolean(right); - pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); - if((AOP_TYPE(result) == AOP_CRY) && ifx){ - jmpTrueOrFalse(ifx, tlbl); - goto release; - } else { - CLRC; - pic14_emitcode("","%05d_DS_:",tlbl->key+100); - } - } - } - // bit = c - // val = c - if(size) - pic14_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){ - pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); - // result = 1 - if(size) - pic14_emitcode(";XXX setb","%s",AOP(result)->aopu.aop_dir); - else - continueIfTrue(ifx); - goto release; - } else { - pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); - // lit = 0, result = boolean(left) - if(size) - pic14_emitcode(";XXX setb","c"); - pic14_toBoolean(right); - if(size){ - symbol *tlbl = newiTempLabel(NULL); - pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); - CLRC; - pic14_emitcode("","%05d_DS_:",tlbl->key+100); - } else { - genIfxJump (ifx,"a"); - goto release; - } - } - pic14_outBitC(result); - goto release ; - } - - /* if left is same as result */ - if(pic14_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 = my_powof2(lit & 0xff); - if(p>=0) { - /* only one bit is set in the literal, so use a bsf instruction */ - emitpcode(POC_BSF, - newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0)); - } else { - if(know_W != (int)(lit & 0xff)) - emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); - know_W = lit & 0xff; - emitpcode(POC_IORWF, popGet(AOP(left),offset)); - } - - } - } else { - emitpcode(POC_MOVFW, popGet(AOP(right),offset)); - emitpcode(POC_IORWF, popGet(AOP(left),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)); - pic14_emitcode(";XXX "," %s,%d",__FILE__,__LINE__); - - - if(size) - pic14_emitcode(";XXX setb","c"); - while(sizer--){ - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - pic14_emitcode(";XXX orl","a,%s", - aopGet(AOP(left),offset,FALSE,FALSE)); - pic14_emitcode(";XXX jnz","%05d_DS_",tlbl->key+100); - offset++; - } - if(size){ - CLRC; - pic14_emitcode("","%05d_DS_:",tlbl->key+100); - pic14_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: - emitpcode(POC_MOVFW, popGet(AOP(left),offset)); - emitpcode(POC_MOVWF, popGet(AOP(result),offset)); - - break; - default: - emitpcode(POC_MOVLW, popGetLit(t)); - emitpcode(POC_IORFW, popGet(AOP(left),offset)); - emitpcode(POC_MOVWF, popGet(AOP(result),offset)); - } - continue; - } - - // faster than result <- left, anl result,right - // and better if result is SFR - emitpcode(POC_MOVFW,popGet(AOP(right),offset)); - emitpcode(POC_IORFW,popGet(AOP(left),offset)); - emitpcode(POC_MOVWF, popGet(AOP(result),offset)); - } - } - -release : - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genXor - code for xclusive or */ -/*-----------------------------------------------------------------*/ -static void genXor (iCode *ic, iCode *ifx) -{ - operand *left, *right, *result; - int size, offset=0; - unsigned long lit = 0L; - - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - aopOp((left = IC_LEFT(ic)),ic,FALSE); - aopOp((right= IC_RIGHT(ic)),ic,FALSE); - aopOp((result=IC_RESULT(ic)),ic,TRUE); - - /* 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 result = right then exchange them */ - if(pic14_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); - - 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) - {emitpcode(POC_BSF, popGet(AOP(result),offset)); - pic14_emitcode("setb","%s",AOP(result)->aopu.aop_dir);} - else if(ifx) - continueIfTrue(ifx); - goto release; - } - pic14_emitcode("setb","c"); - } else{ - // lit == (0 or 1) - if(lit == 0){ - // lit == 0, result = left - if(size && pic14_sameRegs(AOP(result),AOP(left))) - goto release; - pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - } else{ - // lit == 1, result = not(left) - if(size && pic14_sameRegs(AOP(result),AOP(left))){ - emitpcode(POC_MOVLW, popGet(AOP(result),offset)); - emitpcode(POC_XORWF, popGet(AOP(result),offset)); - pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir); - goto release; - } else { - assert ( !"incomplete genXor" ); - pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); - pic14_emitcode("cpl","c"); - } - } - } - - } else { - // right != literal - symbol *tlbl = newiTempLabel(NULL); - if (AOP_TYPE(right) == AOP_CRY){ - // c = bit ^ bit; - pic14_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); - } - else{ - int sizer = AOP_SIZE(right); - // c = bit ^ val - // if val>>1 != 0, result = 1 - pic14_emitcode("setb","c"); - while(sizer){ - MOVA(aopGet(AOP(right),sizer-1,FALSE,FALSE)); - if(sizer == 1) - // test the msb of the lsb - pic14_emitcode("anl","a,#0xfe"); - pic14_emitcode("jnz","%05d_DS_",tlbl->key+100); - sizer--; - } - // val = (0,1) - pic14_emitcode("rrc","a"); - } - pic14_emitcode("jnb","%s,%05d_DS_",AOP(left)->aopu.aop_dir,(tlbl->key+100)); - pic14_emitcode("cpl","c"); - pic14_emitcode("","%05d_DS_:",(tlbl->key+100)); - } - // bit = c - // val = c - if(size) - pic14_outBitC(result); - // if(bit | ...) - else if((AOP_TYPE(result) == AOP_CRY) && ifx) - genIfxJump(ifx, "c"); - goto release ; - } - - if(pic14_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 { - emitpcode(POC_MOVLW, popGetLit(t)); - emitpcode(POC_XORWF,popGet(AOP(left),offset)); - } - } else { - emitpcode(POC_MOVFW,popGet(AOP(right),offset)); - emitpcode(POC_XORWF,popGet(AOP(left),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)); - if(size) - pic14_emitcode("setb","c"); - while(sizer--){ - if((AOP_TYPE(right) == AOP_LIT) && - (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){ - MOVA(aopGet(AOP(left),offset,FALSE,FALSE)); - } else { - MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); - pic14_emitcode("xrl","a,%s", - aopGet(AOP(left),offset,FALSE,FALSE)); - } - pic14_emitcode("jnz","%05d_DS_",tlbl->key+100); - offset++; - } - if(size){ - CLRC; - pic14_emitcode("","%05d_DS_:",tlbl->key+100); - pic14_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: - emitpcode(POC_MOVFW,popGet(AOP(left),offset)); - emitpcode(POC_MOVWF,popGet(AOP(result),offset)); - break; - case 0xff: - emitpcode(POC_COMFW,popGet(AOP(left),offset)); - emitpcode(POC_MOVWF,popGet(AOP(result),offset)); - break; - default: - emitpcode(POC_MOVLW, popGetLit(t)); - emitpcode(POC_XORFW,popGet(AOP(left),offset)); - emitpcode(POC_MOVWF,popGet(AOP(result),offset)); - } - continue; - } - - // faster than result <- left, anl result,right - // and better if result is SFR - emitpcode(POC_MOVFW,popGet(AOP(right),offset)); - emitpcode(POC_XORFW,popGet(AOP(left),offset)); - emitpcode(POC_MOVWF,popGet(AOP(result),offset)); - } - } - -release : - freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genInline - write the inline code out */ -/*-----------------------------------------------------------------*/ -static void genInline (iCode *ic) -{ - char *buffer, *bp, *bp1; - bool inComment = FALSE; - - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - _G.inLine += (!options.asmpeep); - - buffer = bp = bp1 = Safe_strdup (IC_INLINE (ic)); - - while (*bp) - { - switch (*bp) - { - case ';': - inComment = TRUE; - ++bp; - break; - - case '\n': - inComment = FALSE; - *bp++ = '\0'; - if (*bp1) - addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process - bp1 = bp; - break; - - default: - /* Add \n for labels, not dirs such as c:\mydir */ - if (!inComment && (*bp == ':') && (isspace((unsigned char)bp[1]))) - { - ++bp; - *bp = '\0'; - ++bp; - /* print label, use this special format with NULL directive - * to denote that the argument should not be indented with tab */ - addpCode2pBlock(pb, newpCodeAsmDir(NULL, bp1)); // inline directly, no process - bp1 = bp; - } - else - ++bp; - break; - } - } - if ((bp1 != bp) && *bp1) - addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process - - Safe_free (buffer); - - _G.inLine -= (!options.asmpeep); -} - -/*-----------------------------------------------------------------*/ -/* genRRC - rotate right with carry */ -/*-----------------------------------------------------------------*/ -static void genRRC (iCode *ic) -{ - operand *left , *result ; - int size, offset = 0, same; - - FENTRY; - /* rotate right with carry */ - left = IC_LEFT(ic); - result=IC_RESULT(ic); - aopOp (left,ic,FALSE); - aopOp (result,ic,FALSE); - - DEBUGpic14_AopType(__LINE__,left,NULL,result); - - same = pic14_sameRegs(AOP(result),AOP(left)); - - size = AOP_SIZE(result); - - /* get the lsb and put it into the carry */ - emitpcode(POC_RRFW, popGet(AOP(left),size-1)); - - offset = 0 ; - - while(size--) { - - if(same) { - emitpcode(POC_RRF, popGet(AOP(left),offset)); - } else { - emitpcode(POC_RRFW, popGet(AOP(left),offset)); - emitpcode(POC_MOVWF, popGet(AOP(result),offset)); - } - - offset++; - } - - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genRLC - generate code for rotate left with carry */ -/*-----------------------------------------------------------------*/ -static void genRLC (iCode *ic) -{ - operand *left , *result ; - int size, offset = 0; - int same; - - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* rotate right with carry */ - left = IC_LEFT(ic); - result=IC_RESULT(ic); - aopOp (left,ic,FALSE); - aopOp (result,ic,FALSE); - - DEBUGpic14_AopType(__LINE__,left,NULL,result); - - same = pic14_sameRegs(AOP(result),AOP(left)); - - /* move it to the result */ - size = AOP_SIZE(result); - - /* get the msb and put it into the carry */ - emitpcode(POC_RLFW, popGet(AOP(left),size-1)); - - offset = 0 ; - - while(size--) { - - if(same) { - emitpcode(POC_RLF, popGet(AOP(left),offset)); - } else { - emitpcode(POC_RLFW, popGet(AOP(left),offset)); - emitpcode(POC_MOVWF, popGet(AOP(result),offset)); - } - - offset++; - } - - - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* genGetHbit - generates code get highest order bit */ -/*-----------------------------------------------------------------*/ -static void genGetHbit (iCode *ic) -{ - operand *left, *result; - left = IC_LEFT(ic); - result=IC_RESULT(ic); - aopOp (left,ic,FALSE); - aopOp (result,ic,FALSE); - - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* get the highest order byte into a */ - MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE)); - if(AOP_TYPE(result) == AOP_CRY){ - pic14_emitcode("rlc","a"); - pic14_outBitC(result); - } - else{ - pic14_emitcode("rl","a"); - pic14_emitcode("anl","a,#0x01"); - pic14_outAcc(result); - } - - - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); -} - -/*-----------------------------------------------------------------*/ -/* AccLsh - shift left accumulator by known count */ -/* MARK: pic14 always rotates through CARRY! */ -/*-----------------------------------------------------------------*/ -static void AccLsh (pCodeOp *pcop,int shCount) -{ - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - shCount &= 0x0007; // shCount : 0..7 - switch(shCount){ - case 0 : - return; - break; - case 1 : - emitCLRC; - emitpcode(POC_RLF,pcop); - return; - break; - case 2 : - emitpcode(POC_RLF,pcop); - emitpcode(POC_RLF,pcop); - break; - case 3 : - emitpcode(POC_RLF,pcop); - emitpcode(POC_RLF,pcop); - emitpcode(POC_RLF,pcop); - break; - case 4 : - emitpcode(POC_SWAPF,pcop); - break; - case 5 : - emitpcode(POC_SWAPF,pcop); - emitpcode(POC_RLF,pcop); - break; - case 6 : - emitpcode(POC_SWAPF,pcop); - emitpcode(POC_RLF,pcop); - emitpcode(POC_RLF,pcop); - break; - case 7 : - emitpcode(POC_RRFW,pcop); - emitpcode(POC_RRF,pcop); - break; - } - /* clear invalid bits */ - emitpcode(POC_MOVLW, popGetLit ((unsigned char)(~((1UL << shCount) - 1)))); - emitpcode(POC_ANDWF, pcop); -} - -/*-----------------------------------------------------------------*/ -/* AccRsh - shift right accumulator by known count */ -/* MARK: pic14 always rotates through CARRY! */ -/* maskmode - 0: leave invalid bits undefined (caller should mask) */ -/* 1: mask out invalid bits (zero-extend) */ -/* 2: sign-extend result (pretty slow) */ -/*-----------------------------------------------------------------*/ -static void AccRsh (pCodeOp *pcop,int shCount, int mask_mode) -{ - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - shCount &= 0x0007; // shCount : 0..7 - switch(shCount){ - case 0 : - return; - break; - case 1 : - /* load sign if needed */ - if (mask_mode == 2) emitpcode(POC_RLFW,pcop); - else if (mask_mode == 1) emitCLRC; - emitpcode(POC_RRF,pcop); - return; - break; - case 2 : - /* load sign if needed */ - if (mask_mode == 2) emitpcode(POC_RLFW,pcop); - emitpcode(POC_RRF,pcop); - /* load sign if needed */ - if (mask_mode == 2) emitpcode(POC_RLFW,pcop); - emitpcode(POC_RRF,pcop); - if (mask_mode == 2) return; - break; - case 3 : - /* load sign if needed */ - if (mask_mode == 2) emitpcode(POC_RLFW,pcop); - emitpcode(POC_RRF,pcop); - /* load sign if needed */ - if (mask_mode == 2) emitpcode(POC_RLFW,pcop); - emitpcode(POC_RRF,pcop); - /* load sign if needed */ - if (mask_mode == 2) emitpcode(POC_RLFW,pcop); - emitpcode(POC_RRF,pcop); - if (mask_mode == 2) return; - break; - case 4 : - emitpcode(POC_SWAPF,pcop); - break; - case 5 : - emitpcode(POC_SWAPF,pcop); - emitpcode(POC_RRF,pcop); - break; - case 6 : - emitpcode(POC_SWAPF,pcop); - emitpcode(POC_RRF,pcop); - emitpcode(POC_RRF,pcop); - break; - case 7 : - if (mask_mode == 2) - { - /* load sign */ - emitpcode(POC_RLFW,pcop); - emitpcode(POC_CLRF,pcop); - emitSKPNC; - emitpcode(POC_COMF,pcop); - return; - } else { - emitpcode(POC_RLFW,pcop); - emitpcode(POC_RLF,pcop); - } - break; - } - - if (mask_mode == 0) - { - /* leave invalid bits undefined */ - return; - } - - /* clear invalid bits -- zero-extend */ - emitpcode(POC_MOVLW, popGetLit (0x00ff >> shCount)); - emitpcode(POC_ANDWF, pcop); - - if (mask_mode == 2) { - /* sign-extend */ - emitpcode(POC_MOVLW, popGetLit (0x00ff << (8 - shCount))); - emitpcode(POC_BTFSC, newpCodeOpBit (get_op(pcop,NULL,0), 7 - shCount ,0)); - emitpcode(POC_IORWF, pcop); - } -} - -#if 0 -/*-----------------------------------------------------------------*/ -/* AccSRsh - signed right shift accumulator by known count */ -/*-----------------------------------------------------------------*/ -static void AccSRsh (int shCount) -{ - symbol *tlbl ; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(shCount != 0){ - if(shCount == 1){ - pic14_emitcode("mov","c,acc.7"); - pic14_emitcode("rrc","a"); - } else if(shCount == 2){ - pic14_emitcode("mov","c,acc.7"); - pic14_emitcode("rrc","a"); - pic14_emitcode("mov","c,acc.7"); - pic14_emitcode("rrc","a"); - } else { - tlbl = newiTempLabel(NULL); - /* rotate right accumulator */ - AccRol(8 - shCount); - /* and kill the higher order bits */ - pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]); - pic14_emitcode("jnb","acc.%d,%05d_DS_",7-shCount,tlbl->key+100); - pic14_emitcode("orl","a,#0x%02x", - (unsigned char)~SRMask[shCount]); - pic14_emitcode("","%05d_DS_:",tlbl->key+100); - } - } -} - -/*-----------------------------------------------------------------*/ -/* shiftR1Left2Result - shift right one byte from left to result */ -/*-----------------------------------------------------------------*/ -static void shiftR1Left2ResultSigned (operand *left, int offl, - operand *result, int offr, - int shCount) -{ - int same; - - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr); - - switch(shCount) { - case 1: - emitpcode(POC_RLFW, popGet(AOP(left),offl)); - if(same) - emitpcode(POC_RRF, popGet(AOP(result),offr)); - else { - emitpcode(POC_RRFW, popGet(AOP(left),offl)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - } - - break; - case 2: - - emitpcode(POC_RLFW, popGet(AOP(left),offl)); - if(same) - emitpcode(POC_RRF, popGet(AOP(result),offr)); - else { - emitpcode(POC_RRFW, popGet(AOP(left),offl)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - } - emitpcode(POC_RLFW, popGet(AOP(result),offr)); - emitpcode(POC_RRF, popGet(AOP(result),offr)); - - break; - - case 3: - if(same) - emitpcode(POC_SWAPF, popGet(AOP(result),offr)); - else { - emitpcode(POC_SWAPFW, popGet(AOP(left),offl)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - } - - emitpcode(POC_RLFW, popGet(AOP(result),offr)); - emitpcode(POC_RLFW, popGet(AOP(result),offr)); - emitpcode(POC_ANDLW, popGetLit(0x1f)); - - emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0)); - emitpcode(POC_IORLW, popGetLit(0xe0)); - - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - break; - - case 4: - emitpcode(POC_SWAPFW, popGet(AOP(left),offl)); - emitpcode(POC_ANDLW, popGetLit(0x0f)); - emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0)); - emitpcode(POC_IORLW, popGetLit(0xf0)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - break; - case 5: - if(same) { - emitpcode(POC_SWAPF, popGet(AOP(result),offr)); - } else { - emitpcode(POC_SWAPFW, popGet(AOP(left),offl)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - } - emitpcode(POC_RRFW, popGet(AOP(result),offr)); - emitpcode(POC_ANDLW, popGetLit(0x07)); - emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),3,0)); - emitpcode(POC_IORLW, popGetLit(0xf8)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - break; - - case 6: - if(same) { - emitpcode(POC_MOVLW, popGetLit(0x00)); - emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0)); - emitpcode(POC_MOVLW, popGetLit(0xfe)); - emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0)); - emitpcode(POC_IORLW, popGetLit(0x01)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - } else { - emitpcode(POC_CLRF, popGet(AOP(result),offr)); - emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0)); - emitpcode(POC_DECF, popGet(AOP(result),offr)); - emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),6,0)); - emitpcode(POC_BCF, newpCodeOpBit(aopGet(AOP(result),offr,FALSE,FALSE),0,0)); - } - break; - - case 7: - if(same) { - emitpcode(POC_MOVLW, popGetLit(0x00)); - emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),LSB,FALSE,FALSE),7,0)); - emitpcode(POC_MOVLW, popGetLit(0xff)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - } else { - emitpcode(POC_CLRF, popGet(AOP(result),offr)); - emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(left),offl,FALSE,FALSE),7,0)); - emitpcode(POC_DECF, popGet(AOP(result),offr)); - } - - default: - break; - } -} - -/*-----------------------------------------------------------------*/ -/* shiftR1Left2Result - shift right one byte from left to result */ -/*-----------------------------------------------------------------*/ -static void shiftR1Left2Result (operand *left, int offl, - operand *result, int offr, - int shCount, int sign) -{ - int same; - - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - same = ((left == result) || (AOP(left) == AOP(result))) && (offl == offr); - - /* Copy the msb into the carry if signed. */ - if(sign) { - shiftR1Left2ResultSigned(left,offl,result,offr,shCount); - return; - } - - - - switch(shCount) { - case 1: - emitCLRC; - if(same) - emitpcode(POC_RRF, popGet(AOP(result),offr)); - else { - emitpcode(POC_RRFW, popGet(AOP(left),offl)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - } - break; - case 2: - emitCLRC; - if(same) { - emitpcode(POC_RRF, popGet(AOP(result),offr)); - } else { - emitpcode(POC_RRFW, popGet(AOP(left),offl)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - } - emitCLRC; - emitpcode(POC_RRF, popGet(AOP(result),offr)); - - break; - case 3: - if(same) - emitpcode(POC_SWAPF, popGet(AOP(result),offr)); - else { - emitpcode(POC_SWAPFW, popGet(AOP(left),offl)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - } - - emitpcode(POC_RLFW, popGet(AOP(result),offr)); - emitpcode(POC_RLFW, popGet(AOP(result),offr)); - emitpcode(POC_ANDLW, popGetLit(0x1f)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - break; - - case 4: - emitpcode(POC_SWAPFW, popGet(AOP(left),offl)); - emitpcode(POC_ANDLW, popGetLit(0x0f)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - break; - - case 5: - emitpcode(POC_SWAPFW, popGet(AOP(left),offl)); - emitpcode(POC_ANDLW, popGetLit(0x0f)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - emitCLRC; - emitpcode(POC_RRF, popGet(AOP(result),offr)); - - break; - case 6: - - emitpcode(POC_RLFW, popGet(AOP(left),offl)); - emitpcode(POC_ANDLW, popGetLit(0x80)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - emitpcode(POC_RLF, popGet(AOP(result),offr)); - emitpcode(POC_RLF, popGet(AOP(result),offr)); - break; - - case 7: - - emitpcode(POC_RLFW, popGet(AOP(left),offl)); - emitpcode(POC_CLRF, popGet(AOP(result),offr)); - emitpcode(POC_RLF, popGet(AOP(result),offr)); - - break; - - default: - break; - } -} - -/*-----------------------------------------------------------------*/ -/* shiftL1Left2Result - shift left one byte from left to result */ -/*-----------------------------------------------------------------*/ -static void shiftL1Left2Result (operand *left, int offl, - operand *result, int offr, int shCount) -{ - int same; - - // char *l; - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr); - DEBUGpic14_emitcode ("; ***","same = %d",same); - // l = aopGet(AOP(left),offl,FALSE,FALSE); - // MOVA(l); - /* shift left accumulator */ - //AccLsh(shCount); // don't comment out just yet... - // aopPut(AOP(result),"a",offr); - - switch(shCount) { - case 1: - /* Shift left 1 bit position */ - emitpcode(POC_MOVFW, popGet(AOP(left),offl)); - if(same) { - emitpcode(POC_ADDWF, popGet(AOP(left),offl)); - } else { - emitpcode(POC_ADDFW, popGet(AOP(left),offl)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - } - break; - case 2: - emitpcode(POC_RLFW, popGet(AOP(left),offl)); - emitpcode(POC_ANDLW,popGetLit(0x7e)); - emitpcode(POC_MOVWF,popGet(AOP(result),offr)); - emitpcode(POC_ADDWF,popGet(AOP(result),offr)); - break; - case 3: - emitpcode(POC_RLFW, popGet(AOP(left),offl)); - emitpcode(POC_ANDLW,popGetLit(0x3e)); - emitpcode(POC_MOVWF,popGet(AOP(result),offr)); - emitpcode(POC_ADDWF,popGet(AOP(result),offr)); - emitpcode(POC_RLF, popGet(AOP(result),offr)); - break; - case 4: - emitpcode(POC_SWAPFW,popGet(AOP(left),offl)); - emitpcode(POC_ANDLW, popGetLit(0xf0)); - emitpcode(POC_MOVWF,popGet(AOP(result),offr)); - break; - case 5: - emitpcode(POC_SWAPFW,popGet(AOP(left),offl)); - emitpcode(POC_ANDLW, popGetLit(0xf0)); - emitpcode(POC_MOVWF,popGet(AOP(result),offr)); - emitpcode(POC_ADDWF,popGet(AOP(result),offr)); - break; - case 6: - emitpcode(POC_SWAPFW,popGet(AOP(left),offl)); - emitpcode(POC_ANDLW, popGetLit(0x30)); - emitpcode(POC_MOVWF,popGet(AOP(result),offr)); - emitpcode(POC_ADDWF,popGet(AOP(result),offr)); - emitpcode(POC_RLF, popGet(AOP(result),offr)); - break; - case 7: - emitpcode(POC_RRFW, popGet(AOP(left),offl)); - emitpcode(POC_CLRF, popGet(AOP(result),offr)); - emitpcode(POC_RRF, popGet(AOP(result),offr)); - break; - - default: - DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount); - } - -} -#endif - -/*-----------------------------------------------------------------*/ -/* movLeft2Result - move byte from left to result */ -/*-----------------------------------------------------------------*/ -static void movLeft2Result (operand *left, int offl, - operand *result, int offr) -{ - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){ - aopGet(AOP(left),offl,FALSE,FALSE); - - emitpcode(POC_MOVFW, popGet(AOP(left),offl)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - } -} - -/*-----------------------------------------------------------------*/ -/* shiftLeft_Left2ResultLit - shift left by known count */ -/*-----------------------------------------------------------------*/ - -static void shiftLeft_Left2ResultLit (operand *left, operand *result, int shCount) -{ - int size, same, offr, i; - - size = AOP_SIZE(left); - if (AOP_SIZE(result) < size) size = AOP_SIZE(result); - - same = pic14_sameRegs (AOP(left), AOP(result)); - - offr = shCount / 8; - shCount = shCount & 0x07; - - size -= offr; - - switch (shCount) - { - case 0: /* takes 0 or 2N cycles (for offr==0) */ - if (!same || offr) { - for (i=size-1; i >= 0; i--) - movLeft2Result (left, i, result, offr + i); - } // if - break; - - case 1: /* takes 1N+1 or 2N+1 cycles (or offr==0) */ - if (same && offr) { - shiftLeft_Left2ResultLit (left, result, 8 * offr); - shiftLeft_Left2ResultLit (result, result, shCount); - return; /* prevent clearing result again */ - } else { - emitCLRC; - for (i=0; i < size; i++) { - if (same && !offr) { - emitpcode (POC_RLF, popGet (AOP(left), i)); - } else { - emitpcode (POC_RLFW, popGet (AOP(left), i)); - emitpcode (POC_MOVWF, popGet (AOP(result), i + offr)); - } // if - } // for - } // if (offr) - break; - - case 4: /* takes 3+5(N-1) = 5N-2 cycles (for offr==0) */ - /* works in-place/with offr as well */ - emitpcode (POC_SWAPFW, popGet (AOP(left), size-1)); - emitpcode (POC_ANDLW, popGetLit (0xF0)); - emitpcode (POC_MOVWF, popGet(AOP(result), size-1+offr)); - - for (i = size - 2; i >= 0; i--) - { - emitpcode (POC_SWAPFW, popGet (AOP(left), i)); - emitpcode (POC_MOVWF, popGet (AOP(result), i + offr)); - emitpcode (POC_ANDLW, popGetLit (0x0F)); - emitpcode (POC_IORWF, popGet (AOP(result), i + offr + 1)); - emitpcode (POC_XORWF, popGet (AOP(result), i + offr)); - } // for i - break; - - case 7: /* takes 2(N-1)+3 = 2N+1 cycles */ - /* works in-place/with offr as well */ - emitpcode (POC_RRFW, popGet (AOP(left), size-1)); - for (i = size-2; i >= 0; i--) { - emitpcode (POC_RRFW, popGet (AOP(left), i)); - emitpcode (POC_MOVWF, popGet (AOP(result), offr + i + 1)); - } // for i - emitpcode (POC_CLRF, popGet (AOP(result), offr)); - emitpcode (POC_RRF, popGet (AOP(result), offr)); - break; + if(pic14_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 { + emitpcode(POC_MOVLW, popGetLit(t)); + emitpcode(POC_XORWF,popGet(AOP(left),offset)); + } + } else { + emitpcode(POC_MOVFW,popGet(AOP(right),offset)); + emitpcode(POC_XORWF,popGet(AOP(left),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)); + if(size) + pic14_emitcode("setb","c"); + while(sizer--){ + if((AOP_TYPE(right) == AOP_LIT) && + (((lit >> (offset*8)) & 0x0FFL) == 0x00L)){ + MOVA(aopGet(AOP(left),offset,FALSE,FALSE)); + } else { + MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); + pic14_emitcode("xrl","a,%s", + aopGet(AOP(left),offset,FALSE,FALSE)); + } + pic14_emitcode("jnz","%05d_DS_",tlbl->key+100); + offset++; + } + if(size){ + CLRC; + pic14_emitcode("","%05d_DS_:",tlbl->key+100); + pic14_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: + emitpcode(POC_MOVFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); + break; + case 0xff: + emitpcode(POC_COMFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); + break; + default: + emitpcode(POC_MOVLW, popGetLit(t)); + emitpcode(POC_XORFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); + } + continue; + } - default: - shiftLeft_Left2ResultLit (left, result, offr * 8 + shCount-1); - shiftLeft_Left2ResultLit (result, result, 1); - return; /* prevent clearing result again */ - break; - } // switch + // faster than result <- left, anl result,right + // and better if result is SFR + emitpcode(POC_MOVFW,popGet(AOP(right),offset)); + emitpcode(POC_XORFW,popGet(AOP(left),offset)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset)); + } + } - while (0 < offr--) - { - emitpcode (POC_CLRF, popGet (AOP(result), offr)); - } // while +release : + freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ -/* shiftRight_Left2ResultLit - shift right by known count */ +/* genInline - write the inline code out */ /*-----------------------------------------------------------------*/ - -static void shiftRight_Left2ResultLit (operand *left, operand *result, int shCount, int sign) +static void genInline (iCode *ic) { - int size, same, offr, i; - - size = AOP_SIZE(left); - if (AOP_SIZE(result) < size) size = AOP_SIZE(result); + char *buffer, *bp, *bp1; + bool inComment = FALSE; - same = pic14_sameRegs (AOP(left), AOP(result)); + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - offr = shCount / 8; - shCount = shCount & 0x07; + _G.inLine += (!options.asmpeep); - size -= offr; + buffer = bp = bp1 = Safe_strdup (IC_INLINE (ic)); - if (size) + while (*bp) { - switch (shCount) + switch (*bp) { - case 0: /* takes 0 or 2N cycles (for offr==0) */ - if (!same || offr) { - for (i=0; i < size; i++) - movLeft2Result (left, i + offr, result, i); - } // if - break; - - case 1: /* takes 1N+1(3) or 2N+1(3) cycles (or offr==0) */ - emitpComment ("%s:%d: shCount=%d, size=%d, sign=%d, same=%d, offr=%d", __FUNCTION__, __LINE__, shCount, size, sign, same, offr); - if (same && offr) { - shiftRight_Left2ResultLit (left, result, 8 * offr, sign); - shiftRight_Left2ResultLit (result, result, shCount, sign); - return; /* prevent sign-extending result again */ - } else { - emitCLRC; - if (sign) { - emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(left), AOP_SIZE(left)-1, FALSE, FALSE), 7, 0)); - emitSETC; - } - for (i = size-1; i >= 0; i--) { - if (same && !offr) { - emitpcode (POC_RRF, popGet (AOP(left), i)); - } else { - emitpcode (POC_RRFW, popGet (AOP(left), i + offr)); - emitpcode (POC_MOVWF, popGet (AOP(result), i)); - } - } // for i - } // if (offr) - break; - - case 4: /* takes 3(6)+5(N-1) = 5N-2(+1) cycles (for offr==0) */ - /* works in-place/with offr as well */ - emitpcode (POC_SWAPFW, popGet (AOP(left), offr)); - emitpcode (POC_ANDLW, popGetLit (0x0F)); - emitpcode (POC_MOVWF, popGet(AOP(result), 0)); + case ';': + inComment = TRUE; + ++bp; + break; - for (i = 1; i < size; i++) - { - emitpcode (POC_SWAPFW, popGet (AOP(left), i + offr)); - emitpcode (POC_MOVWF, popGet (AOP(result), i)); - emitpcode (POC_ANDLW, popGetLit (0xF0)); - emitpcode (POC_IORWF, popGet (AOP(result), i - 1)); - emitpcode (POC_XORWF, popGet (AOP(result), i)); - } // for i + case '\n': + inComment = FALSE; + *bp++ = '\0'; + if (*bp1) + addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process + bp1 = bp; + break; - if (sign) + default: + /* Add \n for labels, not dirs such as c:\mydir */ + if (!inComment && (*bp == ':') && (isspace((unsigned char)bp[1]))) { - emitpcode (POC_MOVLW, popGetLit (0xF0)); - emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(result), size-1, FALSE, FALSE), 3, 0)); - emitpcode (POC_IORWF, popGet (AOP(result), size-1)); - } // if - break; - - case 7: /* takes 2(N-1)+3(4) = 2N+1(2) cycles */ - /* works in-place/with offr as well */ - emitpcode (POC_RLFW, popGet (AOP(left), offr)); - for (i = 0; i < size-1; i++) { - emitpcode (POC_RLFW, popGet (AOP(left), offr + i + 1)); - emitpcode (POC_MOVWF, popGet (AOP(result), i)); - } // for i - emitpcode (POC_CLRF, popGet (AOP(result), size-1)); - if (!sign) { - emitpcode (POC_RLF, popGet (AOP(result), size-1)); - } else { - emitSKPNC; - emitpcode (POC_DECF, popGet (AOP(result), size-1)); + ++bp; + *bp = '\0'; + ++bp; + /* print label, use this special format with NULL directive + * to denote that the argument should not be indented with tab */ + addpCode2pBlock(pb, newpCodeAsmDir(NULL, bp1)); // inline directly, no process + bp1 = bp; } - break; + else + ++bp; + break; + } + } + if ((bp1 != bp) && *bp1) + addpCode2pBlock(pb, newpCodeAsmDir(bp1, NULL)); // inline directly, no process - default: - shiftRight_Left2ResultLit (left, result, offr * 8 + shCount-1, sign); - shiftRight_Left2ResultLit (result, result, 1, sign); - return; /* prevent sign extending result again */ - break; - } // switch - } // if + Safe_free (buffer); - addSign (result, size, sign); + _G.inLine -= (!options.asmpeep); } -#if 0 /*-----------------------------------------------------------------*/ -/* shiftL2Left2Result - shift left two bytes from left to result */ +/* genRRC - rotate right with carry */ /*-----------------------------------------------------------------*/ -static void shiftL2Left2Result (operand *left, int offl, - operand *result, int offr, int shCount) +static void genRRC (iCode *ic) { + operand *left , *result ; + int size, offset = 0, same; + FENTRY; + /* rotate right with carry */ + left = IC_LEFT(ic); + result=IC_RESULT(ic); + aopOp (left,ic,FALSE); + aopOp (result,ic,FALSE); - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic14_AopType(__LINE__,left,NULL,result); - if(pic14_sameRegs(AOP(result), AOP(left))) { - switch(shCount) { - case 0: - break; - case 1: - case 2: - case 3: + same = pic14_sameRegs(AOP(result),AOP(left)); - emitpcode(POC_MOVFW,popGet(AOP(result),offr)); - emitpcode(POC_ADDWF,popGet(AOP(result),offr)); - emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); + size = AOP_SIZE(result); - while(--shCount) { - emitCLRC; - emitpcode(POC_RLF, popGet(AOP(result),offr)); - emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); - } + /* get the lsb and put it into the carry */ + emitpcode(POC_RRFW, popGet(AOP(left),size-1)); - break; - case 4: - case 5: - emitpcode(POC_MOVLW, popGetLit(0x0f)); - emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_SWAPF, popGet(AOP(result),offr)); - emitpcode(POC_ANDFW, popGet(AOP(result),offr)); - emitpcode(POC_XORWF, popGet(AOP(result),offr)); - emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16)); - if(shCount >=5) { - emitpcode(POC_RLF, popGet(AOP(result),offr)); - emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); - } - break; - case 6: - emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_RRF, popGet(AOP(result),offr)); - emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_RRF, popGet(AOP(result),offr)); - emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_ANDLW,popGetLit(0xc0)); - emitpcode(POC_XORFW,popGet(AOP(result),offr)); - emitpcode(POC_XORWF,popGet(AOP(result),offr)); - emitpcode(POC_XORFW,popGet(AOP(result),offr)); - emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16)); - break; - case 7: - emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_RRFW, popGet(AOP(result),offr)); - emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16)); - emitpcode(POC_CLRF, popGet(AOP(result),offr)); - emitpcode(POC_RRF, popGet(AOP(result),offr)); - } + offset = 0 ; - } else { - switch(shCount) { - case 0: - break; - case 1: - case 2: - case 3: - /* note, use a mov/add for the shift since the mov has a - chance of getting optimized out */ - emitpcode(POC_MOVFW, popGet(AOP(left),offl)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - emitpcode(POC_ADDWF, popGet(AOP(result),offr)); - emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16)); - - while(--shCount) { - emitCLRC; - emitpcode(POC_RLF, popGet(AOP(result),offr)); - emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); - } - break; + while(size--) { - case 4: - case 5: - emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16)); - emitpcode(POC_ANDLW, popGetLit(0xF0)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_SWAPFW,popGet(AOP(left),offl)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - emitpcode(POC_ANDLW, popGetLit(0xF0)); - emitpcode(POC_XORWF, popGet(AOP(result),offr)); - emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16)); - - - if(shCount == 5) { - emitpcode(POC_RLF, popGet(AOP(result),offr)); - emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); - } - break; - case 6: - emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16)); - emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16)); - emitpcode(POC_RRFW, popGet(AOP(result),offl)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - - emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_RRF, popGet(AOP(result),offr)); - emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_ANDLW,popGetLit(0xc0)); - emitpcode(POC_XORFW,popGet(AOP(result),offr)); - emitpcode(POC_XORWF,popGet(AOP(result),offr)); - emitpcode(POC_XORFW,popGet(AOP(result),offr)); - emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16)); - break; - case 7: - emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16)); - emitpcode(POC_RRFW, popGet(AOP(left),offl)); - emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16)); - emitpcode(POC_CLRF, popGet(AOP(result),offr)); - emitpcode(POC_RRF, popGet(AOP(result),offr)); + if(same) { + emitpcode(POC_RRF, popGet(AOP(left),offset)); + } else { + emitpcode(POC_RRFW, popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); } + + offset++; } + freeAsmop(left,NULL,ic,TRUE); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ -/* shiftR2Left2Result - shift right two bytes from left to result */ +/* genRLC - generate code for rotate left with carry */ /*-----------------------------------------------------------------*/ -static void shiftR2Left2Result (operand *left, int offl, - operand *result, int offr, - int shCount, int sign) +static void genRLC (iCode *ic) { - int same=0; + operand *left , *result ; + int size, offset = 0; + int same; FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - same = pic14_sameRegs(AOP(result), AOP(left)); + /* rotate right with carry */ + left = IC_LEFT(ic); + result=IC_RESULT(ic); + aopOp (left,ic,FALSE); + aopOp (result,ic,FALSE); - if(same && ((offl + MSB16) == offr)){ - same=1; - /* don't crash result[offr] */ - MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); - pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); - } - /* else { - movLeft2Result(left,offl, result, offr); - MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); - } - */ - /* a:x >> shCount (x = lsb(result))*/ - switch(shCount) { - case 0: - break; - case 1: - case 2: - case 3: - if(sign) - emitpcode(POC_RLFW,popGet(AOP(left),offl+MSB16)); - else - emitCLRC; + DEBUGpic14_AopType(__LINE__,left,NULL,result); - if(same) { - emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16)); - emitpcode(POC_RRF,popGet(AOP(result),offr)); - } else { - emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16)); - emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16)); - emitpcode(POC_RRFW, popGet(AOP(left),offl)); - emitpcode(POC_MOVWF,popGet(AOP(result),offr)); - } + same = pic14_sameRegs(AOP(result),AOP(left)); - while(--shCount) { - if(sign) - emitpcode(POC_RLFW,popGet(AOP(result),offr+MSB16)); - else - emitCLRC; - emitpcode(POC_RRF,popGet(AOP(result),offr+MSB16)); - emitpcode(POC_RRF,popGet(AOP(result),offr)); - } - break; - case 4: - case 5: - if(same) { + /* move it to the result */ + size = AOP_SIZE(result); - emitpcode(POC_MOVLW, popGetLit(0xf0)); - emitpcode(POC_ANDWF, popGet(AOP(result),offr)); - emitpcode(POC_SWAPF, popGet(AOP(result),offr)); + /* get the msb and put it into the carry */ + emitpcode(POC_RLFW, popGet(AOP(left),size-1)); - emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_ANDFW, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_ADDWF, popGet(AOP(result),offr)); - } else { - emitpcode(POC_SWAPFW,popGet(AOP(left),offl)); - emitpcode(POC_ANDLW, popGetLit(0x0f)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr)); - - emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16)); - emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_ANDLW, popGetLit(0xf0)); - emitpcode(POC_XORWF, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_ADDWF, popGet(AOP(result),offr)); - } + offset = 0 ; - if(shCount >=5) { - emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_RRF, popGet(AOP(result),offr)); - } + while(size--) { - if(sign) { - emitpcode(POC_MOVLW, popGetLit(0xf0 + (shCount-4)*8 )); - emitpcode(POC_BTFSC, - newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0)); - emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16)); + if(same) { + emitpcode(POC_RLF, popGet(AOP(left),offset)); + } else { + emitpcode(POC_RLFW, popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result),offset)); } - break; + offset++; + } - case 6: - if(same) { - emitpcode(POC_RLF, popGet(AOP(result),offr)); - emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); - - emitpcode(POC_RLF, popGet(AOP(result),offr)); - emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_RLFW, popGet(AOP(result),offr)); - emitpcode(POC_ANDLW,popGetLit(0x03)); - if(sign) { - emitpcode(POC_BTFSC, - newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0)); - emitpcode(POC_IORLW,popGetLit(0xfc)); - } - emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16)); - emitpcode(POC_XORWF,popGet(AOP(result),offr+MSB16)); - emitpcode(POC_XORFW,popGet(AOP(result),offr+MSB16)); - emitpcode(POC_MOVWF,popGet(AOP(result),offr)); - } else { - emitpcode(POC_RLFW, popGet(AOP(left),offl)); - emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16)); - emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16)); - emitpcode(POC_MOVWF,popGet(AOP(result),offr)); - emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_RLF, popGet(AOP(result),offr)); - emitpcode(POC_RLFW, popGet(AOP(result),offr+MSB16)); - emitpcode(POC_ANDLW,popGetLit(0x03)); - if(sign) { - emitpcode(POC_BTFSC, - newpCodeOpBit(aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0)); - emitpcode(POC_IORLW,popGetLit(0xfc)); - } - emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16)); - //emitpcode(POC_RLF, popGet(AOP(result),offr)); + freeAsmop(left,NULL,ic,TRUE); + freeAsmop(result,NULL,ic,TRUE); +} +/*-----------------------------------------------------------------*/ +/* genGetHbit - generates code get highest order bit */ +/*-----------------------------------------------------------------*/ +static void genGetHbit (iCode *ic) +{ + operand *left, *result; + left = IC_LEFT(ic); + result=IC_RESULT(ic); + aopOp (left,ic,FALSE); + aopOp (result,ic,FALSE); - } + FENTRY; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* get the highest order byte into a */ + MOVA(aopGet(AOP(left),AOP_SIZE(left) - 1,FALSE,FALSE)); + if(AOP_TYPE(result) == AOP_CRY){ + pic14_emitcode("rlc","a"); + pic14_outBitC(result); + } + else{ + pic14_emitcode("rl","a"); + pic14_emitcode("anl","a,#0x01"); + pic14_outAcc(result); + } - break; - case 7: - emitpcode(POC_RLFW, popGet(AOP(left),offl)); - emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16)); - emitpcode(POC_MOVWF,popGet(AOP(result),offr)); - emitpcode(POC_CLRF, popGet(AOP(result),offr+MSB16)); - if(sign) { - emitSKPNC; - emitpcode(POC_DECF, popGet(AOP(result),offr+MSB16)); - } else - emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16)); - } + + freeAsmop(left,NULL,ic,TRUE); + freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ -/* shiftLLeftOrResult - shift left one byte from left, or to result*/ +/* AccLsh - shift left accumulator by known count */ +/* MARK: pic14 always rotates through CARRY! */ /*-----------------------------------------------------------------*/ -static void shiftLLeftOrResult (operand *left, int offl, - operand *result, int offr, int shCount) +static void AccLsh (pCodeOp *pcop,int shCount) { FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - /* shift left accumulator */ - AccLsh(left,offl,shCount); - /* or with result */ - emitpcode (POC_IORWF, popGet (AOP(result), offr)); - assert ( !"broken (modifies left, fails for left==result))" ); + shCount &= 0x0007; // shCount : 0..7 + switch(shCount){ + case 0 : + return; + break; + case 1 : + emitCLRC; + emitpcode(POC_RLF,pcop); + return; + break; + case 2 : + emitpcode(POC_RLF,pcop); + emitpcode(POC_RLF,pcop); + break; + case 3 : + emitpcode(POC_RLF,pcop); + emitpcode(POC_RLF,pcop); + emitpcode(POC_RLF,pcop); + break; + case 4 : + emitpcode(POC_SWAPF,pcop); + break; + case 5 : + emitpcode(POC_SWAPF,pcop); + emitpcode(POC_RLF,pcop); + break; + case 6 : + emitpcode(POC_SWAPF,pcop); + emitpcode(POC_RLF,pcop); + emitpcode(POC_RLF,pcop); + break; + case 7 : + emitpcode(POC_RRFW,pcop); + emitpcode(POC_RRF,pcop); + break; + } + /* clear invalid bits */ + emitpcode(POC_MOVLW, popGetLit ((unsigned char)(~((1UL << shCount) - 1)))); + emitpcode(POC_ANDWF, pcop); } /*-----------------------------------------------------------------*/ -/* shiftRLeftOrResult - shift right one byte from left,or to result*/ +/* AccRsh - shift right accumulator by known count */ +/* MARK: pic14 always rotates through CARRY! */ +/* maskmode - 0: leave invalid bits undefined (caller should mask) */ +/* 1: mask out invalid bits (zero-extend) */ +/* 2: sign-extend result (pretty slow) */ /*-----------------------------------------------------------------*/ -static void shiftRLeftOrResult (operand *left, int offl, - operand *result, int offr, int shCount) +static void AccRsh (pCodeOp *pcop,int shCount, int mask_mode) { FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + shCount &= 0x0007; // shCount : 0..7 + switch(shCount){ + case 0 : + return; + break; + case 1 : + /* load sign if needed */ + if (mask_mode == 2) emitpcode(POC_RLFW,pcop); + else if (mask_mode == 1) emitCLRC; + emitpcode(POC_RRF,pcop); + return; + break; + case 2 : + /* load sign if needed */ + if (mask_mode == 2) emitpcode(POC_RLFW,pcop); + emitpcode(POC_RRF,pcop); + /* load sign if needed */ + if (mask_mode == 2) emitpcode(POC_RLFW,pcop); + emitpcode(POC_RRF,pcop); + if (mask_mode == 2) return; + break; + case 3 : + /* load sign if needed */ + if (mask_mode == 2) emitpcode(POC_RLFW,pcop); + emitpcode(POC_RRF,pcop); + /* load sign if needed */ + if (mask_mode == 2) emitpcode(POC_RLFW,pcop); + emitpcode(POC_RRF,pcop); + /* load sign if needed */ + if (mask_mode == 2) emitpcode(POC_RLFW,pcop); + emitpcode(POC_RRF,pcop); + if (mask_mode == 2) return; + break; + case 4 : + emitpcode(POC_SWAPF,pcop); + break; + case 5 : + emitpcode(POC_SWAPF,pcop); + emitpcode(POC_RRF,pcop); + break; + case 6 : + emitpcode(POC_SWAPF,pcop); + emitpcode(POC_RRF,pcop); + emitpcode(POC_RRF,pcop); + break; + case 7 : + if (mask_mode == 2) + { + /* load sign */ + emitpcode(POC_RLFW,pcop); + emitpcode(POC_CLRF,pcop); + emitSKPNC; + emitpcode(POC_COMF,pcop); + return; + } else { + emitpcode(POC_RLFW,pcop); + emitpcode(POC_RLF,pcop); + } + break; + } + + if (mask_mode == 0) + { + /* leave invalid bits undefined */ + return; + } - /* shift right accumulator */ - AccRsh(left,offl,shCount); - /* or with result */ - emitpcode (POC_IORWF, popGet (AOP(result), offr)); - assert ( !"broken (modifies left, fails for left==result))" ); + /* clear invalid bits -- zero-extend */ + emitpcode(POC_MOVLW, popGetLit (0x00ff >> shCount)); + emitpcode(POC_ANDWF, pcop); + + if (mask_mode == 2) { + /* sign-extend */ + emitpcode(POC_MOVLW, popGetLit (0x00ff << (8 - shCount))); + emitpcode(POC_BTFSC, newpCodeOpBit (get_op(pcop,NULL,0), 7 - shCount ,0)); + emitpcode(POC_IORWF, pcop); + } } /*-----------------------------------------------------------------*/ -/* genlshOne - left shift a one byte quantity by known count */ +/* movLeft2Result - move byte from left to result */ /*-----------------------------------------------------------------*/ -static void genlshOne (operand *result, operand *left, int shCount) +static void movLeft2Result (operand *left, int offl, + operand *result, int offr) { FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - shiftL1Left2Result(left, LSB, result, LSB, shCount); + if(!pic14_sameRegs(AOP(left),AOP(result)) || (offl != offr)){ + aopGet(AOP(left),offl,FALSE,FALSE); + + emitpcode(POC_MOVFW, popGet(AOP(left),offl)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr)); + } } /*-----------------------------------------------------------------*/ -/* genlshTwo - left shift two bytes by known amount != 0 */ +/* shiftLeft_Left2ResultLit - shift left by known count */ /*-----------------------------------------------------------------*/ -static void genlshTwo (operand *result,operand *left, int shCount) + +static void shiftLeft_Left2ResultLit (operand *left, operand *result, int shCount) { - int size; + int size, same, offr, i; - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - size = pic14_getDataSize(result); + size = AOP_SIZE(left); + if (AOP_SIZE(result) < size) size = AOP_SIZE(result); - /* if shCount >= 8 */ - if (shCount >= 8) { - shCount -= 8 ; + same = pic14_sameRegs (AOP(left), AOP(result)); - if (size > 1){ - if (shCount) - shiftL1Left2Result(left, LSB, result, MSB16, shCount); - else - movLeft2Result(left, LSB, result, MSB16); - } - emitpcode(POC_CLRF,popGet(AOP(result),LSB)); - } + offr = shCount / 8; + shCount = shCount & 0x07; - /* 1 <= shCount <= 7 */ - else { - if(size == 1) - shiftL1Left2Result(left, LSB, result, LSB, shCount); - else - shiftL2Left2Result(left, LSB, result, LSB, shCount); - } -} + size -= offr; + + switch (shCount) + { + case 0: /* takes 0 or 2N cycles (for offr==0) */ + if (!same || offr) { + for (i=size-1; i >= 0; i--) + movLeft2Result (left, i, result, offr + i); + } // if + break; + + case 1: /* takes 1N+1 or 2N+1 cycles (or offr==0) */ + if (same && offr) { + shiftLeft_Left2ResultLit (left, result, 8 * offr); + shiftLeft_Left2ResultLit (result, result, shCount); + return; /* prevent clearing result again */ + } else { + emitCLRC; + for (i=0; i < size; i++) { + if (same && !offr) { + emitpcode (POC_RLF, popGet (AOP(left), i)); + } else { + emitpcode (POC_RLFW, popGet (AOP(left), i)); + emitpcode (POC_MOVWF, popGet (AOP(result), i + offr)); + } // if + } // for + } // if (offr) + break; -/*-----------------------------------------------------------------*/ -/* shiftLLong - shift left one long from left to result */ -/* offl = LSB or MSB16 */ -/*-----------------------------------------------------------------*/ -static void shiftLLong (operand *left, operand *result, int offr ) -{ - char *l; - int size = AOP_SIZE(result); + case 4: /* takes 3+5(N-1) = 5N-2 cycles (for offr==0) */ + /* works in-place/with offr as well */ + emitpcode (POC_SWAPFW, popGet (AOP(left), size-1)); + emitpcode (POC_ANDLW, popGetLit (0xF0)); + emitpcode (POC_MOVWF, popGet(AOP(result), size-1+offr)); - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(size >= LSB+offr){ - l = aopGet(AOP(left),LSB,FALSE,FALSE); - MOVA(l); - pic14_emitcode("add","a,acc"); - if (pic14_sameRegs(AOP(left),AOP(result)) && - size >= MSB16+offr && offr != LSB ) - pic14_emitcode("xch","a,%s", - aopGet(AOP(left),LSB+offr,FALSE,FALSE)); - else - aopPut(AOP(result),"a",LSB+offr); - } + for (i = size - 2; i >= 0; i--) + { + emitpcode (POC_SWAPFW, popGet (AOP(left), i)); + emitpcode (POC_MOVWF, popGet (AOP(result), i + offr)); + emitpcode (POC_ANDLW, popGetLit (0x0F)); + emitpcode (POC_IORWF, popGet (AOP(result), i + offr + 1)); + emitpcode (POC_XORWF, popGet (AOP(result), i + offr)); + } // for i + break; - if(size >= MSB16+offr){ - if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) { - l = aopGet(AOP(left),MSB16,FALSE,FALSE); - MOVA(l); - } - pic14_emitcode("rlc","a"); - if (pic14_sameRegs(AOP(left),AOP(result)) && - size >= MSB24+offr && offr != LSB) - pic14_emitcode("xch","a,%s", - aopGet(AOP(left),MSB16+offr,FALSE,FALSE)); - else - aopPut(AOP(result),"a",MSB16+offr); - } + case 7: /* takes 2(N-1)+3 = 2N+1 cycles */ + /* works in-place/with offr as well */ + emitpcode (POC_RRFW, popGet (AOP(left), size-1)); + for (i = size-2; i >= 0; i--) { + emitpcode (POC_RRFW, popGet (AOP(left), i)); + emitpcode (POC_MOVWF, popGet (AOP(result), offr + i + 1)); + } // for i + emitpcode (POC_CLRF, popGet (AOP(result), offr)); + emitpcode (POC_RRF, popGet (AOP(result), offr)); + break; - if(size >= MSB24+offr){ - if (!(pic14_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) { - l = aopGet(AOP(left),MSB24,FALSE,FALSE); - MOVA(l); - } - pic14_emitcode("rlc","a"); - if (pic14_sameRegs(AOP(left),AOP(result)) && - size >= MSB32+offr && offr != LSB ) - pic14_emitcode("xch","a,%s", - aopGet(AOP(left),MSB24+offr,FALSE,FALSE)); - else - aopPut(AOP(result),"a",MSB24+offr); - } + default: + shiftLeft_Left2ResultLit (left, result, offr * 8 + shCount-1); + shiftLeft_Left2ResultLit (result, result, 1); + return; /* prevent clearing result again */ + break; + } // switch - if(size > MSB32+offr){ - if (!(pic14_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) { - l = aopGet(AOP(left),MSB32,FALSE,FALSE); - MOVA(l); - } - pic14_emitcode("rlc","a"); - aopPut(AOP(result),"a",MSB32+offr); - } - if(offr != LSB) - aopPut(AOP(result),zero,LSB); + while (0 < offr--) + { + emitpcode (POC_CLRF, popGet (AOP(result), offr)); + } // while } /*-----------------------------------------------------------------*/ -/* genlshFour - shift four byte by a known amount != 0 */ +/* shiftRight_Left2ResultLit - shift right by known count */ /*-----------------------------------------------------------------*/ -static void genlshFour (operand *result, operand *left, int shCount) + +static void shiftRight_Left2ResultLit (operand *left, operand *result, int shCount, int sign) { - int size; + int size, same, offr, i; - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - size = AOP_SIZE(result); + size = AOP_SIZE(left); + if (AOP_SIZE(result) < size) size = AOP_SIZE(result); - /* if shifting more that 3 bytes */ - if (shCount >= 24 ) { - shCount -= 24; - if (shCount) - /* lowest order of left goes to the highest - order of the destination */ - shiftL1Left2Result(left, LSB, result, MSB32, shCount); - else - movLeft2Result(left, LSB, result, MSB32); - aopPut(AOP(result),zero,LSB); - aopPut(AOP(result),zero,MSB16); - aopPut(AOP(result),zero,MSB32); - return; - } + same = pic14_sameRegs (AOP(left), AOP(result)); - /* more than two bytes */ - else if ( shCount >= 16 ) { - /* lower order two bytes goes to higher order two bytes */ - shCount -= 16; - /* if some more remaining */ - if (shCount) - shiftL2Left2Result(left, LSB, result, MSB24, shCount); - else { - movLeft2Result(left, MSB16, result, MSB32); - movLeft2Result(left, LSB, result, MSB24); - } - aopPut(AOP(result),zero,MSB16); - aopPut(AOP(result),zero,LSB); - return; - } + offr = shCount / 8; + shCount = shCount & 0x07; - /* if more than 1 byte */ - else if ( shCount >= 8 ) { - /* lower order three bytes goes to higher order three bytes */ - shCount -= 8; - if(size == 2){ - if(shCount) - shiftL1Left2Result(left, LSB, result, MSB16, shCount); - else - movLeft2Result(left, LSB, result, MSB16); - } - else{ /* size = 4 */ - if(shCount == 0){ - movLeft2Result(left, MSB24, result, MSB32); - movLeft2Result(left, MSB16, result, MSB24); - movLeft2Result(left, LSB, result, MSB16); - aopPut(AOP(result),zero,LSB); - } - else if(shCount == 1) - shiftLLong(left, result, MSB16); - else{ - shiftL2Left2Result(left, MSB16, result, MSB24, shCount); - shiftL1Left2Result(left, LSB, result, MSB16, shCount); - shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount); - aopPut(AOP(result),zero,LSB); - } - } - } + size -= offr; - /* 1 <= shCount <= 7 */ - else if(shCount <= 2){ - shiftLLong(left, result, LSB); - if(shCount == 2) - shiftLLong(result, result, LSB); - } - /* 3 <= shCount <= 7, optimize */ - else{ - shiftL2Left2Result(left, MSB24, result, MSB24, shCount); - shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount); - shiftL2Left2Result(left, LSB, result, LSB, shCount); - } -} -#endif + if (size) + { + switch (shCount) + { + case 0: /* takes 0 or 2N cycles (for offr==0) */ + if (!same || offr) { + for (i=0; i < size; i++) + movLeft2Result (left, i + offr, result, i); + } // if + break; -#if 0 -/*-----------------------------------------------------------------*/ -/* genLeftShiftLiteral - left shifting by known count */ -/*-----------------------------------------------------------------*/ -static void genLeftShiftLiteral (operand *left, - operand *right, - operand *result, - iCode *ic) -{ - int shCount = (int) ulFromVal (AOP(right)->aopu.aop_lit); - //int size; + case 1: /* takes 1N+1(3) or 2N+1(3) cycles (or offr==0) */ + emitpComment ("%s:%d: shCount=%d, size=%d, sign=%d, same=%d, offr=%d", __FUNCTION__, __LINE__, shCount, size, sign, same, offr); + if (same && offr) { + shiftRight_Left2ResultLit (left, result, 8 * offr, sign); + shiftRight_Left2ResultLit (result, result, shCount, sign); + return; /* prevent sign-extending result again */ + } else { + emitCLRC; + if (sign) { + emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(left), AOP_SIZE(left)-1, FALSE, FALSE), 7, 0)); + emitSETC; + } + for (i = size-1; i >= 0; i--) { + if (same && !offr) { + emitpcode (POC_RRF, popGet (AOP(left), i)); + } else { + emitpcode (POC_RRFW, popGet (AOP(left), i + offr)); + emitpcode (POC_MOVWF, popGet (AOP(result), i)); + } + } // for i + } // if (offr) + break; - FENTRY; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - freeAsmop(right,NULL,ic,TRUE); + case 4: /* takes 3(6)+5(N-1) = 5N-2(+1) cycles (for offr==0) */ + /* works in-place/with offr as well */ + emitpcode (POC_SWAPFW, popGet (AOP(left), offr)); + emitpcode (POC_ANDLW, popGetLit (0x0F)); + emitpcode (POC_MOVWF, popGet(AOP(result), 0)); - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); + for (i = 1; i < size; i++) + { + emitpcode (POC_SWAPFW, popGet (AOP(left), i + offr)); + emitpcode (POC_MOVWF, popGet (AOP(result), i)); + emitpcode (POC_ANDLW, popGetLit (0xF0)); + emitpcode (POC_IORWF, popGet (AOP(result), i - 1)); + emitpcode (POC_XORWF, popGet (AOP(result), i)); + } // for i - size = getSize(operandType(result)); + if (sign) + { + emitpcode (POC_MOVLW, popGetLit (0xF0)); + emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(result), size-1, FALSE, FALSE), 3, 0)); + emitpcode (POC_IORWF, popGet (AOP(result), size-1)); + } // if + break; -#if VIEW_SIZE - pic14_emitcode("; shift left ","result %d, left %d",size, - AOP_SIZE(left)); -#endif + case 7: /* takes 2(N-1)+3(4) = 2N+1(2) cycles */ + /* works in-place/with offr as well */ + emitpcode (POC_RLFW, popGet (AOP(left), offr)); + for (i = 0; i < size-1; i++) { + emitpcode (POC_RLFW, popGet (AOP(left), offr + i + 1)); + emitpcode (POC_MOVWF, popGet (AOP(result), i)); + } // for i + emitpcode (POC_CLRF, popGet (AOP(result), size-1)); + if (!sign) { + emitpcode (POC_RLF, popGet (AOP(result), size-1)); + } else { + emitSKPNC; + emitpcode (POC_DECF, popGet (AOP(result), size-1)); + } + break; - /* I suppose that the left size >= result size */ - if(shCount == 0){ - while(size--){ - movLeft2Result(left, size, result, size); - } - } + default: + shiftRight_Left2ResultLit (left, result, offr * 8 + shCount-1, sign); + shiftRight_Left2ResultLit (result, result, 1, sign); + return; /* prevent sign extending result again */ + break; + } // switch + } // if - else if(shCount >= (size * 8)) - while(size--) - aopPut(AOP(result),zero,size); - else{ - switch (size) { - case 1: - genlshOne (result,left,shCount); - break; - - case 2: - case 3: - genlshTwo (result,left,shCount); - break; - - case 4: - genlshFour (result,left,shCount); - break; - } - } - freeAsmop(left,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); + addSign (result, size, sign); } -#endif /*-----------------------------------------------------------------* * genMultiAsm - repeat assembly instruction for size of register. @@ -8101,35 +6314,6 @@ static void genAddrOf (iCode *ic) } -#if 0 -/*-----------------------------------------------------------------*/ -/* genFarFarAssign - assignment when both are in far space */ -/*-----------------------------------------------------------------*/ -static void genFarFarAssign (operand *result, operand *right, iCode *ic) -{ - int size = AOP_SIZE(right); - int offset = 0; - char *l ; - /* first push the right side on to the stack */ - while (size--) { - l = aopGet(AOP(right),offset++,FALSE,FALSE); - MOVA(l); - pic14_emitcode ("push","acc"); - } - - freeAsmop(right,NULL,ic,FALSE); - /* now assign DPTR to result */ - aopOp(result,ic,FALSE); - size = AOP_SIZE(result); - while (size--) { - pic14_emitcode ("pop","acc"); - aopPut(AOP(result),"a",--offset); - } - freeAsmop(result,NULL,ic,FALSE); - -} -#endif - /*-----------------------------------------------------------------*/ /* genAssign - generate code for assignment */ /*-----------------------------------------------------------------*/ @@ -8320,138 +6504,6 @@ static void genJumpTab (iCode *ic) } -/*-----------------------------------------------------------------*/ -/* genMixedOperation - gen code for operators between mixed types */ -/*-----------------------------------------------------------------*/ -/* -TSD - Written for the PIC port - but this unfortunately is buggy. -This routine is good in that it is able to efficiently promote -types to different (larger) sizes. Unfortunately, the temporary -variables that are optimized out by this routine are sometimes -used in other places. So until I know how to really parse the -iCode tree, I'm going to not be using this routine :(. -*/ -static int genMixedOperation (iCode *ic) -{ - FENTRY; -#if 0 - operand *result = IC_RESULT(ic); - sym_link *ctype = operandType(IC_LEFT(ic)); - operand *right = IC_RIGHT(ic); - int ret = 0; - int big,small; - int offset; - - iCode *nextic; - operand *nextright=NULL,*nextleft=NULL,*nextresult=NULL; - - pic14_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); - - nextic = ic->next; - if(!nextic) - return 0; - - nextright = IC_RIGHT(nextic); - nextleft = IC_LEFT(nextic); - nextresult = IC_RESULT(nextic); - - aopOp(right,ic,FALSE); - aopOp(result,ic,FALSE); - aopOp(nextright, nextic, FALSE); - aopOp(nextleft, nextic, FALSE); - aopOp(nextresult, nextic, FALSE); - - if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_RIGHT(nextic)))) { - - operand *t = right; - right = nextright; - nextright = t; - - pic14_emitcode(";remove right +",""); - - } else if (pic14_sameRegs(AOP(IC_RESULT(ic)), AOP(IC_LEFT(nextic)))) { - /* - operand *t = right; - right = nextleft; - nextleft = t; - */ - pic14_emitcode(";remove left +",""); - } else - return 0; - - big = AOP_SIZE(nextleft); - small = AOP_SIZE(nextright); - - switch(nextic->op) { - - case '+': - pic14_emitcode(";optimize a +",""); - /* if unsigned or not an integral type */ - if (AOP_TYPE(IC_LEFT(nextic)) == AOP_CRY) { - pic14_emitcode(";add a bit to something",""); - } else { - - pic14_emitcode("movf","%s,w",AOP(nextright)->aopu.aop_dir); - - if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ) { - pic14_emitcode("addwf","%s,w",AOP(nextleft)->aopu.aop_dir); - pic14_emitcode("movwf","%s",aopGet(AOP(IC_RESULT(nextic)),0,FALSE,FALSE)); - } else - pic14_emitcode("addwf","%s,f",AOP(nextleft)->aopu.aop_dir); - - offset = 0; - while(--big) { - - offset++; - - if(--small) { - if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){ - pic14_emitcode("movf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE)); - pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) ); - } - - pic14_emitcode("movf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE)); - emitSKPNC; - pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(nextic))->aopu.aop_dir, - AOP(IC_RIGHT(nextic))->aopu.aop_dir); - pic14_emitcode(" incf","%s,w", aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE)); - pic14_emitcode("movwf","%s", aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE)); - - } else { - pic14_emitcode("rlf","known_zero,w"); - - /* - if right is signed - btfsc right,7 - addlw ff - */ - if (!pic14_sameRegs(AOP(IC_LEFT(nextic)), AOP(IC_RESULT(nextic))) ){ - pic14_emitcode("addwf","%s,w",aopGet(AOP(IC_LEFT(nextic)),offset,FALSE,FALSE)); - pic14_emitcode("movwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) ); - } else { - pic14_emitcode("addwf","%s,f",aopGet(AOP(IC_RESULT(nextic)),offset,FALSE,FALSE) ); - } - } - } - ret = 1; - } - } - ret = 1; - -release: - freeAsmop(right,NULL,ic,TRUE); - freeAsmop(result,NULL,ic,TRUE); - freeAsmop(nextright,NULL,ic,TRUE); - freeAsmop(nextleft,NULL,ic,TRUE); - if(ret) - nextic->generated = 1; - - return ret; -#else - return 0; -#endif -} /*-----------------------------------------------------------------*/ /* genCast - gen code for casting */ /*-----------------------------------------------------------------*/ @@ -8612,14 +6664,7 @@ static void genCast (iCode *ic) } /* so we now know that the size of destination is greater - than the size of the source. - Now, if the next iCode is an operator then we might be - able to optimize the operation without performing a cast. - */ - if(0 && genMixedOperation(ic)) { - /* XXX: cannot optimize: must copy regs! */ - goto release; - } + than the size of the source. */ /* we move to result for the size of source */ size = AOP_SIZE(right);