-
- } else if ((AOP_TYPE(left) == AOP_LIT)) {
- 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 ) {
- 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 */
-
- symbol *lbl = newiTempLabel(NULL);
-
-#ifndef _swapp
- if(AOP_TYPE(right) == AOP_LIT) {
-
- //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-
- DEBUGpic14_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign);
-
- /* special cases */
-
- if(lit == 0) {
-
- 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));
-
- if(ifx) ifx->generated = 1;
- return;
-
- }
- size--;
-
- 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);
- }
-
- } else {
- if(lit == 1) {
- genSkipz2(&rFalseIfx,1);
- } else {
- emitpcode(POC_ADDLW, popGetLit(i));
- genSkipc(&rFalseIfx);
- }
- }
-
- 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 */
-
- if(sign) {
-
- if(lit == 0) {
- genSkipCond(&rFalseIfx,left,size,7);
- if(ifx) ifx->generated = 1;
- return;
- }
-
- if(lit <0x100) {
- DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
-
- //rFalseIfx.condition ^= 1;
- //genSkipCond(&rFalseIfx,left,size,7);
- //rFalseIfx.condition ^= 1;
-
- 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));
-
- emitpcode(POC_MOVLW, popGetLit(0x100-lit));
- emitpcode(POC_ADDFW, popGet(AOP(left),0));
- emitpcode(POC_MOVFW, popGet(AOP(left),1));
-
- while(size > 1)
- emitpcode(POC_IORFW, popGet(AOP(left),size--));
-
- if(rFalseIfx.condition) {
- emitSKPZ;
- emitpcode(POC_GOTO, popGetLabel(truelbl->key));
-
- } else {
- emitSKPNZ;
- }
-
- genSkipc(&rFalseIfx);
- emitpLabel(truelbl->key);
- if(ifx) ifx->generated = 1;
- return;
-
- }
-
- if(size == 1) {
-
- 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);
-
-
- if(ifx) ifx->generated = 1;
- return;
-
- }
- } 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);
-
-
- if(ifx) ifx->generated = 1;
- return;
-
- }
-
- }
-
-
- if(lit & (0x80 << (size*8))) {
- /* lit is negative */
- DEBUGpic14_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit);
-
- //genSkipCond(&rFalseIfx,left,size,7);
-
- emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(left),size,FALSE,FALSE),7,0));
-
- if(rFalseIfx.condition)
- emitpcode(POC_GOTO, popGetLabel(truelbl->key));
- else
- emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
-
-
- } 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));
-
- }
-
- /* There are no more special cases, so perform a general compare */
-
- emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
- emitpcode(POC_SUBFW, popGet(AOP(left),size));
-
- while(size--) {
-
- emitpcode(POC_MOVLW, popGetLit((lit >> (size*8)) & 0xff));
- emitSKPNZ;
- emitpcode(POC_SUBFW, popGet(AOP(left),size));
- }
- //rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
-
- emitpLabel(truelbl->key);
-
- if(ifx) ifx->generated = 1;
- return;
-
-
- }
-
-
- /* 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);
-
-
- /* General case - compare to an unsigned literal on the right.*/
-
- i = (lit >> (size*8)) & 0xff;
- emitpcode(POC_MOVLW, popGetLit(i));
- emitpcode(POC_SUBFW, popGet(AOP(left),size));
- while(size--) {
- i = (lit >> (size*8)) & 0xff;
-
- 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));
- }
- }
-
-
- emitpLabel(lbl->key);
- //if(emitFinalCheck)
- genSkipc(&rFalseIfx);
- if(sign)
- 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));
-
-
- DEBUGpic14_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign);
-
- /* Special cases */
- if((lit == 0) && (sign == 0)){
-
- size--;
- emitpcode(POC_MOVFW, popGet(AOP(right),size));
- while(size)
- emitpcode(POC_IORFW, 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)
- emitpcode(POC_GOTO,popGetLabel(rFalseIfx.lbl->key));
-
- if(ifx) ifx->generated = 1;
- return;
- }
-
- if(sign) {
- /* signed comparisons to a literal byte */
-
- int lp1 = (lit+1) & 0xff;
-
- 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);
- break;
- }
- if(ifx) ifx->generated = 1;
- } else {
- /* unsigned comparisons to a literal byte */
-
- 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:
- 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);
- 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));
- }
- break;
- }
- }
-
- //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 */
-
-
- 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;
- }
-
- 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);
-
-
- if(ifx) ifx->generated = 1;
- return;
- }
-
- 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));
-
- if(rFalseIfx.condition)
- emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
- else
- emitpcode(POC_GOTO, popGetLabel(truelbl->key));
-
-
- } 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;
-
- //emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),size,FALSE,FALSE),7,0));
- //emitpcode(POC_GOTO, popGetLabel(rFalseIfx.lbl->key));
-
- 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));
-
- }
-
-
- emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
- emitpcode(POC_SUBFW, popGet(AOP(right),size));
-
- while(size--) {
-
- emitpcode(POC_MOVLW, popGetLit((lp1 >> (size*8)) & 0xff));
- emitSKPNZ;
- emitpcode(POC_SUBFW, popGet(AOP(right),size));
- }
- rFalseIfx.condition ^= 1;
- //rFalseIfx.condition = 1;
- genSkipc(&rFalseIfx);
-
- 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) {
- 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);
- }
-
- 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));
- }
- }
-
-
- emitpLabel(lbl->key);
-
- rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
- }
-
- if(sign)
- emitpLabel(truelbl->key);
- if(ifx) ifx->generated = 1;
- return;
- }
- }
- /* Compare two variables */
-
- DEBUGpic14_emitcode(";sign","%d",sign);
-
- 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));
- } 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);
-
- if(ifx) ifx->generated = 1;
- return;
- }
-
- } else {
-
- emitpcode(POC_MOVFW, popGet(AOP(right),size));
- emitpcode(POC_SUBFW, popGet(AOP(left),size));
- }
-
-
- /* 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));
-
-
- }
-
- emitpLabel(lbl->key);
-
- 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);
- }
- //genSkipc(&rFalseIfx);
- 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 */
- }
-
+
+ /*************************************************
+ * make sure that left is register (or the like) *
+ *************************************************/
+ if (!isAOP_REGlike(left)) {
+ DEBUGpc ("swapping arguments (AOP_TYPEs %d/%d)", AOP_TYPE(left), AOP_TYPE(right));
+ assert (isAOP_LIT(left));
+ assert (isAOP_REGlike(right));
+ // swap left and right
+ // left < right <==> right > left <==> (right >= left + 1)
+ lit = ulFromVal(AOP(left)->aopu.aop_lit);
+
+ if ( (!sign && (lit & mask) == mask) || (sign && (lit & mask) == (mask >> 1)) ) {
+ // MAXVALUE < right? always false
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
+ } // if
+
+ // This fails for lit = 0xFF (unsigned) AND lit = 0x7F (signed),
+ // that's why we handled it above.
+ lit++;
+
+ dummy = left;
+ left = right;
+ right = dummy;
+
+ performedLt ^= 1; // instead of "left < right" we check for "right >= left+1, i.e. "right < left+1"
+ } else if (isAOP_LIT(right)) {
+ lit = ulFromVal(AOP(right)->aopu.aop_lit);
+ } // if
+
+ assert (isAOP_REGlike(left)); // left must be register or the like
+ assert (isAOP_REGlike(right) || isAOP_LIT(right)); // right may be register-like or a literal
+
+ /*************************************************
+ * special cases go here *
+ *************************************************/
+
+ if (isAOP_LIT(right)) {
+ if (!sign) {
+ // unsigned comparison to a literal
+ DEBUGpc ("unsigned compare: left %s lit(0x%X=%lu), size=%d", performedLt ? "<" : ">=", lit, lit, size+1);
+ if (lit == 0) {
+ // unsigned left < 0? always false
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
+ }
+ } else {
+ // signed comparison to a literal
+ DEBUGpc ("signed compare: left %s lit(0x%X=%ld), size=%d, mask=%x", performedLt ? "<" : ">=", lit, lit, size+1, mask);
+ if ((lit & mask) == ((0x80 << (size*8)) & mask)) {
+ // signed left < 0x80000000? always false
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
+ } else if (lit == 0) {
+ // compare left < 0; set CARRY if SIGNBIT(left) is set
+ if (performedLt) emitSETC; else emitCLRC;
+ emitpcode (POC_BTFSS, newpCodeOpBit (aopGet (AOP(left), size, FALSE, FALSE), 7, 0));
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
+ }
+ } // if (!sign)
+ } // right is literal
+
+ /*************************************************
+ * perform a general case comparison *
+ * make sure we get CARRY==1 <==> left >= right *
+ *************************************************/
+ // compare most significant bytes
+ //DEBUGpc ("comparing bytes at offset %d", size);
+ if (!sign) {
+ // unsigned comparison
+ pic14_mov2w_regOrLit (AOP(right), lit, size);
+ emitpcode (POC_SUBFW, popGet (AOP(left), size));
+ } else {
+ // signed comparison
+ // (add 2^n to both operands then perform an unsigned comparison)
+ if (isAOP_LIT(right)) {
+ // left >= LIT <-> LIT-left <= 0 <-> LIT-left == 0 OR !(LIT-left >= 0)
+ unsigned char litbyte = (lit >> (8*size)) & 0xFF;
+
+ if (litbyte == 0x80) {
+ // left >= 0x80 -- always true, but more bytes to come
+ mov2w (AOP(left), size);
+ emitpcode (POC_XORLW, popGetLit (0x80)); // set ZERO flag
+ emitSETC;
+ } else {
+ // left >= LIT <-> left + (-LIT) >= 0 <-> left + (0x100-LIT) >= 0x100
+ mov2w (AOP(left), size);
+ emitpcode (POC_ADDLW, popGetLit (0x80));
+ emitpcode (POC_ADDLW, popGetLit ((0x100 - (litbyte + 0x80)) & 0x00FF));
+ } // if
+ } else {
+ pCodeOp *pctemp = popGetTempReg();
+ mov2w (AOP(left), size);
+ emitpcode (POC_ADDLW, popGetLit (0x80));
+ emitpcode (POC_MOVWF, pctemp);
+ mov2w (AOP(right), size);
+ emitpcode (POC_ADDLW, popGetLit (0x80));
+ emitpcode (POC_SUBFW, pctemp);
+ popReleaseTempReg(pctemp);
+ }
+ } // if (!sign)
+
+ // compare remaining bytes (treat as unsigned case from above)
+ templbl = newiTempLabel ( NULL );
+ offs = size;
+ while (offs--) {
+ //DEBUGpc ("comparing bytes at offset %d", offs);
+ emitSKPZ;
+ emitpcode (POC_GOTO, popGetLabel (templbl->key));
+ pic14_mov2w_regOrLit (AOP(right), lit, offs);
+ emitpcode (POC_SUBFW, popGet (AOP(left), offs));
+ } // while (offs)
+ emitpLabel (templbl->key);
+ goto result_in_carry;
+
+result_in_carry:
+
+ /****************************************************
+ * now CARRY contains the result of the comparison: *
+ * SUBWF sets CARRY iff *
+ * F-W >= 0 <==> F >= W <==> !(F < W) *
+ * (F=left, W=right) *
+ ****************************************************/
+
+ if (performedLt) {
+ invert_result = 1;
+ // value will be used in the following genSkipc()
+ rIfx.condition ^= 1;
+ } // if
+
+correct_result_in_carry:
+
+ // assign result to variable (if neccessary)
+ if (result && AOP_TYPE(result) != AOP_CRY) {
+ //DEBUGpc ("assign result");
+ size = AOP_SIZE(result);
+ while (size--) {
+ emitpcode (POC_CLRF, popGet (AOP(result), size));
+ } // while
+ if (invert_result) {
+ emitSKPC;
+ emitpcode (POC_BSF, newpCodeOpBit (aopGet (AOP(result), 0, FALSE, FALSE), 0, 0));
+ } else {
+ emitpcode (POC_RLF, popGet (AOP(result), 0));
+ }
+ } // if (result)
+
+ // perform conditional jump
+ if (ifx) {
+ //DEBUGpc ("generate control flow");
+ genSkipc (&rIfx);
+ ifx->generated = 1;
+ } // if