Search code examples
assemblyarm64

arm64 ldp instruction encoding


Suppose I write the following:

asm("ldp x0, x0 [x0, #0]!");

Since the registers and the immediate are all 0, we can easily see the opcode encoding: Godbolt renders it as 0xa9c00000.

The ARM documentation for a 64-bit pre-index LDP instruction seems to indicate it is 0x6dc00000. In the linked document, it shows.

  • bits 31-30 are opc so are 0b01.
  • bits 29-22 are 0b10110111.
  • bits 21-0 are all zero because imm7, Rt2, Rn, and Rt are all zero.
  • Together that makes 0b 01 10110111 0000000 00000 00000 00000 -> 0x6dc00000.

If that "opc" field is BIG ENDIAN for some reason, then I'll get 0xadc00000, which is now only one bit away...

I just don't get it...?

How am I misreading the ARM document?


Solution

  • You're looking at the wrong ldp. The documentation you linked is for the SIMD/NEON registers. You'd be loading d0, not x0. You need to look at the general-purpose register version.

    And indeed if you feed ldp d0, d0, [x0, #0]! into godbolt, then you get 0x6dc00000 just as you expected.