+
+ /* 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)
+ // xx = bit ^ yy;
+ if (AOP_TYPE (left) == AOP_CRY)
+ {
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ // c = bit & literal;
+ if (lit >> 1)
+ {
+ // lit>>1 != 0 => result = 1
+ if (AOP_TYPE (result) == AOP_CRY)
+ {
+ if (size)
+ emitcode ("setb", "%s", AOP (result)->aopu.aop_dir);
+ else if (ifx)
+ continueIfTrue (ifx);
+ goto release;
+ }
+ emitcode ("setb", "c");
+ }
+ else
+ {
+ // lit == (0 or 1)
+ if (lit == 0)
+ {
+ // lit == 0, result = left
+ if (size && sameRegs (AOP (result), AOP (left)))
+ goto release;
+ emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
+ }
+ else
+ {
+ // lit == 1, result = not(left)
+ if (size && sameRegs (AOP (result), AOP (left)))
+ {
+ emitcode ("cpl", "%s", AOP (result)->aopu.aop_dir);
+ goto release;
+ }
+ else
+ {
+ emitcode ("mov", "c,%s", AOP (left)->aopu.aop_dir);
+ emitcode ("cpl", "c");
+ }
+ }
+ }
+
+ }
+ 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));
+ 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));
+ emitcode ("xrl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
+ aopPut (AOP (result), "a", offset);
+ }
+ else
+ emitcode ("xrl", "%s,%s",
+ aopGet (AOP (left), offset, FALSE, TRUE),
+ aopGet (AOP (right), offset, FALSE, FALSE));
+ }
+ else
+ {
+ if (AOP_TYPE (left) == AOP_ACC)
+ emitcode ("xrl", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE));
+ else
+ {
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
+ if (IS_AOP_PREG (left))
+ {
+ emitcode ("xrl", "a,%s", aopGet (AOP (left), offset, FALSE, TRUE));
+ aopPut (AOP (result), "a", offset);
+ }
+ else
+ emitcode ("xrl", "%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 = 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));
+ }
+ else
+ {
+ if (AOP_TYPE(right)==AOP_REG && AOP_TYPE(left)==AOP_ACC) {
+ emitcode ("xrl", "a,%s",
+ aopGet (AOP (right), offset, FALSE, FALSE));
+ } else {
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
+ emitcode ("xrl", "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 (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
+ {
+ aopPut (AOP (result),
+ aopGet (AOP (left), offset, FALSE, FALSE),
+ offset);
+ continue;
+ }
+ }
+ // 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));
+ else
+ {
+ MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
+ emitcode ("xrl", "a,%s",
+ aopGet (AOP (left), offset, FALSE, TRUE));
+ }
+ 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);
+}
+
+/*-----------------------------------------------------------------*/
+/* genInline - write the inline code out */
+/*-----------------------------------------------------------------*/
+static void
+genInline (iCode * ic)
+{
+ char *buffer, *bp, *bp1;
+
+ _G.inLine += (!options.asmpeep);
+
+ buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1);
+ strcpy (buffer, IC_INLINE (ic));
+
+ /* emit each line as a code */
+ while (*bp)
+ {
+ if (*bp == '\n')
+ {
+ *bp++ = '\0';
+ emitcode (bp1, "");
+ bp1 = bp;
+ }
+ else
+ {
+ if (*bp == ':')
+ {
+ bp++;
+ *bp = '\0';
+ bp++;
+ emitcode (bp1, "");
+ bp1 = bp;
+ }
+ else
+ bp++;
+ }
+ }
+ if (bp1 != bp)
+ emitcode (bp1, "");
+ /* emitcode("",buffer); */
+ _G.inLine -= (!options.asmpeep);
+}
+
+/*-----------------------------------------------------------------*/
+/* genRRC - rotate right with carry */
+/*-----------------------------------------------------------------*/
+static void
+genRRC (iCode * ic)
+{
+ operand *left, *result;
+ int size, offset = 0;
+ char *l;
+
+ /* rotate right with carry */
+ left = IC_LEFT (ic);
+ result = IC_RESULT (ic);
+ aopOp (left, ic, FALSE);
+ aopOp (result, ic, FALSE);
+
+ /* move it to the result */
+ size = AOP_SIZE (result);
+ offset = size - 1;
+ if (size == 1) { /* special case for 1 byte */
+ l = aopGet (AOP (left), offset, FALSE, FALSE);
+ MOVA (l);
+ emitcode ("rr", "a");
+ goto release;
+ }
+ CLRC;
+ while (size--)
+ {
+ l = aopGet (AOP (left), offset, FALSE, FALSE);
+ MOVA (l);
+ emitcode ("rrc", "a");
+ if (AOP_SIZE (result) > 1)
+ aopPut (AOP (result), "a", offset--);
+ }
+ /* now we need to put the carry into the
+ highest order byte of the result */
+ if (AOP_SIZE (result) > 1)
+ {
+ l = aopGet (AOP (result), AOP_SIZE (result) - 1, FALSE, FALSE);
+ MOVA (l);
+ }
+ emitcode ("mov", "acc.7,c");
+ release:
+ aopPut (AOP (result), "a", AOP_SIZE (result) - 1);
+ freeAsmop (left, NULL, ic, TRUE);
+ freeAsmop (result, NULL, ic, TRUE);