X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fgenarith.c;h=fe7788522b861e40d097deacf5af8aee7d2a68da;hb=de6743d71bc9d1e681e14c9bb874b7b21f2f12c0;hp=39f3dcbdb21d765781cf159bb9cc4f1b9c50e027;hpb=d10151253d907646b1040f76f9b152f2f9d25835;p=fw%2Fsdcc diff --git a/src/pic16/genarith.c b/src/pic16/genarith.c index 39f3dcbd..fe778852 100644 --- a/src/pic16/genarith.c +++ b/src/pic16/genarith.c @@ -416,6 +416,7 @@ static void adjustArithmeticResult(iCode *ic) } #endif +#if 0 /*-----------------------------------------------------------------*/ /* genAddlit - generates code for addition */ /*-----------------------------------------------------------------*/ @@ -438,6 +439,7 @@ static void genAddLit2byte (operand *result, int offr, int lit) } } +#endif static void emitMOVWF(operand *reg, int offset) { @@ -456,19 +458,90 @@ static void emitMOVWF(operand *reg, int offset) static void genAddLit (iCode *ic, int lit) { - int size,same; - int lo; + int size,sizeL,same; + int i, llit; operand *result; operand *left; + sym_link *lleft; FENTRY; left = IC_LEFT(ic); + lleft = operandType (left); result = IC_RESULT(ic); same = pic16_sameRegs(AOP(left), AOP(result)); size = pic16_getDataSize(result); + sizeL = pic16_getDataSize(left); + llit = lit; + +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + /* move left to result -- possibly sign extend */ + for (i=0; i < MIN(size, sizeL); i++) { + pic16_mov2f (AOP(result), AOP(left), i); + } // for i +#undef MIN + + /* extend to result size */ + if (IS_UNSIGNED(lleft)) { + /* zero-extend */ + for (i = sizeL; i < size; i++) { + pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i)); + } // for i + } else { + /* sign-extend */ + if (size == sizeL + 1) { + pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), sizeL)); + pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7)); + pic16_emitpcode (POC_SETF, pic16_popGet (AOP(result), sizeL)); + } else { + pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg)); + pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit_simple (AOP(left),sizeL-1,7)); + pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg)); + + for (i=sizeL; i < size; i++) { + pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(result), i)); + } // for i + } // if + } // if (SIGNED) + + /* special cases */ + if (lit == 0) { + /* nothing to do */ + } else if (lit == 1) { + switch (size) { + case 1: + /* handled below */ + break; + case 2: + pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(result), 0)); + break; + default: + assert (size > 2); + pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), 0)); + for (i=1; i < size-1; i++) { + emitSKPNC; /* a jump here saves up to 2(size-2)cycles */ + pic16_emitpcode (POC_INCF, pic16_popGet(AOP(result), i)); + } // for i + emitSKPNC; + break; + } // switch + + pic16_emitpcode (POC_INCF, pic16_popGet (AOP(result), size-1)); + } else { + /* general case */ + + /* add literal to result */ + for (i=0; i < size; i++) { + pic16_emitpcode (POC_MOVLW, pic16_popGetLit (llit)); + llit >>= 8; /* FIXME: arithmetic right shift for signed literals? */ + pic16_emitpcode (i == 0 ? POC_ADDWF : POC_ADDWFC, + pic16_popGet (AOP(result), i)); + } + } + +#if 0 if(same) { @@ -739,6 +812,7 @@ static void genAddLit (iCode *ic, int lit) } } } +#endif } /*-----------------------------------------------------------------*/ @@ -985,7 +1059,7 @@ void pic16_genPlus (iCode *ic) for(i=size; i< AOP_SIZE(result); i++) { pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),i)); pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode(POC_COMF, pic16_popGet(AOP(result),i)); + pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),i)); pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),i)); pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),i)); } @@ -1020,20 +1094,16 @@ void pic16_genPlus (iCode *ic) // add leftover bytes // either left or right is too short for (i=size; i < AOP_SIZE(result); i++) { - fprintf (stderr, "%s:%d: new code...\n", __FUNCTION__, __LINE__); - pic16_emitcode ("; ", "new arithmetics... test me..."); // get right operand into WREG if (i < AOP_SIZE(right)) { pic16_mov2w (AOP(right), i); } else { - pic16_emitcode ("; =##", "right too short"); // right is too short pic16_emitpcode (POC_CLRF, pic16_popCopyReg (&pic16_pc_wreg)); if (!SPEC_USIGN(getSpec(operandType(right)))) { - pic16_emitcode ("; =##", "right signed"); // right operand is signed pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),AOP_SIZE(right)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode(POC_COMF, pic16_popCopyReg (&pic16_pc_wreg)); + pic16_emitpcode(POC_SETF, pic16_popCopyReg (&pic16_pc_wreg)); } } @@ -1046,111 +1116,24 @@ void pic16_genPlus (iCode *ic) pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i)); } } else { - pic16_emitcode ("; =##", "left too short"); // left is too short pic16_emitpcode (POC_CLRF, pic16_popGet (AOP(result), i)); if (!SPEC_USIGN(getSpec(operandType(left)))) { - pic16_emitcode ("; =##", "left signed"); // left operand is signed pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode(POC_COMF, pic16_popGet (AOP(result), i)); + pic16_emitpcode(POC_SETF, pic16_popGet (AOP(result), i)); } pic16_emitpcode (POC_ADDWFC, pic16_popGet (AOP(result), i)); } } // for i goto release; - -#if 0 - // add leftover bytes - if (SPEC_USIGN(getSpec(operandType(right)))) { - // right is unsigned - for(i=size; i< AOP_SIZE(result); i++) { - if (pic16_sameRegs(AOP(left), AOP(result))) - { - pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i)); - } else { // not same - pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i)); - } - } - } else { - // right is signed - for(i=size; i< AOP_SIZE(result); i++) { - if(size < AOP_SIZE(left)) { - pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode(POC_COMFW, pic16_popCopyReg(&pic16_pc_wreg)); - if (pic16_sameRegs(AOP(left), AOP(result))) - { - pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(left),i)); - } else { // not same - pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),i)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),i)); - } - } else { - pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), i)); - } - } - } - goto release; -#endif } } assert( 0 ); - // TODO: anything from here to before "release:" is probably obsolete and should be removed - // when the regression tests are stable - - if (AOP_SIZE(result) > AOP_SIZE(right)) { - int sign = !(SPEC_USIGN(getSpec(operandType(left))) | - SPEC_USIGN(getSpec(operandType(right))) ); - - - /* Need to extend result to higher bytes */ - size = AOP_SIZE(result) - AOP_SIZE(right) - 1; - - /* First grab the carry from the lower bytes */ - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset)); - - - if(sign) { - /* Now this is really horrid. Gotta check the sign of the addends and propogate - * to the result */ - - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset)); - - /* if chars or ints or being signed extended to longs: */ - if(size) { - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff)); - } - } - - offset++; - while(size--) { - - if(sign) - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); - else - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); - - offset++; - } - } - - - //adjustArithmeticResult(ic); - - release: + +release: pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); pic16_freeAsmop(result,NULL,ic,TRUE); @@ -1271,7 +1254,7 @@ void pic16_addSign(operand *result, int offset, int sign) if(size == 1) { pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset)); pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset)); + pic16_emitpcode(POC_SETF, pic16_popGet(AOP(result),offset)); } else { pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0)); @@ -1576,7 +1559,7 @@ void pic16_genMinus (iCode *ic) if (!SPEC_USIGN(operandType(IC_RIGHT(ic)))) { // signed -- sign extend the right operand pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RIGHT(ic)),AOP_SIZE(IC_RIGHT(ic))-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode (POC_COMF, pic16_popCopyReg (&pic16_pc_wreg)); + pic16_emitpcode (POC_SETF, pic16_popCopyReg (&pic16_pc_wreg)); } } if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic)))) { @@ -1591,7 +1574,7 @@ void pic16_genMinus (iCode *ic) if (!SPEC_USIGN(operandType(IC_LEFT(ic)))) { // signed -- sign extend the left operand pic16_emitpcode (POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_LEFT(ic)),AOP_SIZE(IC_LEFT(ic))-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode (POC_COMF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact! + pic16_emitpcode (POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset)); // keep CARRY/#BORROW bit intact! } pic16_emitpcode(POC_SUBWFB_D1, pic16_popGet(AOP(IC_RESULT(ic)),offset)); }