- /* Doesnt include _G.stack.pushed */
- int abso = aop->aopu.aop_stk + offset + _G.stack.offset;
-
- if (aop->aopu.aop_stk > 0)
- {
- abso += _G.stack.param_offset;
- }
- assert (pairId == PAIR_HL);
- /* In some cases we can still inc or dec hl */
- if (_G.pairs[pairId].last_type == AOP_STK && abs (_G.pairs[pairId].offset - abso) < 3)
- {
- adjustPair (_pairs[pairId].name, &_G.pairs[pairId].offset, abso);
- }
- else
- {
+ /* Doesnt include _G.stack.pushed */
+ int abso = aop->aopu.aop_stk + offset + _G.stack.offset;
+
+ if (aop->aopu.aop_stk > 0)
+ {
+ abso += _G.stack.param_offset;
+ }
+ assert (pairId == PAIR_HL);
+ /* In some cases we can still inc or dec hl */
+ if (_G.pairs[pairId].last_type == AOP_STK && abs (_G.pairs[pairId].offset - abso) < 3)
+ {
+ adjustPair (_pairs[pairId].name, &_G.pairs[pairId].offset, abso);
+ }
+ else
+ {
- switch (offset)
- {
- case 2:
- tsprintf (buffer, sizeof(buffer), "!bankimmeds", aop->aopu.aop_immd);
- break;
- case 1:
- tsprintf (buffer, sizeof(buffer), "!msbimmeds", aop->aopu.aop_immd);
- break;
- case 0:
- tsprintf (buffer, sizeof(buffer), "!lsbimmeds", aop->aopu.aop_immd);
- break;
- default:
- wassertl (0, "Fetching from beyond the limits of an immediate value.");
- }
+ switch (offset)
+ {
+ case 2:
+ tsprintf (buffer, sizeof(buffer), "!bankimmeds", aop->aopu.aop_immd);
+ break;
+ case 1:
+ tsprintf (buffer, sizeof(buffer), "!msbimmeds", aop->aopu.aop_immd);
+ break;
+ case 0:
+ tsprintf (buffer, sizeof(buffer), "!lsbimmeds", aop->aopu.aop_immd);
+ break;
+ default:
+ wassertl (0, "Fetching from beyond the limits of an immediate value.");
+ }
- {
- /* PENDING: re-target */
- if (!strcmp (s, "!*hl") || !strcmp (s, "(hl)") || !strcmp (s, "[hl]"))
- {
- emit2 ("ld a,!*hl");
- s = "a";
- }
- setupPair (PAIR_HL, aop, offset);
- if (!canAssignToPtr (s))
- {
- emit2 ("ld a,%s", s);
- emit2 ("ld !*hl,a");
- }
- else
- emit2 ("ld !*hl,%s", s);
- }
+ {
+ /* PENDING: re-target */
+ if (!strcmp (s, "!*hl") || !strcmp (s, "(hl)") || !strcmp (s, "[hl]"))
+ {
+ emit2 ("ld a,!*hl");
+ s = "a";
+ }
+ setupPair (PAIR_HL, aop, offset);
+ if (!canAssignToPtr (s))
+ {
+ emit2 ("ld a,%s", s);
+ emit2 ("ld !*hl,a");
+ }
+ else
+ emit2 ("ld !*hl,%s", s);
+ }
- AOP_TYPE (IC_RIGHT (ic)) == AOP_STK ||
- AOP_TYPE (IC_RESULT (ic)) == AOP_STK)
- {
- if ((AOP_SIZE (IC_LEFT (ic)) == 2 ||
- AOP_SIZE (IC_RIGHT (ic)) == 2) &&
- (AOP_SIZE (IC_LEFT (ic)) <= 2 &&
- AOP_SIZE (IC_RIGHT (ic)) <= 2))
- {
- if (getPairId (AOP (IC_RIGHT (ic))) == PAIR_BC)
- {
- /* Swap left and right */
- operand *t = IC_RIGHT (ic);
- IC_RIGHT (ic) = IC_LEFT (ic);
- IC_LEFT (ic) = t;
- }
- if (getPairId (AOP (IC_LEFT (ic))) == PAIR_BC)
- {
- fetchPair (PAIR_HL, AOP (IC_RIGHT (ic)));
- emit2 ("add hl,bc");
- }
- else
- {
- fetchPair (PAIR_DE, AOP (IC_LEFT (ic)));
- fetchPair (PAIR_HL, AOP (IC_RIGHT (ic)));
- emit2 ("add hl,de");
- }
- commitPair (AOP (IC_RESULT (ic)), PAIR_HL);
- goto release;
- }
- }
+ AOP_TYPE (IC_RIGHT (ic)) == AOP_STK ||
+ AOP_TYPE (IC_RESULT (ic)) == AOP_STK)
+ {
+ if ((AOP_SIZE (IC_LEFT (ic)) == 2 ||
+ AOP_SIZE (IC_RIGHT (ic)) == 2) &&
+ (AOP_SIZE (IC_LEFT (ic)) <= 2 &&
+ AOP_SIZE (IC_RIGHT (ic)) <= 2))
+ {
+ if (getPairId (AOP (IC_RIGHT (ic))) == PAIR_BC)
+ {
+ /* Swap left and right */
+ operand *t = IC_RIGHT (ic);
+ IC_RIGHT (ic) = IC_LEFT (ic);
+ IC_LEFT (ic) = t;
+ }
+ if (getPairId (AOP (IC_LEFT (ic))) == PAIR_BC)
+ {
+ fetchPair (PAIR_HL, AOP (IC_RIGHT (ic)));
+ emit2 ("add hl,bc");
+ }
+ else
+ {
+ fetchPair (PAIR_DE, AOP (IC_LEFT (ic)));
+ fetchPair (PAIR_HL, AOP (IC_RIGHT (ic)));
+ emit2 ("add hl,de");
+ }
+ commitPair (AOP (IC_RESULT (ic)), PAIR_HL);
+ goto release;
+ }
+ }
- AOP_TYPE (IC_RIGHT (ic)) == AOP_STK ||
- AOP_TYPE (IC_RESULT (ic)) == AOP_STK)
- {
- if ((AOP_SIZE (IC_LEFT (ic)) == 2 ||
- AOP_SIZE (IC_RIGHT (ic)) == 2) &&
- (AOP_SIZE (IC_LEFT (ic)) <= 2 &&
- AOP_SIZE (IC_RIGHT (ic)) <= 2))
- {
- PAIR_ID left = getPairId (AOP (IC_LEFT (ic)));
- PAIR_ID right = getPairId (AOP (IC_RIGHT (ic)));
-
- if (left == PAIR_INVALID && right == PAIR_INVALID)
- {
- left = PAIR_DE;
- right = PAIR_HL;
- }
- else if (right == PAIR_INVALID)
- right = PAIR_DE;
- else if (left == PAIR_INVALID)
- left = PAIR_DE;
-
- fetchPair (left, AOP (IC_LEFT (ic)));
- /* Order is important. Right may be HL */
- fetchPair (right, AOP (IC_RIGHT (ic)));
-
- emit2 ("ld a,%s", _pairs[left].l);
- emit2 ("sub a,%s", _pairs[right].l);
- emit2 ("ld e,a");
- emit2 ("ld a,%s", _pairs[left].h);
- emit2 ("sbc a,%s", _pairs[right].h);
+ AOP_TYPE (IC_RIGHT (ic)) == AOP_STK ||
+ AOP_TYPE (IC_RESULT (ic)) == AOP_STK)
+ {
+ if ((AOP_SIZE (IC_LEFT (ic)) == 2 ||
+ AOP_SIZE (IC_RIGHT (ic)) == 2) &&
+ (AOP_SIZE (IC_LEFT (ic)) <= 2 &&
+ AOP_SIZE (IC_RIGHT (ic)) <= 2))
+ {
+ PAIR_ID left = getPairId (AOP (IC_LEFT (ic)));
+ PAIR_ID right = getPairId (AOP (IC_RIGHT (ic)));
+
+ if (left == PAIR_INVALID && right == PAIR_INVALID)
+ {
+ left = PAIR_DE;
+ right = PAIR_HL;
+ }
+ else if (right == PAIR_INVALID)
+ right = PAIR_DE;
+ else if (left == PAIR_INVALID)
+ left = PAIR_DE;
+
+ fetchPair (left, AOP (IC_LEFT (ic)));
+ /* Order is important. Right may be HL */
+ fetchPair (right, AOP (IC_RIGHT (ic)));
+
+ emit2 ("ld a,%s", _pairs[left].l);
+ emit2 ("sub a,%s", _pairs[right].l);
+ emit2 ("ld e,a");
+ emit2 ("ld a,%s", _pairs[left].h);
+ emit2 ("sbc a,%s", _pairs[right].h);
- (AOP_TYPE (right) == AOP_LIT && AOP_TYPE (left) != AOP_DIR))
- {
- emit2 ("ld a,%s", aopGet (AOP (left), offset, FALSE));
- if (sign)
- {
- emit2 ("xor a,!immedbyte", 0x80);
- emit2 ("cp %s^!constbyte", aopGet (AOP (right), offset, FALSE), 0x80);
- }
- else
- emit2 ("cp %s", aopGet (AOP (right), offset, FALSE));
- }
+ (AOP_TYPE (right) == AOP_LIT && AOP_TYPE (left) != AOP_DIR))
+ {
+ emit2 ("ld a,%s", aopGet (AOP (left), offset, FALSE));
+ if (sign)
+ {
+ emit2 ("xor a,!immedbyte", 0x80);
+ emit2 ("cp %s^!constbyte", aopGet (AOP (right), offset, FALSE), 0x80);
+ }
+ else
+ emit2 ("cp %s", aopGet (AOP (right), offset, FALSE));
+ }
- {
- if (AOP_TYPE (right) == AOP_LIT)
- {
- lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
- /* optimize if(x < 0) or if(x >= 0) */
- if (lit == 0L)
- {
- if (!sign)
- {
- /* No sign so it's always false */
- _clearCarry();
- }
- else
- {
- /* Just load in the top most bit */
- _moveA (aopGet (AOP (left), AOP_SIZE (left) - 1, FALSE));
- if (!(AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result)) && ifx)
- {
- genIfxJump (ifx, "7");
- return;
- }
- else
- emit2 ("rlc a");
- }
- goto release;
- }
- }
-
- if (sign)
- {
- /* First setup h and l contaning the top most bytes XORed */
- bool fDidXor = FALSE;
- if (AOP_TYPE (left) == AOP_LIT)
- {
- unsigned long lit = (unsigned long)
- floatFromVal (AOP (left)->aopu.aop_lit);
- emit2 ("ld %s,!immedbyte", _fTmp[0],
- 0x80 ^ (unsigned int) ((lit >> ((size - 1) * 8)) & 0x0FFL));
- }
- else
- {
- emit2 ("ld a,%s", aopGet (AOP (left), size - 1, FALSE));
- emit2 ("xor a,!immedbyte", 0x80);
- emit2 ("ld %s,a", _fTmp[0]);
- fDidXor = TRUE;
- }
- if (AOP_TYPE (right) == AOP_LIT)
- {
- unsigned long lit = (unsigned long)
- floatFromVal (AOP (right)->aopu.aop_lit);
- emit2 ("ld %s,!immedbyte", _fTmp[1],
- 0x80 ^ (unsigned int) ((lit >> ((size - 1) * 8)) & 0x0FFL));
- }
- else
- {
- emit2 ("ld a,%s", aopGet (AOP (right), size - 1, FALSE));
- emit2 ("xor a,!immedbyte", 0x80);
- emit2 ("ld %s,a", _fTmp[1]);
- fDidXor = TRUE;
- }
- }
- while (size--)
- {
- /* Do a long subtract */
- if (!sign || size)
- {
- _moveA (aopGet (AOP (left), offset, FALSE));
- }
- if (sign && size == 0)
- {
- emit2 ("ld a,%s", _fTmp[0]);
- emit2 ("%s a,%s", offset == 0 ? "sub" : "sbc", _fTmp[1]);
- }
- else
- {
- /* Subtract through, propagating the carry */
- emit2 ("%s a,%s", offset == 0 ? "sub" : "sbc", aopGet (AOP (right), offset, FALSE));
- offset++;
- }
- }
- }
+ {
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
+ /* optimize if(x < 0) or if(x >= 0) */
+ if (lit == 0L)
+ {
+ if (!sign)
+ {
+ /* No sign so it's always false */
+ _clearCarry();
+ }
+ else
+ {
+ /* Just load in the top most bit */
+ _moveA (aopGet (AOP (left), AOP_SIZE (left) - 1, FALSE));
+ if (!(AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result)) && ifx)
+ {
+ genIfxJump (ifx, "7");
+ return;
+ }
+ else
+ emit2 ("rlc a");
+ }
+ goto release;
+ }
+ }
+
+ if (sign)
+ {
+ /* First setup h and l contaning the top most bytes XORed */
+ bool fDidXor = FALSE;
+ if (AOP_TYPE (left) == AOP_LIT)
+ {
+ unsigned long lit = (unsigned long)
+ floatFromVal (AOP (left)->aopu.aop_lit);
+ emit2 ("ld %s,!immedbyte", _fTmp[0],
+ 0x80 ^ (unsigned int) ((lit >> ((size - 1) * 8)) & 0x0FFL));
+ }
+ else
+ {
+ emit2 ("ld a,%s", aopGet (AOP (left), size - 1, FALSE));
+ emit2 ("xor a,!immedbyte", 0x80);
+ emit2 ("ld %s,a", _fTmp[0]);
+ fDidXor = TRUE;
+ }
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ unsigned long lit = (unsigned long)
+ floatFromVal (AOP (right)->aopu.aop_lit);
+ emit2 ("ld %s,!immedbyte", _fTmp[1],
+ 0x80 ^ (unsigned int) ((lit >> ((size - 1) * 8)) & 0x0FFL));
+ }
+ else
+ {
+ emit2 ("ld a,%s", aopGet (AOP (right), size - 1, FALSE));
+ emit2 ("xor a,!immedbyte", 0x80);
+ emit2 ("ld %s,a", _fTmp[1]);
+ fDidXor = TRUE;
+ }
+ }
+ while (size--)
+ {
+ /* Do a long subtract */
+ if (!sign || size)
+ {
+ _moveA (aopGet (AOP (left), offset, FALSE));
+ }
+ if (sign && size == 0)
+ {
+ emit2 ("ld a,%s", _fTmp[0]);
+ emit2 ("%s a,%s", offset == 0 ? "sub" : "sbc", _fTmp[1]);
+ }
+ else
+ {
+ /* Subtract through, propagating the carry */
+ emit2 ("%s a,%s", offset == 0 ? "sub" : "sbc", aopGet (AOP (right), offset, FALSE));
+ offset++;
+ }
+ }
+ }
- {
- while (size--)
- {
- emit2 ("ld a,%s", aopGet (AOP (left), offset, FALSE));
- if ((AOP_TYPE (right) == AOP_LIT) && lit == 0)
- emit2 ("or a,a");
- else
- emit2 ("cp a,%s", aopGet (AOP (right), offset, FALSE));
- emit2 ("jp nz,!tlabel", lbl->key + 100);
- offset++;
- }
- }
+ {
+ while (size--)
+ {
+ emit2 ("ld a,%s", aopGet (AOP (left), offset, FALSE));
+ if ((AOP_TYPE (right) == AOP_LIT) && lit == 0)
+ emit2 ("or a,a");
+ else
+ emit2 ("cp a,%s", aopGet (AOP (right), offset, FALSE));
+ emit2 ("jp nz,!tlabel", lbl->key + 100);
+ offset++;
+ }
+ }
- {
- _moveA (aopGet (AOP (left), offset, FALSE));
- if ((AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) &&
- ((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0))
- /* PENDING */
- emit2 ("jp nz,!tlabel", lbl->key + 100);
- else
- {
- emit2 ("cp %s", aopGet (AOP (right), offset, FALSE));
- emit2 ("jp nz,!tlabel", lbl->key + 100);
- }
- offset++;
- }
+ {
+ _moveA (aopGet (AOP (left), offset, FALSE));
+ if ((AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) &&
+ ((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0))
+ /* PENDING */
+ emit2 ("jp nz,!tlabel", lbl->key + 100);
+ else
+ {
+ emit2 ("cp %s", aopGet (AOP (right), offset, FALSE));
+ emit2 ("jp nz,!tlabel", lbl->key + 100);
+ }
+ offset++;
+ }
- {
- tlbl = newiTempLabel (NULL);
- gencjneshort (left, right, tlbl);
- if (IC_TRUE (ifx))
- {
- emit2 ("jp !tlabel", IC_TRUE (ifx)->key + 100);
- emitLabel (tlbl->key + 100);
- }
- else
- {
- /* PENDING: do this better */
- symbol *lbl = newiTempLabel (NULL);
- emit2 ("!shortjp !tlabel", lbl->key + 100);
- emitLabel (tlbl->key + 100);
- emit2 ("jp !tlabel", IC_FALSE (ifx)->key + 100);
- emitLabel (lbl->key + 100);
- }
- }
+ {
+ tlbl = newiTempLabel (NULL);
+ gencjneshort (left, right, tlbl);
+ if (IC_TRUE (ifx))
+ {
+ emit2 ("jp !tlabel", IC_TRUE (ifx)->key + 100);
+ emitLabel (tlbl->key + 100);
+ }
+ else
+ {
+ /* PENDING: do this better */
+ symbol *lbl = newiTempLabel (NULL);
+ emit2 ("!shortjp !tlabel", lbl->key + 100);
+ emitLabel (tlbl->key + 100);
+ emit2 ("jp !tlabel", IC_FALSE (ifx)->key + 100);
+ emitLabel (lbl->key + 100);
+ }
+ }
- {
- 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
- {
- _moveA (aopGet (AOP (left), offset, FALSE));
- emit2 ("and a,%s",
- aopGet (AOP (right), offset, FALSE));
- aopPut (AOP (left), "a", offset);
- }
- }
-
- }
- else
- {
- if (AOP_TYPE (left) == AOP_ACC)
- {
- wassertl (0, "Tried to perform an AND where the left operand is allocated into A");
- }
- else
- {
- _moveA (aopGet (AOP (left), offset, FALSE));
- emit2 ("and a,%s",
- aopGet (AOP (right), offset, FALSE));
- aopPut (AOP (left), "a", 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
+ {
+ _moveA (aopGet (AOP (left), offset, FALSE));
+ emit2 ("and a,%s",
+ aopGet (AOP (right), offset, FALSE));
+ aopPut (AOP (left), "a", offset);
+ }
+ }
+
+ }
+ else
+ {
+ if (AOP_TYPE (left) == AOP_ACC)
+ {
+ wassertl (0, "Tried to perform an AND where the left operand is allocated into A");
+ }
+ else
+ {
+ _moveA (aopGet (AOP (left), offset, FALSE));
+ emit2 ("and a,%s",
+ aopGet (AOP (right), offset, FALSE));
+ aopPut (AOP (left), "a", offset);
+ }
+ }
+ }
- {
- 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),
- 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)
- emit2 ("and a,%s", aopGet (AOP (right), offset, FALSE));
- else
- {
- _moveA (aopGet (AOP (left), offset, FALSE));
- emit2 ("and a,%s",
- aopGet (AOP (right), offset, FALSE));
- }
- aopPut (AOP (result), "a", offset);
- }
- }
+ {
+ 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),
+ 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)
+ emit2 ("and a,%s", aopGet (AOP (right), offset, FALSE));
+ else
+ {
+ _moveA (aopGet (AOP (left), offset, FALSE));
+ emit2 ("and a,%s",
+ aopGet (AOP (right), offset, FALSE));
+ }
+ aopPut (AOP (result), "a", offset);
+ }
+ }
- {
- if (AOP_TYPE (right) == AOP_LIT)
- {
- if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
- continue;
- else
- {
- _moveA (aopGet (AOP (left), offset, FALSE));
- emit2 ("or a,%s",
- aopGet (AOP (right), offset, FALSE));
- aopPut (AOP (result), "a", offset);
- }
- }
- else
- {
- if (AOP_TYPE (left) == AOP_ACC)
- emit2 ("or a,%s", aopGet (AOP (right), offset, FALSE));
- else
- {
- _moveA (aopGet (AOP (left), offset, FALSE));
- emit2 ("or a,%s",
- aopGet (AOP (right), offset, FALSE));
- aopPut (AOP (result), "a", offset);
- }
- }
- }
+ {
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
+ continue;
+ else
+ {
+ _moveA (aopGet (AOP (left), offset, FALSE));
+ emit2 ("or a,%s",
+ aopGet (AOP (right), offset, FALSE));
+ aopPut (AOP (result), "a", offset);
+ }
+ }
+ else
+ {
+ if (AOP_TYPE (left) == AOP_ACC)
+ emit2 ("or a,%s", aopGet (AOP (right), offset, FALSE));
+ else
+ {
+ _moveA (aopGet (AOP (left), offset, FALSE));
+ emit2 ("or a,%s",
+ aopGet (AOP (right), offset, FALSE));
+ aopPut (AOP (result), "a", offset);
+ }
+ }
+ }
- 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),
- offset);
- continue;
- }
- }
- // faster than result <- left, anl result,right
- // and better if result is SFR
- if (AOP_TYPE (left) == AOP_ACC)
- emit2 ("or a,%s", aopGet (AOP (right), offset, FALSE));
- else
- {
- _moveA (aopGet (AOP (left), offset, FALSE));
- emit2 ("or a,%s",
- aopGet (AOP (right), offset, FALSE));
- }
- aopPut (AOP (result), "a", offset);
- /* PENDING: something weird is going on here. Add exception. */
- if (AOP_TYPE (result) == AOP_ACC)
- break;
- }
+ 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),
+ offset);
+ continue;
+ }
+ }
+ // faster than result <- left, anl result,right
+ // and better if result is SFR
+ if (AOP_TYPE (left) == AOP_ACC)
+ emit2 ("or a,%s", aopGet (AOP (right), offset, FALSE));
+ else
+ {
+ _moveA (aopGet (AOP (left), offset, FALSE));
+ emit2 ("or a,%s",
+ aopGet (AOP (right), offset, FALSE));
+ }
+ aopPut (AOP (result), "a", offset);
+ /* PENDING: something weird is going on here. Add exception. */
+ if (AOP_TYPE (result) == AOP_ACC)
+ break;
+ }
- {
- if (AOP_TYPE (right) == AOP_LIT)
- {
- if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
- continue;
- else
- {
- _moveA (aopGet (AOP (left), offset, FALSE));
- emit2 ("xor a,%s",
- aopGet (AOP (right), offset, FALSE));
- aopPut (AOP (result), "a", offset);
- }
- }
- else
- {
- if (AOP_TYPE (left) == AOP_ACC)
+ {
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ if (((lit >> (offset * 8)) & 0x0FFL) == 0x00L)
+ continue;
+ else
+ {
+ _moveA (aopGet (AOP (left), offset, FALSE));
+ emit2 ("xor a,%s",
+ aopGet (AOP (right), offset, FALSE));
+ aopPut (AOP (result), "a", offset);
+ }
+ }
+ else
+ {
+ if (AOP_TYPE (left) == AOP_ACC)
- 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),
- offset);
- continue;
- }
- }
- // faster than result <- left, anl result,right
- // and better if result is SFR
- if (AOP_TYPE (left) == AOP_ACC)
+ 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),
+ offset);
+ continue;
+ }
+ }
+ // faster than result <- left, anl result,right
+ // and better if result is SFR
+ if (AOP_TYPE (left) == AOP_ACC)
- /* Left is already in result - so now do the shift */
- if (shCount > 1)
- {
- emit2 ("ld a,!immedbyte+1", shCount);
- emit2 ("!shortjp !tlabel", tlbl1->key + 100);
- emitLabel (tlbl->key + 100);
- }
-
- while (size--)
- {
- l = aopGet (AOP (result), offset, FALSE);
-
- if (offset == 0)
- {
- emit2 ("sla %s", l);
- }
- else
- {
- emit2 ("rl %s", l);
- }
-
- offset++;
- }
- if (shCount > 1)
- {
- emitLabel (tlbl1->key + 100);
- emit2 ("dec a");
- emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
- }
+ /* Left is already in result - so now do the shift */
+ if (shCount > 1)
+ {
+ emit2 ("ld a,!immedbyte+1", shCount);
+ emit2 ("!shortjp !tlabel", tlbl1->key + 100);
+ emitLabel (tlbl->key + 100);
+ }
+
+ while (size--)
+ {
+ l = aopGet (AOP (result), offset, FALSE);
+
+ if (offset == 0)
+ {
+ emit2 ("sla %s", l);
+ }
+ else
+ {
+ emit2 ("rl %s", l);
+ }
+
+ offset++;
+ }
+ if (shCount > 1)
+ {
+ emitLabel (tlbl1->key + 100);
+ emit2 ("dec a");
+ emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
+ }
- {
- if (shCount)
- {
- movLeft2Result (left, LSB, result, MSB16, 0);
- aopPut (AOP (result), "!zero", 0);
- shiftL1Left2Result (left, LSB, result, MSB16, shCount);
- }
- else
- {
- movLeft2Result (left, LSB, result, MSB16, 0);
- aopPut (AOP (result), "!zero", 0);
- }
- }
+ {
+ if (shCount)
+ {
+ movLeft2Result (left, LSB, result, MSB16, 0);
+ aopPut (AOP (result), "!zero", 0);
+ shiftL1Left2Result (left, LSB, result, MSB16, shCount);
+ }
+ else
+ {
+ movLeft2Result (left, LSB, result, MSB16, 0);
+ aopPut (AOP (result), "!zero", 0);
+ }
+ }
- {
- case 1:
- genrshOne (result, left, shCount, sign);
- break;
- case 2:
- genrshTwo (result, left, shCount, sign);
- break;
- case 4:
- wassertl (0, "Asked to shift right a long which should be a function call");
- break;
- default:
- wassertl (0, "Entered default case in right shift delegate");
- }
+ {
+ case 1:
+ genrshOne (result, left, shCount, sign);
+ break;
+ case 2:
+ genrshTwo (result, left, shCount, sign);
+ break;
+ case 4:
+ wassertl (0, "Asked to shift right a long which should be a function call");
+ break;
+ default:
+ wassertl (0, "Entered default case in right shift delegate");
+ }
- {
- /* PENDING: make this better */
- if (!IS_GB && AOP_TYPE (result) == AOP_REG)
- {
- aopPut (AOP (result), "!*hl", offset++);
- }
- else
- {
- emit2 ("ld a,!*pair", _pairs[pair].name);
- aopPut (AOP (result), "a", offset++);
- }
- if (size)
- {
- emit2 ("inc %s", _pairs[pair].name);
- _G.pairs[pair].offset++;
- }
- }
+ {
+ /* PENDING: make this better */
+ if (!IS_GB && AOP_TYPE (result) == AOP_REG)
+ {
+ aopPut (AOP (result), "!*hl", offset++);
+ }
+ else
+ {
+ emit2 ("ld a,!*pair", _pairs[pair].name);
+ aopPut (AOP (result), "a", offset++);
+ }
+ if (size)
+ {
+ emit2 ("inc %s", _pairs[pair].name);
+ _G.pairs[pair].offset++;
+ }
+ }
- {
- aopPut (AOP (result), "!*hl", offset++);
- }
- else
- {
- emit2 ("ld a,!*pair", _pairs[pair].name);
- aopPut (AOP (result), "a", offset++);
- }
- if (size)
- {
- emit2 ("inc %s", _pairs[pair].name);
- _G.pairs[pair].offset++;
- }
- }
+ {
+ aopPut (AOP (result), "!*hl", offset++);
+ }
+ else
+ {
+ emit2 ("ld a,!*pair", _pairs[pair].name);
+ aopPut (AOP (result), "a", offset++);
+ }
+ if (size)
+ {
+ emit2 ("inc %s", _pairs[pair].name);
+ _G.pairs[pair].offset++;
+ }
+ }
- operand * right,
- int pair,
- iCode *ic)
-{
- int offset = 0; /* source byte offset */
- int rlen = 0; /* remaining bitfield length */
- int blen; /* bitfield length */
- int bstr; /* bitfield starting bit within byte */
- int litval; /* source literal value (if AOP_LIT) */
- unsigned char mask; /* bitmask within current byte */
- int extraPair; /* a tempory register */
- bool needPopExtra=0; /* need to restore original value of temp reg */
+ operand * right,
+ int pair,
+ iCode *ic)
+{
+ int offset = 0; /* source byte offset */
+ int rlen = 0; /* remaining bitfield length */
+ int blen; /* bitfield length */
+ int bstr; /* bitfield starting bit within byte */
+ int litval; /* source literal value (if AOP_LIT) */
+ unsigned char mask; /* bitmask within current byte */
+ int extraPair; /* a tempory register */
+ bool needPopExtra=0; /* need to restore original value of temp reg */
- {
- const char *l = aopGet (AOP (right), offset, FALSE);
- if (isRegOrLit (AOP (right)) && !IS_GB)
- {
- emit2 ("ld !*pair,%s", _pairs[PAIR_HL].name, l);
- }
- else
- {
- _moveA (l);
- emit2 ("ld !*pair,a", _pairs[PAIR_HL].name);
- }
- if (size)
- {
- emit2 ("inc %s", _pairs[PAIR_HL].name);
- _G.pairs[PAIR_HL].offset++;
- }
- offset++;
- }
+ {
+ const char *l = aopGet (AOP (right), offset, FALSE);
+ if (isRegOrLit (AOP (right)) && !IS_GB)
+ {
+ emit2 ("ld !*pair,%s", _pairs[PAIR_HL].name, l);
+ }
+ else
+ {
+ _moveA (l);
+ emit2 ("ld !*pair,a", _pairs[PAIR_HL].name);
+ }
+ if (size)
+ {
+ emit2 ("inc %s", _pairs[PAIR_HL].name);
+ _G.pairs[PAIR_HL].offset++;
+ }
+ offset++;
+ }
- {
- const char *l = aopGet (AOP (right), offset, FALSE);
- if (isRegOrLit (AOP (right)) && !IS_GB)
- {
- emit2 ("ld !*pair,%s", _pairs[pairId].name, l);
- }
- else
- {
- _moveA (l);
- emit2 ("ld !*pair,a", _pairs[pairId].name);
- }
- if (size)
- {
- emit2 ("inc %s", _pairs[pairId].name);
- _G.pairs[pairId].offset++;
- }
- offset++;
- }
+ {
+ const char *l = aopGet (AOP (right), offset, FALSE);
+ if (isRegOrLit (AOP (right)) && !IS_GB)
+ {
+ emit2 ("ld !*pair,%s", _pairs[pairId].name, l);
+ }
+ else
+ {
+ _moveA (l);
+ emit2 ("ld !*pair,a", _pairs[pairId].name);
+ }
+ if (size)
+ {
+ emit2 ("inc %s", _pairs[pairId].name);
+ _G.pairs[pairId].offset++;
+ }
+ offset++;
+ }
- {
- if ((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0)
- {
- if (!fXored && size > 1)
- {
- emit2 ("xor a,a");
- fXored = TRUE;
- }
- if (fXored)
- {
- aopPut (AOP (result), "a", offset);
- }
- else
- {
- aopPut (AOP (result), "!zero", offset);
- }
- }
- else
- aopPut (AOP (result),
- aopGet (AOP (right), offset, FALSE),
- offset);
- offset++;
- }
+ {
+ if ((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0)
+ {
+ if (!fXored && size > 1)
+ {
+ emit2 ("xor a,a");
+ fXored = TRUE;
+ }
+ if (fXored)
+ {
+ aopPut (AOP (result), "a", offset);
+ }
+ else
+ {
+ aopPut (AOP (result), "!zero", offset);
+ }
+ }
+ else
+ aopPut (AOP (result),
+ aopGet (AOP (right), offset, FALSE),
+ offset);
+ offset++;
+ }
- {
- /* PENDING: do this check better */
- if (IS_GB && requiresHL (AOP (right)) && requiresHL (AOP (result)))
- {
- _moveA (aopGet (AOP (right), offset, FALSE));
- aopPut (AOP (result), "a", offset);
- }
- else
- aopPut (AOP (result),
- aopGet (AOP (right), offset, FALSE),
- offset);
- offset++;
- }
+ {
+ /* PENDING: do this check better */
+ if (IS_GB && requiresHL (AOP (right)) && requiresHL (AOP (result)))
+ {
+ _moveA (aopGet (AOP (right), offset, FALSE));
+ aopPut (AOP (result), "a", offset);
+ }
+ else
+ aopPut (AOP (result),
+ aopGet (AOP (right), offset, FALSE),
+ offset);
+ offset++;
+ }
+/*-----------------------------------------------------------------*/
+/* genCritical - generate code for start of a critical sequence */
+/*-----------------------------------------------------------------*/
+static void
+genCritical (iCode *ic)
+{
+ symbol *tlbl = newiTempLabel (NULL);
+
+ if (IS_GB)
+ {
+ emit2 ("!di");
+ }
+ else if (IC_RESULT (ic))
+ {
+ aopOp (IC_RESULT (ic), ic, TRUE, FALSE);
+ aopPut (AOP (IC_RESULT (ic)), "!zero", 0);
+ //get interrupt enable flag IFF2 into P/O
+ emit2 ("ld a,i");
+ //disable interrupt
+ emit2 ("!di");
+ //parity odd <==> P/O=0 <==> interrupt enable flag IFF2=0
+ emit2 ("jp po,!tlabel", tlbl->key + 100);
+ aopPut (AOP (IC_RESULT (ic)), "!one", 0);
+ emit2 ("!tlabeldef", (tlbl->key + 100));
+ freeAsmop (IC_RESULT (ic), NULL, ic);
+ }
+ else
+ {
+ //get interrupt enable flag IFF2 into P/O
+ emit2 ("ld a,i");
+ //disable interrupt
+ emit2 ("!di");
+ //save P/O flag
+ emit2 ("push af");
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* genEndCritical - generate code for end of a critical sequence */
+/*-----------------------------------------------------------------*/
+static void
+genEndCritical (iCode *ic)
+{
+ symbol *tlbl = newiTempLabel (NULL);
+
+ if (IS_GB)
+ {
+ emit2 ("!ei");
+ }
+ else if (IC_RIGHT (ic))
+ {
+ aopOp (IC_RIGHT (ic), ic, FALSE, TRUE);
+ _toBoolean (IC_RIGHT (ic));
+ //don't enable interrupts if they were off before
+ emit2 ("!shortjp z,!tlabel", tlbl->key + 100);
+ emit2 ("!ei");
+ emitLabel (tlbl->key + 100);
+ freeAsmop (IC_RIGHT (ic), NULL, ic);
+ }
+ else
+ {
+ //restore P/O flag
+ emit2 ("pop af");
+ //parity odd <==> P/O=0 <==> interrupt enable flag IFF2 was 0 <==>
+ //don't enable interrupts as they were off before
+ emit2 ("jp po,!tlabel", tlbl->key + 100);
+ emit2 ("!ei");
+ emit2 ("!tlabeldef", (tlbl->key + 100));
+ }
+}
+
- {
- if (options.debug)
- {
- debugFile->writeCLine (ic);
- }
- if (!options.noCcodeInAsm) {
- emit2 (";%s:%d: %s", ic->filename, ic->lineno,
- printCLine(ic->filename, ic->lineno));
- }
- cln = ic->lineno;
- }
- if (options.iCodeInAsm) {
- emit2 (";ic:%d: %s", ic->key, printILine(ic));
- }
+ {
+ if (options.debug)
+ {
+ debugFile->writeCLine (ic);
+ }
+ if (!options.noCcodeInAsm)
+ {
+ emit2 (";%s:%d: %s", ic->filename, ic->lineno,
+ printCLine(ic->filename, ic->lineno));
+ }
+ cln = ic->lineno;
+ }
+ if (options.iCodeInAsm)
+ {
+ emit2 (";ic:%d: %s", ic->key, printILine(ic));
+ }
- {
- case '!':
- emitDebug ("; genNot");
- genNot (ic);
- break;
-
- case '~':
- emitDebug ("; genCpl");
- genCpl (ic);
- break;
-
- case UNARYMINUS:
- emitDebug ("; genUminus");
- genUminus (ic);
- break;
-
- case IPUSH:
- emitDebug ("; genIpush");
- genIpush (ic);
- break;
-
- case IPOP:
- /* IPOP happens only when trying to restore a
- spilt live range, if there is an ifx statement
- following this pop then the if statement might
- be using some of the registers being popped which
- would destory the contents of the register so
- we need to check for this condition and handle it */
- if (ic->next &&
- ic->next->op == IFX &&
- regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
- {
+ {
+ case '!':
+ emitDebug ("; genNot");
+ genNot (ic);
+ break;
+
+ case '~':
+ emitDebug ("; genCpl");
+ genCpl (ic);
+ break;
+
+ case UNARYMINUS:
+ emitDebug ("; genUminus");
+ genUminus (ic);
+ break;
+
+ case IPUSH:
+ emitDebug ("; genIpush");
+ genIpush (ic);
+ break;
+
+ case IPOP:
+ /* IPOP happens only when trying to restore a
+ spilt live range, if there is an ifx statement
+ following this pop then the if statement might
+ be using some of the registers being popped which
+ would destory the contents of the register so
+ we need to check for this condition and handle it */
+ if (ic->next &&
+ ic->next->op == IFX &&
+ regsInCommon (IC_LEFT (ic), IC_COND (ic->next)))
+ {
- genIfx (ic->next, ic);
- }
- else
- {
- emitDebug ("; genIpop");
- genIpop (ic);
- }
- break;
-
- case CALL:
- emitDebug ("; genCall");
- genCall (ic);
- break;
-
- case PCALL:
- emitDebug ("; genPcall");
- genPcall (ic);
- break;
-
- case FUNCTION:
- emitDebug ("; genFunction");
- genFunction (ic);
- break;
-
- case ENDFUNCTION:
- emitDebug ("; genEndFunction");
- genEndFunction (ic);
- break;
-
- case RETURN:
- emitDebug ("; genRet");
- genRet (ic);
- break;
-
- case LABEL:
- emitDebug ("; genLabel");
- genLabel (ic);
- break;
-
- case GOTO:
- emitDebug ("; genGoto");
- genGoto (ic);
- break;
-
- case '+':
- emitDebug ("; genPlus");
- genPlus (ic);
- break;
-
- case '-':
- emitDebug ("; genMinus");
- genMinus (ic);
- break;
-
- case '*':
- emitDebug ("; genMult");
- genMult (ic);
- break;
-
- case '/':
- emitDebug ("; genDiv");
- genDiv (ic);
- break;
-
- case '%':
- emitDebug ("; genMod");
- genMod (ic);
- break;
-
- case '>':
- emitDebug ("; genCmpGt");
- genCmpGt (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
- case '<':
- emitDebug ("; genCmpLt");
- genCmpLt (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
- case LE_OP:
- case GE_OP:
- case NE_OP:
-
- /* note these two are xlated by algebraic equivalence
- during parsing SDCC.y */
- werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
- "got '>=' or '<=' shouldn't have come here");
- break;
-
- case EQ_OP:
- emitDebug ("; genCmpEq");
- genCmpEq (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
- case AND_OP:
- emitDebug ("; genAndOp");
- genAndOp (ic);
- break;
-
- case OR_OP:
- emitDebug ("; genOrOp");
- genOrOp (ic);
- break;
-
- case '^':
- emitDebug ("; genXor");
- genXor (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
- case '|':
- emitDebug ("; genOr");
- genOr (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
- case BITWISEAND:
- emitDebug ("; genAnd");
- genAnd (ic, ifxForOp (IC_RESULT (ic), ic));
- break;
-
- case INLINEASM:
- emitDebug ("; genInline");
- genInline (ic);
- break;
-
- case RRC:
- emitDebug ("; genRRC");
- genRRC (ic);
- break;
-
- case RLC:
- emitDebug ("; genRLC");
- genRLC (ic);
- break;
-
- case GETHBIT:
- emitDebug ("; genGetHBIT");
- genGetHbit (ic);
+ genIfx (ic->next, ic);
+ }
+ else
+ {
+ emitDebug ("; genIpop");
+ genIpop (ic);
+ }
+ break;
+
+ case CALL:
+ emitDebug ("; genCall");
+ genCall (ic);
+ break;
+
+ case PCALL:
+ emitDebug ("; genPcall");
+ genPcall (ic);
+ break;
+
+ case FUNCTION:
+ emitDebug ("; genFunction");
+ genFunction (ic);
+ break;
+
+ case ENDFUNCTION:
+ emitDebug ("; genEndFunction");
+ genEndFunction (ic);
+ break;
+
+ case RETURN:
+ emitDebug ("; genRet");
+ genRet (ic);
+ break;
+
+ case LABEL:
+ emitDebug ("; genLabel");
+ genLabel (ic);
+ break;
+
+ case GOTO:
+ emitDebug ("; genGoto");
+ genGoto (ic);
+ break;
+
+ case '+':
+ emitDebug ("; genPlus");
+ genPlus (ic);
+ break;
+
+ case '-':
+ emitDebug ("; genMinus");
+ genMinus (ic);
- case LEFT_OP:
- emitDebug ("; genLeftShift");
- genLeftShift (ic);
- break;
-
- case RIGHT_OP:
- emitDebug ("; genRightShift");
- genRightShift (ic);
- break;
-
- case GET_VALUE_AT_ADDRESS:
- emitDebug ("; genPointerGet");
- genPointerGet (ic);
- break;
-
- case '=':
-
- if (POINTER_SET (ic))
- {
- emitDebug ("; genAssign (pointer)");
- genPointerSet (ic);
- }
- else
- {
- emitDebug ("; genAssign");
- genAssign (ic);
- }
- break;
-
- case IFX:
+ case '*':
+ emitDebug ("; genMult");
+ genMult (ic);
+ break;
+
+ case '/':
+ emitDebug ("; genDiv");
+ genDiv (ic);
+ break;
+
+ case '%':
+ emitDebug ("; genMod");
+ genMod (ic);
+ break;
+
+ case '>':
+ emitDebug ("; genCmpGt");
+ genCmpGt (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
+ case '<':
+ emitDebug ("; genCmpLt");
+ genCmpLt (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
+ case LE_OP:
+ case GE_OP:
+ case NE_OP:
+
+ /* note these two are xlated by algebraic equivalence
+ during parsing SDCC.y */
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "got '>=' or '<=' shouldn't have come here");
+ break;
+
+ case EQ_OP:
+ emitDebug ("; genCmpEq");
+ genCmpEq (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
+ case AND_OP:
+ emitDebug ("; genAndOp");
+ genAndOp (ic);
+ break;
+
+ case OR_OP:
+ emitDebug ("; genOrOp");
+ genOrOp (ic);
+ break;
+
+ case '^':
+ emitDebug ("; genXor");
+ genXor (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
+ case '|':
+ emitDebug ("; genOr");
+ genOr (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
+ case BITWISEAND:
+ emitDebug ("; genAnd");
+ genAnd (ic, ifxForOp (IC_RESULT (ic), ic));
+ break;
+
+ case INLINEASM:
+ emitDebug ("; genInline");
+ genInline (ic);
+ break;
+
+ case RRC:
+ emitDebug ("; genRRC");
+ genRRC (ic);
+ break;
+
+ case RLC:
+ emitDebug ("; genRLC");
+ genRLC (ic);
+ break;
+
+ case GETHBIT:
+ emitDebug ("; genGetHBIT");
+ genGetHbit (ic);
+ break;
+
+ case LEFT_OP:
+ emitDebug ("; genLeftShift");
+ genLeftShift (ic);
+ break;
+
+ case RIGHT_OP:
+ emitDebug ("; genRightShift");
+ genRightShift (ic);
+ break;
+
+ case GET_VALUE_AT_ADDRESS:
+ emitDebug ("; genPointerGet");
+ genPointerGet (ic);
+ break;
+
+ case '=':
+
+ if (POINTER_SET (ic))
+ {
+ emitDebug ("; genAssign (pointer)");
+ genPointerSet (ic);
+ }
+ else
+ {
+ emitDebug ("; genAssign");
+ genAssign (ic);
+ }
+ break;
+
+ case IFX: