This intrinsic inserts a NOP instruction or an
equivalent code sequence into the instruction stream.
The compiler does not optimize away the NOP instructions,
except for normal unreachable code elimination. One NOP instruction
is generated for each __nop intrinsic in the
source.
ARMv6 and previous architectures do not have a NOP instruction,
so the compiler generates a MOV r0,r0 instruction
instead.
In addition, __nop creates a special sequence
point that prevents operations with side effects from moving past
it under all circumstances. Normal sequence points allow operations
with side effects past if they do not affect program behavior. Operations
without side effects are not restricted by the intrinsic, and the
compiler can move them past the sequence point. The __schedule_barrier intrinsic
also creates this special sequence point, without inserting a NOP instruction.
Section 5.1.2.3 of the C standard defines operations with
side effects as those that change the state of the execution environment.
These operations:
In Example 13, given
this code, the compiler ensures that the read from the volatile
variable x is enclosed between two NOP instructions.
Example 13. Volatile access
volatile int x;
int z;
int read_variable(int y)
{
int i;
int a = 0;
__nop();
a = x;
__nop();
return z + y;
}
If the __nop intrinsics are removed, and
the compilation is performed at -O3 -Otime for --cpu=Cortex-M3,
for example, then the compiler can schedule the read of the non-volatile variable z to
be before the read of variable x.
In Example 14, given
this code, the compiler ensures that the write to variable z is
enclosed between two NOP instructions.
Example 14. Modifying memory location
int x;
int z;
int write_variable(int y)
{
int i;
for (i = 0; i < 10; i++)
{
__nop();
z = y;
__nop();
x += y;
}
return z;
}
In this case, if the __nop intrinsics are
removed, then with -O3 -Otime --cpu=Cortex-M3,
the compiler can fold away the loop.
In Example 15, because pure_func has
no side effects, the compiler can move the call to it to outside
of the loop. Still, the compiler ensures that the call to func is
enclosed between two NOP instructions.
Example 15. Calling a pure function
int func(int x);
int pure_func(int x) __pure;
int read(int x)
{
int i;
int a=0;
for (i=0; i<10; i++)
{
__nop();
a += pure_func(x) + func(x);
__nop();
}
return a;
}
Note
You can use the __schedule_barrier intrinsic
to insert a scheduling barrier without generating a NOP instruction.
In the examples above, the compiler would treat __schedule_barrier in
the same way as __nop.
Syntax
See also