In the ARM documentation here, it says that:
C
Set to 1 when the operation resulted in a carry, cleared to 0 otherwise.
and
A carry occurs:
... if the result of a subtraction is positive or zero ...
(Obviously the result has to be treated as a signed number; otherwise a carry would always occur with subtractions).
I know that the carry flag is "inverted" in ARM. Thus, if a subtraction requires a borrow, then the carry flag is not set even though a "carry" (ie unsigned underflow) did occur logically.
This makes sense for this scenario:
CMP 3,5
This will do 3-5. Since 3 < 5, unsigned underflow occurs and the carry flag would not be set in ARM. Using the logic in the ARM documentation, 3-5 results in -2, which is negative, so a carry doesn't occur and thus the carry flag is not set.
Now, according to the ARM documentation linked above, the LO (aka CC) condition code in ARM, which represents an "unsigned, lower" comparison, is true when the carry flag is not set in ARM (ie C == 0). Thus, for the example above, the LO condition code would be true. This makes sense too since 3 is lower than 5 when treating them both as unsigned numbers.
========
Now consider this scenario:
CMP -1,0
This will do -1-0, ie 0xffffffff - 0x00000000. Logically, since 0xffffffff > 0x00000000, no unsigned underflow occurs and the carry flag would be set.
But look at what the ARM documentation says:
A carry occurs:
... if the result of a subtraction is positive or zero ...
According to the documentation above, since -1-0 results in -1, which is negative, a carry doesn't occur and thus the carry flag is not set. But this means that the LO condition code is true, which means that -1 is lower than 0 when treating them both as unsigned numbers (just like how 3 was lower then 5 when we treated them both as unsigned numbers in the previous scenario). Obviously that's not true since 0xffffffff > 0x00000000.
How do I explain this contradiction when I'm trying to calculate the carry-flag logic based off of what the documentation is saying?
Your quote only makes sense if the input values are considered as unsigned, along with the full (33-bit) output. Note the the accompanying description refers to outputs larger than 2^32.