diff options
author | Manolis Tsamis <manolis.tsamis@vrull.eu> | 2023-02-21 12:21:35 +0100 |
---|---|---|
committer | Philipp Tomsich <philipp.tomsich@vrull.eu> | 2023-02-21 12:21:49 +0100 |
commit | bbb58a2302c65b73943e00f2def3384a68177a7f (patch) | |
tree | dc3718c2d2e745067dbee2328299e0e44ee432c2 /llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp | |
parent | d567e06946b70136d344df3d8601c5e02cb596e1 (diff) | |
download | llvm-bbb58a2302c65b73943e00f2def3384a68177a7f.zip llvm-bbb58a2302c65b73943e00f2def3384a68177a7f.tar.gz llvm-bbb58a2302c65b73943e00f2def3384a68177a7f.tar.bz2 |
[RISCV] Add vendor-defined XTheadMemPair (two-GPR Memory Operations) extension
The vendor-defined XTHeadMemPair (no comparable standard extension exists
at the time of writing) extension adds two-GPR load/store pair instructions.
It is supported by the C9xx cores (e.g., found in the wild in the
Allwinner D1) by Alibaba T-Head.
The current (as of this commit) public documentation for this
extension is available at:
https://github.com/T-head-Semi/thead-extension-spec/releases/download/2.2.2/xthead-2023-01-30-2.2.2.pdf
Support for these instructions has already landed in GNU Binutils:
https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=6e17ae625570ff8f3c12c8765b8d45d4db8694bd
Depends on D143847
Reviewed By: craig.topper
Differential Revision: https://reviews.llvm.org/D144002
Diffstat (limited to 'llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp')
-rw-r--r-- | llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index cb20115..cb7b229 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -367,6 +367,10 @@ static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn, uint64_t Address, const MCDisassembler *Decoder); +static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn, + uint64_t Address, + const MCDisassembler *Decoder); + #include "RISCVGenDisassemblerTables.inc" static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn, @@ -427,6 +431,32 @@ static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn, return MCDisassembler::Success; } +static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn, + uint64_t Address, + const MCDisassembler *Decoder) { + uint32_t Rd1 = fieldFromInstruction(Insn, 7, 5); + uint32_t Rs1 = fieldFromInstruction(Insn, 15, 5); + uint32_t Rd2 = fieldFromInstruction(Insn, 20, 5); + uint32_t UImm2 = fieldFromInstruction(Insn, 25, 2); + DecodeGPRRegisterClass(Inst, Rd1, Address, Decoder); + DecodeGPRRegisterClass(Inst, Rd2, Address, Decoder); + DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder); + DecodeStatus Result = decodeUImmOperand<2>(Inst, UImm2, Address, Decoder); + (void)Result; + assert(Result == MCDisassembler::Success && "Invalid immediate"); + + // Disassemble the final operand which is implicit. + unsigned Opcode = Inst.getOpcode(); + bool IsWordOp = (Opcode == RISCV::TH_LWD || Opcode == RISCV::TH_LWUD || + Opcode == RISCV::TH_SWD); + if (IsWordOp) + Inst.addOperand(MCOperand::createImm(3)); + else + Inst.addOperand(MCOperand::createImm(4)); + + return MCDisassembler::Success; +} + DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address, @@ -497,6 +527,13 @@ DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size, if (Result != MCDisassembler::Fail) return Result; } + if (STI.hasFeature(RISCV::FeatureVendorXTHeadMemPair)) { + LLVM_DEBUG(dbgs() << "Trying XTHeadMemPair custom opcode table:\n"); + Result = decodeInstruction(DecoderTableTHeadMemPair32, MI, Insn, Address, + this, STI); + if (Result != MCDisassembler::Fail) + return Result; + } if (STI.hasFeature(RISCV::FeatureVendorXTHeadVdot)) { LLVM_DEBUG(dbgs() << "Trying XTHeadVdot custom opcode table:\n"); Result = |