I am having trouble wrapping my head around the functionality of the IT
instruction (if then). The quick reference card has this:
Operation: If-Then
Assembler:IT{pattern} {cond}
Action: Makes up to four following instructions conditional, according to pattern. pattern is a string of up to three letters. Each letter can be T (Then) or E (Else). The first instruction after IT has condition cond. The following instructions have condition cond if the corresponding letter is T, or the inverse of cond if the corresponding letter is E.
Actually, that synopsis makes a little bit of sense. The architecture manual entry didn't get me anywhere on the journey to understanding:
If-Then condition instruction.
SyntaxIT{x{y{z}}} cond
Where:
x
specifies the condition switch for the second instruction in the IT block.y
Specifies the condition switch for the third instruction in the IT block.z
Specifies the condition switch for the fourth instruction in the IT block.cond
Specifies the condition for the first instruction in the IT block.The condition switch for the second, third and fourth instruction in the IT block can be either:
T
Then. Applies the condition cond to the instruction.E
Else. Applies the inverse condition of cond to the instruction.Note
It is possible to use AL (the always condition) for cond in an IT instruction. If this is done, all of the instructions in the IT block must be unconditional, and each of x, y, and z must be T or omitted but not E. Operation
The IT instruction makes up to four following instructions conditional. The conditions can be all the same, or some of them can be the logical inverse of the others. The conditional instructions following the IT instruction form the IT block.
The instructions in the IT block, including any branches, must specify the condition in the {cond} part of their syntax.
Since (most) every instruction can easily specify a conditional, what good is the IT
instruction?
The MOV instruction copies the value of Operand2 into Rd . In certain circumstances, the assembler can substitute MVN for MOV , or MOV for MVN . Be aware of this when reading disassembly listings.
ARM and Thumb instructions can execute conditionally on the condition flags set by a previous instruction. The conditional instruction can occur either: Immediately after the instruction that updated the flags. After any number of intervening instructions that have not updated the flags.
Usage. The LDR pseudo-instruction is used for two main purposes: to generate literal constants when an immediate value cannot be moved into a register because it is out of range of the MOV and MVN instructions. to load a program-relative or external address into a register.
Condition codes In ARM state, you can use a condition code to control the execution of VFP instructions. The instruction is executed conditionally, according to the status flags in the APSR, in exactly the same way as almost all other ARM instructions.
First note that most instruction can specify a condition code in ARM instruction, not in Thumb.
With IT
instruction, you can specify condition code for up to 4 instructions. For each instruction, you specify if it's part of the If (T) or Else (E).
For example:
ITTET EQ
ADD r0,r0,r0
ADD r1,r0,r0
ADD r2,r0,r0
ADD r3,r0,r0
Will actually translate to:
ADDEQ r0,r0,r0 (Always if for 1st one)
ADDEQ r1,r0,r0 (T for 2nd one)
ADDNE r2,r0,r0 (E for 3rd one)
ADDEQ r3,r0,r0 (T for 4th one)
What IT
actually does is encode 8 bits of information into the ITSTATE
field of the CPSR very cleverly. The original Thumb instruction set had no conditional instructions except for branches, because there simply isn't room in 16 bits to fit a 4-bit condition code on top of enough opcode and operands to be useful. What the Thumb-2 extensions do is retrofit conditional execution to those existing 16-bit encodings, alongside the new 32-bit ones.
If you look at the ARM condition codes, you'll notice that the 3 most significant bits represent a particular flag test, and the lsb indicates either one interpretation or its exact opposite - originally even 0xF was a 'never' counterpart to 0xE's 'always' - so you can encode the base condition in 3 bits, and use the other 5 to encode which way the test should be evaluated for the next instruction plus a stop bit to indicate the number of instructions left to conditionalise. Thus, until it is consumed entirely, the ITSTATE value can be unpacked into an ARM condition code and fed into the pipeline right alongside Thumb instruction encodings being unpacked into their equivalent ARM instructions.
From an architecture perspective it's a really cool feature, although compiler engineers and CPU designers might disagree ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With