summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/Disassembler
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2014-08-15 10:47:12 +0000
committerTim Northover <tnorthover@apple.com>2014-08-15 10:47:12 +0000
commitee843ef0fa305bc2451a7e8c9b962b64108fc348 (patch)
treea2047b967a07f80f7d9fc452b5df5396507faca0 /llvm/lib/Target/ARM/Disassembler
parentccc517c47f9bae58c8bb194f467c9120d3935338 (diff)
downloadbcm5719-llvm-ee843ef0fa305bc2451a7e8c9b962b64108fc348.tar.gz
bcm5719-llvm-ee843ef0fa305bc2451a7e8c9b962b64108fc348.zip
ARM: implement MRS/MSR (banked reg) system instructions.
These are system-only instructions for CPUs with virtualization extensions, allowing a hypervisor easy access to all of the various different AArch32 registers. rdar://problem/17861345 llvm-svn: 215700
Diffstat (limited to 'llvm/lib/Target/ARM/Disassembler')
-rw-r--r--llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index 48bcc9b2dcd..0940e2a2407 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -281,6 +281,8 @@ static DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder);
static DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);
static DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
@@ -4025,6 +4027,29 @@ static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val,
return MCDisassembler::Success;
}
+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);
+
+ // The table of encodings for these banked registers comes from B9.2.3 of the
+ // ARM ARM. There are patterns, but nothing regular enough to make this logic
+ // neater. So by fiat, these values are UNPREDICTABLE:
+ if (!R) {
+ if (SysM == 0x7 || SysM == 0xf || SysM == 0x18 || SysM == 0x19 ||
+ SysM == 0x1a || SysM == 0x1b)
+ return MCDisassembler::SoftFail;
+ } else {
+ if (SysM != 0xe && SysM != 0x10 && SysM != 0x12 && SysM != 0x14 &&
+ SysM != 0x16 && SysM != 0x1c && SysM != 0x1e)
+ return MCDisassembler::SoftFail;
+ }
+
+ Inst.addOperand(MCOperand::CreateImm(Val));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder) {
DecodeStatus S = MCDisassembler::Success;
OpenPOWER on IntegriCloud