asm volatile statement reordering
David Brown
david@westcontrol.com
Tue Oct 17 10:57:00 GMT 2017
On 17/10/17 12:04, Segher Boessenkool wrote:
> On Tue, Oct 17, 2017 at 11:13:36AM +0200, David Brown wrote:
>> My solution to this
>> particular ordering problem is:
>>
>> uint32_t status;
>> asm volatile ("mrs %0, PRIMASK" : "=r" (status) :: );
>> asm volatile ("cpsid i" :: "" (status) :);
>>
>> foo();
>>
>> asm volatile ("msr PRIMASK, %0" :: "r" (status) : );
>
> And that only works for you because you have foo() separately compiled.
> If it was inlined (say with LTO) its instructions could move anywhere.
> That is without changing a character in your source code; your program
> simply does not mean what you think it means.
>
Yes, I am aware of that. I am not fond of "this seems to work in all my
testing" solutions - but they are better than "I know for sure that this
sometimes does /not/ work" code!
If I knew for sure that the no-output assembly statement did not move
(with respect to volatiles), then the code here is as good as if /no/
volatile asm statements moved (with respect to volatiles). In either
case, with LTO or if foo() is in the same file, some or all of foo could
move around - everything except volatile accesses and code that depends
on them. That is always a potential problem, but there are ways around
that - making sure you have dependencies (possibly artificial ones),
using volatile, or the nuclear option of a memory clobber. Typically,
when writing macros for "enter_critical/exit_critical" you include
memory clobbers for safety and ease-of-use despite a possible additional
cost, but here I am trying to establish minimum requirements.
More information about the Gcc-help
mailing list