On Thu, Apr 03, 2003 at 02:28:54AM +0100, Eddie Edwards wrote:
> Jay wrote:
>
> > I confirmed that this is does occur (at least in the VisualBoy emulator).
>
> Oh right an EMULATOR gives a result that doesn't match the ARM docs and
> that's confirmation of a problem with the ARM?! Gimme a break.
OK, I can't reproduce it now with the same conditions as before, so I
retract my complaint. If I investigate again, I will confirm on
actual hardware. It may well be that the emulator is wrong, in which
case I need to consider my development platform.
> Morten wrote:
>
> > of course this might very well be purely academic, but the result is still
> > incorrect regardless of how you turn it. ((0-0)+0+(c)) should never result
> > in 1. as for whether you can work around it, that is a different question.
> > but the fact is that the result is incorrect.
>
> You're simply labouring under a misunderstanding of how carry flags work.
> The only thing incorrect here is following SUBS with ADC. There is no
> meaning to this instruction sequence.
>
> Carry is only defined on ADD. SUB defines borrow, and borrow is mapped into
> the C flag one of two possible ways. To say that ((0-0)+0+(c)) even has
> *meaning* is to make an unwarranted assumption about how this mapping is
> done. Carry and borrow are two distinct concepts, and to treat them as the
> same in code is incorrect. It is your code that is wrong, *not* the CPU.
I agree that the SUBS,ADC sequence is unlikely and inconsequential.
I have no problem with how carry(borrow) works for multi-precision
arithmetic.
However it does confuse a programmer familiar with different
architectures to do:
MOV R0,#5
CMP R0,#10
and not have the carry set. Subtracting 10 from 5 should underflow.
I always view CMP as a subtract, and I am accustomed to underflow
setting carry. I have noticed before that I have to invert the
condition in a branch; BCS <=> BCC. I can live with that too. To
make the code more readable, I have adopted the habit of using BPL/BMI
for common compares unless I *really* need to test the carry. The
sign flag is consistent after addition and subtraction.
What I wonder about is the BHI/BLS instructions which test the carry
flag in combination. The manual says:
HI C set and Z clear Higher (unsigned <= )
LS C clear or Z set Lower or same (unsigned <= )
These HI/LS definitions are correct for a "carry-inverted-on-subtract"
machine, since CMP is a subtract. The above CMP should result in BLS
branch taken.
The problem is that BHI/BLS are incorrect after an addition. If you
do:
MOV R0,#5
ADDS R0,#10
The carry flag will be clear, and so a BLS will be taken. Since the
result is not "lower or same" it seems incorrect to me.
The moral is: only use BHI/BLS after a subtract or compare, not after
an addition. Also, the aliases for BCC/BCS: BLO/BHS are incorrect
after addition. If this were not a carry-inverted machine, these
branches would be correct after both addition and subtraction.
--
Jay Dresser /
jay
@
dresserfamily
.
org