[llvm-dev] Inline ASM ARM syntax to load immediate values with integrated assembler

Peter Smith via llvm-dev llvm-dev at lists.llvm.org
Fri Aug 31 10:27:50 PDT 2018


Hello Emmanuel,

I've not been able to come up with anything that does exactly what you
want. I've put some comments inline.

On 31 August 2018 at 16:48, Emmanuel Blot via llvm-dev
<llvm-dev at lists.llvm.org> wrote:
> Hi,
>
> What would be the proper syntax in a C file, using inline assembly, to
> load a immediate value into an ARM register using clang & integrated
> assembler?
>

I don't think that there is a constraint that doesn't print the #. The
source code refers to a modifier 'c' that does not print the # however
that is rejected by clang. This was added very early on in the ARM
backend and there weren't any tests added so it is possible that it
has bitrotted. I'd be very happy to be proved wrong there.

If you can use constants directly then "ldr r0, =0x1234" will work. It
is possible although ugly to use macros such as:

void __attribute__((naked))
    foo(void)
    {
#define ASM(C) ASM_(C)
#define ASM_(C) \
       asm volatile ( \
          "ldr r0, =" #C "\n"\
          :\
          :\
          :\
          "r0"\
       );
       ASM(CONSTANT)
    }

There may be a much better way than that, but it is all I can think of
right now.

> The following syntax is rejected by LLVM:
>
>     // clang -target armv7em-none-eabi -mthumb
>
>     #define CONSTANT 0x1234
>
>     void __attribute__((naked))
>     foo(void)
>     {
>        asm volatile (
>           "ldr r0, =%0  \n"
>           :
>           :
>           "X" (CONSTANT)
>           :
>           "r0"
>        );
>     }
>
> “X” transforms the constant into a “#1234”, and LLVM does not seem to
> accept “=#1234” syntax. I think the proper syntax should be “ldr r0,
> =0x1234”, but I’ve been unable to find a constraint string that would
> emit the constant w/o the dash prefix.
>
> The “=%0” syntax is accepted by GCC - I’m not sure it is valid,
> although I’m still looking for a comprehensive reference document for
> such a syntax.
>

The ldr r0, = is a pseudo instruction originally implemented in armasm
I believe then in GNU as and then in the llvm integrated assembler.
Unfortunately the precise behaviour isn't written down and does vary
subtly between implementations. I think that it wouldn't be difficult
to change the assembly parser to optionally skip over the '#' as it
has to do that in several other places. May be worth a PR.

Peter

> “mov r0, %0” could work for small encodable value, but not for the
> whole 32-bit range where the pseudo-instruction “ldr r0, =constant" is
> required.
>
> Thanks.
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev


More information about the llvm-dev mailing list