Re: Random failures while loading iwmmxt compiled binaries
Enrico Scholz <[email protected]>
| Newsgroups | gmane.linux.ports.arm.general |
|---|---|
| Message-ID | <[email protected]> |
Enrico Scholz <[email protected]> writes: > I have the problem that program loading segfaults sometimes or aborts > ... > * it is not a compiler bug > > * it is not a eglibc bug > > * it can be only the kernel (iwmmxt state not restored properly between > task switching?) or a bug in the silicon I was able to reproduce it in a non iwmmxt environment (ld.so + libc) by the attached program. Unfortunately, there is still a frequent loading of ELF binaries involved. In error case, the complete 16 wrX registers are zeroed although they were initialized by non-zero values. wcgrX seems to contain valid values. Steps to reproduce: $ arm-linux-gnueabi-gcc -O2 -g test.c ... create chroot in tmpfs on target ... ... cp a.out to /a in chroot ... # while /a | /a | /a | /a | /a | /a | /a | /a | /a | /a | /a; do : done PC is at 0x83c4 LR is at 0x84bc pc : [<000083c4>] lr : [<000084bc>] psr: 20000010 sp : be9b3cf4 ip : be9b3d10 fp : 00000000 r10: 00000000 r9 : 00000000 r8 : 00000000 r7 : 00000000 r6 : 00000012 r5 : 00000004 r4 : 00000000 r3 : 00000005 r2 : 000052ea r1 : 00000000 r0 : 00000012 Enrico _______________________________________________ linux-arm mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-arm
test.c
(application/octet-stream, 2.3 KB)
#include <stdlib.h>
size_t f(void)
{
#if 1
__asm__ __volatile__(
".arch iwmmxt\n"
"mov r0, #0\n"
"mov r1, #1\n"
"tmcrr wr1, r1, r0\n" /* wr1 = 1ull */
/* 'n = 0' */
"mov r3, #0\n"
/* 'masked = 0x12' */
"mov r6, #0x12\n"
"mov r7, #0\n"
/* while (masked) { ... */
"0:\n"
"orrs r0, r6, r7\n"
"beq 4f\n"
/* BUG_ON(n > 4) */
"cmp r3, #4\n"
"bls 1f\n"
"tmrc r5, wcgr0\n"
"tmrrc r8, r9, wr0\n"
"tmrrc r10, r11, wr1\n"
"strb r7, [r7]\n" /* *(char *)0 = 0 */
"1:\n"
/* 'masked >> n' */
"tmcr wcgr0, r3\n" /* wcgr0 = n */
"tmcrr wr0, r6, r7\n" /* wr0 = masked */
"wsrldg wr0, wr0, wcgr0\n" /* masked >> n */
"tmrrc r0, r1, wr0\n" /* (r0,r1) = masked >> n */
/* if ((masked >> n) & 0x01) { ... */
"and r0, r0, #1\n"
"cmp r0, #0\n"
"wslldg wr0, wr1, wcgr0\n" /* wr0 = 1ull << n */
"beq 3f\n"
/* masked ^= 1ull << n */
"tmrrc r0, r1, wr0\n" /* (r0,r1) = 1ull << n */
"eor r6, r6, r0\n"
"eor r7, r7, r1\n"
"3:\n"
"add r3, r3, #1\n" /* ++n */
"b 0b\n"
"4:\n" : : :
"r0", "r1", "r2", "r3", "r4", "r6", "r7");
return 2;
#else
uint64_t masked = a;
size_t n;
size_t m = 0;
for (n = 0; masked != 0; ++n) {
if ((masked & (1ULL << n)) != 0)
{
masked ^= 1ULL << n;
++m;
}
if (n > 4)
__asm__ __volatile__(
".arch iwmmxt\n"
"tmrrc r0, r1, wr10\n"
"tmrrc r2, r3, wr0\n"
"tmrrc r4, r5, wr1\n"
"mov r6, #0\n"
"strb r6, [r6]");
}
return m;
#endif
}
int main(int argc, char *argv[])
{
size_t i;
pid_t p = getpid();
int tmp;
__asm__ __volatile__(
".arch iwmmxt\n"
"tmcrr wr0, %0, %2\n"
"add %0, %0, #1\n"
"tmcrr wr1, %0, %2\n"
"add %0, %0, #1\n"
"tmcrr wr2, %0, %2\n"
"add %0, %0, #1\n"
"tmcrr wr3, %0, %2\n"
"add %0, %0, #1\n"
"tmcrr wr4, %0, %2\n"
"add %0, %0, #1\n"
"tmcrr wr5, %0, %2\n"
"add %0, %0, #1\n"
"tmcrr wr6, %0, %2\n"
"add %0, %0, #1\n"
"tmcrr wr7, %0, %2\n"
"add %0, %0, #1\n"
"tmcrr wr8, %0, %2\n"
"add %0, %0, #1\n"
"tmcrr wr9, %0, %2\n"
"add %0, %0, #1\n"
"tmcrr wr10, %0, %2\n"
"add %0, %0, #1\n"
"tmcrr wr11, %0, %2\n"
"add %0, %0, #1\n"
"tmcrr wr12, %0, %2\n"
"add %0, %0, #1\n"
"tmcrr wr13, %0, %2\n"
"add %0, %0, #1\n"
"tmcrr wr14, %0, %2\n"
"add %0, %0, #1\n"
"tmcrr wr15, %0, %2\n"
"add %0, %0, #1\n"
: "=r"(tmp) : "0"(0), "r"(p));
return f() != 2;
}