X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic%2Fgenarith.c;h=1f5515ed69b0c64bf642d225c55fcce2895f05de;hb=f1007d04010ff2955d4d962c89616311ff4719d6;hp=8bb0747804671a5767aaf656198901baf32dd98c;hpb=08dd337046c6cfa728572976d1a23d3ea5654da6;p=fw%2Fsdcc diff --git a/src/pic/genarith.c b/src/pic/genarith.c index 8bb07478..1f5515ed 100644 --- a/src/pic/genarith.c +++ b/src/pic/genarith.c @@ -25,8 +25,8 @@ what you give them. Help stamp out software-hoarding! Notes: - 000123 mlh Moved aopLiteral to SDCCglue.c to help the split - Made everything static + 000123 mlh Moved aopLiteral to SDCCglue.c to help the split + Made everything static -------------------------------------------------------------------------*/ #include @@ -37,7 +37,7 @@ #include "newalloc.h" #if defined(_MSC_VER) && (_MSC_VER < 1300) -#define __FUNCTION__ __FILE__ +#define __FUNCTION__ __FILE__ #endif #include "common.h" @@ -97,6 +97,47 @@ const char *AopType(short type) return "BAD TYPE"; } +void DebugAop(asmop *aop) +{ + if(!aop) + return; + printf("%s\n",AopType(aop->type)); + printf(" current offset: %d\n",aop->coff); + printf(" size: %d\n",aop->size); + + switch(aop->type) { + case AOP_LIT: + printf(" name: %s\n",aop->aopu.aop_lit->name); + break; + case AOP_REG: + printf(" name: %s\n",aop->aopu.aop_reg[0]->name); + break; + case AOP_CRY: + case AOP_DIR: + printf(" name: %s\n",aop->aopu.aop_dir); + break; + case AOP_DPTR: + case AOP_DPTR2: + case AOP_R0: + case AOP_R1: + case AOP_ACC: + printf("not supported\n"); + break; + case AOP_STK: + printf(" Stack offset: %d\n",aop->aopu.aop_stk); + break; + case AOP_IMMD: + printf(" immediate: %s\n",aop->aopu.aop_immd); + break; + case AOP_STR: + printf(" aop_str[0]: %s\n",aop->aopu.aop_str[0]); + break; + case AOP_PCODE: + //printpCode(stdout,aop->aopu.pcop); + break; + } +} + const char *pCodeOpType( pCodeOp *pcop) { @@ -159,6 +200,7 @@ bool genPlusIncr (iCode *ic) { unsigned int icount ; unsigned int size = pic14_getDataSize(IC_RESULT(ic)); + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); DEBUGpic14_emitcode ("; ","result %s, left %s, right %s", @@ -251,6 +293,7 @@ void pic14_outBitAcc(operand *result) { symbol *tlbl = newiTempLabel(NULL); /* if the result is a bit */ + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (AOP_TYPE(result) == AOP_CRY){ @@ -264,82 +307,6 @@ void pic14_outBitAcc(operand *result) } } -/*-----------------------------------------------------------------*/ -/* genPlusBits - generates code for addition of two bits */ -/*-----------------------------------------------------------------*/ -void genPlusBits (iCode *ic) -{ - - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - DEBUGpic14_emitcode ("; ","result %s, left %s, right %s", - AopType(AOP_TYPE(IC_RESULT(ic))), - AopType(AOP_TYPE(IC_LEFT(ic))), - AopType(AOP_TYPE(IC_RIGHT(ic)))); - /* - The following block of code will add two bits. - Note that it'll even work if the destination is - the carry (C in the status register). - It won't work if the 'Z' bit is a source or destination. - */ - - /* If the result is stored in the accumulator (w) */ - //if(strcmp(aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE),"a") == 0 ) { - switch(AOP_TYPE(IC_RESULT(ic))) { - case AOP_ACC: - emitpcode(POC_CLRW, NULL); - emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0)); - emitpcode(POC_XORLW, popGetLit(1)); - emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0)); - emitpcode(POC_XORLW, popGetLit(1)); - - pic14_emitcode("clrw",""); - pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - pic14_emitcode("xorlw","1"); - pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_LEFT(ic))->aopu.aop_dir, - AOP(IC_LEFT(ic))->aopu.aop_dir); - pic14_emitcode("xorlw","1"); - break; - case AOP_REG: - emitpcode(POC_MOVLW, popGetLit(0)); - emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0)); - emitpcode(POC_XORLW, popGetLit(1)); - emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0)); - emitpcode(POC_XORLW, popGetLit(1)); - emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),0)); - break; - default: - emitpcode(POC_MOVLW, popGet(AOP(IC_RESULT(ic)),0)); - emitpcode(POC_BCF, popGet(AOP(IC_RESULT(ic)),0)); - emitpcode(POC_BTFSC, popGet(AOP(IC_RIGHT(ic)),0)); - emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0)); - emitpcode(POC_BTFSC, popGet(AOP(IC_LEFT(ic)),0)); - emitpcode(POC_XORWF, popGet(AOP(IC_RESULT(ic)),0)); - - pic14_emitcode("movlw","(1 << (%s & 7))", - AOP(IC_RESULT(ic))->aopu.aop_dir, - AOP(IC_RESULT(ic))->aopu.aop_dir); - pic14_emitcode("bcf","(%s >> 3), (%s & 7)", - AOP(IC_RESULT(ic))->aopu.aop_dir, - AOP(IC_RESULT(ic))->aopu.aop_dir); - pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_RIGHT(ic))->aopu.aop_dir, - AOP(IC_RIGHT(ic))->aopu.aop_dir); - pic14_emitcode("xorwf","(%s >>3),f", - AOP(IC_RESULT(ic))->aopu.aop_dir); - pic14_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(IC_LEFT(ic))->aopu.aop_dir, - AOP(IC_LEFT(ic))->aopu.aop_dir); - pic14_emitcode("xorwf","(%s>>3),f", - AOP(IC_RESULT(ic))->aopu.aop_dir); - break; - } - -} - #if 0 /* This is the original version of this code. * @@ -397,7 +364,7 @@ static void adjustArithmeticResult(iCode *ic) GPTRSIZE - 1); } - if (opIsGptr(IC_RESULT(ic)) && + if (opIsGptr(IC_RESULT(ic)) && AOP_SIZE(IC_LEFT(ic)) < GPTRSIZE && AOP_SIZE(IC_RIGHT(ic)) < GPTRSIZE && !pic14_sameRegs(AOP(IC_RESULT(ic)),AOP(IC_LEFT(ic))) && @@ -414,6 +381,7 @@ static void adjustArithmeticResult(iCode *ic) /*-----------------------------------------------------------------*/ static void genAddLit2byte (operand *result, int offr, int lit) { + FENTRY; switch(lit & 0xff) { case 0: @@ -433,6 +401,7 @@ static void genAddLit2byte (operand *result, int offr, int lit) static void emitMOVWF(operand *reg, int offset) { + FENTRY; if(!reg) return; @@ -454,6 +423,7 @@ static void genAddLit (iCode *ic, int lit) operand *result; operand *left; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -461,6 +431,8 @@ static void genAddLit (iCode *ic, int lit) result = IC_RESULT(ic); same = pic14_sameRegs(AOP(left), AOP(result)); size = pic14_getDataSize(result); + if (size > pic14_getDataSize(left)) + size = pic14_getDataSize(left); if(same) { @@ -519,7 +491,7 @@ static void genAddLit (iCode *ic, int lit) emitpcode(POC_INCFSZW, popGet(AOP(result),0)); emitpcode(POC_INCF, popGet(AOP(result),MSB16)); emitpcode(POC_INCF, popGet(AOP(result),MSB16)); - } + } break; case 0xff: @@ -533,7 +505,7 @@ static void genAddLit (iCode *ic, int lit) emitpcode(POC_INCFSZ, popGet(AOP(result),0)); emitpcode(POC_DECF, popGet(AOP(result),MSB16)); break; - /* case 0xff: * 0xffff * + /* case 0xff: * 0xffff * emitpcode(POC_INCFSZW, popGet(AOP(result),0,FALSE,FALSE)); emitpcode(POC_INCF, popGet(AOP(result),MSB16,FALSE,FALSE)); emitpcode(POC_DECF, popGet(AOP(result),0,FALSE,FALSE)); @@ -563,13 +535,13 @@ static void genAddLit (iCode *ic, int lit) emitpcode(POC_MOVLW,popGetLit(hi)); emitpcode(POC_ADDWF,popGet(AOP(result),MSB16)); break; - /* case 0xff: * 0xHHff * + /* case 0xff: * 0xHHff * emitpcode(POC_MOVFW, popGet(AOP(result),0,FALSE,FALSE)); emitpcode(POC_DECF, popGet(AOP(result),MSB16,FALSE,FALSE)); emitpcode(POC_MOVLW,popGetLit(hi)); emitpcode(POC_ADDWF,popGet(AOP(result),MSB16,FALSE,FALSE)); break; - */ default: /* 0xHHLL */ + */ default: /* 0xHHLL */ emitpcode(POC_MOVLW,popGetLit(lo)); emitpcode(POC_ADDWF, popGet(AOP(result),0)); emitpcode(POC_MOVLW,popGetLit(hi)); @@ -579,197 +551,201 @@ static void genAddLit (iCode *ic, int lit) break; } - } - } else { - int carry_info = 0; - int offset = 0; - /* size > 2 */ - DEBUGpic14_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__); - - while(size--) { - lo = BYTEofLONG(lit,0); + } + } else { + int carry_info = 0; + int offset = 0; + /* size > 2 */ + DEBUGpic14_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__); - if(carry_info) { - switch(lo) { - case 0: - switch(carry_info) { - case 1: - emitSKPNZ; - emitpcode(POC_INCF, popGet(AOP(result),offset)); + while(size--) { + lo = BYTEofLONG(lit,0); + + if(carry_info) { + switch(lo) { + case 0: + switch(carry_info) { + case 1: + emitSKPNZ; + emitpcode(POC_INCF, popGet(AOP(result),offset)); + break; + case 2: + emitpcode(POC_RLFW, popGet(AOP(result),offset)); + emitpcode(POC_ANDLW,popGetLit(1)); + emitpcode(POC_ADDWF, popGet(AOP(result),offset)); + break; + default: /* carry_info = 3 */ + emitSKPNC; + emitpcode(POC_INCF, popGet(AOP(result),offset)); + carry_info = 1; + break; + } break; - case 2: - emitpcode(POC_RLFW, popGet(AOP(result),offset)); - emitpcode(POC_ANDLW,popGetLit(1)); - emitpcode(POC_ADDWF, popGet(AOP(result),offset)); + case 0xff: + emitpcode(POC_MOVLW,popGetLit(lo)); + if(carry_info==1) + emitSKPZ; + else + emitSKPC; + emitpcode(POC_ADDWF, popGet(AOP(result),offset)); + break; + default: + emitpcode(POC_MOVLW,popGetLit(lo)); + if(carry_info==1) + emitSKPNZ; + else + emitSKPNC; + emitpcode(POC_MOVLW,popGetLit(lo+1)); + emitpcode(POC_ADDWF, popGet(AOP(result),offset)); + carry_info=2; + break; + } + }else { + /* no carry info from previous step */ + /* this means this is the first time to add */ + switch(lo) { + case 0: break; - default: /* carry_info = 3 */ - emitSKPNC; + case 1: emitpcode(POC_INCF, popGet(AOP(result),offset)); - carry_info = 1; + carry_info=1; break; - } - break; - case 0xff: + default: emitpcode(POC_MOVLW,popGetLit(lo)); - if(carry_info==1) - emitSKPZ; - else - emitSKPC; emitpcode(POC_ADDWF, popGet(AOP(result),offset)); + if(lit <0x100) + carry_info = 3; /* Were adding only one byte and propogating the carry */ + else + carry_info = 2; break; - default: - emitpcode(POC_MOVLW,popGetLit(lo)); - if(carry_info==1) + } + } + offset++; + lit >>= 8; + } + + /* + lo = BYTEofLONG(lit,0); + + if(lit < 0x100) { + if(lo) { + if(lo == 1) { + emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE)); emitSKPNZ; - else + } else { + emitpcode(POC_MOVLW,popGetLit(lo)); + emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE)); emitSKPNC; - emitpcode(POC_MOVLW,popGetLit(lo+1)); - emitpcode(POC_ADDWF, popGet(AOP(result),offset)); - carry_info=2; - break; + } + emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE)); + emitSKPNZ; + emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE)); + emitSKPNZ; + emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE)); + + } + } + + */ + } + } else { + int offset = 1; + DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__); + + if(size == 1) { + + if(AOP_TYPE(left) == AOP_ACC) { + /* left addend is already in accumulator */ + switch(lit & 0xff) { + case 0: + //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); + break; + default: + emitpcode(POC_ADDLW, popGetLit(lit & 0xff)); + //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); } - }else { - /* no carry info from previous step */ - /* this means this is the first time to add */ - switch(lo) { + } else { + /* left addend is in a register */ + switch(lit & 0xff) { case 0: + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitMOVWF(result, 0); + //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); break; case 1: - emitpcode(POC_INCF, popGet(AOP(result),offset)); - carry_info=1; + emitpcode(POC_INCFW, popGet(AOP(left),0)); + //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); break; - default: - emitpcode(POC_MOVLW,popGetLit(lo)); - emitpcode(POC_ADDWF, popGet(AOP(result),offset)); - if(lit <0x100) - carry_info = 3; /* Were adding only one byte and propogating the carry */ - else - carry_info = 2; + case 0xff: + emitpcode(POC_DECFW, popGet(AOP(left),0)); + //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); break; + default: + emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); + emitpcode(POC_ADDFW, popGet(AOP(left),0)); + //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); } } - offset++; - lit >>= 8; - } - - /* - lo = BYTEofLONG(lit,0); - - if(lit < 0x100) { - if(lo) { - if(lo == 1) { - emitpcode(POC_INCF, popGet(AOP(result),0,FALSE,FALSE)); - emitSKPNZ; + + } else { + int clear_carry=0; + + /* left is not the accumulator */ + if(lit & 0xff) { + emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); + emitpcode(POC_ADDFW, popGet(AOP(left),0)); + } else { + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + /* We don't know the state of the carry bit at this point */ + clear_carry = 1; + } + //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); + while(--size) { + + lit >>= 8; + if(lit & 0xff) { + if(clear_carry) { + /* The ls byte of the lit must've been zero - that + means we don't have to deal with carry */ + + emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); + emitpcode(POC_ADDFW, popGet(AOP(left),offset)); + emitpcode(POC_MOVWF, popGet(AOP(left),offset)); + + clear_carry = 0; + + } else { + emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); + //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE)); + emitMOVWF(result,offset); + emitpcode(POC_MOVFW, popGet(AOP(left),offset)); + emitSKPNC; + emitpcode(POC_INCFSZW,popGet(AOP(left),offset)); + emitpcode(POC_ADDWF, popGet(AOP(result),offset)); + } + } else { - emitpcode(POC_MOVLW,popGetLit(lo)); - emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE)); - emitSKPNC; + emitpcode(POC_CLRF, popGet(AOP(result),offset)); + emitpcode(POC_RLF, popGet(AOP(result),offset)); + emitpcode(POC_MOVFW, popGet(AOP(left),offset)); + emitpcode(POC_ADDWF, popGet(AOP(result),offset)); } - emitpcode(POC_INCF, popGet(AOP(result),1,FALSE,FALSE)); - emitSKPNZ; - emitpcode(POC_INCF, popGet(AOP(result),2,FALSE,FALSE)); - emitSKPNZ; - emitpcode(POC_INCF, popGet(AOP(result),3,FALSE,FALSE)); - - } - } + offset++; + } } - - */ } - } else { - int offset = 1; - DEBUGpic14_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__); - - if(size == 1) { - - if(AOP_TYPE(left) == AOP_ACC) { - /* left addend is already in accumulator */ - switch(lit & 0xff) { - case 0: - //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); - emitMOVWF(result,0); - break; - default: - emitpcode(POC_ADDLW, popGetLit(lit & 0xff)); - //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); - emitMOVWF(result,0); - } - } else { - /* left addend is in a register */ - switch(lit & 0xff) { - case 0: - emitpcode(POC_MOVFW, popGet(AOP(left),0)); - emitMOVWF(result, 0); - //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); - emitMOVWF(result,0); - break; - case 1: - emitpcode(POC_INCFW, popGet(AOP(left),0)); - //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); - emitMOVWF(result,0); - break; - case 0xff: - emitpcode(POC_DECFW, popGet(AOP(left),0)); - //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); - emitMOVWF(result,0); - break; - default: - emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); - emitpcode(POC_ADDFW, popGet(AOP(left),0)); - //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); - emitMOVWF(result,0); - } - } - - } else { - int clear_carry=0; - - /* left is not the accumulator */ - if(lit & 0xff) { - emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); - emitpcode(POC_ADDFW, popGet(AOP(left),0)); - } else { - emitpcode(POC_MOVFW, popGet(AOP(left),0)); - /* We don't know the state of the carry bit at this point */ - clear_carry = 1; - } - //emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); - emitMOVWF(result,0); - while(--size) { - - lit >>= 8; - if(lit & 0xff) { - if(clear_carry) { - /* The ls byte of the lit must've been zero - that - means we don't have to deal with carry */ - - emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); - emitpcode(POC_ADDFW, popGet(AOP(left),offset)); - emitpcode(POC_MOVWF, popGet(AOP(left),offset)); - - clear_carry = 0; - - } else { - emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); - //emitpcode(POC_MOVWF, popGet(AOP(result),offset,FALSE,FALSE)); - emitMOVWF(result,offset); - emitpcode(POC_MOVFW, popGet(AOP(left),offset)); - emitSKPNC; - emitpcode(POC_INCFSZW,popGet(AOP(left),offset)); - emitpcode(POC_ADDWF, popGet(AOP(result),offset)); - } - - } else { - emitpcode(POC_CLRF, popGet(AOP(result),offset)); - emitpcode(POC_RLF, popGet(AOP(result),offset)); - emitpcode(POC_MOVFW, popGet(AOP(left),offset)); - emitpcode(POC_ADDWF, popGet(AOP(result),offset)); - } - offset++; - } - } - } + + size = pic14_getDataSize(result); + if (size > pic14_getDataSize(left)) + size = pic14_getDataSize(left); + addSign(result, size, 0); } /*-----------------------------------------------------------------*/ @@ -781,6 +757,7 @@ void genPlus (iCode *ic) /* special cases :- */ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + FENTRY; aopOp (IC_LEFT(ic),ic,FALSE); aopOp (IC_RIGHT(ic),ic,FALSE); @@ -798,13 +775,6 @@ void genPlus (iCode *ic) IC_LEFT(ic) = t; } - /* if both left & right are in bit space */ - if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY && - AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) { - genPlusBits (ic); - goto release ; - } - /* if left in bit space & right literal */ if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY && AOP_TYPE(IC_RIGHT(ic)) == AOP_LIT) { @@ -962,11 +932,9 @@ void genPlus (iCode *ic) else { PIC_OPCODE poc = POC_ADDFW; - if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && ( - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) + if (op_isLitLike (IC_LEFT (ic))) poc = POC_ADDLW; - emitpcode(poc, popGet(AOP(IC_LEFT(ic)),0)); + emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),0,0)); if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0)); } @@ -979,14 +947,13 @@ void genPlus (iCode *ic) if(size){ if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) { - if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && ( - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) { + if (op_isLitLike (IC_LEFT(ic))) + { while(size--){ emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset)); emitSKPNC; emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset)); - emitpcode(POC_ADDLW, popGet(AOP(IC_LEFT(ic)),offset)); + emitpcode(POC_ADDLW, popGetAddr(AOP(IC_LEFT(ic)),offset,0)); emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); offset++; } @@ -1001,13 +968,11 @@ void genPlus (iCode *ic) } } else { PIC_OPCODE poc = POC_MOVFW; - if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && ( - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) + if (op_isLitLike (IC_LEFT(ic))) poc = POC_MOVLW; while(size--){ if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { - emitpcode(poc, popGet(AOP(IC_LEFT(ic)),offset)); + emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0)); emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); } emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset)); @@ -1032,15 +997,15 @@ void genPlus (iCode *ic) if (AOP_SIZE(IC_LEFT(ic)) > AOP_SIZE(IC_RIGHT(ic))) { int leftsize = AOP_SIZE(IC_LEFT(ic)) - AOP_SIZE(IC_RIGHT(ic)); PIC_OPCODE poc = POC_MOVFW; - if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && ( - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) + if (op_isLitLike (IC_LEFT(ic))) poc = POC_MOVLW; while(leftsize-- > 0) { - emitpcode(poc, popGet(AOP(IC_LEFT(ic)),offset)); - emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); + emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0)); emitSKPNC; - emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset)); + emitpcode(POC_ADDLW, popGetLit(0x01)); + emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); + //emitSKPNC; + //emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset)); /* INCF does not update Carry! */ offset++; if (size) size--; @@ -1053,7 +1018,7 @@ void genPlus (iCode *ic) } - if(sign) { + if(sign && offset > 0 && offset < AOP_SIZE(IC_RESULT(ic))) { /* Now this is really horrid. Gotta check the sign of the addends and propogate * to the result */ @@ -1098,6 +1063,7 @@ bool genMinusDec (iCode *ic) { unsigned int icount ; unsigned int size = pic14_getDataSize(IC_RESULT(ic)); + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* will try to generate an increment */ @@ -1166,8 +1132,8 @@ bool genMinusDec (iCode *ic) AOP_SIZE(IC_LEFT(ic)) > 1 ) return FALSE ; - /* we can if the aops of the left & result match or - if they are in registers and the registers are the + /* we can if the aops of the left & result match or + if they are in registers and the registers are the same */ if (pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) { @@ -1203,6 +1169,7 @@ void addSign(operand *result, int offset, int sign) { int size = (pic14_getDataSize(result) - offset); DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + FENTRY; if(size > 0){ if(sign && offset) { @@ -1217,8 +1184,7 @@ void addSign(operand *result, int offset, int sign) emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0)); emitpcode(POC_MOVLW, popGetLit(0xff)); while(size--) - emitpcode(POC_MOVWF, popGet(AOP(result),size)); - + emitpcode(POC_MOVWF, popGet(AOP(result),offset+size)); } } else while(size--) @@ -1226,31 +1192,6 @@ void addSign(operand *result, int offset, int sign) } } -/*-----------------------------------------------------------------*/ -/* genMinusBits - generates code for subtraction of two bits */ -/*-----------------------------------------------------------------*/ -void genMinusBits (iCode *ic) -{ - symbol *lbl = newiTempLabel(NULL); - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY){ - pic14_emitcode("mov","c,%s",AOP(IC_LEFT(ic))->aopu.aop_dir); - pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_RIGHT(ic))->aopu.aop_dir,(lbl->key+100)); - pic14_emitcode("cpl","c"); - pic14_emitcode("","%05d_DS_:",(lbl->key+100)); - pic14_outBitC(IC_RESULT(ic)); - } - else{ - pic14_emitcode("mov","c,%s",AOP(IC_RIGHT(ic))->aopu.aop_dir); - pic14_emitcode("subb","a,acc"); - pic14_emitcode("jnb","%s,%05d_DS_",AOP(IC_LEFT(ic))->aopu.aop_dir,(lbl->key+100)); - pic14_emitcode("inc","a"); - pic14_emitcode("","%05d_DS_:",(lbl->key+100)); - aopPut(AOP(IC_RESULT(ic)),"a",0); - addSign(IC_RESULT(ic), MSB16, SPEC_USIGN(getSpec(operandType(IC_RESULT(ic))))); - } -} - /*-----------------------------------------------------------------*/ /* genMinus - generates code for subtraction */ /*-----------------------------------------------------------------*/ @@ -1259,6 +1200,7 @@ void genMinus (iCode *ic) int size, offset = 0, same=0; unsigned long lit = 0L; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp (IC_LEFT(ic),ic,FALSE); aopOp (IC_RIGHT(ic),ic,FALSE); @@ -1276,14 +1218,6 @@ void genMinus (iCode *ic) AopType(AOP_TYPE(IC_LEFT(ic))), AopType(AOP_TYPE(IC_RIGHT(ic)))); - /* special cases :- */ - /* if both left & right are in bit space */ - if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY && - AOP_TYPE(IC_RIGHT(ic)) == AOP_CRY) { - genPlusBits (ic); - goto release ; - } - /* if I can do an decrement instead of subtract then GOOD for ME */ // if (genMinusDec (ic) == TRUE) @@ -1549,36 +1483,24 @@ void genMinus (iCode *ic) if(size){ if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) { - if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && ( - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) { - while(size--){ - emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset)); - emitSKPC; - emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset)); - emitpcode(POC_SUBLW, popGet(AOP(IC_LEFT(ic)),offset)); - emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); - offset++; - } - } else { - while(size--){ - emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset)); - emitSKPC; - emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset)); - emitpcode(POC_SUBFW, popGet(AOP(IC_LEFT(ic)),offset)); - emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); - offset++; - } + int lit = 0; + if (op_isLitLike (IC_LEFT(ic))) + lit = 1; + while(size--){ + emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset)); + emitSKPC; + emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset)); + emitpcode(lit?POC_SUBLW:POC_SUBFW, popGetAddr(AOP(IC_LEFT(ic)),offset,0)); + emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); + offset++; } } else { PIC_OPCODE poc = POC_MOVFW; - if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && ( - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) + if (op_isLitLike (IC_LEFT(ic))) poc = POC_MOVLW; while(size--){ if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { - emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset)); + emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0)); emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); } emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset)); @@ -1615,9 +1537,10 @@ void genUMult8XLit_16 (operand *left, int same; pCodeOp *temp; + FENTRY; if (AOP_TYPE(right) != AOP_LIT){ fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__); - exit(1); + exit(EXIT_FAILURE); } @@ -1732,7 +1655,7 @@ void genUMult8XLit_16 (operand *left, temp = popGetTempReg(); if(!temp) { fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__); - exit(1); + exit(EXIT_FAILURE); } emitpcode(POC_SWAPFW, popGet(AOP(left),0)); emitpcode(POC_MOVWF, temp); @@ -1771,45 +1694,62 @@ void genUMult8XLit_16 (operand *left, emitpcode(POC_RRF, popGet(AOP(left),0)); return; + } + } else { + + switch(lit) { + case 0: + emitpcode(POC_CLRF, popGet(AOP(result),0)); + emitpcode(POC_CLRF, popCopyReg(result_hi)); + return; + case 2: + if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */ + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_MOVWF, popGet(AOP(result),0)); + emitpcode(POC_ADDWF, popGet(AOP(result),0)); + emitpcode(POC_CLRF, popCopyReg(result_hi)); + emitpcode(POC_RLF, popCopyReg(result_hi)); + return; + case 4: + case 8: + if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */ + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_MOVWF, popGet(AOP(result),0)); + emitpcode(POC_CLRF, popCopyReg(result_hi)); + emitpcode(POC_BCF, popCopyReg(&pc_status)); + emitpcode(POC_RLF, popGet(AOP(result),0)); + emitpcode(POC_RLF, popCopyReg(result_hi)); + emitpcode(POC_RLF, popGet(AOP(result),0)); + emitpcode(POC_RLF, popCopyReg(result_hi)); + if (lit >= 8) { + emitpcode(POC_RLF, popGet(AOP(result),0)); + emitpcode(POC_RLF, popCopyReg(result_hi)); + } + return; + } + + } + + if (AOP_TYPE(left) != AOP_ACC) /* Check if w is already loaded */ + emitpcode(POC_MOVFW, popGet(AOP(left),0)); + emitpcode(POC_CLRF, popGet(AOP(result),0)); + emitpcode(POC_CLRF, popCopyReg(result_hi)); + + have_first_bit = 0; + for(i=0; i<8; i++) { + + if(lit & 1) { + emitpcode(POC_ADDWF, popCopyReg(result_hi)); + have_first_bit = 1; + } + + if(have_first_bit) { + emitpcode(POC_RRF, popCopyReg(result_hi)); + emitpcode(POC_RRF, popGet(AOP(result),0)); + } + + lit >>= 1; } - } else { - - switch(lit) { - case 0: - emitpcode(POC_CLRF, popGet(AOP(result),0)); - emitpcode(POC_CLRF, popCopyReg(result_hi)); - return; - case 2: - emitpcode(POC_MOVFW, popGet(AOP(left),0)); - emitpcode(POC_MOVWF, popGet(AOP(result),0)); - emitpcode(POC_ADDWF, popGet(AOP(result),0)); - emitpcode(POC_CLRF, popCopyReg(result_hi)); - emitpcode(POC_RLF, popCopyReg(result_hi)); - return; - } - - } - - emitpcode(POC_MOVFW, popGet(AOP(left),0)); - emitpcode(POC_CLRF, popGet(AOP(result),0)); - emitpcode(POC_CLRF, popCopyReg(result_hi)); - - have_first_bit = 0; - for(i=0; i<8; i++) { - - if(lit & 1) { - emitpcode(POC_ADDWF, popCopyReg(result_hi)); - have_first_bit = 1; - } - - if(have_first_bit) { - emitpcode(POC_RRF, popCopyReg(result_hi)); - emitpcode(POC_RRF, popGet(AOP(result),0)); - } - - lit >>= 1; - } - } /*-----------------------------------------------------------------* @@ -1827,6 +1767,7 @@ void genUMult8X8_16 (operand *left, int i; int looped = 1; + FENTRY; if(!result_hi) { result_hi = PCOR(popGet(AOP(result),1)); } @@ -1920,6 +1861,7 @@ void genSMult8X8_16 (operand *left, pCodeOpReg *result_hi) { + FENTRY; if(!result_hi) { result_hi = PCOR(popGet(AOP(result),1)); } @@ -1945,7 +1887,12 @@ void genMult8X8_8 (operand *left, operand *right, operand *result) { - pCodeOp *result_hi = popGetTempReg(); + pCodeOp *result_hi; + FENTRY; + if (result && result->aop && result->aop->type==2 && result->aop->size>=1) { + result->aop->aopu.aop_reg[0]->isFree = 0; /* Sometimes (ie part of last instruction in a blk) the result reg is pre marked as free, which mean on the next line popGetTempReg() will return this reg instead of allocating a new one. */ + } + result_hi = popGetTempReg(); if (AOP_TYPE(right) == AOP_LIT) genUMult8XLit_16(left,right,result,PCOR(result_hi));