diff options
author | Tim Northover <tnorthover@apple.com> | 2014-08-15 10:47:12 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2014-08-15 10:47:12 +0000 |
commit | ee843ef0fa305bc2451a7e8c9b962b64108fc348 (patch) | |
tree | a2047b967a07f80f7d9fc452b5df5396507faca0 /llvm/lib/Target/ARM/Disassembler | |
parent | ccc517c47f9bae58c8bb194f467c9120d3935338 (diff) | |
download | bcm5719-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.cpp | 25 |
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; |