llvm.org GIT mirror llvm / 09e28e3
Thumb2 M-class MSR instruction support changes This patch implements a few changes related to the Thumb2 M-class MSR instruction: * better handling of unpredictable encodings, * recognition of the _g and _nzcvqg variants by the asm parser only if the DSP extension is available, preferred output of MSR APSR moves with the _<bits> suffix for v7-M. Patch by Petr Pavlu. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216874 91177308-0d34-0410-b5e6-96231b3b80d8 Renato Golin 5 years ago
8 changed file(s) with 175 addition(s) and 103 deletion(s). Raw diff Collapse all Expand all
40124012 //
40134013 // This MRS has a mask field in bits 7-0 and can take more values than
40144014 // the A/R class (a full msr_mask).
4015 def t2MRS_M : T2I<(outs rGPR:$Rd), (ins msr_mask:$mask), NoItinerary,
4016 "mrs", "\t$Rd, $mask", []>,
4015 def t2MRS_M : T2I<(outs rGPR:$Rd), (ins msr_mask:$SYSm), NoItinerary,
4016 "mrs", "\t$Rd, $SYSm", []>,
40174017 Requires<[IsThumb,IsMClass]> {
40184018 bits<4> Rd;
4019 bits<8> mask;
4019 bits<8> SYSm;
40204020 let Inst{31-12} = 0b11110011111011111000;
40214021 let Inst{11-8} = Rd;
4022 let Inst{19-16} = 0b1111;
4023 let Inst{7-0} = mask;
4022 let Inst{7-0} = SYSm;
4023
4024 let Unpredictable{20-16} = 0b11111;
4025 let Unpredictable{13} = 0b1;
40244026 }
40254027
40264028
40764078 let Inst{20} = 0b0;
40774079 let Inst{19-16} = Rn;
40784080 let Inst{15-12} = 0b1000;
4079 let Inst{11-0} = SYSm;
4081 let Inst{11-10} = SYSm{11-10};
4082 let Inst{9-8} = 0b00;
4083 let Inst{7-0} = SYSm{7-0};
4084
4085 let Unpredictable{20} = 0b1;
4086 let Unpredictable{13} = 0b1;
4087 let Unpredictable{9-8} = 0b11;
40804088 }
40814089
40824090
263263 }
264264 bool hasARM() const {
265265 return !(STI.getFeatureBits() & ARM::FeatureNoARM);
266 }
267 bool hasThumb2DSP() const {
268 return STI.getFeatureBits() & ARM::FeatureDSPThumb2;
266269 }
267270
268271 void SwitchMode() {
39273930 // should really only be allowed when writing a special register. Note
39283931 // they get dropped in the MRS instruction reading a special register as
39293932 // the SYSm field is only 8 bits.
3930 //
3931 // FIXME: the _g and _nzcvqg versions are only allowed if the processor
3932 // includes the DSP extension but that is not checked.
39333933 .Case("apsr", 0x800)
39343934 .Case("apsr_nzcvq", 0x800)
39353935 .Case("apsr_g", 0x400)
39593959 .Default(~0U);
39603960
39613961 if (FlagsVal == ~0U)
3962 return MatchOperand_NoMatch;
3963
3964 if (!hasThumb2DSP() && (FlagsVal & 0x400))
3965 // The _g and _nzcvqg versions are only valid if the DSP extension is
3966 // available.
39623967 return MatchOperand_NoMatch;
39633968
39643969 if (!hasV7Ops() && FlagsVal >= 0x811 && FlagsVal <= 0x813)
39753975
39763976 static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val,
39773977 uint64_t Address, const void *Decoder) {
3978 DecodeStatus S = MCDisassembler::Success;
39783979 uint64_t FeatureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
39793980 .getFeatureBits();
39803981 if (FeatureBits & ARM::FeatureMClass) {
40054006 return MCDisassembler::Fail;
40064007 }
40074008
4008 // The ARMv7-M architecture has an additional 2-bit mask value in the MSR
4009 // instruction (bits {11,10}). The mask is used only with apsr, iapsr,
4010 // eapsr and xpsr, it has to be 0b10 in other cases. Bit mask{1} indicates
4011 // if the NZCVQ bits should be moved by the instruction. Bit mask{0}
4012 // indicates the move for the GE{3:0} bits, the mask{0} bit can be set
4013 // only if the processor includes the DSP extension.
4014 if ((FeatureBits & ARM::HasV7Ops) && Inst.getOpcode() == ARM::t2MSR_M) {
4015 unsigned Mask = (Val >> 10) & 3;
4016 if (Mask == 0 || (Mask != 2 && ValLow > 3) ||
4017 (!(FeatureBits & ARM::FeatureDSPThumb2) && Mask == 1))
4018 return MCDisassembler::Fail;
4009 if (Inst.getOpcode() == ARM::t2MSR_M) {
4010 unsigned Mask = fieldFromInstruction(Val, 10, 2);
4011 if (!(FeatureBits & ARM::HasV7Ops)) {
4012 // The ARMv6-M MSR bits {11-10} can be only 0b10, other values are
4013 // unpredictable.
4014 if (Mask != 2)
4015 S = MCDisassembler::SoftFail;
4016 }
4017 else {
4018 // The ARMv7-M architecture stores an additional 2-bit mask value in
4019 // MSR bits {11-10}. The mask is used only with apsr, iapsr, eapsr and
4020 // xpsr, it has to be 0b10 in other cases. Bit mask{1} indicates if
4021 // the NZCVQ bits should be moved by the instruction. Bit mask{0}
4022 // indicates the move for the GE{3:0} bits, the mask{0} bit can be set
4023 // only if the processor includes the DSP extension.
4024 if (Mask == 0 || (Mask != 2 && ValLow > 3) ||
4025 (!(FeatureBits & ARM::FeatureDSPThumb2) && (Mask & 1)))
4026 S = MCDisassembler::SoftFail;
4027 }
40194028 }
40204029 } else {
40214030 // A/R class
40234032 return MCDisassembler::Fail;
40244033 }
40254034 Inst.addOperand(MCOperand::CreateImm(Val));
4026 return MCDisassembler::Success;
4035 return S;
40274036 }
40284037
40294038 static DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Val,
806806 const MCOperand &Op = MI->getOperand(OpNum);
807807 unsigned SpecRegRBit = Op.getImm() >> 4;
808808 unsigned Mask = Op.getImm() & 0xf;
809
810 if (getAvailableFeatures() & ARM::FeatureMClass) {
809 uint64_t FeatureBits = getAvailableFeatures();
810
811 if (FeatureBits & ARM::FeatureMClass) {
811812 unsigned SYSm = Op.getImm();
812813 unsigned Opcode = MI->getOpcode();
813 // For reads of the special registers ignore the "mask encoding" bits
814 // which are only for writes.
815 if (Opcode == ARM::t2MRS_M)
816 SYSm &= 0xff;
814
815 // For writes, handle extended mask bits if the DSP extension is present.
816 if (Opcode == ARM::t2MSR_M && (FeatureBits & ARM::FeatureDSPThumb2)) {
817 switch (SYSm) {
818 case 0x400: O << "apsr_g"; return;
819 case 0xc00: O << "apsr_nzcvqg"; return;
820 case 0x401: O << "iapsr_g"; return;
821 case 0xc01: O << "iapsr_nzcvqg"; return;
822 case 0x402: O << "eapsr_g"; return;
823 case 0xc02: O << "eapsr_nzcvqg"; return;
824 case 0x403: O << "xpsr_g"; return;
825 case 0xc03: O << "xpsr_nzcvqg"; return;
826 }
827 }
828
829 // Handle the basic 8-bit mask.
830 SYSm &= 0xff;
831
832 if (Opcode == ARM::t2MSR_M && (FeatureBits & ARM::HasV7Ops)) {
833 // ARMv7-M deprecates using MSR APSR without a _ qualifier as an
834 // alias for MSR APSR_nzcvq.
835 switch (SYSm) {
836 case 0: O << "apsr_nzcvq"; return;
837 case 1: O << "iapsr_nzcvq"; return;
838 case 2: O << "eapsr_nzcvq"; return;
839 case 3: O << "xpsr_nzcvq"; return;
840 }
841 }
842
817843 switch (SYSm) {
818844 default: llvm_unreachable("Unexpected mask value!");
819 case 0:
820 case 0x800: O << "apsr"; return; // with _nzcvq bits is an alias for aspr
821 case 0x400: O << "apsr_g"; return;
822 case 0xc00: O << "apsr_nzcvqg"; return;
823 case 1:
824 case 0x801: O << "iapsr"; return; // with _nzcvq bits is an alias for iapsr
825 case 0x401: O << "iapsr_g"; return;
826 case 0xc01: O << "iapsr_nzcvqg"; return;
827 case 2:
828 case 0x802: O << "eapsr"; return; // with _nzcvq bits is an alias for eapsr
829 case 0x402: O << "eapsr_g"; return;
830 case 0xc02: O << "eapsr_nzcvqg"; return;
831 case 3:
832 case 0x803: O << "xpsr"; return; // with _nzcvq bits is an alias for xpsr
833 case 0x403: O << "xpsr_g"; return;
834 case 0xc03: O << "xpsr_nzcvqg"; return;
835 case 5:
836 case 0x805: O << "ipsr"; return;
837 case 6:
838 case 0x806: O << "epsr"; return;
839 case 7:
840 case 0x807: O << "iepsr"; return;
841 case 8:
842 case 0x808: O << "msp"; return;
843 case 9:
844 case 0x809: O << "psp"; return;
845 case 0x10:
846 case 0x810: O << "primask"; return;
847 case 0x11:
848 case 0x811: O << "basepri"; return;
849 case 0x12:
850 case 0x812: O << "basepri_max"; return;
851 case 0x13:
852 case 0x813: O << "faultmask"; return;
853 case 0x14:
854 case 0x814: O << "control"; return;
845 case 0: O << "apsr"; return;
846 case 1: O << "iapsr"; return;
847 case 2: O << "eapsr"; return;
848 case 3: O << "xpsr"; return;
849 case 5: O << "ipsr"; return;
850 case 6: O << "epsr"; return;
851 case 7: O << "iepsr"; return;
852 case 8: O << "msp"; return;
853 case 9: O << "psp"; return;
854 case 16: O << "primask"; return;
855 case 17: O << "basepri"; return;
856 case 18: O << "basepri_max"; return;
857 case 19: O << "faultmask"; return;
858 case 20: O << "control"; return;
855859 }
856860 }
857861
None @ RUN: llvm-mc -triple=thumbv7m-apple-darwin -show-encoding < %s | FileCheck %s
1 @ RUN: llvm-mc -triple=thumbv6m -show-encoding < %s | FileCheck %s
0 @ RUN: llvm-mc -triple=thumbv6m -show-encoding < %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-V6M %s
1 @ RUN: llvm-mc -triple=thumbv7m -show-encoding < %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-V7M %s
2
23 .syntax unified
3 .globl _func
44
55 @ Check that the assembler can handle the documented syntax from the ARM ARM.
66 @ These tests test instruction encodings specific to v6m & v7m (FeatureMClass).
3939
4040 msr apsr, r0
4141 msr apsr_nzcvq, r0
42 msr apsr_g, r0
43 msr apsr_nzcvqg, r0
4442 msr iapsr, r0
4543 msr iapsr_nzcvq, r0
46 msr iapsr_g, r0
47 msr iapsr_nzcvqg, r0
4844 msr eapsr, r0
4945 msr eapsr_nzcvq, r0
50 msr eapsr_g, r0
51 msr eapsr_nzcvqg, r0
5246 msr xpsr, r0
5347 msr xpsr_nzcvq, r0
54 msr xpsr_g, r0
55 msr xpsr_nzcvqg, r0
5648 msr ipsr, r0
5749 msr epsr, r0
5850 msr iepsr, r0
6153 msr primask, r0
6254 msr control, r0
6355
64 @ CHECK: msr apsr, r0 @ encoding: [0x80,0xf3,0x00,0x88]
65 @ CHECK: msr apsr, r0 @ encoding: [0x80,0xf3,0x00,0x88]
66 @ CHECK: msr apsr_g, r0 @ encoding: [0x80,0xf3,0x00,0x84]
67 @ CHECK: msr apsr_nzcvqg, r0 @ encoding: [0x80,0xf3,0x00,0x8c]
68 @ CHECK: msr iapsr, r0 @ encoding: [0x80,0xf3,0x01,0x88]
69 @ CHECK: msr iapsr, r0 @ encoding: [0x80,0xf3,0x01,0x88]
70 @ CHECK: msr iapsr_g, r0 @ encoding: [0x80,0xf3,0x01,0x84]
71 @ CHECK: msr iapsr_nzcvqg, r0 @ encoding: [0x80,0xf3,0x01,0x8c]
72 @ CHECK: msr eapsr, r0 @ encoding: [0x80,0xf3,0x02,0x88]
73 @ CHECK: msr eapsr, r0 @ encoding: [0x80,0xf3,0x02,0x88]
74 @ CHECK: msr eapsr_g, r0 @ encoding: [0x80,0xf3,0x02,0x84]
75 @ CHECK: msr eapsr_nzcvqg, r0 @ encoding: [0x80,0xf3,0x02,0x8c]
76 @ CHECK: msr xpsr, r0 @ encoding: [0x80,0xf3,0x03,0x88]
77 @ CHECK: msr xpsr, r0 @ encoding: [0x80,0xf3,0x03,0x88]
78 @ CHECK: msr xpsr_g, r0 @ encoding: [0x80,0xf3,0x03,0x84]
79 @ CHECK: msr xpsr_nzcvqg, r0 @ encoding: [0x80,0xf3,0x03,0x8c]
56 @ CHECK-V6M: msr apsr, r0 @ encoding: [0x80,0xf3,0x00,0x88]
57 @ CHECK-V6M: msr apsr, r0 @ encoding: [0x80,0xf3,0x00,0x88]
58 @ CHECK-V6M: msr iapsr, r0 @ encoding: [0x80,0xf3,0x01,0x88]
59 @ CHECK-V6M: msr iapsr, r0 @ encoding: [0x80,0xf3,0x01,0x88]
60 @ CHECK-V6M: msr eapsr, r0 @ encoding: [0x80,0xf3,0x02,0x88]
61 @ CHECK-V6M: msr eapsr, r0 @ encoding: [0x80,0xf3,0x02,0x88]
62 @ CHECK-V6M: msr xpsr, r0 @ encoding: [0x80,0xf3,0x03,0x88]
63 @ CHECK-V6M: msr xpsr, r0 @ encoding: [0x80,0xf3,0x03,0x88]
64 @ CHECK-V7M: msr apsr_nzcvq, r0 @ encoding: [0x80,0xf3,0x00,0x88]
65 @ CHECK-V7M: msr apsr_nzcvq, r0 @ encoding: [0x80,0xf3,0x00,0x88]
66 @ CHECK-V7M: msr iapsr_nzcvq, r0 @ encoding: [0x80,0xf3,0x01,0x88]
67 @ CHECK-V7M: msr iapsr_nzcvq, r0 @ encoding: [0x80,0xf3,0x01,0x88]
68 @ CHECK-V7M: msr eapsr_nzcvq, r0 @ encoding: [0x80,0xf3,0x02,0x88]
69 @ CHECK-V7M: msr eapsr_nzcvq, r0 @ encoding: [0x80,0xf3,0x02,0x88]
70 @ CHECK-V7M: msr xpsr_nzcvq, r0 @ encoding: [0x80,0xf3,0x03,0x88]
71 @ CHECK-V7M: msr xpsr_nzcvq, r0 @ encoding: [0x80,0xf3,0x03,0x88]
8072 @ CHECK: msr ipsr, r0 @ encoding: [0x80,0xf3,0x05,0x88]
8173 @ CHECK: msr epsr, r0 @ encoding: [0x80,0xf3,0x06,0x88]
8274 @ CHECK: msr iepsr, r0 @ encoding: [0x80,0xf3,0x07,0x88]
0 @ RUN: llvm-mc -triple=thumbv7em -show-encoding < %s | FileCheck %s
1 @ RUN: not llvm-mc -triple=thumbv7m -show-encoding 2>&1 < %s | FileCheck --check-prefix=CHECK-V7M %s
2
3 .syntax unified
4
5 @ Check that the assembler can handle the documented syntax from the ARM ARM.
6 @ These tests test instruction encodings specific to ARMv7E-M.
7
8 @------------------------------------------------------------------------------
9 @ MSR
10 @------------------------------------------------------------------------------
11
12 msr apsr_g, r0
13 msr apsr_nzcvqg, r0
14 msr iapsr_g, r0
15 msr iapsr_nzcvqg, r0
16 msr eapsr_g, r0
17 msr eapsr_nzcvqg, r0
18 msr xpsr_g, r0
19 msr xpsr_nzcvqg, r0
20
21 @ CHECK: msr apsr_g, r0 @ encoding: [0x80,0xf3,0x00,0x84]
22 @ CHECK: msr apsr_nzcvqg, r0 @ encoding: [0x80,0xf3,0x00,0x8c]
23 @ CHECK: msr iapsr_g, r0 @ encoding: [0x80,0xf3,0x01,0x84]
24 @ CHECK: msr iapsr_nzcvqg, r0 @ encoding: [0x80,0xf3,0x01,0x8c]
25 @ CHECK: msr eapsr_g, r0 @ encoding: [0x80,0xf3,0x02,0x84]
26 @ CHECK: msr eapsr_nzcvqg, r0 @ encoding: [0x80,0xf3,0x02,0x8c]
27 @ CHECK: msr xpsr_g, r0 @ encoding: [0x80,0xf3,0x03,0x84]
28 @ CHECK: msr xpsr_nzcvqg, r0 @ encoding: [0x80,0xf3,0x03,0x8c]
29 @ CHECK-V7M: error: invalid operand for instruction
30 @ CHECK-V7M-NEXT: msr apsr_g, r0
31 @ CHECK-V7M-NEXT: ^
32 @ CHECK-V7M: error: invalid operand for instruction
33 @ CHECK-V7M-NEXT: msr apsr_nzcvqg, r0
34 @ CHECK-V7M-NEXT: ^
35 @ CHECK-V7M: error: invalid operand for instruction
36 @ CHECK-V7M-NEXT: msr iapsr_g, r0
37 @ CHECK-V7M-NEXT: ^
38 @ CHECK-V7M: error: invalid operand for instruction
39 @ CHECK-V7M-NEXT: msr iapsr_nzcvqg, r0
40 @ CHECK-V7M-NEXT: ^
41 @ CHECK-V7M: error: invalid operand for instruction
42 @ CHECK-V7M-NEXT: msr eapsr_g, r0
43 @ CHECK-V7M-NEXT: ^
44 @ CHECK-V7M: error: invalid operand for instruction
45 @ CHECK-V7M-NEXT: msr eapsr_nzcvqg, r0
46 @ CHECK-V7M-NEXT: ^
47 @ CHECK-V7M: error: invalid operand for instruction
48 @ CHECK-V7M-NEXT: msr xpsr_g, r0
49 @ CHECK-V7M-NEXT: ^
50 @ CHECK-V7M: error: invalid operand for instruction
51 @ CHECK-V7M-NEXT: msr xpsr_nzcvqg, r0
52 @ CHECK-V7M-NEXT: ^
None # RUN: not llvm-mc -disassemble %s -triple=thumbv7-apple-darwin9 -mcpu cortex-m3 2>&1 | FileCheck %s
0 # RUN: not llvm-mc -disassemble %s -triple=thumbv7em 2>&1 | FileCheck --check-prefix=CHECK %s
1 # RUN: not llvm-mc -disassemble %s -triple=thumbv7m 2>&1 | FileCheck --check-prefix=CHECK --check-prefix=CHECK-V7M %s
12
23 #------------------------------------------------------------------------------
34 # Undefined encodings for mrs
1314 #------------------------------------------------------------------------------
1415
1516 # invalid mask = '00'
16 # CHECK: warning: invalid instruction encoding
17 # CHECK: warning: potentially undefined instruction encoding
1718 # CHECK-NEXT: [0x80 0xf3 0x00 0x80]
1819 [0x80 0xf3 0x00 0x80]
1920
2021 # invalid mask = '11' with SYSm not in {0..3}
21 # CHECK: warning: invalid instruction encoding
22 # CHECK-NEXT: [0x80 0xf3 0x04 0x8c]
23 [0x80 0xf3 0x04 0x8c]
22 # CHECK: warning: potentially undefined instruction encoding
23 # CHECK-NEXT: [0x80 0xf3 0x05 0x8c]
24 [0x80 0xf3 0x05 0x8c]
2425
25 # invalid mask = '01' (Cortex-M3 does not have the DSP extension)
26 # CHECK: warning: invalid instruction encoding
27 # CHECK-NEXT: [0x80 0xf3 0x00 0x84]
26 # invalid mask = '01' (ThumbV7M does not have the DSP extension)
27 # CHECK-V7M: warning: potentially undefined instruction encoding
28 # CHECK-V7M-NEXT: [0x80 0xf3 0x00 0x84]
2829 [0x80 0xf3 0x00 0x84]
2930
3031 # invalid SYSm
None # RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 -mcpu cortex-m4 | FileCheck %s
0 # RUN: llvm-mc --disassemble %s -triple=thumbv7em | FileCheck %s
11
22 #------------------------------------------------------------------------------
33 # MRS
3838 # MSR
3939 #------------------------------------------------------------------------------
4040
41 # CHECK: msr apsr, r0
41 # CHECK: msr apsr_nzcvq, r0
4242 # CHECK: msr apsr_g, r0
4343 # CHECK: msr apsr_nzcvqg, r0
4444
4646 0x80 0xf3 0x00 0x84
4747 0x80 0xf3 0x00 0x8c
4848
49 # CHECK: msr iapsr, r0
49 # CHECK: msr iapsr_nzcvq, r0
5050 # CHECK: msr iapsr_g, r0
5151 # CHECK: msr iapsr_nzcvqg, r0
5252
5454 0x80 0xf3 0x01 0x84
5555 0x80 0xf3 0x01 0x8c
5656
57 # CHECK: msr eapsr, r0
57 # CHECK: msr eapsr_nzcvq, r0
5858 # CHECK: msr eapsr_g, r0
5959 # CHECK: msr eapsr_nzcvqg, r0
6060
6262 0x80 0xf3 0x02 0x84
6363 0x80 0xf3 0x02 0x8c
6464
65 # CHECK: msr xpsr, r0
65 # CHECK: msr xpsr_nzcvq, r0
6666 # CHECK: msr xpsr_g, r0
6767 # CHECK: msr xpsr_nzcvqg, r0
6868