Hice algunas pruebas con gcc 4.5.2 (construido con LTO). Si puedo compilar este código:
static inline void __DMB(void) { asm volatile ("dmb"); }
static inline void __DMB2(void) { asm volatile ("dmb" ::: "memory"); }
char x;
char test1 (void)
{
x = 15;
return x;
}
char test2 (void)
{
x = 15;
__DMB();
return x;
}
char test3 (void)
{
x = 15;
__DMB2();
return x;
}
usando arm-none-eabi-gcc -Os -mcpu=cortex-m3 -mthumb -c dmb.c
, a continuación, a partir arm-none-eabi-objdump -d dmb.o
me sale esto:
00000000 <test1>:
0: 4b01 ldr r3, [pc, #4] ; (8 <test1+0x8>)
2: 200f movs r0, #15
4: 7018 strb r0, [r3, #0]
6: 4770 bx lr
8: 00000000 .word 0x00000000
0000000c <test2>:
c: 4b02 ldr r3, [pc, #8] ; (18 <test2+0xc>)
e: 200f movs r0, #15
10: 7018 strb r0, [r3, #0]
12: f3bf 8f5f dmb sy
16: 4770 bx lr
18: 00000000 .word 0x00000000
0000001c <test3>:
1c: 4b03 ldr r3, [pc, #12] ; (2c <test3+0x10>)
1e: 220f movs r2, #15
20: 701a strb r2, [r3, #0]
22: f3bf 8f5f dmb sy
26: 7818 ldrb r0, [r3, #0]
28: 4770 bx lr
2a: bf00 nop
2c: 00000000 .word 0x00000000
Es obvio que __DBM()
sólo se inserta la instrucción dmb
y se tarda DMB2()
a la fuerza en realidad el compilador purgar los valores almacenados en caché en los registros.
Supongo que encontré un error CMSIS.
Buena pregunta. Tenga en cuenta que Linux utiliza el clobber 'memory': http://lxr.free-electrons.com/source/arch/arm/include/asm/system.h?v=2.6.39#L135 – ninjalj
@ninjalj: Gracias por el enlazar. (no apareció en google rápido) – jpc