diff options
author | Victor Huang <wei.huang@ibm.com> | 2020-01-23 14:01:02 -0600 |
---|---|---|
committer | Victor Huang <wei.huang@ibm.com> | 2020-01-24 07:27:25 -0600 |
commit | 5cee34013cfd4edea0041bc0b73121cc4ad76ccf (patch) | |
tree | 6512b657b92f21fbaecbf0c914cd274422343232 /llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp | |
parent | 06ae3748db8a23568f2f238a9534ea9052725ea3 (diff) | |
download | llvm-5cee34013cfd4edea0041bc0b73121cc4ad76ccf.zip llvm-5cee34013cfd4edea0041bc0b73121cc4ad76ccf.tar.gz llvm-5cee34013cfd4edea0041bc0b73121cc4ad76ccf.tar.bz2 |
[PowerPC][Future] Add prefixed instruction paddi to future CPU
Future CPU will include support for prefixed instructions.
These prefixed instructions are formed by a 4 byte prefix
immediately followed by a 4 byte instruction effectively
making an 8 byte instruction. The new instruction paddi
is a prefixed form of addi.
This patch adds paddi and all of the support required
for that instruction. The majority of the patch deals with
supporting the new prefixed instructions. The addition of
paddi is mainly to allow for testing.
Differential Revision: https://reviews.llvm.org/D72569
Diffstat (limited to 'llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp')
-rw-r--r-- | llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp index e3c0f95..872fe4b 100644 --- a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp +++ b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp @@ -191,6 +191,14 @@ static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, return MCDisassembler::Success; } +static DecodeStatus decodeImmZeroOperand(MCInst &Inst, uint64_t Imm, + int64_t Address, const void *Decoder) { + if (Imm != 0) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::createImm(Imm)); + return MCDisassembler::Success; +} + static DecodeStatus decodeMemRIOperands(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder) { // Decode the memri field (imm, reg), which has the low 16-bits as the @@ -324,6 +332,29 @@ DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address, raw_ostream &CS) const { + auto *ReadFunc = IsLittleEndian ? support::endian::read32le + : support::endian::read32be; + + // If this is an 8-byte prefixed instruction, handle it here. + // Note: prefixed instructions aren't technically 8-byte entities - the prefix + // appears in memory at an address 4 bytes prior to that of the base + // instruction regardless of endianness. So we read the two pieces and + // rebuild the 8-byte instruction. + // TODO: In this function we call decodeInstruction several times with + // different decoder tables. It may be possible to only call once by + // looking at the top 6 bits of the instruction. + if (STI.getFeatureBits()[PPC::FeaturePrefixInstrs] && Bytes.size() >= 8) { + uint32_t Prefix = ReadFunc(Bytes.data()); + uint32_t BaseInst = ReadFunc(Bytes.data() + 4); + uint64_t Inst = BaseInst | (uint64_t)Prefix << 32; + DecodeStatus result = decodeInstruction(DecoderTable64, MI, Inst, Address, + this, STI); + if (result != MCDisassembler::Fail) { + Size = 8; + return result; + } + } + // Get the four bytes of the instruction. Size = 4; if (Bytes.size() < 4) { @@ -332,8 +363,7 @@ DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size, } // Read the instruction in the proper endianness. - uint32_t Inst = IsLittleEndian ? support::endian::read32le(Bytes.data()) - : support::endian::read32be(Bytes.data()); + uint64_t Inst = ReadFunc(Bytes.data()); if (STI.getFeatureBits()[PPC::FeatureQPX]) { DecodeStatus result = |