The following program (derived from a gcc test case): int arr[4][4] = {{0, 1, 1, -1}, {-1, -1, 1, -1}, {1, -1, 1, 1}, {1, -1, -1, 0}}; long long foo () { long long ll = 0; ll += arr[1][0]; ll += arr[1][1]; return ll; } int main () { return foo () > 0 ? 1 : 0; } Will compile with gcc 4.8.3 -O2 to: 0000000000400450 <main>: 400450: 90000100 adrp x0, 420000 <_GLOBAL_OFFSET_TABLE_+0x28> 400454: 91008000 add x0, x0, #0x20 400458: b9801001 ldrsw x1, [x0,#16] 40045c: b9801400 ldrsw x0, [x0,#20] 400460: 8b000020 add x0, x1, x0 400464: eb1f001f cmp x0, xzr 400468: 1a9fd7e0 cset w0, gt 40046c: d65f03c0 ret but with gcc 5.3 -O2 it will generate: 0000000000400420 <main>: 400420: 90000080 adrp x0, 410000 <__FRAME_END__+0xf850> 400424: 9127a000 add x0, x0, #0x9e8 400428: 69420001 ldpsw x1, x0, [x0,#16] 40042c: 8b000020 add x0, x1, x0 400430: eb1f001f cmp x0, xzr 400434: 1a9fd7e0 cset w0, gt 400438: d65f03c0 ret 40043c: d503201f nop valgrind doesn't recognize te ldpsw instruction: ARM64 front end: load_store disInstr(arm64): unhandled instruction 0x69420001 disInstr(arm64): 0110'1001 0100'0010 0000'0000 0000'0001 ==17992== valgrind: Unrecognised instruction at address 0x400428. ==17992== at 0x400428: foo (foo.c:7) ==17992== by 0x400428: main (foo.c:12) ==17992== Your program just tried to execute an instruction that Valgrind ==17992== did not recognise. There are two possible reasons for this. ==17992== 1. Your program has a bug and erroneously jumped to a non-code ==17992== location. If you are running Memcheck and you just saw a ==17992== warning about a bad jump, it's probably your program's fault. ==17992== 2. The instruction is legitimate but Valgrind doesn't handle it, ==17992== i.e. it's Valgrind's fault. If you think this is the case or ==17992== you are not sure, please let us know and we'll try to fix it. ==17992== Either way, Valgrind will now raise a SIGILL signal which will ==17992== probably kill your program. ==17992== ==17992== Process terminating with default action of signal 4 (SIGILL) ==17992== Illegal opcode at address 0x400428 ==17992== at 0x400428: foo (foo.c:7) ==17992== by 0x400428: main (foo.c:12) Reproducible: Always
Created attachment 97896 [details] VEX implementation of ldpsw I couldn't find a precise arm64 instruction encoding table, so needed some experimenting to see when ldp does sign extension. With some experimenting found that INSN(30,25) == BITS6(1,1,0,1,0,0) is probably the correct check. It does some sanity checking to make sure it really is an LD instruction and that X isn't set to make sure no instructions are decoded that don't make sense.
Created attachment 97897 [details] tests for ldpsw This groups the ldpsw tests with the ldp tests. Which causes some extra changes in later tests. Maybe the new tests should just go at the end instead?
(In reply to Mark Wielaard from comment #1) > I couldn't find a precise arm64 instruction encoding table This is all documented in the ARMv8 Architecture Reference Manual, which is available from http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.subset.architecture.reference/index.html (you'll need to fill in a form to create an account on the webserver and there may be a click-through license of some kind).
(In reply to Peter Maydell from comment #3) > (In reply to Mark Wielaard from comment #1) > > I couldn't find a precise arm64 instruction encoding table > > This is all documented in the ARMv8 Architecture Reference Manual, which is > available from > http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.subset. > architecture.reference/index.html Thanks for the reference, but that document is behind some legal click wrap license and seems to not be usable for public reference.
Created attachment 97909 [details] Revised VEX implementation
VEX fix in r3212.
Testcases added in valgrind svn r15830.
*** Bug 364435 has been marked as a duplicate of this bug. ***