Pair word instruction, like ldpsw, are undefined if the address for loading is specified in a register also used as a destination register.
One example from libopcodes is:
ldpsw x12, x6, [x6],#-8
From the bytes:
In this case, x6 is both a destination for the load, as well as supplying the address for the load, which should be undefined.
Are you sure that you are not seeing an error for this instruction ?
When I assemble it using either the current development sources, or the
latest version of the sources on the 2.26 branch, I get:
Warning: unpredictable transfer with writeback -- `ldpsw x12,x6,[x6],#-8'
I'm not assembling this instruction, I am disassembling it from raw bytes. I probably should have specified that this instruction is produced as decoder output, not as assembler output.
> I'm not assembling this instruction, I am disassembling it from raw bytes.
Ah - OK - that makes sense. I am not sure if it is really worth fixing this problem though. It would take a lot of effort to add code to check for all the possible undefined instructions in the AArch64 disassembler. I know that there already is code to display instructions whose binaries are completely unrecognised, but that is different. At the moment the disassembler does not have any code to detect illegal/undefined forms of recognised instructions, and adding that code would take a lot of time, and probably introduce new bugs.
This may not be a valid output from the libopcodes disassembler, but there are a lot of tools out there, and not all of them may produce expected instructions. People can also edit binaries themselves, placing arbitrary bytes. Furthermore, this instruction executes without any signal on at least one chip, where it both loads a word into x6 and applies the post-fix after loading in the word, a completely unspecified (though maybe predictable) behavior. Identifying invalid instructions like this is essential to debugging code that behaves unexpectedly.
Created attachment 9204 [details]
OK - please could you try out this patch. It is quite larger as it has to add
the framework to support running verification checks when disassembling
instructions. The patch only adds a check on the LDPSW instruction for now,
mainly as a proof of concept. But assuming that you are happy with it, I can
create follow up patches to add other checks, as time permits.
The master branch has been updated by Nick Clifton <firstname.lastname@example.org>:
Author: Nick Clifton <email@example.com>
Date: Thu Apr 28 09:11:03 2016 +0100
Add support to AArch64 disassembler for verifying instructions. Add verifier for LDPSW.
opcodes * aarch64-dis.c (aarch64_opcode_decode): Run verifier if present.
* aarch64-opc.c (verify_ldpsw): New function.
* aarch64-opc.h (verify_ldpsw): New prototype.
* aarch64-tbl.h: Add initialiser for verifier field.
(LDPSW): Set verifier to verify_ldpsw.
binutils* testsuite/binutils-all/aarch64/illegal.s: New test.
* testsuite/binutils-all/aarch64/illegal.d: New test driver.
include * opcode/aarch64.h (struct aarch64_opcode): Add verifier field.
Patch applied. PR closed (for now).