+#elif 0 /* VR 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));
+ }
+ }
+}
+
+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(EXIT_FAILURE);
+ }
+
+ /* 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__);
+
+ /* using PRODL:PRODH as a temporary register here */
+ 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 );
+ }
+
+ }
+ }
+}
+
+#endif /* } */
+
+
+