On Wed, Feb 2, 2011 at 11:04 AM, David Gilbert david.gilbert@linaro.org wrote:
On 2 February 2011 10:47, Dave Martin dave.martin@linaro.org wrote:
On Tue, Feb 1, 2011 at 12:33 PM, David Gilbert david.gilbert@linaro.org wrote:
Hi, What do people understand to be the expected semantics of IT blocks in the cases below, of which there has been some confusion in relation to a recent Qt issue.
The code in question had a sequence something like:
comparison IT... EQ blahEQ TEQ BEQ
The important bits here are that we have an IT EQ block and two special cases:
1) There is a TEQ in the IT block - are all comparisons in the block allowed and do their effects immediately take effect? As far as I can tell this is allowed and any flag changes are used straight away;
Yes; yes; and: you're right. This was a specific intention, since there was always a common idiom on ARM of sequences like this:
CMP r0, #1 CMPEQ r1, #2 CMPEQ r2, #3 BEQ ...
with the effect of "if(r0==1 && r1==2 && r2==3) ..."
2) There is a BEQ at the end of the IT block, as far as I can tell, as long as the destination of the BEQ is close it shouldn't make any difference if the BEQ is included in the IT block or not.
Again, I believe you're right. The assembler will generate different code, because the explicit conditional branch encodings are not allowed in IT blocks. But the assembler takes care of this for you:
00000000 <f>: 0: d001 beq.n 6 <g>
versus
2: bf08 it eq 4: e7ff beq.n 6 <g>
00000006 <g>:
Both snippets are equivalent, though as you say, with IT you can insert more code between the branch and its destination before the assembler will barf with a fixup overflow, because the unconditional branch encoding (e000..e7fff) has more bits to express the branch offset.
Thanks for the confirmation Dave.
The key things I'm aware of that you need to what out for with IT are:
* A few instructions (such as IT itself) are not allowed inside IT blocks. * branching into the middle of an IT block * only the last instruction in an IT block is allowed to be a branch (B{L}, B{L}X, LDR pc, LDM/POP ... {pc} etc.)
These result in undefined behaviour.
The compiler should never make these mistakes, but it could happen in hand-written assembler.
The assembler will often warn you about such cases, but be vigilant--- there are some it won't pick up at present.
Cheers ---Dave