+ /* if right is bit then exchange them */
+ if (AOP_TYPE (right) == AOP_CRY &&
+ AOP_TYPE (left) != AOP_CRY)
+ {
+ operand *tmp = right;
+ right = left;
+ left = tmp;
+ }
+ if (AOP_TYPE (right) == AOP_LIT)
+ lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+
+ size = AOP_SIZE (result);
+
+ // if(bit & yy)
+ // result = bit & yy;
+ if (AOP_TYPE (left) == AOP_CRY)
+ {
+ // c = bit & literal;
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ if (lit & 1)
+ {
+ if (size && sameRegs (AOP (result), AOP (left)))
+ // no change
+ goto release;
+ emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
+ }
+ else
+ {
+ // bit(result) = 0;
+ if (size && (AOP_TYPE (result) == AOP_CRY))
+ {
+ emitcode ("clr", "%s", AOP (result)->aopu.aop_dir);
+ goto release;
+ }
+ if ((AOP_TYPE (result) == AOP_CRY) && ifx)
+ {
+ jumpIfTrue (ifx);
+ goto release;
+ }
+ emitcode ("clr", "c");
+ }
+ }
+ else
+ {
+ if (AOP_TYPE (right) == AOP_CRY)
+ {
+ // c = bit & bit;
+ emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
+ emitcode ("anl", "c,%s", AOP (left)->aopu.aop_dir);
+ }
+ else
+ {
+ // c = bit & val;
+ MOVA (aopGet (AOP (right), 0, FALSE, FALSE));
+ // c = lsb
+ emitcode ("rrc", "a");
+ emitcode ("anl", "c,%s", AOP (left)->aopu.aop_dir);
+ }
+ }
+ // bit = c
+ // val = c
+ if (size)
+ outBitC (result);
+ // if(bit & ...)
+ else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
+ genIfxJump (ifx, "c");
+ goto release;
+ }
+
+ // if(val & 0xZZ) - size = 0, ifx != FALSE -
+ // bit = val & 0xZZ - size = 1, ifx = FALSE -
+ if ((AOP_TYPE (right) == AOP_LIT) &&
+ (AOP_TYPE (result) == AOP_CRY) &&
+ (AOP_TYPE (left) != AOP_CRY))
+ {
+ int posbit = isLiteralBit (lit);
+ /* left & 2^n */
+ if (posbit)
+ {
+ posbit--;
+ MOVA (aopGet (AOP (left), posbit >> 3, FALSE, FALSE));
+ // bit = left & 2^n
+ if (size)
+ emitcode ("mov", "c,acc.%d", posbit & 0x07);
+ // if(left & 2^n)
+ else
+ {
+ if (ifx)
+ {
+ sprintf (buffer, "acc.%d", posbit & 0x07);
+ genIfxJump (ifx, buffer);
+ }
+ goto release;
+ }
+ }
+ else
+ {
+ symbol *tlbl = newiTempLabel (NULL);
+ int sizel = AOP_SIZE (left);
+ if (size)
+ emitcode ("setb", "c");
+ while (sizel--)
+ {
+ if ((bytelit = ((lit >> (offset * 8)) & 0x0FFL)) != 0x0L)
+ {
+ MOVA (aopGet (AOP (left), offset, FALSE, FALSE));
+ // byte == 2^n ?
+ if ((posbit = isLiteralBit (bytelit)) != 0)
+ emitcode ("jb", "acc.%d,%05d$", (posbit - 1) & 0x07, tlbl->key + 100);
+ else
+ {
+ if (bytelit != 0x0FFL)
+ emitcode ("anl", "a,%s",
+ aopGet (AOP (right), offset, FALSE, TRUE));
+ emitcode ("jnz", "%05d$", tlbl->key + 100);
+ }
+ }
+ offset++;
+ }
+ // bit = left & literal
+ if (size)
+ {
+ emitcode ("clr", "c");
+ emitcode ("", "%05d$:", tlbl->key + 100);
+ }
+ // if(left & literal)
+ else
+ {
+ if (ifx)
+ jmpTrueOrFalse (ifx, tlbl);
+ goto release;
+ }
+ }
+ outBitC (result);
+ goto release;
+ }
+
+ /* if left is same as result */
+ if (sameRegs (AOP (result), AOP (left)))
+ {
+ for (; size--; offset++)
+ {
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ if ((bytelit = (int) ((lit >> (offset * 8)) & 0x0FFL)) == 0x0FF)
+ continue;
+ else if (bytelit == 0)
+ aopPut (AOP (result), zero, offset);
+ else if (IS_AOP_PREG (result))
+ {
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
+ emitcode ("anl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
+ aopPut (AOP (result), "a", offset);
+ }
+ else
+ emitcode ("anl", "%s,%s",
+ aopGet (AOP (left), offset, FALSE, TRUE),
+ aopGet (AOP (right), offset, FALSE, FALSE));
+ }
+ else
+ {
+ if (AOP_TYPE (left) == AOP_ACC)
+ emitcode ("anl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
+ else
+ {
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
+ if (IS_AOP_PREG (result))
+ {
+ emitcode ("anl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
+ aopPut (AOP (result), "a", offset);
+
+ }
+ else
+ emitcode ("anl", "%s,a",
+ aopGet (AOP (left), offset, FALSE, TRUE));
+ }
+ }
+ }
+ }
+ else
+ {
+ // left & result in different registers
+ if (AOP_TYPE (result) == AOP_CRY)
+ {
+ // result = bit
+ // if(size), result in bit
+ // if(!size && ifx), conditional oper: if(left & right)
+ symbol *tlbl = newiTempLabel (NULL);
+ int sizer = min (AOP_SIZE (left), AOP_SIZE (right));
+ if (size)
+ emitcode ("setb", "c");
+ while (sizer--)
+ {
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
+ emitcode ("anl", "a,%s",
+ aopGet (AOP (left), offset, FALSE, FALSE));
+ emitcode ("jnz", "%05d$", tlbl->key + 100);
+ offset++;
+ }
+ if (size)
+ {
+ CLRC;
+ emitcode ("", "%05d$:", tlbl->key + 100);
+ outBitC (result);
+ }
+ else if (ifx)
+ jmpTrueOrFalse (ifx, tlbl);
+ }
+ else
+ {
+ for (; (size--); offset++)
+ {
+ // normal case
+ // result = left & right
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ if ((bytelit = (int) ((lit >> (offset * 8)) & 0x0FFL)) == 0x0FF)
+ {
+ aopPut (AOP (result),
+ aopGet (AOP (left), offset, FALSE, FALSE),
+ offset);
+ continue;
+ }
+ else if (bytelit == 0)
+ {
+ aopPut (AOP (result), zero, offset);
+ continue;
+ }
+ }
+ // faster than result <- left, anl result,right
+ // and better if result is SFR
+ if (AOP_TYPE (left) == AOP_ACC)
+ emitcode ("anl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
+ else
+ {
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
+ emitcode ("anl", "a,%s",
+ aopGet (AOP (left), offset, FALSE, FALSE));
+ }
+ aopPut (AOP (result), "a", offset);
+ }
+ }
+ }
+
+release:
+ freeAsmop (left, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (right, NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (result, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genOr - code for or */
+/*-----------------------------------------------------------------*/
+static void
+genOr (iCode * ic, iCode * ifx)