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 | df698b032c9a9797e92b0ab3d4aebe6cf7112b2c (patch) | |
tree | 328fbdee9206d0a97eadfa429448d9613611737f /llvm/lib/Target/ARM/Disassembler | |
parent | a64608455099dc7146afdf72ce1c2391314cbc14 (diff) | |
download | bcm5719-llvm-df698b032c9a9797e92b0ab3d4aebe6cf7112b2c.tar.gz bcm5719-llvm-df698b032c9a9797e92b0ab3d4aebe6cf7112b2c.zip |
Fix decoding of VMOVSRR and VMOVRRS, which account for the overwhelming majority of decoder crashes detected by randomized testing.
llvm-svn: 138269
Diffstat (limited to 'llvm/lib/Target/ARM/Disassembler')
-rw-r--r-- | llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
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; +} |