llvm.org GIT mirror llvm / 0fd4f3c
Fix the encoding of the armv7m (MClass) for MSR APSR writes which was missing the 0b10 mask encoding bits. Make MSR APSR writes without a _<bits> qualifier an alias for MSR APSR_nzcvq even though ARM as deprecated it use. Also add support for suffixes (_nzcvq, _g, _nzcvqg) for APSR versions. Some FIXMEs in the code for better error checking when versions shouldn't be used. rdar://11457025 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157019 91177308-0d34-0410-b5e6-96231b3b80d8 Kevin Enderby 8 years ago
4 changed file(s) with 82 addition(s) and 15 deletion(s). Raw diff Collapse all Expand all
36823682 def t2MSR_M : T2I<(outs), (ins msr_mask:$SYSm, rGPR:$Rn),
36833683 NoItinerary, "msr", "\t$SYSm, $Rn", []>,
36843684 Requires<[IsThumb,IsMClass]> {
3685 bits<8> SYSm;
3685 bits<12> SYSm;
36863686 bits<4> Rn;
36873687 let Inst{31-21} = 0b11110011100;
36883688 let Inst{20} = 0b0;
36893689 let Inst{19-16} = Rn;
36903690 let Inst{15-12} = 0b1000;
3691 let Inst{7-0} = SYSm;
3691 let Inst{11-0} = SYSm;
36923692 }
36933693
36943694
33233323 // See ARMv6-M 10.1.1
33243324 std::string Name = Mask.lower();
33253325 unsigned FlagsVal = StringSwitch(Name)
3326 .Case("apsr", 0)
3327 .Case("iapsr", 1)
3328 .Case("eapsr", 2)
3329 .Case("xpsr", 3)
3326 // Note: in the documentation:
3327 // ARM deprecates using MSR APSR without a _ qualifier as an alias
3328 // for MSR APSR_nzcvq.
3329 // but we do make it an alias here. This is so to get the "mask encoding"
3330 // bits correct on MSR APSR writes.
3331 //
3332 // FIXME: Note the 0xc00 "mask encoding" bits version of the registers
3333 // should really only be allowed when writing a special register. Note
3334 // they get dropped in the MRS instruction reading a special register as
3335 // the SYSm field is only 8 bits.
3336 //
3337 // FIXME: the _g and _nzcvqg versions are only allowed if the processor
3338 // includes the DSP extension but that is not checked.
3339 .Case("apsr", 0x800)
3340 .Case("apsr_nzcvq", 0x800)
3341 .Case("apsr_g", 0x400)
3342 .Case("apsr_nzcvqg", 0xc00)
3343 .Case("iapsr", 0x801)
3344 .Case("iapsr_nzcvq", 0x801)
3345 .Case("iapsr_g", 0x401)
3346 .Case("iapsr_nzcvqg", 0xc01)
3347 .Case("eapsr", 0x802)
3348 .Case("eapsr_nzcvq", 0x802)
3349 .Case("eapsr_g", 0x402)
3350 .Case("eapsr_nzcvqg", 0xc02)
3351 .Case("xpsr", 0x803)
3352 .Case("xpsr_nzcvq", 0x803)
3353 .Case("xpsr_g", 0x403)
3354 .Case("xpsr_nzcvqg", 0xc03)
33303355 .Case("ipsr", 5)
33313356 .Case("epsr", 6)
33323357 .Case("iepsr", 7)
646646 unsigned Mask = Op.getImm() & 0xf;
647647
648648 if (getAvailableFeatures() & ARM::FeatureMClass) {
649 switch (Op.getImm()) {
649 unsigned SYSm = Op.getImm();
650 unsigned Opcode = MI->getOpcode();
651 // For reads of the special registers ignore the "mask encoding" bits
652 // which are only for writes.
653 if (Opcode == ARM::t2MRS_M)
654 SYSm &= 0xff;
655 switch (SYSm) {
650656 default: llvm_unreachable("Unexpected mask value!");
651 case 0: O << "apsr"; return;
652 case 1: O << "iapsr"; return;
653 case 2: O << "eapsr"; return;
654 case 3: O << "xpsr"; return;
657 case 0:
658 case 0x800: O << "apsr"; return; // with _nzcvq bits is an alias for aspr
659 case 0x400: O << "apsr_g"; return;
660 case 0xc00: O << "apsr_nzcvqg"; return;
661 case 1:
662 case 0x801: O << "iapsr"; return; // with _nzcvq bits is an alias for iapsr
663 case 0x401: O << "iapsr_g"; return;
664 case 0xc01: O << "iapsr_nzcvqg"; return;
665 case 2:
666 case 0x802: O << "eapsr"; return; // with _nzcvq bits is an alias for eapsr
667 case 0x402: O << "eapsr_g"; return;
668 case 0xc02: O << "eapsr_nzcvqg"; return;
669 case 3:
670 case 0x803: O << "xpsr"; return; // with _nzcvq bits is an alias for xpsr
671 case 0x403: O << "xpsr_g"; return;
672 case 0xc03: O << "xpsr_nzcvqg"; return;
655673 case 5: O << "ipsr"; return;
656674 case 6: O << "epsr"; return;
657675 case 7: O << "iepsr"; return;
4343 @------------------------------------------------------------------------------
4444
4545 msr apsr, r0
46 msr apsr_nzcvq, r0
47 msr apsr_g, r0
48 msr apsr_nzcvqg, r0
4649 msr iapsr, r0
50 msr iapsr_nzcvq, r0
51 msr iapsr_g, r0
52 msr iapsr_nzcvqg, r0
4753 msr eapsr, r0
54 msr eapsr_nzcvq, r0
55 msr eapsr_g, r0
56 msr eapsr_nzcvqg, r0
4857 msr xpsr, r0
58 msr xpsr_nzcvq, r0
59 msr xpsr_g, r0
60 msr xpsr_nzcvqg, r0
4961 msr ipsr, r0
5062 msr epsr, r0
5163 msr iepsr, r0
5769 msr faultmask, r0
5870 msr control, r0
5971
60 @ CHECK: msr apsr, r0 @ encoding: [0x80,0xf3,0x00,0x80]
61 @ CHECK: msr iapsr, r0 @ encoding: [0x80,0xf3,0x01,0x80]
62 @ CHECK: msr eapsr, r0 @ encoding: [0x80,0xf3,0x02,0x80]
63 @ CHECK: msr xpsr, r0 @ encoding: [0x80,0xf3,0x03,0x80]
72 @ CHECK: msr apsr, r0 @ encoding: [0x80,0xf3,0x00,0x88]
73 @ CHECK: msr apsr, r0 @ encoding: [0x80,0xf3,0x00,0x88]
74 @ CHECK: msr apsr_g, r0 @ encoding: [0x80,0xf3,0x00,0x84]
75 @ CHECK: msr apsr_nzcvqg, r0 @ encoding: [0x80,0xf3,0x00,0x8c]
76 @ CHECK: msr iapsr, r0 @ encoding: [0x80,0xf3,0x01,0x88]
77 @ CHECK: msr iapsr, r0 @ encoding: [0x80,0xf3,0x01,0x88]
78 @ CHECK: msr iapsr_g, r0 @ encoding: [0x80,0xf3,0x01,0x84]
79 @ CHECK: msr iapsr_nzcvqg, r0 @ encoding: [0x80,0xf3,0x01,0x8c]
80 @ CHECK: msr eapsr, r0 @ encoding: [0x80,0xf3,0x02,0x88]
81 @ CHECK: msr eapsr, r0 @ encoding: [0x80,0xf3,0x02,0x88]
82 @ CHECK: msr eapsr_g, r0 @ encoding: [0x80,0xf3,0x02,0x84]
83 @ CHECK: msr eapsr_nzcvqg, r0 @ encoding: [0x80,0xf3,0x02,0x8c]
84 @ CHECK: msr xpsr, r0 @ encoding: [0x80,0xf3,0x03,0x88]
85 @ CHECK: msr xpsr, r0 @ encoding: [0x80,0xf3,0x03,0x88]
86 @ CHECK: msr xpsr_g, r0 @ encoding: [0x80,0xf3,0x03,0x84]
87 @ CHECK: msr xpsr_nzcvqg, r0 @ encoding: [0x80,0xf3,0x03,0x8c]
6488 @ CHECK: msr ipsr, r0 @ encoding: [0x80,0xf3,0x05,0x80]
6589 @ CHECK: msr epsr, r0 @ encoding: [0x80,0xf3,0x06,0x80]
6690 @ CHECK: msr iepsr, r0 @ encoding: [0x80,0xf3,0x07,0x80]