+
+ }
+ else
+ {
+ // right != literal
+ symbol *tlbl = newiTempLabel (NULL);
+ if (AOP_TYPE (right) == AOP_CRY)
+ {
+ // c = bit ^ bit;
+ emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
+ }
+ else
+ {
+ int sizer = AOP_SIZE (right);
+ // c = bit ^ val
+ // if val>>1 != 0, result = 1
+ emitcode ("setb", "c");
+ while (sizer)
+ {
+ MOVA (aopGet (AOP (right), sizer - 1, FALSE, FALSE, TRUE));
+ if (sizer == 1)
+ // test the msb of the lsb
+ emitcode ("anl", "a,#0xfe");
+ emitcode ("jnz", "%05d$", tlbl->key + 100);
+ sizer--;
+ }
+ // val = (0,1)
+ emitcode ("rrc", "a");
+ }
+ emitcode ("jnb", "%s,%05d$", AOP (left)->aopu.aop_dir, (tlbl->key + 100));
+ emitcode ("cpl", "c");
+ emitcode ("", "%05d$:", (tlbl->key + 100));
+ }
+ // bit = c
+ // val = c
+ if (size)
+ outBitC (result);
+ // if(bit | ...)
+ else if ((AOP_TYPE (result) == AOP_CRY) && ifx)
+ genIfxJump (ifx, "c");
+ goto release;
+ }
+
+ if (sameRegs (AOP (result), AOP (left)))
+ {
+ /* if left is same as result */
+ for (; size--; offset++)
+ {
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
+ continue;
+ else if (IS_AOP_PREG (left))
+ {
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+ emitcode ("xrl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+ aopPut (AOP (result), "a", offset);
+ }
+ else
+ emitcode ("xrl", "%s,%s",
+ aopGet (AOP (left), offset, FALSE, TRUE, FALSE),
+ aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+ }
+ else
+ {
+ if (AOP_TYPE (left) == AOP_ACC)
+ emitcode ("xrl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+ else
+ {
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+ if (IS_AOP_PREG (left))
+ {
+ emitcode ("xrl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+ aopPut (AOP (result), "a", offset);
+ }
+ else
+ emitcode ("xrl", "%s,a",
+ aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+ }
+ }
+ }
+ }
+ 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 = max (AOP_SIZE (left), AOP_SIZE (right));
+ if (size)
+ emitcode ("setb", "c");
+ while (sizer--)
+ {
+ if ((AOP_TYPE (right) == AOP_LIT) &&
+ (((lit >> (offset * 8)) & 0x0FFL) == 0x00L))
+ {
+ MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+ }
+ else
+ {
+ if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
+ emitcode ("xrl", "a,%s",
+ aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+ } else {
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+ emitcode ("xrl", "a,%s",
+ aopGet (AOP (left), offset, FALSE, 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 (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
+ {
+ aopPut (AOP (result),
+ aopGet (AOP (left), offset, FALSE, FALSE, FALSE),
+ offset);
+ continue;
+ }
+ D (emitcode (";", "better literal XOR.");
+ );
+ MOVA (aopGet (AOP (left), offset, FALSE, FALSE, TRUE));
+ emitcode ("xrl", "a, %s", aopGet (AOP (right), offset,
+ FALSE, FALSE, FALSE));
+ }
+ else
+ {
+ // faster than result <- left, anl result,right
+ // and better if result is SFR
+ if (AOP_TYPE (left) == AOP_ACC)
+ {
+ emitcode ("xrl", "a,%s", aopGet (AOP (right), offset,
+ FALSE, FALSE, FALSE));
+ }
+ else
+ {
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE, TRUE));
+ emitcode ("xrl", "a,%s",
+ aopGet (AOP (left), offset, FALSE, TRUE, FALSE));
+ }
+ }
+ aopPut (AOP (result), "a", offset);
+ }