aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
diff options
context:
space:
mode:
authorVictor Huang <wei.huang@ibm.com>2020-01-23 14:01:02 -0600
committerVictor Huang <wei.huang@ibm.com>2020-01-24 07:27:25 -0600
commit5cee34013cfd4edea0041bc0b73121cc4ad76ccf (patch)
tree6512b657b92f21fbaecbf0c914cd274422343232 /llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp
parent06ae3748db8a23568f2f238a9534ea9052725ea3 (diff)
downloadllvm-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.cpp34
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 =