- pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit >> (size*8)) & 0xff));
- emitSKPNZ;
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
- }
- //rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
-
- pic16_emitpLabel(truelbl->key);
-
- if(ifx) ifx->generated = 1;
- return;
-
-
- }
-
-
- /* sign is out of the way. So now do an unsigned compare */
- DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit);
-
-
- /* General case - compare to an unsigned literal on the right.*/
-
- i = (lit >> (size*8)) & 0xff;
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
- while(size--) {
- i = (lit >> (size*8)) & 0xff;
-
- if(i) {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
- emitSKPNZ;
- pic16_emitpcode(POC_SUBFW, pic16_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)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size));
- }
- }
-
-
- pic16_emitpLabel(lbl->key);
-// pic16_emitpLabel(truelbl->key);
- //if(emitFinalCheck)
- genSkipc(&rFalseIfx);
- if(sign)
- pic16_emitpLabel(truelbl->key);
-
- if(ifx) ifx->generated = 1;
- return;
-
-
- }
-#endif // _swapp
-
- if(AOP_TYPE(left) == AOP_LIT) {
- //symbol *lbl = newiTempLabel(NULL);
-
- //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit));
-
-
- DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
-
- /* Special cases */
- if((lit == 0) && (sign == 0)){
-
- size--;
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- while(size)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
-
- genSkipz2(&rFalseIfx,0);
- if(ifx) ifx->generated = 1;
- return;
- }
-
- if(size==1) {
- /* Special cases */
- lit &= 0xff;
- if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
- /* degenerate compare can never be true */
- if(rFalseIfx.condition == 0)
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
-
- if(ifx) ifx->generated = 1;
- return;
- }
-
- if(sign) {
- /* signed comparisons to a literal byte */
-
- int lp1 = (lit+1) & 0xff;
-
- DEBUGpic16_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:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
- genSkipz2(&rFalseIfx,1);
- break;
- default:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
- rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
- break;
- }
- } else {
- /* unsigned comparisons to a literal byte */
-
- switch(lit & 0xff ) {
- case 0:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
- genSkipz2(&rFalseIfx,0);
- break;
- case 0x7f:
- rFalseIfx.condition ^= 1;
- genSkipCond(&rFalseIfx,right,0,7);
- break;
-
- default:
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- rFalseIfx.condition ^= 1;
- if (AOP_TYPE(result) == AOP_CRY)
- genSkipc(&rFalseIfx);
- else {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
- }
- break;
- }
- }
-
- if(ifx) ifx->generated = 1;
- if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
- goto check_carry;
- return;
-
- } else {
-
- /* Size is greater than 1 */
-
- if(sign) {
- int lp1 = lit+1;
-
- size--;
-
- if(lp1 == 0) {
- /* this means lit = 0xffffffff, or -1 */
-
-
- DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__);
- rFalseIfx.condition ^= 1;
- genSkipCond(&rFalseIfx,right,size,7);
- if(ifx) ifx->generated = 1;
-
- if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
- goto check_carry;
-
- return;
- }
-
- if(lit == 0) {
- int s = size;
-
- if(rFalseIfx.condition) {
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
- }
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- while(size--)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
-
-
- emitSKPZ;
- if(rFalseIfx.condition) {
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
- pic16_emitpLabel(truelbl->key);
- }else {
- rFalseIfx.condition ^= 1;
- genSkipCond(&rFalseIfx,right,s,7);
- }
-
- if(ifx) ifx->generated = 1;
-
- if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
- goto check_carry;
-
- return;
- }
-
- if((size == 1) && (0 == (lp1&0xff))) {
- /* lower byte of signed word is zero */
- DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
- i = ((lp1 >> 8) & 0xff) ^0x80;
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
-
- if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) {
- emitTOGC;
- if(ifx) ifx->generated = 1;
- goto check_carry;
- } else {
- rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
- if(ifx) ifx->generated = 1;
- }
-
- return;
- }
-
- if(lit & (0x80 << (size*8))) {
- /* Lit is less than zero */
- DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
- //rFalseIfx.condition ^= 1;
- //genSkipCond(&rFalseIfx,left,size,7);
- //rFalseIfx.condition ^= 1;
- pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
-
- if(rFalseIfx.condition)
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
- else
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
-
-
- } else {
- /* Lit is greater than or equal to zero */
- DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
- //rFalseIfx.condition ^= 1;
- //genSkipCond(&rFalseIfx,right,size,7);
- //rFalseIfx.condition ^= 1;
-
- //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
- //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
-
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- if(rFalseIfx.condition)
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
- else
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
-
- }
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
-
- while(size--) {
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
- emitSKPNZ;
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
- }
- rFalseIfx.condition ^= 1;
- //rFalseIfx.condition = 1;
- genSkipc(&rFalseIfx);
-
- pic16_emitpLabel(truelbl->key);
-
- if(ifx) ifx->generated = 1;
-
-
- if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
- goto check_carry;
-
- return;
- // end of if (sign)
- } else {
-
- /* compare word or long to an unsigned literal on the right.*/
-
-
- size--;
- if(lit < 0xff) {
- DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
- switch (lit) {
- case 0:
- break; /* handled above */
-/*
- case 0xff:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- while(size--)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
- genSkipz2(&rFalseIfx,0);
- break;
-*/
- default:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- while(--size)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
-
- emitSKPZ;
- if(rFalseIfx.condition)
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
- else
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
-
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
-
- rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
- }
-
- pic16_emitpLabel(truelbl->key);
-
- if(ifx) ifx->generated = 1;
-
- if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
- goto check_carry;
-
- return;
- }
-
-
- lit++;
- DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
- i = (lit >> (size*8)) & 0xff;
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
-
- while(size--) {
- i = (lit >> (size*8)) & 0xff;
-
- if(i) {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
- emitSKPNZ;
- pic16_emitpcode(POC_SUBFW, pic16_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)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
- }
- }
-
-
- pic16_emitpLabel(lbl->key);
-
- rFalseIfx.condition ^= 1;
-
- genSkipc(&rFalseIfx);
- }
-
- if(sign)
- pic16_emitpLabel(truelbl->key);
- if(ifx) ifx->generated = 1;
-
- if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
- goto check_carry;
-
- return;
- }
- }
- /* Compare two variables */
-
- DEBUGpic16_emitcode(";sign","%d",sign);
-
- size--;
- if(sign) {
- /* Sigh. thus sucks... */
- if(size) {
- pCodeOp *pctemp;
-
- pctemp = pic16_popGetTempReg(1);
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
- pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
- pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
- pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
- pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
- pic16_popReleaseTempReg(pctemp, 1);
- } else {
- /* Signed char comparison */
- /* Special thanks to Nikolai Golovchenko for this snippet */
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
- pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- genSkipc(&rFalseIfx);
-
- if(ifx) ifx->generated = 1;
-
- if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
- goto check_carry;
-
- return;
- }
-
- } else {
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
- }
-
-
- /* The rest of the bytes of a multi-byte compare */
- while (size) {
-
- emitSKPZ;
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
- size--;
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
-
-
- }
-
- pic16_emitpLabel(lbl->key);
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
- (AOP_TYPE(result) == AOP_REG)) {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
- } else {
- genSkipc(&rFalseIfx);
- }
- //genSkipc(&rFalseIfx);
- if(ifx) ifx->generated = 1;
-
-
- if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
- goto check_carry;
-
- return;
-
- }
-
-check_carry:
- if ((AOP_TYPE(result) != AOP_CRY)
- && AOP_SIZE(result)) {
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
-
- pic16_outBitC(result);
- } else {
- DEBUGpic16_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
- pic16_outBitC(result);
- /* leave the result in acc */
- }
-
-}
-
-#else /* old version of genCmp() */ /* } else { */
-
-/* check all condition and return appropriate instruction, POC_CPFSGT or POC_CPFFSLT */
-static int selectCompareOp(resolvedIfx *rIfx, iCode *ifx,
- operand *result, int offset, int invert_op)
-{
- /* add code here */
-
- /* check condition, > or < ?? */
- if(rIfx->condition != 0)invert_op ^= 1;
-
- if(ifx && IC_FALSE(ifx))invert_op ^= 1;
-
- if(!ifx)invert_op ^= 1;
-
- DEBUGpic16_emitcode("; +++", "%s:%d %s] rIfx->condition= %d, ifx&&IC_FALSE(ifx)= %d, invert_op = %d",
- __FILE__, __LINE__, __FUNCTION__, rIfx->condition, (ifx && IC_FALSE(ifx)), invert_op);
-
- /* do selection */
- if(!invert_op)return POC_CPFSGT;
- else return POC_CPFSLT;
-}
-
-static int compareAopfirstpass=1;
-
-static void compareAop(resolvedIfx *resIfx, iCode *ifx, symbol *falselbl,
- operand *oper, int offset, operand *result,
- int sign, int invert_op, pCodeOp *pcop, pCodeOp *pcop2,
- symbol *tlbl)
-{
- int op;
- symbol *truelbl;
-
- /* invert if there is a result to be loaded, in order to fit,
- * SETC/CLRC sequence */
- if(AOP_SIZE(result))invert_op ^= 1;
-
-// if(sign && !offset)invert_op ^= 1;
-
-// if(sign)invert_op ^= 1;
-
- op = selectCompareOp(resIfx, ifx, result, offset, invert_op);
-
- if(AOP_SIZE(result) && compareAopfirstpass) {
- if(!ifx) {
- if(pcop2)
- pic16_emitpcode(POC_SETF, pcop2);
- else
- emitSETC;
- } else {
- if(pcop2)
- pic16_emitpcode(POC_CLRF, pcop2);
- else
- emitCLRC;
- }
- }
-
- compareAopfirstpass = 0;
-
- /* there is a bug when comparing operands with size > 1,
- * because higher bytes can be equal and test should be performed
- * to the next lower byte, current algorithm, considers operands
- * inequal in these cases! -- VR 20041107 */
-
-
- if(pcop)
- pic16_emitpcode(op, pcop);
- else
- pic16_emitpcode(op, pic16_popGet(AOP(oper), offset));
-
-
- if((!sign || !offset) && AOP_SIZE(result)) {
- if(!ifx) {
- if(pcop2)
- pic16_emitpcode(POC_CLRF, pcop2);
- else
- emitCLRC;
- } else {
- if(pcop2)
- pic16_emitpcode(POC_SETF, pcop2);
- else
- emitSETC;
- }
-
- /* don't emit final branch (offset == 0) */
- if(offset) {
-
- if(pcop2)
- pic16_emitpcode(POC_RRCF, pcop2);
-
- pic16_emitpcode(POC_BNC, pic16_popGetLabel(falselbl->key));
- }
- } else {
- if((ifx && (IC_TRUE(ifx)!=NULL)) || (sign && !offset)) {
- DEBUGpic16_emitcode ("; +++","%s: %d: ifx = %p, IC_TRUE(ifx) = %d, sign = %d, offset = %d",
- __FUNCTION__, __LINE__, ifx, (ifx&&IC_TRUE(ifx)), sign, offset);
-
- truelbl = newiTempLabel( NULL );
- pic16_emitpcode(POC_BRA, pic16_popGetLabel(truelbl->key));
- if((!ifx || !IC_TRUE(ifx)) && (sign && !offset))
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl->key));
- else
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(resIfx->lbl->key));
- pic16_emitpLabel(truelbl->key);
- } else {
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(resIfx->lbl->key));
- }
- }
-}
-
-
-
-
-#if 1 /* { */
-static void genCmp (operand *left, operand *right,
- operand *result, iCode *ifx, int sign)
-{
- int size, cmpop=1;
- long lit = 0L;
- resolvedIfx rFalseIfx;
- symbol *falselbl, *tlbl;
-
- FENTRY;
-
- DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
-
- resolveIfx(&rFalseIfx, ifx);
- size = max(AOP_SIZE(left), AOP_SIZE(right));
-
- /* if left & right are bit variables */
- if(AOP_TYPE(left) == AOP_CRY
- && AOP_TYPE(right) == AOP_CRY ) {
-
- pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
- pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
-
- werror(W_POSSBUG2, __FILE__, __LINE__);
- exit(-1);
- }
-
- /* 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 = /*(unsigned long)*/floatFromVal(AOP(right)->aopu.aop_lit);
-
-// lit = (lit - 1) & mask;
- right = left;
- left = tmp;
- rFalseIfx.condition ^= 1; /* reverse compare */
- } else
- if ((AOP_TYPE(left) == AOP_LIT)) {
- /* float compares are handled by support functions */
- lit = /*(unsigned long)*/floatFromVal(AOP(left)->aopu.aop_lit);
- }
-
- /* actual comparing algorithm */
-// size = AOP_SIZE( right );
-
- falselbl = newiTempLabel( NULL );
- if(AOP_TYPE(left) == AOP_LIT) {
- /* compare to literal */
- DEBUGpic16_emitcode ("; ***","%s: %d: compare to literal", __FUNCTION__, __LINE__);
-
- if(sign) {
- pCodeOp *pct, *pct2;
- symbol *tlbl1;
-
- /* signed compare */
- DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__);
-
- pct = pic16_popCopyReg(&pic16_pc_prodl);
- pct2 = pic16_popCopyReg(&pic16_pc_prodh);
- tlbl = newiTempLabel( NULL );
-
- /* first compare signs:
- * a. if both are positive, compare just like unsigned
- * b. if both are negative, invert cmpop, compare just like unsigned
- * c. if different signs, determine the result directly */
-
- size--;
-
-#if 1
- /* { */
- tlbl1 = newiTempLabel( NULL );
-// pic16_emitpcode(POC_RLCFW, pic16_popGet( AOP(right), size)); /* move sign to carry */
-
- if(lit > 0) {
-
- /* literal is zero or positive:
- * a. if carry is zero, too, continue compare,
- * b. if carry is set, then continue depending on cmpop ^ condition:
- * 1. '<' return false (literal < variable),
- * 2. '>' return true (literal > variable) */
-// pic16_emitpcode(POC_BNC, pic16_popGetLabel( tlbl1->key ));
- pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7));
-
-
- if(cmpop ^ rFalseIfx.condition)pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key ));
- else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key ));
- } else
- if(lit < 0) {
-
- /* literal is negative:
- * a. if carry is set, too, continue compare,
- * b. if carry is zero, then continue depending on cmpop ^ condition:
- * 1. '<' return true (literal < variable),
- * 2. '>' return false (literal > variable) */
-// pic16_emitpcode(POC_BC, pic16_popGetLabel( tlbl1->key ));
- pic16_emitpcode(POC_BTFSS, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7));
-
- if(!(cmpop ^ rFalseIfx.condition))pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key ));
- else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key));
- }
-#if 1
- else {
- /* lit == 0 */
- pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7));
-
- if(!(cmpop ^ rFalseIfx.condition))pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key ));
- else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key));
- }
-#endif
-
-
- pic16_emitpLabel( tlbl1->key );
-#endif /* } */
-
- compareAopfirstpass=1;
-// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
-// pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right), size));
-// pic16_emitpcode(POC_MOVWF, pct);
-
-// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x80));
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size)));
-// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
- compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, pct2, tlbl);
-
- /* generic case */
- while( size-- ) {
-// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
-// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0));
-// pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right), size));
-// pic16_emitpcode(POC_MOVWF, pct);
-
-// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x80));
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x0));
- compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, pct2, tlbl);
-// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
-// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl);
- }
-// }
-
- if(ifx)ifx->generated = 1;
-
- if(AOP_SIZE(result)) {
- pic16_emitpLabel(tlbl->key);
- pic16_emitpLabel(falselbl->key);
- pic16_outBitOp( result, pct2 );
- } else {
- pic16_emitpLabel(tlbl->key);
- }
- } else {
-
-
- /* unsigned compare */
- DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
-
- compareAopfirstpass=1;
- while(size--) {
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size)));
- compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL);
-
- }
-
- if(ifx)ifx->generated = 1;
-
-
- if(AOP_SIZE(result)) {
- pic16_emitpLabel(falselbl->key);
- pic16_outBitC( result );
- }
-
- }
- } else {
- /* compare registers */
- DEBUGpic16_emitcode ("; ***","%s: %d: compare registers", __FUNCTION__, __LINE__);
-
-
- if(sign) {
- pCodeOp *pct, *pct2;
-
- /* signed compare */
- DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__);
-
- pct = pic16_popCopyReg(&pic16_pc_prodl); /* first temporary register */
- pct2 = pic16_popCopyReg(&pic16_pc_prodh); /* second temporary register */
- tlbl = newiTempLabel( NULL );
-
- compareAopfirstpass=1;
-
- size--;
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size));
-// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
- pic16_emitpcode(POC_MOVWF, pct);
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
-// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
-
- /* WREG already holds left + 0x80 */
- compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
-
- while( size-- ) {
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size));
-// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
- pic16_emitpcode(POC_MOVWF, pct);
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
-// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0));
-
- /* WREG already holds left + 0x80 */
- compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl);
-// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl);
- }
-
- if(ifx)ifx->generated = 1;
-
- if(AOP_SIZE(result)) {
- pic16_emitpLabel(tlbl->key);
- pic16_emitpLabel(falselbl->key);
- pic16_outBitOp( result, pct2 );
- } else {
- pic16_emitpLabel(tlbl->key);
- }
-
- } else {
- /* unsigned compare */
- DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__);
-
- compareAopfirstpass=1;
- while(size--) {
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size));
- compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL);
-
- }
-
- if(ifx)ifx->generated = 1;
- if(AOP_SIZE(result)) {
-
- pic16_emitpLabel(falselbl->key);
- pic16_outBitC( result );
- }
-
- }
- }
-}
-
-#else /* } else { */
-
-/* new version of genCmp -- VR 20041012 */
-static void genCmp (operand *left,operand *right,
- operand *result, iCode *ifx, int sign)
-{
- int size; //, offset = 0 ;
- unsigned long lit = 0L,i = 0;
- resolvedIfx rFalseIfx;
- int willCheckCarry=0;
- // resolvedIfx rTrueIfx;
- symbol *truelbl;
-
- FENTRY;
-
- /* General concept:
- * subtract right from left if at the end the carry flag is set then we
- * know that left is greater than right */
-
- resolveIfx(&rFalseIfx,ifx);
- truelbl = newiTempLabel(NULL);
- size = max(AOP_SIZE(left),AOP_SIZE(right));
-
- DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
-
- /* POC_CPFSGT compare f, wreg, skip if f greater than wreg
- * POC_CPFSLT compare f, wreg, skip if f less then wreg */
-
-
- /* 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 = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-
-// lit = (lit - 1) & mask;
- right = left;
- left = tmp;
- rFalseIfx.condition ^= 1; /* reverse compare */
- } else
- if ((AOP_TYPE(left) == AOP_LIT)) {
- /* float compares are handled by support functions */
- lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
- }
-
-
- //if(IC_TRUE(ifx) == NULL)
- /* if left & right are bit variables */
- if (AOP_TYPE(left) == AOP_CRY &&
- AOP_TYPE(right) == AOP_CRY ) {
-
- pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir);
- pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir);
-
- } else {
- symbol *lbl = newiTempLabel(NULL);
-
- if(AOP_TYPE(left) == AOP_LIT) {
- DEBUGpic16_emitcode(";left lit","lit = 0x%x, sign=%d",lit,sign);
-
- if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
- willCheckCarry = 1;
- else willCheckCarry = 0;
-
- /* Special cases */
- if((lit == 0) && (sign == 0)) {
- /* unsigned compare to 0 */
- DEBUGpic16_emitcode("; unsigned compare to 0","lit = 0x%x, sign=%d",lit,sign);
-
- size--;
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- while(size)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size));
-
- genSkipz2(&rFalseIfx,0);
- if(ifx)ifx->generated = 1;
- return;
- }
-
- if(size==1) {
- /* Special cases */
- lit &= 0xff;
- if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) {
- /* degenerate compare can never be true */
- if(rFalseIfx.condition == 0)
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key));
-
- if(ifx) ifx->generated = 1;
- return;
- }
-
- if(sign) {
- /* signed comparisons to a literal byte */
- DEBUGpic16_emitcode(";signed compare to literal","%d: lit = 0x%x, sign=%d",__LINE__, lit,sign);
-
- int lp1 = (lit+1) & 0xff;
-
- DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x condition = %d lp1 = %i",__LINE__,lit, rFalseIfx.condition, lp1);
- switch (lp1) {
- case 0:
- rFalseIfx.condition ^= 1;
- genSkipCond(&rFalseIfx,right,0,7);
- break;
- case 0x7f:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f));
- genSkipz2(&rFalseIfx,1);
- break;
- default:
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit ));
-
- if(rFalseIfx.condition)
- pic16_emitpcode(POC_CPFSLT, pic16_popGet(AOP(right), 0));
- else
- pic16_emitpcode(POC_CPFSGT, pic16_popGet(AOP(right), 0));
-
- if(willCheckCarry) {
- if(!rFalseIfx.condition) { emitCLRC; emitSETC; }
- else { emitSETC; emitCLRC; }
-
- } else {
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
- }
-
-/* pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80));
- rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
-*/
- break;
- }
- } else {
- /* unsigned comparisons to a literal byte */
- DEBUGpic16_emitcode("; unsigned compare to literal","%d: lit = 0x%x, sign=%d",__LINE__, lit,sign);
-
- switch(lit & 0xff ) {
- /* special cases */
- case 0:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
- genSkipz2(&rFalseIfx,0);
- break;
- case 0x7f:
- rFalseIfx.condition ^= 1;
- genSkipCond(&rFalseIfx,right,0,7);
- break;
- default:
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- rFalseIfx.condition ^= 1;
- if (AOP_TYPE(result) == AOP_CRY)
- genSkipc(&rFalseIfx);
- else {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
- }
- break;
- }
- }
-
- if(ifx) ifx->generated = 1;
- if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result)))
- goto check_carry;
- return;
-
- } else {
-
- /* Size is greater than 1 */
-
- if(sign) {
- int lp1 = lit+1;
-
- size--;
-
- if(lp1 == 0) {
- /* this means lit = 0xffffffff, or -1 */
-
-
- DEBUGpic16_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) {
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
- }
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- while(size--)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
-
-
- emitSKPZ;
- if(rFalseIfx.condition) {
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
- pic16_emitpLabel(truelbl->key);
- }else {
- rFalseIfx.condition ^= 1;
- genSkipCond(&rFalseIfx,right,s,7);
- }
-
- if(ifx) ifx->generated = 1;
- return;
- }
-
- if((size == 1) && (0 == (lp1&0xff))) {
- /* lower byte of signed word is zero */
- DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit);
- i = ((lp1 >> 8) & 0xff) ^0x80;
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i));
- rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
-
-
- if(ifx) ifx->generated = 1;
- return;
- }
-
- if(lit & (0x80 << (size*8))) {
- /* Lit is less than zero */
- DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit);
- //rFalseIfx.condition ^= 1;
- //genSkipCond(&rFalseIfx,left,size,7);
- //rFalseIfx.condition ^= 1;
- pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
-
- if(rFalseIfx.condition)
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
- else
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
-
-
- } else {
- /* Lit is greater than or equal to zero */
- DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit);
- //rFalseIfx.condition ^= 1;
- //genSkipCond(&rFalseIfx,right,size,7);
- //rFalseIfx.condition ^= 1;
-
- //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0));
- //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
-
- pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER));
- if(rFalseIfx.condition)
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
- else
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
-
- }
-
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
-
- while(size--) {
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff));
- emitSKPNZ;
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
- }
- rFalseIfx.condition ^= 1;
- //rFalseIfx.condition = 1;
- genSkipc(&rFalseIfx);
-
- pic16_emitpLabel(truelbl->key);
-
- if(ifx) ifx->generated = 1;
- return;
- // end of if (sign)
- } else {
-
- /* compare word or long to an unsigned literal on the right.*/
-
-
- size--;
- if(lit < 0xff) {
- DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit);
- switch (lit) {
- case 0:
- break; /* handled above */
-/*
- case 0xff:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- while(size--)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
- genSkipz2(&rFalseIfx,0);
- break;
-*/
- default:
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- while(--size)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
-
- emitSKPZ;
- if(rFalseIfx.condition)
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key));
- else
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key));
-
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0));
-
- rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
- }
-
- pic16_emitpLabel(truelbl->key);
-
- if(ifx) ifx->generated = 1;
- return;
- }
-
-
- lit++;
- DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit);
- i = (lit >> (size*8)) & 0xff;
-
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
-
- while(size--) {
- i = (lit >> (size*8)) & 0xff;
-
- if(i) {
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i));
- emitSKPNZ;
- pic16_emitpcode(POC_SUBFW, pic16_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)
- pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
- }
- }
-
-
- pic16_emitpLabel(lbl->key);
-
- rFalseIfx.condition ^= 1;
-
- genSkipc(&rFalseIfx);
- }
-
- if(sign)
- pic16_emitpLabel(truelbl->key);
- if(ifx) ifx->generated = 1;
- return;
- }
- }
- /* Compare two variables */
-
- DEBUGpic16_emitcode(";sign","%d",sign);
-
- size--;
- if(sign) {
- /* Sigh. thus sucks... */
- if(size) {
- pCodeOp *pctemp;
-
- pctemp = pic16_popGetTempReg(1);
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size));
- pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr));
- pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80));
- pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
- pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size));
- pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr));
- pic16_popReleaseTempReg(pctemp, 1);
- } else {
- /* Signed char comparison */
- /* Special thanks to Nikolai Golovchenko for this snippet */
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */
- pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0));
- pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0));
- pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80));
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- genSkipc(&rFalseIfx);
-
- if(ifx) ifx->generated = 1;
- return;
- }
-
- } else {
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
- }
-
-
- /* The rest of the bytes of a multi-byte compare */
- while (size) {
-
- emitSKPZ;
- pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key));
- size--;
-
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size));
- pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size));
-
-
- }
-
- pic16_emitpLabel(lbl->key);
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) ||
- (AOP_TYPE(result) == AOP_REG)) {
- pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
- pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0));
- } else {
- genSkipc(&rFalseIfx);
- }
- //genSkipc(&rFalseIfx);
- if(ifx) ifx->generated = 1;
-
- return;
-
- }
-
-check_carry:
- if ((AOP_TYPE(result) != AOP_CRY)
- && AOP_SIZE(result)) {
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key );
-
- pic16_outBitC(result);
- } else {
- DEBUGpic16_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
- pic16_outBitC(result);
- /* leave the result in acc */
- }
-
-}
-#endif /* } */
-
-
-#endif /* } */
-
-
-
-/*-----------------------------------------------------------------*/
-/* genCmpGt :- greater than comparison */
-/*-----------------------------------------------------------------*/
-static void genCmpGt (iCode *ic, iCode *ifx)
-{
- operand *left, *right, *result;
- sym_link *letype , *retype;
- int sign ;
-
- FENTRY;
-
- 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 */
- pic16_aopOp (left,ic,FALSE);
- pic16_aopOp (right,ic,FALSE);
- pic16_aopOp (result,ic,TRUE);
-
- genCmp(right, left, result, ifx, sign);
-
- pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(result,NULL,ic,TRUE);
-}
-
-/*-----------------------------------------------------------------*/
-/* genCmpLt - less than comparisons */
-/*-----------------------------------------------------------------*/
-static void genCmpLt (iCode *ic, iCode *ifx)
-{
- operand *left, *right, *result;
- sym_link *letype , *retype;
- int sign ;
-
- FENTRY;
-
- 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 */
- pic16_aopOp (left,ic,FALSE);
- pic16_aopOp (right,ic,FALSE);
- pic16_aopOp (result,ic,TRUE);
-
- genCmp(left, right, result, ifx, sign);
-
- pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
- pic16_freeAsmop(result,NULL,ic,TRUE);
-}
-
-#if 0
-// not needed ATM
-// FIXME reenable literal optimisation when the pic16 port is stable
-
-/*-----------------------------------------------------------------*/
-/* genc16bit2lit - compare a 16 bit value to a literal */
-/*-----------------------------------------------------------------*/
-static void genc16bit2lit(operand *op, int lit, int offset)
-{
- int i;
-
- DEBUGpic16_emitcode ("; ***","%s %d, lit = %d",__FUNCTION__,__LINE__,lit);
- if( (lit&0xff) == 0)
- i=1;
- else
- i=0;
-
- switch( BYTEofLONG(lit,i)) {
- case 0:
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
- break;
- case 1:
- pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
- break;
- case 0xff:
- pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
- break;
- default:
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(op),offset+i));
- pic16_emitpcode(POC_XORLW,pic16_popGetLit(BYTEofLONG(lit,i)));
- }
-
- i ^= 1;
-
- switch( BYTEofLONG(lit,i)) {
- case 0:
- pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(op),offset+i));
- break;
- case 1:
- emitSKPNZ;
- pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(op),offset+i));
- break;
- case 0xff:
- emitSKPNZ;
- pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(op),offset+i));
- break;
- default:
- pic16_emitpcode(POC_MOVLW,pic16_popGetLit(BYTEofLONG(lit,i)));
- emitSKPNZ;
- pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(op),offset+i));
-
- }
-
-}
-#endif
-
-#if 0
-// not needed ATM
-/*-----------------------------------------------------------------*/
-/* gencjneshort - compare and jump if not equal */
-/*-----------------------------------------------------------------*/
-static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
-{
- int size = max(AOP_SIZE(left),AOP_SIZE(right));
- int offset = 0;
- int res_offset = 0; /* the result may be a different size then left or right */
- int res_size = AOP_SIZE(result);
- resolvedIfx rIfx;
- symbol *lbl, *lbl_done;
-
- unsigned long lit = 0L;
- int preserve_result = 0; /* don't touch result before we are done, if left/right == result */
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
- if(result)
- DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
- resolveIfx(&rIfx,ifx);
- lbl = newiTempLabel(NULL);
- lbl_done = newiTempLabel(NULL);
-
-
- /* if the left side is a literal or
- if the right is in a pointer register and left
- is not */
- if ((AOP_TYPE(left) == AOP_LIT) ||
- (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
- operand *t = right;
- right = left;
- left = t;
- }
- if(AOP_TYPE(right) == AOP_LIT)
- lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-
- if ( regsInCommon(left, result) || regsInCommon(right, result) )
- preserve_result = 1;
-
- if(result && !preserve_result)
- {
- int i;
- for(i = 0; i < AOP_SIZE(result); i++)
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
- }
-
-
- /* if the right side is a literal then anything goes */
- if (AOP_TYPE(right) == AOP_LIT &&
- AOP_TYPE(left) != AOP_DIR ) {
- switch(size) {
- case 2:
- genc16bit2lit(left, lit, 0);
- emitSKPZ;
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
- break;
- default:
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- while (size--) {
- if(lit & 0xff) {
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
- } else {
- pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
- }
-
- emitSKPZ;
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
- offset++;
- if(res_offset < res_size-1)
- res_offset++;
- lit >>= 8;
- }
- break;
- }
- }
-
- /* if the right side is in a register or in direct space or
- if the left is a pointer register & right is not */
- else if (AOP_TYPE(right) == AOP_REG ||
- AOP_TYPE(right) == AOP_DIR ||
- (AOP_TYPE(left) == AOP_DIR && AOP_TYPE(right) == AOP_LIT) ||
- (IS_AOP_PREG(left) && !IS_AOP_PREG(right))) {
- //int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
- int lbl_key = lbl->key;
-
- if(result) {
- // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset));
- //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
- }else {
- DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
- fprintf(stderr, "%s %d error - expecting result to be non_null\n",
- __FUNCTION__,__LINE__);
- return;
- }
-
-/* switch(size) { */
-/* case 2: */
-/* genc16bit2lit(left, lit, 0); */
-/* emitSKPNZ; */
-/* pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); */
-/* break; */
-/* default: */
- while (size--) {
- int emit_skip=1;
- if((AOP_TYPE(left) == AOP_DIR) &&
- ((AOP_TYPE(right) == AOP_REG) || (AOP_TYPE(right) == AOP_DIR))) {
-
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
-
- } else if((AOP_TYPE(left) == AOP_DIR) && (AOP_TYPE(right) == AOP_LIT)){
-
- switch (lit & 0xff) {
- case 0:
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
- break;
- case 1:
- pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset));
- //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key));
- emit_skip=0;
- break;
- case 0xff:
- pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
- //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
- //pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
- emit_skip=0;
- break;
- default:
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff));
- }
- lit >>= 8;
-
- } else {
- pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset));
- }
- if(emit_skip) {
- if(AOP_TYPE(result) == AOP_CRY) {
- pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
- if(rIfx.condition)
- emitSKPNZ;
- else
- emitSKPZ;
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
- } else {
- /* fix me. probably need to check result size too */
- //pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),0));
- if(rIfx.condition)
- emitSKPZ;
- else
- emitSKPNZ;
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_key));
- //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset));
- }
- if(ifx)
- ifx->generated=1;
- }
- emit_skip++;
- offset++;
- if(res_offset < res_size-1)
- res_offset++;
- }
-/* break; */
-/* } */
- } else if(AOP_TYPE(right) == AOP_REG &&
- AOP_TYPE(left) != AOP_DIR){
-
- while(size--) {
- pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset));
- pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(right),offset));
- pic16_emitcode(";***","%s %d",__FUNCTION__,__LINE__);
- if(rIfx.condition)
- emitSKPNZ;
- else
- emitSKPZ;
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
- offset++;
- if(res_offset < res_size-1)
- res_offset++;
- }
-
- }else{
- /* right is a pointer reg need both a & b */
- while(size--) {
- char *l = pic16_aopGet(AOP(left),offset,FALSE,FALSE);
- if(strcmp(l,"b"))
- pic16_emitcode("mov","b,%s",l);
- MOVA(pic16_aopGet(AOP(right),offset,FALSE,FALSE));
- pic16_emitcode("cjne","a,b,%05d_DS_",lbl->key+100);
- offset++;
- }
- }
-
- if(result && preserve_result)
- {
- int i;
- for(i = 0; i < AOP_SIZE(result); i++)
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
- }
-
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0));
-
- if(result && preserve_result)
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_done->key));
-
- if(!rIfx.condition)
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key));
-
- pic16_emitpLabel(lbl->key);
-
- if(result && preserve_result)
- {
- int i;
- for(i = 0; i < AOP_SIZE(result); i++)
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
-
- pic16_emitpLabel(lbl_done->key);
- }
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if(ifx)
- ifx->generated = 1;
-}
-#endif
-
-#if 0
-/*-----------------------------------------------------------------*/
-/* gencjne - compare and jump if not equal */
-/*-----------------------------------------------------------------*/
-static void gencjne(operand *left, operand *right, iCode *ifx)
-{
- symbol *tlbl = newiTempLabel(NULL);
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- gencjneshort(left, right, lbl);
-
- pic16_emitcode("mov","a,%s",one);
- pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100);
- pic16_emitcode("","%05d_DS_:",lbl->key+100);
- pic16_emitcode("clr","a");
- pic16_emitcode("","%05d_DS_:",tlbl->key+100);
-
- pic16_emitpLabel(lbl->key);
- pic16_emitpLabel(tlbl->key);
-
-}
-#endif
-
-
-/*-----------------------------------------------------------------*/
-/* is_LitOp - check if operand has to be treated as literal */
-/*-----------------------------------------------------------------*/
-static bool is_LitOp(operand *op)
-{
- return ((AOP_TYPE(op) == AOP_LIT)
- || ( (AOP_TYPE(op) == AOP_PCODE)
- && ( (AOP(op)->aopu.pcop->type == PO_LITERAL)
- || (AOP(op)->aopu.pcop->type == PO_IMMEDIATE) )));
-}
-
-/*-----------------------------------------------------------------*/
-/* is_LitAOp - check if operand has to be treated as literal */
-/*-----------------------------------------------------------------*/
-static bool is_LitAOp(asmop *aop)
-{
- return ((aop->type == AOP_LIT)
- || ( (aop->type == AOP_PCODE)
- && ( (aop->aopu.pcop->type == PO_LITERAL)
- || (aop->aopu.pcop->type == PO_IMMEDIATE) )));
-}
-
-
-
-/*-----------------------------------------------------------------*/
-/* genCmpEq - generates code for equal to */
-/*-----------------------------------------------------------------*/
-static void genCmpEq (iCode *ic, iCode *ifx)
-{
- operand *left, *right, *result;
- symbol *falselbl = newiTempLabel(NULL);
- symbol *donelbl = newiTempLabel(NULL);
-
- int preserve_result = 0;
- int generate_result = 0;
- int i=0;
- unsigned long lit = -1;
-
- FENTRY;
-
- pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
- pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
- pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);
-
- DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
-
- if( (AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(left) == AOP_CRY) )
- {
- werror(W_POSSBUG2, __FILE__, __LINE__);
- DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
- fprintf(stderr, "%s %d error - left/right CRY operands not supported\n",__FUNCTION__,__LINE__);
- goto release;
- }
-
- if (is_LitOp(left) || (AOP_TYPE(right) == AOP_ACC))
- {
- operand *tmp = right ;
- right = left;
- left = tmp;
- }
-
- if (AOP_TYPE(right) == AOP_LIT) {
- lit = (unsigned long) floatFromVal (AOP(right)->aopu.aop_lit);
- }
-
- if ( regsInCommon(left, result) || regsInCommon(right, result) )
- preserve_result = 1;
-
- if(result && AOP_SIZE(result))
- generate_result = 1;
-
- if(generate_result && !preserve_result)
- {
- for(i = 0; i < AOP_SIZE(result); i++)
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
- }
-
- for(i=0; i < AOP_SIZE(left); i++)
- {
- if(AOP_TYPE(left) != AOP_ACC)
- {
- if(is_LitOp(left))
- pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left), i));
- else
- pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), i));
- }
- if(is_LitOp(right)) {
- if (is_LitOp(left) || (0 != ((lit >> (8*i))&0x00FF))) {
- pic16_emitpcode(POC_XORLW, pic16_popGet(AOP(right), i));
- }
- } else
- pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right), i));
-
- pic16_emitpcode(POC_BNZ,pic16_popGetLabel(falselbl->key));
- }
-
- // result == true
-
- if(generate_result && preserve_result)
- {
- for(i = 0; i < AOP_SIZE(result); i++)
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
- }
-
- if(generate_result)
- pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0)); // result = true
-
- if(generate_result && preserve_result)
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
-
- if(ifx && IC_TRUE(ifx))
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key));
-
- if(ifx && IC_FALSE(ifx))
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key));
-
- pic16_emitpLabel(falselbl->key);
-
- // result == false
-
- if(ifx && IC_FALSE(ifx))
- pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key));
-
- if(generate_result && preserve_result)
- {
- for(i = 0; i < AOP_SIZE(result); i++)
- pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i));
- }
-
- pic16_emitpLabel(donelbl->key);
-
- if(ifx)
- ifx->generated = 1;
-
-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);
-
-}
-
-
-#if 0
-// old version kept for reference
-
-/*-----------------------------------------------------------------*/
-/* genCmpEq - generates code for equal to */
-/*-----------------------------------------------------------------*/
-static void genCmpEq (iCode *ic, iCode *ifx)
-{
- operand *left, *right, *result;
- unsigned long lit = 0L;
- int size,offset=0;
- symbol *falselbl = newiTempLabel(NULL);
-
-
- DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
-
- if(ifx)
- DEBUGpic16_emitcode ("; ifx is non-null","");
- else
- DEBUGpic16_emitcode ("; ifx is null","");
-
- pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE);
- pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE);
- pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE);