diff options
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/ARM/ARMInstrVFP.td | 3 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 45 |
2 files changed, 48 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMInstrVFP.td b/lib/Target/ARM/ARMInstrVFP.td index 6f0a18bf8d..d4bf8cde9c 100644 --- a/lib/Target/ARM/ARMInstrVFP.td +++ b/lib/Target/ARM/ARMInstrVFP.td @@ -521,6 +521,7 @@ def VMOVRRS : AVConv3I<0b11000101, 0b1010, // Some single precision VFP instructions may be executed on both NEON and VFP // pipelines. let D = VFPNeonDomain; + let DecoderMethod = "DecodeVMOVRRS"; } } // neverHasSideEffects @@ -559,6 +560,8 @@ def VMOVSRR : AVConv5I<0b11000100, 0b1010, // Some single precision VFP instructions may be executed on both NEON and VFP // pipelines. let D = VFPNeonDomain; + + let DecoderMethod = "DecodeVMOVSRR"; } // FMRDH: SPR -> GPR diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index ad1692ca3b..db35c1891c 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -175,6 +175,10 @@ static DecodeStatus DecodeVST3LN(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); static DecodeStatus DecodeVST4LN(llvm::MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeVMOVSRR(llvm::MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); +static DecodeStatus DecodeVMOVRRS(llvm::MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); static DecodeStatus DecodeThumbAddSpecialReg(llvm::MCInst &Inst, uint16_t Insn, @@ -3195,3 +3199,44 @@ static DecodeStatus DecodeVST4LN(llvm::MCInst &Inst, unsigned Insn, return S; } +static DecodeStatus DecodeVMOVSRR(llvm::MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + DecodeStatus S = Success; + unsigned Rt = fieldFromInstruction32(Insn, 12, 4); + unsigned Rt2 = fieldFromInstruction32(Insn, 16, 4); + unsigned Rm = fieldFromInstruction32(Insn, 0, 4); + unsigned pred = fieldFromInstruction32(Insn, 28, 4); + Rm |= fieldFromInstruction32(Insn, 5, 1) << 4; + + if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F) + CHECK(S, Unpredictable); + + CHECK(S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder)); + CHECK(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)); + CHECK(S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder)); + CHECK(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)); + CHECK(S, DecodePredicateOperand(Inst, pred, Address, Decoder)); + + return S; +} + +static DecodeStatus DecodeVMOVRRS(llvm::MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + DecodeStatus S = Success; + unsigned Rt = fieldFromInstruction32(Insn, 12, 4); + unsigned Rt2 = fieldFromInstruction32(Insn, 16, 4); + unsigned Rm = fieldFromInstruction32(Insn, 0, 4); + unsigned pred = fieldFromInstruction32(Insn, 28, 4); + Rm |= fieldFromInstruction32(Insn, 5, 1) << 4; + + if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F) + CHECK(S, Unpredictable); + + CHECK(S, DecodeGPRRegisterClass(Inst, Rt , Address, Decoder)); + CHECK(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)); + CHECK(S, DecodeSPRRegisterClass(Inst, Rm , Address, Decoder)); + CHECK(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)); + CHECK(S, DecodePredicateOperand(Inst, pred, Address, Decoder)); + + return S; +} |