[LLVMdev] Bug in ARM Thumb inline asm?

Richard Pennington rich at pennware.com
Tue Feb 10 13:10:15 PST 2015


I'm porting the musl C library to ARM Thumb. It looks like inline asm is 
failing in some cases. Here's one:

The lseek system call looks like this:
...
         off_t result;
         return syscall(SYS__llseek, fd, offset>>32, offset, &result, 
whence) ? -1 : result;
...

Which eventually goes through this macro:

static inline long __syscall5(long n, long a, long b, long c, long d, 
long e)
{
         register long r7 __asm__("r7") = n;
         register long r0 __asm__("r0") = a;
         register long r1 __asm__("r1") = b;
         register long r2 __asm__("r2") = c;
         register long r3 __asm__("r3") = d;
         register long r4 __asm__("r4") = e;
         __asm_syscall("r"(r7), "0"(r0), "r"(r1), "r"(r2), "r"(r3), 
"r"(r4));
}

And then this macro:
#define __asm_syscall(...) do { \
         __asm__ __volatile__ ( "svc 0" \
         : "=r"(r0) : __VA_ARGS__ : "memory"); \
         return r0; \
         } while (0)

Gives:
Disassembly of section .text:

00000000 <lseek>:
    0:   b590            push    {r4, r7, lr}
    2:   af01            add     r7, sp, #4
    4:   b083            sub     sp, #12
    6:   278c            movs    r7, #140        ; 0x8c
    8:   46ec            mov     ip, sp
    a:   4619            mov     r1, r3
    c:   68bc            ldr     r4, [r7, #8]    ; XXX r7 is clobbered here.
    e:   4663            mov     r3, ip
   10:   df00            svc     0
   12:   f7ff fffe       bl      0 <__syscall_ret>
   16:   9a00            ldr     r2, [sp, #0]
   18:   9901            ldr     r1, [sp, #4]
   1a:   2800            cmp     r0, #0
   1c:   bf1c            itt     ne
   1e:   f04f 32ff       movne.w r2, #4294967295 ; 0xffffffff
   22:   f04f 31ff       movne.w r1, #4294967295 ; 0xffffffff
   26:   4610            mov     r0, r2
   28:   b003            add     sp, #12
   2a:   bd90            pop     {r4, r7, pc}

The question is, does the line

register long r7 __asm__("r7") = n;

make any guarantee about the value of r7 in the asm block?

Adding the -fomit-frame-pointer flag fixes it, but is the bug in the 
code or in the compiler?

-Rich



More information about the llvm-dev mailing list