Allow only disassembling of M-class MSR masks that the assembler knows how to assemble back.

Note: The current code in DecodeMSRMask() rejects the unpredictable A/R MSR mask '0000' with Fail. The code in the patch follows this style and rejects unpredictable M-class MSR masks also with Fail (instead of SoftFail). If SoftFail is preferred in this case then additional changes to ARMInstPrinter (to print non-symbolic masks) and ARMAsmParser (to parse non-symbolic masks) will be needed.

Patch by Petr Pavlu!



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214505 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
James Molloy
2014-08-01 12:42:11 +00:00
parent 93b7c0b8fe
commit ea029d5b15
3 changed files with 172 additions and 5 deletions
@@ -3974,7 +3974,53 @@ static DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Val,
static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val,
uint64_t Address, const void *Decoder) {
if (!Val) return MCDisassembler::Fail;
uint64_t FeatureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
.getFeatureBits();
if (FeatureBits & ARM::FeatureMClass) {
unsigned ValLow = Val & 0xff;
// Validate the SYSm value first.
switch (ValLow) {
case 0: // apsr
case 1: // iapsr
case 2: // eapsr
case 3: // xpsr
case 5: // ipsr
case 6: // epsr
case 7: // iepsr
case 8: // msp
case 9: // psp
case 16: // primask
case 20: // control
break;
case 17: // basepri
case 18: // basepri_max
case 19: // faultmask
if (!(FeatureBits & ARM::HasV7Ops))
// Values basepri, basepri_max and faultmask are only valid for v7m.
return MCDisassembler::Fail;
break;
default:
return MCDisassembler::Fail;
}
// The ARMv7-M architecture has an additional 2-bit mask value in the MSR
// instruction (bits {11,10}). The mask is used only with apsr, iapsr,
// eapsr and xpsr, it has to be 0b10 in other cases. Bit mask{1} indicates
// if the NZCVQ bits should be moved by the instruction. Bit mask{0}
// indicates the move for the GE{3:0} bits, the mask{0} bit can be set
// only if the processor includes the DSP extension.
if ((FeatureBits & ARM::HasV7Ops) && Inst.getOpcode() == ARM::t2MSR_M) {
unsigned Mask = (Val >> 10) & 3;
if (Mask == 0 || (Mask != 2 && ValLow > 3) ||
(!(FeatureBits & ARM::FeatureDSPThumb2) && Mask == 1))
return MCDisassembler::Fail;
}
} else {
// A/R class
if (Val == 0)
return MCDisassembler::Fail;
}
Inst.addOperand(MCOperand::CreateImm(Val));
return MCDisassembler::Success;
}