3

How does one insert a compiler level memory barrier using IAR embedded workbench for ARM? The equivalent in GCC would be asm volatile ("" : : : "memory")

The words barrier and fence are absent from the User Guide.

LogicG8
  • 1,767
  • 16
  • 26
  • AFAIK, IAR uses a GCC compiler. – Basile Starynkevitch Sep 10 '15 at 15:37
  • @BasileStarynkevitch: Good one! They have their own compiler! – too honest for this site Sep 10 '15 at 15:43
  • 1
    C11 `stdatomics` provide a standard way - called fences. Otherwise use the intrinsics, Any way you have to carefully select which barrier you need. – too honest for this site Sep 10 '15 at 15:45
  • 1
    @Olaf: I believe that IAR does not yet support C11 just C90 or C99 – LogicG8 Sep 10 '15 at 15:54
  • Too bad. So you are left with the CMSIS intrinsics. A better & more recent compiler/toolchain would be the better way. I can recommend gcc/binutils. – too honest for this site Sep 10 '15 at 15:57
  • If the compiler only knows a function's prototype, it *must* assume the function includes a memory barrier, and so it cannot reorder memory accesses around such a function. You can just declare an `extern void foo(void)` and define it in a different translation unit `void foo(void) {return;}`, provided you do not enable link-time optimizations. – EOF Sep 10 '15 at 15:57
  • @EOF That's not at all the same as having an actual memory barrier – Tom Tanner Sep 10 '15 at 15:58
  • @EOF: Barriers also affect the hardware. Also, your approach inhibits optimization, not to forget about poisoning the global name space. – too honest for this site Sep 10 '15 at 16:01
  • 1
    @TomTanner, Olaf: It's a compiler-barrier, same as the gcc-inline-assembly with memory clobber the OP posted. – EOF Sep 10 '15 at 16:02
  • @EOF: That is an interesting idea. I use opaque pointers so I do not want to lose LTO but combining that with a volatile function pointer could remedy that problem. Still it is not ideal. I may be stuck with an inline assembly DMB instruction – LogicG8 Sep 10 '15 at 16:40
  • You could potentially dynamically link this particular function. I'm not sure a volatile function pointer would actually be less overhead than a real memory barrier, considering the cost of indirect branches. – EOF Sep 10 '15 at 16:45
  • Hmm, "An example of how to use clobbered memory" on page 162 of the linked document looks rather familiar in terms of syntax. Given that it apparently treats memory clobbers similarly to GCC, I'd be somewhat surprised if a similar construct didn't also act as a code motion barrier in the same way. – Notlikethat Sep 10 '15 at 19:37
  • @rcgldr: You should read the corresponding documentation from ARM. Once there is DMA, of course. Then ther are some configurations, e.g. NVIC/interrupt vectors, etc. which require barriers. Not to talk about interrupt handlers and shared data-structures like semaphores, queues, etc. – too honest for this site Sep 11 '15 at 02:38
  • @LogicG8: if you need an instruction scheduling barrier, and doing an inline asm DMB also provides that guarantee, would an inline asm NOP not do the same without the load/store penalty? If not, the inline asm DMB might not be sufficient... – unixsmurf Sep 11 '15 at 23:44
  • @unixsmurf - My comments were a follow up to my comment / question asking if this was a multi-core setup. There's also the issue of DMA or memory mapped I/O, so I was trying to find out what issues the OP was concerned about. I've deleted my previous comments, and will delete this one later to get rid of the clutter. – rcgldr Sep 12 '15 at 03:02
  • @rcgldr: Thanks - I've deleted my comment, and will delete this one too later. – unixsmurf Sep 12 '15 at 10:18
  • @unixsmurf: I am going try using a NOP and check that the generated assembly looks correct. – LogicG8 Sep 12 '15 at 13:16

1 Answers1

2

You can use the same inline assembler as in gcc if your IAR-tools are new enough. To get the hardware effects you can try putting a DMB instruction in the inline assembler statement or simply use the __DMB() intrinsic function.

Manos Nikolaidis
  • 21,608
  • 12
  • 74
  • 82
PNY
  • 29
  • 3