[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