Bug 360425 - arm64 unsupported instruction ldpsw
Summary: arm64 unsupported instruction ldpsw
Status: RESOLVED FIXED
Alias: None
Product: valgrind
Classification: Developer tools
Component: vex (show other bugs)
Version: unspecified
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
: 364435 (view as bug list)
Depends on:
Blocks:
 
Reported: 2016-03-11 20:36 UTC by Mark Wielaard
Modified: 2016-07-05 07:39 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
VEX implementation of ldpsw (4.15 KB, patch)
2016-03-14 15:02 UTC, Mark Wielaard
Details
tests for ldpsw (569.06 KB, patch)
2016-03-14 15:04 UTC, Mark Wielaard
Details
Revised VEX implementation (3.73 KB, patch)
2016-03-15 13:11 UTC, Julian Seward
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Wielaard 2016-03-11 20:36:53 UTC
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
Comment 1 Mark Wielaard 2016-03-14 15:02:30 UTC
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.
Comment 2 Mark Wielaard 2016-03-14 15:04:10 UTC
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?
Comment 3 Peter Maydell 2016-03-14 15:30:19 UTC
(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).
Comment 4 Mark Wielaard 2016-03-14 16:01:20 UTC
(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.
Comment 5 Julian Seward 2016-03-15 13:11:56 UTC
Created attachment 97909 [details]
Revised VEX implementation
Comment 6 Julian Seward 2016-03-15 14:25:29 UTC
VEX fix in r3212.
Comment 7 Mark Wielaard 2016-03-15 15:08:34 UTC
Testcases added in valgrind svn r15830.
Comment 8 Julian Seward 2016-07-05 07:39:18 UTC
*** Bug 364435 has been marked as a duplicate of this bug. ***