summaryrefslogtreecommitdiff
path: root/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
commit044eb2f6afba375a914ac9d8024f8f5142bb912e (patch)
tree1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /lib/Target/ARM/Disassembler/ARMDisassembler.cpp
parenteb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff)
Notes
Diffstat (limited to 'lib/Target/ARM/Disassembler/ARMDisassembler.cpp')
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassembler.cpp91
1 files changed, 86 insertions, 5 deletions
diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index 5ab236b7fd4c..a29a2eeccfe8 100644
--- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -1,4 +1,4 @@
-//===-- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA --------------===//
+//===- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA ---------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,6 +10,7 @@
#include "MCTargetDesc/ARMAddressingModes.h"
#include "MCTargetDesc/ARMBaseInfo.h"
#include "MCTargetDesc/ARMMCTargetDesc.h"
+#include "Utils/ARMBaseInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCFixedLenDisassembler.h"
@@ -31,7 +32,7 @@ using namespace llvm;
#define DEBUG_TYPE "arm-disassembler"
-typedef MCDisassembler::DecodeStatus DecodeStatus;
+using DecodeStatus = MCDisassembler::DecodeStatus;
namespace {
@@ -117,6 +118,7 @@ public:
private:
mutable ITStatus ITBlock;
+
DecodeStatus AddThumbPredicate(MCInst&) const;
void UpdateThumbVFPPredicate(MCInst&) const;
};
@@ -320,6 +322,10 @@ static DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeNEONComplexLane64Instruction(MCInst &Inst,
+ unsigned Val,
+ uint64_t Address,
+ const void *Decoder);
static DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
uint64_t Address, const void *Decoder);
@@ -398,6 +404,8 @@ static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
uint64_t Address, const void *Decoder);
static DecodeStatus DecoderForMRRC2AndMCRR2(MCInst &Inst, unsigned Val,
uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeForVMRSandVMSR(MCInst &Inst, unsigned Val,
+ uint64_t Address, const void *Decoder);
#include "ARMGenDisassemblerTables.inc"
@@ -486,6 +494,13 @@ DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
}
}
+ Result =
+ decodeInstruction(DecoderTableCoProc32, MI, Insn, Address, this, STI);
+ if (Result != MCDisassembler::Fail) {
+ Size = 4;
+ return checkDecodedInstruction(MI, Size, Address, OS, CS, Insn, Result);
+ }
+
Size = 4;
return MCDisassembler::Fail;
}
@@ -821,6 +836,14 @@ DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
}
}
+ Result =
+ decodeInstruction(DecoderTableThumb2CoProc32, MI, Insn32, Address, this, STI);
+ if (Result != MCDisassembler::Fail) {
+ Size = 4;
+ Check(Result, AddThumbPredicate(MI));
+ return Result;
+ }
+
Size = 0;
return MCDisassembler::Fail;
}
@@ -2744,7 +2767,6 @@ static DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn,
break;
}
-
// First input register
switch (Inst.getOpcode()) {
case ARM::VST1q16:
@@ -3843,7 +3865,6 @@ static DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
return S;
}
-
static DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Insn,
uint64_t Address, const void *Decoder) {
unsigned imm = fieldFromInstruction(Insn, 0, 7);
@@ -4167,7 +4188,6 @@ static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val,
static DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Val,
uint64_t Address, const void *Decoder) {
-
unsigned R = fieldFromInstruction(Val, 5, 1);
unsigned SysM = fieldFromInstruction(Val, 0, 5);
@@ -5199,6 +5219,39 @@ static DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
return S;
}
+static DecodeStatus DecodeNEONComplexLane64Instruction(MCInst &Inst,
+ unsigned Insn,
+ uint64_t Address,
+ const void *Decoder) {
+ unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
+ Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
+ unsigned Vn = (fieldFromInstruction(Insn, 16, 4) << 0);
+ Vn |= (fieldFromInstruction(Insn, 7, 1) << 4);
+ unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
+ Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
+ unsigned q = (fieldFromInstruction(Insn, 6, 1) << 0);
+ unsigned rotate = (fieldFromInstruction(Insn, 20, 2) << 0);
+
+ DecodeStatus S = MCDisassembler::Success;
+
+ auto DestRegDecoder = q ? DecodeQPRRegisterClass : DecodeDPRRegisterClass;
+
+ if (!Check(S, DestRegDecoder(Inst, Vd, Address, Decoder)))
+ return MCDisassembler::Fail;
+ if (!Check(S, DestRegDecoder(Inst, Vd, Address, Decoder)))
+ return MCDisassembler::Fail;
+ if (!Check(S, DestRegDecoder(Inst, Vn, Address, Decoder)))
+ return MCDisassembler::Fail;
+ if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
+ return MCDisassembler::Fail;
+ // The lane index does not have any bits in the encoding, because it can only
+ // be 0.
+ Inst.addOperand(MCOperand::createImm(0));
+ Inst.addOperand(MCOperand::createImm(rotate));
+
+ return S;
+}
+
static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
uint64_t Address, const void *Decoder) {
DecodeStatus S = MCDisassembler::Success;
@@ -5270,3 +5323,31 @@ static DecodeStatus DecoderForMRRC2AndMCRR2(MCInst &Inst, unsigned Val,
return S;
}
+
+static DecodeStatus DecodeForVMRSandVMSR(MCInst &Inst, unsigned Val,
+ uint64_t Address,
+ const void *Decoder) {
+ const FeatureBitset &featureBits =
+ ((const MCDisassembler *)Decoder)->getSubtargetInfo().getFeatureBits();
+ DecodeStatus S = MCDisassembler::Success;
+
+ unsigned Rt = fieldFromInstruction(Val, 12, 4);
+
+ if (featureBits[ARM::ModeThumb] && !featureBits[ARM::HasV8Ops]) {
+ if (Rt == 13 || Rt == 15)
+ S = MCDisassembler::SoftFail;
+ Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder));
+ } else
+ Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder));
+
+ if (featureBits[ARM::ModeThumb]) {
+ Inst.addOperand(MCOperand::createImm(ARMCC::AL));
+ Inst.addOperand(MCOperand::createReg(0));
+ } else {
+ unsigned pred = fieldFromInstruction(Val, 28, 4);
+ if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
+ return MCDisassembler::Fail;
+ }
+
+ return S;
+}