3

I am having a problem with inline assembly with the IAR compiler for ARM, Cortex-M4. Here is a simple example of my problem; put the following code in a file, say, named test.c

void irqrestore(int flags)
{
  asm volatile(
      "tst    %0, #1\n"
      "bne    1f\n"
      "cpsie  i\n"
      "1:\n"
      :
      : "r" (flags)
      : "memory");
}

Now try compiling with IAR compiler:

$ iccarm --thumb test.c

   IAR ANSI C/C++ Compiler V6.40.2.53884/W32 for ARM
   Copyright 1999-2012 IAR Systems AB.

    asm volatile(
    ^
"C:\home\NuttX\nuttx\test.c",6  Error[Og010]: Inline assembler instruction
          does not have a unique size: "        bne    ?1_0"

Errors: 1
Warnings: none

Any ideas what is going wrong? If I change the "bne 1f\n" to "bne 1\n", it compiles fine, but I'm not sure if it is correct.

Bob
  • 587
  • 8
  • 17
  • 1
    The IAR compiler may not support [*numeric local labels*](https://sourceware.org/binutils/docs-2.20/as/Symbol-Names.html) as [tag:gas] does. Give the `1:` another name like `branch_around_int_disable:` and use `bne branch_around_int_disable`. If the IAR doesn't understand `1f`, means a *forward* numeric label, then your observed behavior makes sense. – artless noise May 21 '14 at 16:46
  • 2
    The IAR inline assembler syntax is greatly different from the GNU syntax. I don't believe they are compatible at all. http://stackoverflow.com/questions/13156795/gcc-inline-assembly-to-iar-inline-assembly is a related question, I believe. – rjp May 21 '14 at 17:04
  • an: No, a name like you suggested doesn't work, nor do either work when moving the label before the bne instruction. – Bob May 21 '14 at 17:40
  • RJP: Looked at that reference, but couldn't find any info there that works for this situation. Thanks anyways! – Bob May 21 '14 at 17:41
  • @RJP, recent versions of the IAR tools for ARM support GNU-style inline assembler. – Lindydancer May 23 '14 at 07:37
  • @Lindydancer Good to know. Do you know what version they started doing this in? – rjp May 27 '14 at 14:23

1 Answers1

3

Answer: From IAR, I was told (and have confirmed) that the following is the correct syntax:

  "bne.n  1f\n"

Or in context:

void irqrestore(int flags)
{
  asm volatile(
      "tst    %0, #1\n"
      "bne.n    1f\n"
      "cpsie  i\n"
      "1:\n"
      :
      : "r" (flags)
      : "memory");
}
Bob
  • 587
  • 8
  • 17
  • So, the IAR compiler's inline assembler is unable to determine the branch length. gcc-4.8 handles this with `gcc -mthumb -O3 -c foo.c -o foo.o` (and other options). There is no need to specify the specific branch type. – artless noise May 22 '14 at 15:04