From: dseal@armltd.co.uk (David Seal) Subject: Doing comparisons correctly (was square roots) Date: 26 Nov 91 19:49:10 GMT In article <1991Nov22.104626.8428@odin.diku.dk> torbenm@diku.dk (Torben AEgidius Mogensen) writes: >Also, my ARM code used unsigned numbers but compared them as if they >were signed (using PL). Comparison of unsigned numbers requires HS. Oops. Yes, comparison of unsigned numbers should use HS/HI/LS/LO (note HS and LO are other names for CS and CC, by the way). But comparison of signed numbers should use GE/GT/LE/LT, not PL or MI!!! You should in general not use PL and MI after comparisons. They *can* be used after CMP Rn,#0, though GE and LT will do just as well. Comparing against any other value, PL and MI can produce misleading results. E.g. consider CMP Rn,#1. If Rn happens to contain the negative value &80000000, CMP Rn,#1 will set the condition flags according to the value &80000000-1 = &7FFFFFFF (giving a positive result - note there has been a signed overflow in this calculation). This means that it will clear the N flag, and code using PL/MI will decide that &80000000 >= 1 as a signed quantity! More generally, code using PL/MI will get the answer wrong whenever the implicit subtraction in the comparison suffers a signed overflow. The GE/GT/LE/LT conditions take into account the possibility of signed overflow and so don't get the answer wrong when it happens. When should you use PL/MI? Generally: (a) When you want to test the top bit of a value; (b) When you want to check the sign of a value without disturbing the C flag, TEQ Rn,#0 followed by use of PL/MI does the trick; (c) The one exception I know to the above rule about not using PL/MI after a comparison: if you're comparing two values of a steadily incrementing clock, and you're reasonably confident that they aren't more than 2^31-1 ticks apart, you should use PL/MI after a compare instruction. This sort of "cyclic comparison" is rather peculiar - for instance, you will find that &40000000 > 0, &80000000 > &40000000, &C0000000 > &80000000 and 0 > &C0000000. The normal rule that if a > b and b > c, then a > c does not apply to this type of comparison! This cyclic comparison should be used in programs manipulating interval timer values, in order to make certain they don't go wrong when the timer wraps round from positive to negative values. David Seal dseal@armltd.co.uk