diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2022-01-27 22:06:42 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2022-01-27 22:06:42 +0000 | 
| commit | 6f8fc217eaa12bf657be1c6468ed9938d10168b3 (patch) | |
| tree | a1fd89b864d9b93e2ad68fe1dcf7afee2e3c8d76 /llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp | |
| parent | 77fc4c146f0870ffb09c1afb823ccbe742c5e6ff (diff) | |
Diffstat (limited to 'llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp')
| -rw-r--r-- | llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp | 55 | 
1 files changed, 55 insertions, 0 deletions
| diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index 96d410e42be2..9ce00f76d9c7 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -238,6 +238,12 @@ static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm,                                         uint64_t Addr, const void *Decoder);  static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,                                   const void *Decoder); +static DecodeStatus DecodeCPYMemOpInstruction(MCInst &Inst, uint32_t insn, +                                              uint64_t Addr, +                                              const void *Decoder); +static DecodeStatus DecodeSETMemOpInstruction(MCInst &Inst, uint32_t insn, +                                              uint64_t Addr, +                                              const void *Decoder);  static bool Check(DecodeStatus &Out, DecodeStatus In) {    switch (In) { @@ -1842,3 +1848,52 @@ static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,    }    return Fail;  } + +static DecodeStatus DecodeCPYMemOpInstruction(MCInst &Inst, uint32_t insn, +                                              uint64_t Addr, +                                              const void *Decoder) { +  unsigned Rd = fieldFromInstruction(insn, 0, 5); +  unsigned Rs = fieldFromInstruction(insn, 16, 5); +  unsigned Rn = fieldFromInstruction(insn, 5, 5); + +  // None of the registers may alias: if they do, then the instruction is not +  // merely unpredictable but actually entirely unallocated. +  if (Rd == Rs || Rs == Rn || Rd == Rn) +    return MCDisassembler::Fail; + +  // All three register operands are written back, so they all appear +  // twice in the operand list, once as outputs and once as inputs. +  if (!DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) || +      !DecodeGPR64commonRegisterClass(Inst, Rs, Addr, Decoder) || +      !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) || +      !DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) || +      !DecodeGPR64commonRegisterClass(Inst, Rs, Addr, Decoder) || +      !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder)) +    return MCDisassembler::Fail; + +  return MCDisassembler::Success; +} + +static DecodeStatus DecodeSETMemOpInstruction(MCInst &Inst, uint32_t insn, +                                              uint64_t Addr, +                                              const void *Decoder) { +  unsigned Rd = fieldFromInstruction(insn, 0, 5); +  unsigned Rm = fieldFromInstruction(insn, 16, 5); +  unsigned Rn = fieldFromInstruction(insn, 5, 5); + +  // None of the registers may alias: if they do, then the instruction is not +  // merely unpredictable but actually entirely unallocated. +  if (Rd == Rm || Rm == Rn || Rd == Rn) +    return MCDisassembler::Fail; + +  // Rd and Rn (not Rm) register operands are written back, so they appear +  // twice in the operand list, once as outputs and once as inputs. +  if (!DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) || +      !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) || +      !DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) || +      !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) || +      !DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder)) +    return MCDisassembler::Fail; + +  return MCDisassembler::Success; +} | 
