llvm.org GIT mirror llvm / 46e136c
ARM: fix CPS decoding when ambiguous with QADD Handle the case when the disassembler table can't tell the difference between some encodings of QADD and CPS. Add some necessary safe guards in CPS decoding as well. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183610 91177308-0d34-0410-b5e6-96231b3b80d8 Amaury de la Vieuville 7 years ago
4 changed file(s) with 47 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
32783278
32793279 // Saturating add/subtract
32803280
3281 let DecoderMethod = "DecodeQADDInstruction" in
32813282 def QADD : AAI<0b00010000, 0b00000101, "qadd",
32823283 [(set GPRnopc:$Rd, (int_arm_qadd GPRnopc:$Rm, GPRnopc:$Rn))],
32833284 (ins GPRnopc:$Rm, GPRnopc:$Rn), "\t$Rd, $Rm, $Rn">;
3285
32843286 def QSUB : AAI<0b00010010, 0b00000101, "qsub",
32853287 [(set GPRnopc:$Rd, (int_arm_qsub GPRnopc:$Rm, GPRnopc:$Rn))],
32863288 (ins GPRnopc:$Rm, GPRnopc:$Rn), "\t$Rd, $Rm, $Rn">;
357357 static DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
358358 uint64_t Address, const void *Decoder);
359359 static DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
360 uint64_t Address, const void *Decoder);
361 static DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
360362 uint64_t Address, const void *Decoder);
361363 static DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Insn,
362364 uint64_t Address, const void *Decoder);
17291731 if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
17301732 return MCDisassembler::Fail;
17311733
1734 return S;
1735 }
1736
1737 static DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
1738 uint64_t Address, const void *Decoder) {
1739 DecodeStatus S = MCDisassembler::Success;
1740
1741 unsigned Rd = fieldFromInstruction(Insn, 12, 4);
1742 unsigned Rm = fieldFromInstruction(Insn, 0, 4);
1743 unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1744 unsigned pred = fieldFromInstruction(Insn, 28, 4);
1745
1746 if (pred == 0xF)
1747 return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
1748
1749 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
1750 return MCDisassembler::Fail;
1751 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1752 return MCDisassembler::Fail;
1753 if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
1754 return MCDisassembler::Fail;
1755 if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1756 return MCDisassembler::Fail;
17321757 return S;
17331758 }
17341759
18251850 unsigned mode = fieldFromInstruction(Insn, 0, 5);
18261851
18271852 DecodeStatus S = MCDisassembler::Success;
1853
1854 // This decoder is called from multiple location that do not check
1855 // the full encoding is valid before they do.
1856 if (fieldFromInstruction(Insn, 5, 1) != 0 ||
1857 fieldFromInstruction(Insn, 16, 1) != 0 ||
1858 fieldFromInstruction(Insn, 20, 8) != 0x10)
1859 return MCDisassembler::Fail;
18281860
18291861 // imod == '01' --> UNPREDICTABLE
18301862 // NOTE: Even though this is technically UNPREDICTABLE, we choose to
453453 # CHECK: cpsie aif
454454 # CHECK: cps #15
455455 # CHECK: cpsid if, #10
456 # CHECK: cpsid af, #17
457 # CHECK: cpsie f, #26
456458
457459 0xc0 0x01 0x08 0xf1
458460 0x0f 0x00 0x02 0xf1
459461 0xca 0x00 0x0e 0xf1
462 0x51 0x01 0x0e 0xf1
463 0x5a 0x00 0x0a 0xf1
460464
461465
462466 #------------------------------------------------------------------------------
0 # CPS: various encodings that are ambiguous with other instructions
1
2 # RUN: echo "0x9f 0xff 0x4e 0xf1" | llvm-mc -triple=armv7 -disassemble 2>&1 | FileCheck %s
3 # RUN: echo "0x80 0x80 0x2c 0xf1" | llvm-mc -triple=armv7 -disassemble 2>&1 | FileCheck %s
4 # RUN: echo "0xce 0x3f 0x28 0xf1" | llvm-mc -triple=armv7 -disassemble 2>&1 | FileCheck %s
5 # RUN: echo "0x80 0x00 0x20 0xf1" | llvm-mc -triple=armv7 -disassemble 2>&1 | FileCheck %s
6 # RUN: echo "0xa0 0x00 0x00 0xf1" | llvm-mc -triple=armv7 -disassemble 2>&1 | FileCheck %s
7
8 # CHECK: invalid instruction encoding