diff options
author | James Molloy <james.molloy@arm.com> | 2014-08-01 12:42:11 +0000 |
---|---|---|
committer | James Molloy <james.molloy@arm.com> | 2014-08-01 12:42:11 +0000 |
commit | 137ce60ecfe86a6b9b99ccbb42493f4bced7bbcf (patch) | |
tree | aaf203cb869a12e5e78e3e08542f7e5d57bc0eb9 /llvm/lib/Target/ARM | |
parent | d6807dafb3acbc7c48c1020cf028325960997ed1 (diff) | |
download | bcm5719-llvm-137ce60ecfe86a6b9b99ccbb42493f4bced7bbcf.tar.gz bcm5719-llvm-137ce60ecfe86a6b9b99ccbb42493f4bced7bbcf.zip |
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!
llvm-svn: 214505
Diffstat (limited to 'llvm/lib/Target/ARM')
-rw-r--r-- | llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 4d4038deac7..48bcc9b2dcd 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -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; } |