+ _startLazyDPSEvaluation ();
+ while (size--)
+ {
+ emitcode ("pop", "acc");
+ aopPut (AOP (IC_RESULT (ic)), "a", size);
+ }
+ _endLazyDPSEvaluation ();
+ }
+
+ adjustArithmeticResult (ic);
+
+release:
+ freeAsmop (IC_LEFT (ic), NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (IC_RIGHT (ic), NULL, ic, (RESULTONSTACK (ic) ? FALSE : TRUE));
+ freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genMinusDec :- does subtraction with deccrement if possible */
+/*-----------------------------------------------------------------*/
+static bool
+genMinusDec (iCode * ic)
+{
+ unsigned int icount;
+ unsigned int size = getDataSize (IC_RESULT (ic));
+
+ /* will try to generate an increment */
+ /* if the right side is not a literal
+ we cannot */
+ if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT)
+ return FALSE;
+
+ /* if the literal value of the right hand side
+ is greater than 4 then it is not worth it */
+ if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 4)
+ return FALSE;
+
+ /* if decrement 16 bits in register */
+ if (AOP_TYPE (IC_LEFT (ic)) == AOP_REG &&
+ AOP_TYPE (IC_RESULT (ic)) == AOP_REG &&
+ sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) &&
+ (size > 1) &&
+ (icount == 1))
+ {
+ symbol *tlbl;
+ int emitTlbl;
+ int labelRange;
+
+ /* If the next instruction is a goto and the goto target
+ * is <= 5 instructions previous to this, we can generate
+ * jumps straight to that target.
+ */
+ if (ic->next && ic->next->op == GOTO
+ && (labelRange = findLabelBackwards (ic, IC_LABEL (ic->next)->key)) != 0
+ && labelRange <= 5)
+ {
+ emitcode (";", "tail decrement optimized (range %d)", labelRange);
+ tlbl = IC_LABEL (ic->next);
+ emitTlbl = 0;
+ }
+ else
+ {
+ tlbl = newiTempLabel (NULL);
+ emitTlbl = 1;
+ }
+
+ emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE));
+ if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+ AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR ||
+ IS_AOP_PREG (IC_RESULT (ic)))
+ emitcode ("cjne", "%s,#0xff,%05d$"
+ ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE)
+ ,tlbl->key + 100);
+ else
+ {
+ emitcode ("mov", "a,#0xff");
+ emitcode ("cjne", "a,%s,%05d$"
+ ,aopGet (AOP (IC_RESULT (ic)), LSB, FALSE, FALSE, FALSE)
+ ,tlbl->key + 100);
+ }
+ emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE));
+ if (size > 2)
+ {
+ if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+ AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR ||
+ IS_AOP_PREG (IC_RESULT (ic)))
+ emitcode ("cjne", "%s,#0xff,%05d$"
+ ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE)
+ ,tlbl->key + 100);
+ else
+ {
+ emitcode ("cjne", "a,%s,%05d$"
+ ,aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE, FALSE, FALSE)
+ ,tlbl->key + 100);
+ }
+ emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE));
+ }
+ if (size > 3)
+ {
+ if (AOP_TYPE (IC_RESULT (ic)) == AOP_REG ||
+ AOP_TYPE (IC_RESULT (ic)) == AOP_DPTR ||
+ IS_AOP_PREG (IC_RESULT (ic)))
+ emitcode ("cjne", "%s,#0xff,%05d$"
+ ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE)
+ ,tlbl->key + 100);
+ else
+ {
+ emitcode ("cjne", "a,%s,%05d$"
+ ,aopGet (AOP (IC_RESULT (ic)), MSB24, FALSE, FALSE, FALSE)
+ ,tlbl->key + 100);
+ }
+ emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), MSB32, FALSE, FALSE, FALSE));
+ }
+ if (emitTlbl)
+ {
+ emitcode ("", "%05d$:", tlbl->key + 100);
+ }
+ return TRUE;
+ }
+
+ /* if the sizes are greater than 1 then we cannot */
+ if (AOP_SIZE (IC_RESULT (ic)) > 1 ||
+ AOP_SIZE (IC_LEFT (ic)) > 1)
+ return FALSE;
+
+ /* we can if the aops of the left & result match or
+ if they are in registers and the registers are the
+ same */
+ if (
+ AOP_TYPE (IC_LEFT (ic)) == AOP_REG &&
+ AOP_TYPE (IC_RESULT (ic)) == AOP_REG &&
+ sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))))
+ {
+
+ _startLazyDPSEvaluation ();
+ while (icount--)
+ {
+ emitcode ("dec", "%s", aopGet (AOP (IC_RESULT (ic)), 0, FALSE, FALSE, FALSE));
+ }
+ _endLazyDPSEvaluation ();