diff options
author | Simon Tatham <simon.tatham@arm.com> | 2019-06-27 12:40:40 +0000 |
---|---|---|
committer | Simon Tatham <simon.tatham@arm.com> | 2019-06-27 12:40:40 +0000 |
commit | 02449f9c3cf59836335d7e8c6ca76c84c5d9880c (patch) | |
tree | da5e817bc6fc751c09bddbc8308cd023c28aeb67 /llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp | |
parent | c5cff5d3d16b1b774aecdf24a3cf869bf9349359 (diff) | |
download | bcm5719-llvm-02449f9c3cf59836335d7e8c6ca76c84c5d9880c.tar.gz bcm5719-llvm-02449f9c3cf59836335d7e8c6ca76c84c5d9880c.zip |
[ARM] Tighten restrictions on use of SP in v8.1-M CSEL.
In the `CSEL Rd,Rm,Rn` instruction family (also including CSINC, CSINV
and CSNEG), the architecture lists it as CONSTRAINED UNPREDICTABLE
(i.e. SoftFail) to use SP in the Rd or Rm slot, but outright illegal
to use it in the Rn slot, not least because some encodings of that
form are used by MVE instructions such as UQRSHLL.
MC was treating all three slots the same, as SoftFail. So the only
reason UQRSHLL was disassembled correctly at all was because the MVE
decode table is separate from the Thumb2 one and takes priority; if
you turned off MVE, then encodings such as `[0x5f,0xea,0x0d,0x83]`
would disassemble as spurious CSELs.
Fixed by inventing another version of the `GPRwithZR` register class,
which disallows SP completely instead of just SoftFailing it.
Reviewers: DavidSpickett, ostannard
Subscribers: javed.absar, kristof.beyls, hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D63862
llvm-svn: 364531
Diffstat (limited to 'llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 9e0a63da7df..c6ae7d26bf9 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -194,6 +194,8 @@ static DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst &Inst, static DecodeStatus DecodeGPRwithZRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeGPRwithZRnospRegisterClass( + MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo, @@ -1184,12 +1186,22 @@ DecodeGPRwithZRRegisterClass(MCInst &Inst, unsigned RegNo, } if (RegNo == 13) - S = MCDisassembler::SoftFail; + Check(S, MCDisassembler::SoftFail); Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder)); return S; } +static DecodeStatus +DecodeGPRwithZRnospRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, const void *Decoder) { + DecodeStatus S = MCDisassembler::Success; + if (RegNo == 13) + return MCDisassembler::Fail; + Check(S, DecodeGPRwithZRRegisterClass(Inst, RegNo, Address, Decoder)); + return S; +} + static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { if (RegNo > 7) |