ld a,e
or d
jr NZ,.divide ; Branch if divisor is non-zero
- ld bc,#0x00 ; Divide by zero error
- ld d,b
- ld e,c
+ ld b,d ; Divide by zero error: D=E=0
+ ld c,e
scf ; Set carry, invalid result
ret
.divide:
ld hl,#0
-; ld l,c ; L = low byte of dividend/quotient
-; ld h,b ; H = high byte of dividend/quotient
-; ld bc,#0x00 ; BC = remainder
- or a ; Clear carry to start
- ex af,af'
- ld a,#16 ; 16 bits in dividend
+ ld a,b
+ ld b,#16 ; 16 bits in dividend
.dvloop:
+ ;; Cleaned up on April 2009 by Marco Bodrato(http://bodrato.it/ )
;; Shift next bit of quotient into bit 0 of dividend
;; Shift next MSB of dividend into LSB of remainder
- ;; BC holds both dividend and quotient. While we shift a bit from
+ ;; AC holds both dividend and quotient. While we shift a bit from
;; MSB of dividend, we shift next bit of quotient in from carry
;; HL holds remainder
- ;; Do a 32-bit left shift, shifting carry to L, L to H,
- ;; H to C, C to B
- ex af,af'
+ ;; Do a 32-bit left shift, shifting carry to C, C to A,
+ ;; A to HL
rl c ; Carry (next bit of quotient) to bit 0
- rl b ; Clears carry since BC was 0
- adc hl,hl
+ rla
+ adc hl,hl ; HL < 32768 before, no carry, ever.
;; If remainder is >= divisor, next bit of quotient is 1. This
;; bit goes to carry
- push hl ; Save current remainder
sbc hl,de
-; ld a,c ; Substract divisor from remainder
-; sbc e
-; ld c,a
-; ld a,b
-; sbc d
-; ld b,a
+ jr NC,.nodrop ; Jump if remainder is >= dividend
+ add hl,de ; Otherwise, restore remainder
+ ;; The add above sets the carry, because sbc hl,de did set it.
+.nodrop:
ccf ; Complement borrow so 1 indicates a
; successful substraction (this is the
; next bit of quotient)
- jr C,.drop ; Jump if remainder is >= dividend
- pop hl ; Otherwise, restore remainder
- jr .nodrop
-.drop:
- inc sp
- inc sp
-.nodrop:
- ex af,af'
- dec a ; DEC does not affect carry flag
- jp NZ,.dvloop
- ex af,af'
+ djnz .dvloop
;; Shift last carry bit into quotient
- ld d,h ; DE = remainder
- ld e,l
- rl c ; Carry to L
-; ld c,l ; C = low byte of quotient
- rl b
-; ld b,h ; B = high byte of quotient
- or a ; Clear carry, valid result
+ ex de,hl ; DE = remainder, HL = divisor...
+ ;; HL does not contain remainder, it contains the divisor!
+ ; ld d,h ; DE = remainder
+ ; ld e,l
+ rl c ; Carry to C
+ rla
+ ld b,a ; BC = quotient
+ ;; Carry now contains the same value it contained before
+ ;; entering .dvloop[*]: "0" = valid result.
ret
{
if (pairId == PAIR_HL || pairId == PAIR_IY)
{
- if (_G.pairs[pairId].last_type == AOP_IMMD && left->type == AOP_IMMD)
+ if ((_G.pairs[pairId].last_type == AOP_IMMD && left->type == AOP_IMMD) ||
+ (_G.pairs[pairId].last_type == AOP_IY && left->type == AOP_IY))
{
if (_G.pairs[pairId].base && !strcmp (_G.pairs[pairId].base, base))
{
_G.pairs[pairId].last_type = aop->type;
}
+/* Can be used for local labels where Code generation takes care of spilling */
+static void
+emitLabelNoSpill (int key)
+{
+ emit2 ("!tlabeldef", key);
+ _G.lines.current->isLabel = 1;
+}
+
static void
emitLabel (int key)
{
emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
}
}
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
return TRUE;
}
{
emit2 ("!shortjp Z,!tlabel", tlbl->key + 100);
emit2 ("ld a,!one");
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
outAcc (result);
}
}
emit2 ("ld l,#0x00");
emit2 ("ld d,l");
emit2 ("ld b,#0x08");
- emitLabel (tlbl1->key + 100);
+ emitLabelNoSpill (tlbl1->key + 100);
emit2 ("add hl,hl");
emit2 ("jp NC,!tlabel", tlbl2->key + 100);
emit2 ("add hl,de");
- emitLabel (tlbl2->key + 100);
+ emitLabelNoSpill (tlbl2->key + 100);
emit2 ("djnz !tlabel", tlbl1->key + 100);
spillPair(PAIR_HL);
emit2 ("!shortjp !tlabel", tlbl->key + 100);
emitLabel (lbl->key + 100);
emit2 ("xor a,a");
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
_pop (pop);
}
{
_pop (pop);
emit2 ("jp !tlabel", IC_TRUE (ifx)->key + 100);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
_pop (pop);
}
else
symbol *lbl = newiTempLabel (NULL);
_pop (pop);
emit2 ("!shortjp !tlabel", lbl->key + 100);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
_pop (pop);
emit2 ("jp !tlabel", IC_FALSE (ifx)->key + 100);
- emitLabel (lbl->key + 100);
+ emitLabelNoSpill (lbl->key + 100);
}
}
/* mark the icode as generated */
_toBoolean (left);
emit2 ("!shortjp Z,!tlabel", tlbl->key + 100);
_toBoolean (right);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
outBitAcc (result);
}
_toBoolean (left);
emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
_toBoolean (right);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
outBitAcc (result);
}
{
symbol *nlbl = newiTempLabel (NULL);
emit2 ("jp !tlabel", nlbl->key + 100);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
emit2 ("jp !tlabel", IC_TRUE (ic)->key + 100);
- emitLabel (nlbl->key + 100);
+ emitLabelNoSpill (nlbl->key + 100);
}
else
{
emit2 ("jp !tlabel", IC_FALSE (ic)->key + 100);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
}
ic->generated = 1;
}
{
emit2 ("ld a,!immedbyte", shCount);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
emitRsh2 (AOP (result), size, is_signed);
{
emit2 ("ld a,!immedbyte+1", shCount);
emit2 ("!shortjp !tlabel", tlbl1->key + 100);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
}
while (size--)
}
if (shCount > 1)
{
- emitLabel (tlbl1->key + 100);
+ emitLabelNoSpill (tlbl1->key + 100);
emit2 ("dec a");
emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
}
_pop (PAIR_AF);
emit2 ("!shortjp !tlabel", tlbl1->key + 100);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
l = aopGet (AOP (result), offset, FALSE);
while (size--)
}
offset++;
}
- emitLabel (tlbl1->key + 100);
+ emitLabelNoSpill (tlbl1->key + 100);
emit2 ("dec a");
emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
_pop (PAIR_AF);
emit2 ("!shortjp !tlabel", tlbl1->key + 100);
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
while (size--)
{
l = aopGet (AOP (result), offset--, FALSE);
emit2 ("rr %s", l);
}
}
- emitLabel (tlbl1->key + 100);
+ emitLabelNoSpill (tlbl1->key + 100);
emit2 ("dec a");
emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100);
emit2 ("bit %d,a", blen - 1);
emit2 ("jp Z,!tlabel", tlbl->key + 100);
emit2 ("or a,!immedbyte", (unsigned char) (0xff << blen));
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
}
aopPut (AOP (result), "a", offset++);
goto finish;
emit2 ("bit %d,a", blen - 1 - 8);
emit2 ("jp Z,!tlabel", tlbl->key + 100);
emit2 ("or a,!immedbyte", (unsigned char) (0xff << (blen - 8)));
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
}
emit2 ("ld h,a");
spillPair (PAIR_HL);
emit2 ("bit %d,a", rlen - 1);
emit2 ("jp Z,!tlabel", tlbl->key + 100);
emit2 ("or a,!immedbyte", (unsigned char) (0xff << rlen));
- emitLabel (tlbl->key + 100);
+ emitLabelNoSpill (tlbl->key + 100);
}
aopPut (AOP (result), "a", offset++);
}