Hi Richard,
Am I right in understanding that fsf's primary objection to -mimplicit-it is the resulting unpredictability of the size of the assembler output for asm blocks? Note that the assmbler output size is _already_ unpredictable: what about the variable size of Thumb-2 instructions already, and what about use of assembler directives such as:
#define nops(count) asm( \ ".rept " #count "\n\t" "nop\n\t" ".endr" \ )
Presumably this will defeat GCC's literal pool placement on any architecture which has literal pools. Indeed, we can come with an inexhaustible supply of such cases: it's an inevitable result of the separation between GCC and the assembler.
If for Thumb-2 I assume we already have a heuristic that attempts to count the number of instructions and predicts the maximum size of the asm block as n*4 bytes (where n is the instruction count), would it be feasible to estimate a bound of n*6 bytes if using -mimplicit-it? Or, do we dump the literal before the asm block to be on the safe side (and if so, why doesn't this work equally well when using -mimplicit-it?)
Re the suggestion that inline asm should be "fixed" to include explicit IT instructions, do you know a practical way to do this?
My concern is that with GCC -marm, the inline asm is passed as-is to be interpreted non-unified syntax (for backwards compatibility purposes), whereas with -march>=armv6t2 -mthumb, the asm is passed (again as-is) to be interpreted in unified syntax. But with explicit IT blocks, it's impossible to be compatible with both syntaxes if my understanding is correct: Am I right in thinking that current GNU as in non-unified syntax mode, and indeed legacy versions of the tools will treat the IT instructions as an error and barf? Can you think of a way of working round this?
The best I can think of right now is ghastly preprocessor stuff along the lines of
#ifdef __thumb__ /* or more correctly __thumb2__ ? */ #define __asm_it_generic(mnemonic,cond) #mnemonic " " #cond "\n\t" #else #define __asm_it_generic(mnemonic,cond) /* expands to nothing */ #endif
#define __it(cond) __asm_it_generic(it,cond) #define __ite(cond) __asm_it_generic(ite,cond)
/* ... */
asm( __it(eq) "moveq r0, #0\n\t" __ite(eq) "bleq func1\n\t" "blne func2\n\t" );
An alternative, if we are happy to "fix" source packages in a way which breaks building them with older tools, is to pass unified assembler assembler in unified syntax too. But that would require some work in the code gen backend for arm if I understand correctly. But it's a huge task to port everything and some upstream projects may not accept the changes at all. My concern is that without some transitional approach, there's simply too much existing code for this to be viable.
Do you know when unified assmbler support was introduced in fsf?
Cheers ---Dave