aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2013-08-07 15:07:10 -0700
committerStephen Hines <srhines@google.com>2013-08-07 15:07:10 -0700
commitfab2daa4a1127ecb217abe2b07c1769122b6fee1 (patch)
tree268ebfd1963fd98ba412e76819afdf95a7d4267b /lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
parent8197ac1c1a0a91baa70c4dea8cb488f254ef974c (diff)
parent10251753b6897adcd22cc981c0cc42f348c109de (diff)
downloadexternal_llvm-fab2daa4a1127ecb217abe2b07c1769122b6fee1.zip
external_llvm-fab2daa4a1127ecb217abe2b07c1769122b6fee1.tar.gz
external_llvm-fab2daa4a1127ecb217abe2b07c1769122b6fee1.tar.bz2
Merge commit '10251753b6897adcd22cc981c0cc42f348c109de' into merge-20130807
Conflicts: lib/Archive/ArchiveReader.cpp lib/Support/Unix/PathV2.inc Change-Id: I29d8c1e321a4a380b6013f00bac6a8e4b593cc4e
Diffstat (limited to 'lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp')
-rw-r--r--lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp47
1 files changed, 42 insertions, 5 deletions
diff --git a/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
index 1c397b5..a88a8e8 100644
--- a/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
+++ b/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
@@ -38,7 +38,7 @@ typedef MCDisassembler::DecodeStatus DecodeStatus;
namespace {
/// AArch64 disassembler for all AArch64 platforms.
class AArch64Disassembler : public MCDisassembler {
- const MCRegisterInfo *RegInfo;
+ OwningPtr<const MCRegisterInfo> RegInfo;
public:
/// Initializes the disassembler.
///
@@ -46,8 +46,7 @@ public:
: MCDisassembler(STI), RegInfo(Info) {
}
- ~AArch64Disassembler() {
- }
+ ~AArch64Disassembler() {}
/// See MCDisassembler.
DecodeStatus getInstruction(MCInst &instr,
@@ -57,7 +56,7 @@ public:
raw_ostream &vStream,
raw_ostream &cStream) const;
- const MCRegisterInfo *getRegInfo() const { return RegInfo; }
+ const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); }
};
}
@@ -86,6 +85,9 @@ static DecodeStatus DecodeFPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
static DecodeStatus DecodeFPR128RegisterClass(llvm::MCInst &Inst,
unsigned RegNo, uint64_t Address,
const void *Decoder);
+static DecodeStatus DecodeVPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder);
static DecodeStatus DecodeVPR128RegisterClass(llvm::MCInst &Inst,
unsigned RegNo, uint64_t Address,
const void *Decoder);
@@ -127,6 +129,10 @@ static DecodeStatus DecodeRegExtendOperand(llvm::MCInst &Inst,
unsigned ShiftAmount,
uint64_t Address,
const void *Decoder);
+template <A64SE::ShiftExtSpecifiers Ext, bool IsHalf>
+static DecodeStatus
+DecodeNeonMovImmShiftOperand(llvm::MCInst &Inst, unsigned ShiftAmount,
+ uint64_t Address, const void *Decoder);
static DecodeStatus Decode32BitShiftOperand(llvm::MCInst &Inst,
unsigned ShiftAmount,
@@ -337,9 +343,20 @@ DecodeFPR128RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
return MCDisassembler::Success;
}
+static DecodeStatus DecodeVPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ if (RegNo > 31)
+ return MCDisassembler::Fail;
+
+ uint16_t Register = getReg(Decoder, AArch64::VPR64RegClassID, RegNo);
+ Inst.addOperand(MCOperand::CreateReg(Register));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus
DecodeVPR128RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
- uint64_t Address, const void *Decoder) {
+ uint64_t Address, const void *Decoder) {
if (RegNo > 31)
return MCDisassembler::Fail;
@@ -800,4 +817,24 @@ extern "C" void LLVMInitializeAArch64Disassembler() {
createAArch64Disassembler);
}
+template <A64SE::ShiftExtSpecifiers Ext, bool IsHalf>
+static DecodeStatus
+DecodeNeonMovImmShiftOperand(llvm::MCInst &Inst, unsigned ShiftAmount,
+ uint64_t Address, const void *Decoder) {
+ bool IsLSL = false;
+ if (Ext == A64SE::LSL)
+ IsLSL = true;
+ else if (Ext != A64SE::MSL)
+ return MCDisassembler::Fail;
+
+ // MSL and LSLH accepts encoded shift amount 0 or 1.
+ if ((!IsLSL || (IsLSL && IsHalf)) && ShiftAmount != 0 && ShiftAmount != 1)
+ return MCDisassembler::Fail;
+ // LSL accepts encoded shift amount 0, 1, 2 or 3.
+ if (IsLSL && ShiftAmount > 3)
+ return MCDisassembler::Fail;
+
+ Inst.addOperand(MCOperand::CreateImm(ShiftAmount));
+ return MCDisassembler::Success;
+}