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;
}