+/*-----------------------------------------------------------------*/
+/* genDjnz - generate decrement & jump if not zero instrucion */
+/*-----------------------------------------------------------------*/
+static int
+genDjnz (iCode * ic, iCode * ifx)
+{
+ symbol *lbl, *lbl1;
+ if (!ifx)
+ return 0;
+
+ /* if the if condition has a false label
+ then we cannot save */
+ if (IC_FALSE (ifx))
+ return 0;
+
+ /* if the minus is not of the form a = a - 1 */
+ if (!isOperandEqual (IC_RESULT (ic), IC_LEFT (ic)) ||
+ !IS_OP_LITERAL (IC_RIGHT (ic)))
+ return 0;
+
+ if (operandLitValue (IC_RIGHT (ic)) != 1)
+ return 0;
+
+ /* if the size of this greater than one then no
+ saving */
+ if (getSize (operandType (IC_RESULT (ic))) > 1)
+ return 0;
+
+ /* otherwise we can save BIG */
+
+ D (emitcode (";", "genDjnz"));
+
+ lbl = newiTempLabel (NULL);
+ lbl1 = newiTempLabel (NULL);
+
+ aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
+
+ if (AOP_NEEDSACC(IC_RESULT(ic)))
+ {
+ /* If the result is accessed indirectly via
+ * the accumulator, we must explicitly write
+ * it back after the decrement.
+ */
+ char *rByte = aopGet (IC_RESULT(ic), 0, FALSE, FALSE, NULL);
+
+ if (strcmp(rByte, "a"))
+ {
+ /* Something is hopelessly wrong */
+ fprintf(stderr, "*** warning: internal error at %s:%d\n",
+ __FILE__, __LINE__);
+ /* We can just give up; the generated code will be inefficient,
+ * but what the hey.
+ */
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+ return 0;
+ }
+ emitcode ("dec", "%s", rByte);
+ aopPut (IC_RESULT (ic), rByte, 0);
+ emitcode ("jnz", "!tlabel", lbl->key + 100);
+ }
+ else if (IS_AOP_PREG (IC_RESULT (ic)))
+ {
+ emitcode ("dec", "%s",
+ aopGet (IC_RESULT (ic), 0, FALSE, FALSE, NULL));
+ MOVA (aopGet (IC_RESULT (ic), 0, FALSE, FALSE, NULL));
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+ ifx->generated = 1;
+ emitcode ("jnz", "!tlabel", lbl->key + 100);
+ }
+ else
+ {
+ emitcode ("djnz", "%s,!tlabel", aopGet (IC_RESULT (ic), 0, FALSE, TRUE, NULL),
+ lbl->key + 100);
+ }
+ emitcode ("sjmp", "!tlabel", lbl1->key + 100);
+ emitLabel (lbl);
+ emitcode ("ljmp", "!tlabel", IC_TRUE (ifx)->key + 100);
+ emitLabel (lbl1);
+
+ if (!ifx->generated)
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+ ifx->generated = 1;
+ return 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* genReceive - generate code for a receive iCode */
+/*-----------------------------------------------------------------*/
+static void
+genReceive (iCode * ic)
+{
+ int size = getSize (operandType (IC_RESULT (ic)));
+ int offset = 0;
+ int rb1off ;
+
+ D (emitcode (";", "genReceive"));
+
+ if (ic->argreg == 1)
+ {
+ /* first parameter */
+ if (AOP_IS_STR(IC_RESULT(ic)))
+ {
+ /* Nothing to do: it's already in the proper place. */
+ return;
+ }
+ else
+ {
+ bool useDp2;
+
+ useDp2 = isOperandInFarSpace (IC_RESULT (ic)) &&
+ (OP_SYMBOL (IC_RESULT (ic))->isspilt ||
+ IS_TRUE_SYMOP (IC_RESULT (ic)));
+
+ _G.accInUse++;
+ aopOp (IC_RESULT (ic), ic, FALSE, useDp2);
+ _G.accInUse--;
+
+ /* Sanity checking... */
+ if (AOP_USESDPTR(IC_RESULT(ic)))
+ {
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "genReceive got unexpected DPTR.");
+ }
+ assignResultValue (IC_RESULT (ic), NULL);
+ }
+ }
+ else if (ic->argreg > 12)
+ { /* bit parameters */
+ if (OP_SYMBOL (IC_RESULT (ic))->regs[0]->rIdx != ic->argreg-5)
+ {
+ aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
+ emitcode ("mov", "c,%s", rb1regs[ic->argreg-5]);
+ outBitC(IC_RESULT (ic));
+ }
+ }
+ else
+ {
+ /* second receive onwards */
+ /* this gets a little tricky since unused receives will be
+ eliminated, we have saved the reg in the type field . and
+ we use that to figure out which register to use */
+ aopOp (IC_RESULT (ic), ic, FALSE, FALSE);
+ rb1off = ic->argreg;
+ while (size--)
+ {
+ aopPut (IC_RESULT (ic), rb1regs[rb1off++ -5], offset++);
+ }
+ }
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+}
+