ARM condition codes
| Meaning | Mnemonic | Prefix | Hex | Status Flags |
| Equal | eq | 0 0 0 0 | 0 | Z = 1 |
| Not Equal | ne | 0 0 0 1 | 1 | Z = 0 |
| Carry Set | cs | 0 0 1 0 | 2 | C = 1 |
| Carry Clear | cc | 0 0 1 1 | 3 | C = 0 |
| Unsigned Higher or Same | hs | 0 0 1 0 | 2 | C = 1 |
| Unsigned Lower | lo | 0 0 1 1 | 3 | C = 0 |
| Minus/Negative | mi | 0 1 0 0 | 4 | N = 1 |
| Plus/Positive or Zero | pl | 0 1 0 1 | 5 | N = 0 |
| Overflow | vs | 0 1 1 0 | 6 | V = 1 |
| No Overflow | vc | 0 1 1 1 | 7 | V = 0 |
| Unsigned Higher | hi | 1 0 0 0 | 8 | C = 1, Z = 0 |
| Unsigned Lower or Same | ls | 1 0 0 1 | 9 | C = 0, Z = 1 |
| Signed Greater than or Equal | ge | 1 0 1 0 | A | N = V |
| Signed Less than | lt | 1 0 1 1 | B | N != V |
| Signed Greater than | gt | 1 1 0 0 | C | Z = 0, N = V |
| Signed Less than or Equal | le | 1 1 0 1 | D | Z = 1, N != V |
| Always | al | 1 1 1 0 | E | |
| Never | nv | 1 1 1 1 | F | (deprecated) |
Note that cs === hs, likewise cc === lo, so don’t be too surprised should the disassembler/listing file show "the other one", though I’ll patch up what I can.
(I’ll favour hs and lo, to avoid the distraction of asking myself why is that condition code displayed as "condition code"?)
Condition codes apply to all ARM instructions (bar some exceptions noted below), which can significantly improve code density.
Examples
| Instruction | Description |
| cmp r0, 5 | if a=5 then fn(10) end if |
| moveq r0, 10 | |
| bleq fn | |
| cmp r0, 0 | r0 := iff(x<=0)?0:1) |
| movle r0, 0 | |
| movgt r0, 1 | |
| cmp r0, 'A' | if c='A' or c='B' then y = 1 end if |
| cmpne r0, 'B' | |
| moveq r1, 1 |
See also ARM branches.
Be aware that "never" is (quite fairly, tbh) considered a ripe picking ground by the ARM engineers for extending the opcode space. While I don’t (afaik) use or support any of the following you should take note that some "never" are co-opted, and this table will likely grow for newer chips:
| Unconditional Instructions | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| Change Processor State | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | imd | M | 0 | SBZ | A | I | F | 0 | mode | |||||||||||
| Set Endianness | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | SBZ | E | 0 | 0 | 0 | 0 | 0 | SBZ | ||||||||
| Cache Preload | 1 | 1 | 1 | 1 | 0 | 1 | X | 1 | U | 1 | 0 | 1 | Rn | 1 | 1 | 1 | 1 | addr_mode | ||||||||||||||
| Save Return State | 1 | 1 | 1 | 1 | 1 | 0 | 0 | P | U | 1 | W | 0 | 1 | 1 | 0 | 1 | SBZ | 0 | 1 | 0 | 1 | SBZ | mode | |||||||||
| Return From Exception | 1 | 1 | 1 | 1 | 1 | 0 | 0 | P | U | 0 | W | 1 | Rn | SBZ | 1 | 0 | 1 | 0 | SBZ | |||||||||||||
| Branch w/link & chng2thumb | 1 | 1 | 1 | 1 | 1 | 0 | 1 | H | 24-bit offset | |||||||||||||||||||||||
| Addnl coproc dbl reg xfer | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | L | Rn | Rd | cp_num | opcode | CRm | |||||||||||||||
| Addnl coproc reg transfer | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | opc1 | L | CRn | Rd | cp_num | opc2 | 1 | CRm | ||||||||||||||||
| Undefined Instruction | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x |
I now think one of those is the blx instruction, that I couldn’t find before....
I may in fact myself co-opt undefined as a "data hole marker", since I can embed a length in it and of course, like the data it signals, it would never actually be executed - as long as I can count things right, a simple ".word 0xFF00000n" should do it, you could even get all fancy and embed type and even name info, nothing to stop you daisy-chaining them or even created a doubly linked list...