diff options
author | Owen Anderson <resistor@mac.com> | 2011-08-22 20:27:12 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2011-08-22 20:27:12 +0000 |
commit | 357ec6850be0dff0038ea3a14f16066705284c0b (patch) | |
tree | 4f03aa9a989251da5cef06c686d07c36eb8ef938 /lib/Target/ARM/Disassembler/ARMDisassembler.cpp | |
parent | eeb37f1a568185c46f600fb34769ec376bf5bfaf (diff) |
Fix decoding of VMOVSRR and VMOVRRS, which account for the overwhelming majority of decoder crashes detected by randomized testing.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138269 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/Disassembler/ARMDisassembler.cpp')
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
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; +} |