CMP and SUB instructions of ARM CPU.

CMP and SUB instructions of ARM CPU.

Post by HiSt » Sun, 17 May 2009 11:47:38


Hello!


Somewhere in the specifications of ARM CPUs
it states that CMP is like a SUB instruction
without register overwrite...

mov r0,0
mov r1,1
cmp r0,r1

As "cmp r0,r1" is equivalent to
"sub r0,r0,r1" (without writing r0)
and equivalent to "r0-r1"
then the Carry flag (C) should be set in this example,
but IT IS NOT, at least for the CMP instruction.

This means that the CS (Carry Set) and CC (Carry Clear)
condition codes must be interpreted inverted:
CC == "r0 unsigned lower than r1", (normally r0 > r1)
CS == "r0 unsigned higher or same than r1", (normally r0 <= r1)

This leads to weird condition codes for
comparing and branching, for people that
have been programming i86 and 68000.

Is this a specification fault of ARM?


Greetings!
H.Samso (thebitsclub.tripod.com)
 
 
 

CMP and SUB instructions of ARM CPU.

Post by Ben Aviso » Sun, 17 May 2009 21:17:29


[...]

It's not wrong, it's just different. ARM uses C as a NOT-borrow flag for
subtraction operations. Yes, it's different from some architectures, but
it's the same as others, notably the 6502 (which was the previous
architecture used by ARM's original designer, Acorn Computers).

This behaviour is also entirely consistent with ARM's RISC philosophy: when
the C flag is defined in this way, the only difference between ADC and SBC
is that the second source register is NOTted for SBC.

Ben

 
 
 

CMP and SUB instructions of ARM CPU.

Post by HiSt » Mon, 18 May 2009 01:08:58


> > mov 0,0 >>>> mov 1,1> > > cmp 0,r>
> [...> >> > This leads to weird condition codes fo> >> > comparing and branching, for people tha> >> > have been programming i86 and 68000>
> It's not wrong, it's just different. ARM uses C as a NOT-borrow flag fo>
> subtraction operations. Yes, it's different from some architectures, bu>
> it's the same as others, notably the 6502 (which was the previou>
> architecture used by ARM's original designer, Acorn Computers)>
> This behaviour is also entirely consistent with ARM's RISC philosophy: whe>
> the C flag is defined in this way, the only difference between ADC and SB>
> is that the second source register is NOTted for SBC>
> Ben


Then the specification would better state (in the next revision)
that it offers a Borrow (B) flag when using SUB, and that it is
a Carry (C) flag when using ADD. For unsigned, at least.

Because, when using ADD with the 2complement of the substractor,
and substractor is higher, the Carry is not set (Borrow). But if the
substractor is lower, and adding its 2complement, the carry is set
(Borrow).

Borrow is the inverted Carry:
<0 < r1: r0 + complement2(r1)> -> Carry Clear

You mean that when using SUB it negates the Carry,
very advanced. :)
Maybe it uses a complement2() and Add() the ARM processor, when
instructing a SUB.

Greetings,
H.Samso (thebitsclub.tripod.com)
 
 
 

CMP and SUB instructions of ARM CPU.

Post by Wilco Dijk » Mon, 18 May 2009 03:02:24


Basically the Carry flag is just the carry-out of the 32-bit adder (ie. bit 32).
There is no borrow flag or anything similar. The ARM-ARM explicitly states
that subtract is done by inverting the input and forcing the carry input flag to 1.
You're right that the meaning of that carry flag depends on the operation you've
done, after an add it gives you unsigned overflow, after subtract it tells you
which operand is larger. If you use CC/CS for add, and LO/HI/LS/HS for sub
then you can avoid having to think about the details...


All ALUs use ones-complement and set the carry-in to implement subtract.
This is almost the same as your complement2() except when both operands
are zero (0 + 0 gives carry clear, 0 - 0 gives carry set).

Wilco