From df698b032c9a9797e92b0ab3d4aebe6cf7112b2c Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Mon, 22 Aug 2011 20:27:12 +0000 Subject: Fix decoding of VMOVSRR and VMOVRRS, which account for the overwhelming majority of decoder crashes detected by randomized testing. llvm-svn: 138269 --- llvm/lib/Target/ARM/ARMInstrVFP.td | 3 ++ .../Target/ARM/Disassembler/ARMDisassembler.cpp | 45 ++++++++++++++++++++++ 2 files changed, 48 insertions(+) (limited to 'llvm/lib/Target') diff --git a/llvm/lib/Target/ARM/ARMInstrVFP.td b/llvm/lib/Target/ARM/ARMInstrVFP.td index 6f0a18bf8dd..d4bf8cde9c9 100644 --- a/llvm/lib/Target/ARM/ARMInstrVFP.td +++ b/llvm/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/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index ad1692ca3b8..db35c1891c0 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/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; +} -- cgit v1.2.3