llvm.org GIT mirror llvm / 2edda52
[ARM] Replace fp-only-sp and d16 with fp64 and d32. Those two subtarget features were awkward because their semantics are reversed: each one indicates the _lack_ of support for something in the architecture, rather than the presence. As a consequence, you don't get the behavior you want if you combine two sets of feature bits. Each SubtargetFeature for an FP architecture version now comes in four versions, one for each combination of those options. So you can still say (for example) '+vfp2' in a feature string and it will mean what it's always meant, but there's a new string '+vfp2d16sp' meaning the version without those extra options. A lot of this change is just mechanically replacing positive checks for the old features with negative checks for the new ones. But one more interesting change is that I've rearranged getFPUFeatures() so that the main FPU feature is appended to the output list *before* rather than after the features derived from the Restriction field, so that -fp64 and -d32 can override defaults added by the main feature. Reviewers: dmgreen, samparker, SjoerdMeijer Subscribers: srhines, javed.absar, eraman, kristof.beyls, hiraditya, zzheng, Petar.Avramovic, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D60691 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@361845 91177308-0d34-0410-b5e6-96231b3b80d8 Simon Tatham 2 months ago
45 changed file(s) with 313 addition(s) and 259 deletion(s). Raw diff Collapse all Expand all
139139 /// Apply a feature flag and return the re-computed feature bits, including
140140 /// all feature bits implied by the flag.
141141 FeatureBitset ApplyFeatureFlag(StringRef FS);
142
143 /// Set/clear additional feature bits, including all other bits they imply.
144 FeatureBitset SetFeatureBitsTransitively(const FeatureBitset& FB);
145 FeatureBitset ClearFeatureBitsTransitively(const FeatureBitset &FB);
142146
143147 /// Check whether the subtarget features are enabled/disabled as per
144148 /// the provided string, ignoring all other features.
191191
192192 FeatureBitset MCSubtargetInfo::ToggleFeature(const FeatureBitset &FB) {
193193 FeatureBits ^= FB;
194 return FeatureBits;
195 }
196
197 FeatureBitset MCSubtargetInfo::SetFeatureBitsTransitively(
198 const FeatureBitset &FB) {
199 SetImpliedBits(FeatureBits, FB, ProcFeatures);
200 return FeatureBits;
201 }
202
203 FeatureBitset MCSubtargetInfo::ClearFeatureBitsTransitively(
204 const FeatureBitset &FB) {
205 for (unsigned I = 0, E = FB.size(); I < E; I++) {
206 if (FB[I]) {
207 FeatureBits.reset(I);
208 ClearImpliedBits(FeatureBits, I, ProcFeatures);
209 }
210 }
194211 return FeatureBits;
195212 }
196213
193193 default:
194194 break;
195195 case ARMBuildAttrs::Not_Allowed:
196 Features.AddFeature("vfp2", false);
197 Features.AddFeature("vfp3", false);
198 Features.AddFeature("vfp4", false);
196 Features.AddFeature("vfp2d16sp", false);
197 Features.AddFeature("vfp3d16sp", false);
198 Features.AddFeature("vfp4d16sp", false);
199199 break;
200200 case ARMBuildAttrs::AllowFPv2:
201201 Features.AddFeature("vfp2");
158158 if (FPUKind >= FK_LAST || FPUKind == FK_INVALID)
159159 return false;
160160
161 // fp-only-sp and d16 subtarget features are independent of each other, so we
162 // must enable/disable both.
163 switch (FPUNames[FPUKind].Restriction) {
164 case FPURestriction::SP_D16:
165 Features.push_back("+fp-only-sp");
166 Features.push_back("+d16");
167 break;
168 case FPURestriction::D16:
169 Features.push_back("-fp-only-sp");
170 Features.push_back("+d16");
171 break;
172 case FPURestriction::None:
173 Features.push_back("-fp-only-sp");
174 Features.push_back("-d16");
175 break;
176 }
177
178161 // FPU version subtarget features are inclusive of lower-numbered ones, so
179162 // enable the one corresponding to this version and disable all that are
180163 // higher. We also have to make sure to disable fp16 when vfp4 is disabled,
213196 Features.push_back("-vfp4");
214197 Features.push_back("-fp-armv8");
215198 break;
199 }
200
201 // fp64 and d32 subtarget features are independent of each other, so we
202 // must disable/enable both.
203 if (FPUKind == FK_NONE) {
204 Features.push_back("-fp64");
205 Features.push_back("-d32");
206 } else {
207 switch (FPUNames[FPUKind].Restriction) {
208 case FPURestriction::SP_D16:
209 Features.push_back("-fp64");
210 Features.push_back("-d32");
211 break;
212 case FPURestriction::D16:
213 Features.push_back("+fp64");
214 Features.push_back("-d32");
215 break;
216 case FPURestriction::None:
217 Features.push_back("+fp64");
218 Features.push_back("+d32");
219 break;
220 }
216221 }
217222
218223 // crypto includes neon, so we handle this similarly to FPU version.
3131 //
3232
3333 // Floating Point, HW Division and Neon Support
34 def FeatureVFP2 : SubtargetFeature<"vfp2", "HasVFPv2", "true",
35 "Enable VFP2 instructions">;
36
37 def FeatureVFP3 : SubtargetFeature<"vfp3", "HasVFPv3", "true",
38 "Enable VFP3 instructions",
39 [FeatureVFP2]>;
34 def FeatureFP64 : SubtargetFeature<"fp64", "HasFP64", "true",
35 "Floating point unit supports "
36 "double precision">;
37
38 def FeatureD32 : SubtargetFeature<"d32", "HasD32", "true",
39 "Extend FP to 32 double registers">;
40
41 multiclass VFPver
42 list prev = [],
43 list otherimplies = []> {
44 def _D16_SP: SubtargetFeature<
45 name#"d16sp", query#"D16SP", "true",
46 description#" with only 16 d-registers and no double precision",
47 !foreach(v, prev, !cast(v # "_D16_SP")) # otherimplies>;
48 def _SP: SubtargetFeature<
49 name#"sp", query#"SP", "true",
50 description#" with no double precision",
51 !foreach(v, prev, !cast(v # "_SP")) #
52 otherimplies # [FeatureD32, !cast(NAME # "_D16_SP")]>;
53 def _D16: SubtargetFeature<
54 name#"d16", query#"D16", "true",
55 description#" with only 16 d-registers",
56 !foreach(v, prev, !cast(v # "_D16")) #
57 otherimplies # [FeatureFP64, !cast(NAME # "_D16_SP")]>;
58 def "": SubtargetFeature<
59 name, query, "true", description,
60 prev # otherimplies # [
61 !cast(NAME # "_D16"),
62 !cast(NAME # "_SP")]>;
63 }
64
65 defm FeatureVFP2: VFPver<"vfp2", "HasVFPv2", "Enable VFP2 instructions">;
66 defm FeatureVFP3: VFPver<"vfp3", "HasVFPv3", "Enable VFP3 instructions",
67 [FeatureVFP2]>;
4068
4169 def FeatureNEON : SubtargetFeature<"neon", "HasNEON", "true",
4270 "Enable NEON instructions",
4674 "Enable half-precision "
4775 "floating point">;
4876
49 def FeatureVFP4 : SubtargetFeature<"vfp4", "HasVFPv4", "true",
50 "Enable VFP4 instructions",
51 [FeatureVFP3, FeatureFP16]>;
52
53 def FeatureFPARMv8 : SubtargetFeature<"fp-armv8", "HasFPARMv8",
54 "true", "Enable ARMv8 FP",
55 [FeatureVFP4]>;
77 defm FeatureVFP4: VFPver<"vfp4", "HasVFPv4", "Enable VFP4 instructions",
78 [FeatureVFP3], [FeatureFP16]>;
79
80 defm FeatureFPARMv8: VFPver<"fp-armv8", "HasFPARMv8", "Enable ARMv8 FP",
81 [FeatureVFP4]>;
5682
5783 def FeatureFullFP16 : SubtargetFeature<"fullfp16", "HasFullFP16", "true",
5884 "Enable full half-precision "
5985 "floating point",
60 [FeatureFPARMv8]>;
86 [FeatureFPARMv8_D16_SP]>;
6187
6288 def FeatureFP16FML : SubtargetFeature<"fp16fml", "HasFP16FML", "true",
6389 "Enable full half-precision "
6490 "floating point fml instructions",
6591 [FeatureFullFP16]>;
66
67 def FeatureVFPOnlySP : SubtargetFeature<"fp-only-sp", "FPOnlySP", "true",
68 "Floating point unit supports "
69 "single precision only">;
70
71 def FeatureD16 : SubtargetFeature<"d16", "HasD16", "true",
72 "Restrict FP to 16 double registers">;
7392
7493 def FeatureHWDivThumb : SubtargetFeature<"hwdiv",
7594 "HasHardwareDivideInThumb", "true",
942961 FeatureHasRetAddrStack,
943962 FeatureSlowFPBrcc,
944963 FeatureHasSlowFPVMLx,
945 FeatureVFP3,
946 FeatureD16,
964 FeatureVFP3_D16,
947965 FeatureAvoidPartialCPSR]>;
948966
949967 def : ProcessorModel<"cortex-r5", CortexA8Model, [ARMv7r, ProcR5,
950968 FeatureHasRetAddrStack,
951 FeatureVFP3,
952 FeatureD16,
969 FeatureVFP3_D16,
953970 FeatureSlowFPBrcc,
954971 FeatureHWDivARM,
955972 FeatureHasSlowFPVMLx,
957974
958975 def : ProcessorModel<"cortex-r7", CortexA8Model, [ARMv7r, ProcR7,
959976 FeatureHasRetAddrStack,
960 FeatureVFP3,
961 FeatureD16,
977 FeatureVFP3_D16,
962978 FeatureFP16,
963979 FeatureMP,
964980 FeatureSlowFPBrcc,
968984
969985 def : ProcessorModel<"cortex-r8", CortexA8Model, [ARMv7r,
970986 FeatureHasRetAddrStack,
971 FeatureVFP3,
972 FeatureD16,
987 FeatureVFP3_D16,
973988 FeatureFP16,
974989 FeatureMP,
975990 FeatureSlowFPBrcc,
9901005 FeatureUseAA,
9911006 FeatureHasNoBranchPredictor]>;
9921007
993 def : ProcessorModel<"cortex-m4", CortexM4Model, [ARMv7em,
994 FeatureVFP4,
995 FeatureVFPOnlySP,
996 FeatureD16,
1008 def : ProcessorModel<"cortex-m4", CortexM4Model, [ARMv7em,
1009 FeatureVFP4_D16_SP,
9971010 FeaturePrefLoopAlign32,
9981011 FeatureHasSlowFPVMLx,
9991012 FeatureUseMISched,
10011014 FeatureHasNoBranchPredictor]>;
10021015
10031016 def : ProcNoItin<"cortex-m7", [ARMv7em,
1004 FeatureFPARMv8,
1005 FeatureD16]>;
1017 FeatureFPARMv8_D16]>;
10061018
10071019 def : ProcNoItin<"cortex-m23", [ARMv8mBaseline,
10081020 FeatureNoMovt]>;
10091021
10101022 def : ProcessorModel<"cortex-m33", CortexM4Model, [ARMv8mMainline,
10111023 FeatureDSP,
1012 FeatureFPARMv8,
1013 FeatureD16,
1014 FeatureVFPOnlySP,
1024 FeatureFPARMv8_D16_SP,
10151025 FeaturePrefLoopAlign32,
10161026 FeatureHasSlowFPVMLx,
10171027 FeatureUseMISched,
10201030
10211031 def : ProcessorModel<"cortex-m35p", CortexM4Model, [ARMv8mMainline,
10221032 FeatureDSP,
1023 FeatureFPARMv8,
1024 FeatureD16,
1025 FeatureVFPOnlySP,
1033 FeatureFPARMv8_D16_SP,
10261034 FeaturePrefLoopAlign32,
10271035 FeatureHasSlowFPVMLx,
10281036 FeatureUseMISched,
656656 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
657657 ARMBuildAttrs::IEEEDenormals);
658658 else {
659 if (!STI.hasVFP2()) {
659 if (!STI.hasVFP2Base()) {
660660 // When the target doesn't have an FPU (by design or
661661 // intention), the assumptions made on the software support
662662 // mirror that of the equivalent hardware support *if it
666666 if (STI.hasV7Ops())
667667 ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal,
668668 ARMBuildAttrs::PreserveFPSign);
669 } else if (STI.hasVFP3()) {
669 } else if (STI.hasVFP3Base()) {
670670 // In VFPv4, VFPv4U, VFPv3, or VFPv3U, it is preserved. That is,
671671 // the sign bit of the zero matches the sign bit of the input or
672672 // result that is being flushed to zero.
132132 ScheduleHazardRecognizer *ARMBaseInstrInfo::
133133 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
134134 const ScheduleDAG *DAG) const {
135 if (Subtarget.isThumb2() || Subtarget.hasVFP2())
135 if (Subtarget.isThumb2() || Subtarget.hasVFP2Base())
136136 return (ScheduleHazardRecognizer *)new ARMHazardRecognizer(II, DAG);
137137 return TargetInstrInfo::CreateTargetPostRAHazardRecognizer(II, DAG);
138138 }
829829 Opc = ARM::VMOVRS;
830830 else if (SPRDest && GPRSrc)
831831 Opc = ARM::VMOVSR;
832 else if (ARM::DPRRegClass.contains(DestReg, SrcReg) && !Subtarget.isFPOnlySP())
832 else if (ARM::DPRRegClass.contains(DestReg, SrcReg) && Subtarget.hasFP64())
833833 Opc = ARM::VMOVD;
834834 else if (ARM::QPRRegClass.contains(DestReg, SrcReg))
835835 Opc = ARM::VORRq;
889889 BeginIdx = ARM::dsub_0;
890890 SubRegs = 4;
891891 Spacing = 2;
892 } else if (ARM::DPRRegClass.contains(DestReg, SrcReg) && Subtarget.isFPOnlySP()) {
892 } else if (ARM::DPRRegClass.contains(DestReg, SrcReg) &&
893 !Subtarget.hasFP64()) {
893894 Opc = ARM::VMOVS;
894895 BeginIdx = ARM::ssub_0;
895896 SubRegs = 2;
14801481 // copyPhysReg() calls. Look for VMOVS instructions that can legally be
14811482 // widened to VMOVD. We prefer the VMOVD when possible because it may be
14821483 // changed into a VORR that can go down the NEON pipeline.
1483 if (!MI.isCopy() || Subtarget.dontWidenVMOVS() || Subtarget.isFPOnlySP())
1484 if (!MI.isCopy() || Subtarget.dontWidenVMOVS() || !Subtarget.hasFP64())
14841485 return false;
14851486
14861487 // Look for a copy between even S-registers. That is where we keep floats
148148 const uint32_t *
149149 ARMBaseRegisterInfo::getSjLjDispatchPreservedMask(const MachineFunction &MF) const {
150150 const ARMSubtarget &STI = MF.getSubtarget();
151 if (!STI.useSoftFloat() && STI.hasVFP2() && !STI.isThumb1Only())
151 if (!STI.useSoftFloat() && STI.hasVFP2Base() && !STI.isThumb1Only())
152152 return CSR_NoRegs_RegMask;
153153 else
154154 return CSR_FPRegs_RegMask;
192192 if (STI.isR9Reserved())
193193 markSuperRegs(Reserved, ARM::R9);
194194 // Reserve D16-D31 if the subtarget doesn't support them.
195 if (!STI.hasVFP3() || STI.hasD16()) {
195 if (!STI.hasD32()) {
196196 static_assert(ARM::D31 == ARM::D16 + 15, "Register list not consecutive!");
197197 for (unsigned R = 0; R < 16; ++R)
198198 markSuperRegs(Reserved, ARM::D16 + R);
440440 }
441441
442442 // Require VFP2 for loading fp constants.
443 if (!Subtarget->hasVFP2()) return false;
443 if (!Subtarget->hasVFP2Base()) return false;
444444
445445 // MachineConstantPool wants an explicit alignment.
446446 unsigned Align = DL.getPrefTypeAlignment(CFP->getType());
968968 RC = isThumb2 ? &ARM::rGPRRegClass : &ARM::GPRnopcRegClass;
969969 break;
970970 case MVT::f32:
971 if (!Subtarget->hasVFP2()) return false;
971 if (!Subtarget->hasVFP2Base()) return false;
972972 // Unaligned loads need special handling. Floats require word-alignment.
973973 if (Alignment && Alignment < 4) {
974974 needVMOV = true;
981981 }
982982 break;
983983 case MVT::f64:
984 if (!Subtarget->hasVFP2()) return false;
984 // Can load and store double precision even without FeatureFP64
985 if (!Subtarget->hasVFP2Base()) return false;
985986 // FIXME: Unaligned loads need special handling. Doublewords require
986987 // word-alignment.
987988 if (Alignment && Alignment < 4)
11061107 }
11071108 break;
11081109 case MVT::f32:
1109 if (!Subtarget->hasVFP2()) return false;
1110 if (!Subtarget->hasVFP2Base()) return false;
11101111 // Unaligned stores need special handling. Floats require word-alignment.
11111112 if (Alignment && Alignment < 4) {
11121113 unsigned MoveReg = createResultReg(TLI.getRegClassFor(MVT::i32));
11211122 }
11221123 break;
11231124 case MVT::f64:
1124 if (!Subtarget->hasVFP2()) return false;
1125 // Can load and store double precision even without FeatureFP64
1126 if (!Subtarget->hasVFP2Base()) return false;
11251127 // FIXME: Unaligned stores need special handling. Doublewords require
11261128 // word-alignment.
11271129 if (Alignment && Alignment < 4)
13521354 if (!SrcEVT.isSimple()) return false;
13531355 MVT SrcVT = SrcEVT.getSimpleVT();
13541356
1355 if (Ty->isFloatTy() && !Subtarget->hasVFP2())
1356 return false;
1357
1358 if (Ty->isDoubleTy() && (!Subtarget->hasVFP2() || Subtarget->isFPOnlySP()))
1357 if (Ty->isFloatTy() && !Subtarget->hasVFP2Base())
1358 return false;
1359
1360 if (Ty->isDoubleTy() && (!Subtarget->hasVFP2Base() || !Subtarget->hasFP64()))
13591361 return false;
13601362
13611363 // Check to see if the 2nd operand is a constant that we can encode directly
15051507
15061508 bool ARMFastISel::SelectFPExt(const Instruction *I) {
15071509 // Make sure we have VFP and that we're extending float to double.
1508 if (!Subtarget->hasVFP2() || Subtarget->isFPOnlySP()) return false;
1510 if (!Subtarget->hasVFP2Base() || !Subtarget->hasFP64()) return false;
15091511
15101512 Value *V = I->getOperand(0);
15111513 if (!I->getType()->isDoubleTy() ||
15241526
15251527 bool ARMFastISel::SelectFPTrunc(const Instruction *I) {
15261528 // Make sure we have VFP and that we're truncating double to float.
1527 if (!Subtarget->hasVFP2() || Subtarget->isFPOnlySP()) return false;
1529 if (!Subtarget->hasVFP2Base() || !Subtarget->hasFP64()) return false;
15281530
15291531 Value *V = I->getOperand(0);
15301532 if (!(I->getType()->isFloatTy() &&
15431545
15441546 bool ARMFastISel::SelectIToFP(const Instruction *I, bool isSigned) {
15451547 // Make sure we have VFP.
1546 if (!Subtarget->hasVFP2()) return false;
1548 if (!Subtarget->hasVFP2Base()) return false;
15471549
15481550 MVT DstVT;
15491551 Type *Ty = I->getType();
15751577
15761578 unsigned Opc;
15771579 if (Ty->isFloatTy()) Opc = isSigned ? ARM::VSITOS : ARM::VUITOS;
1578 else if (Ty->isDoubleTy() && !Subtarget->isFPOnlySP())
1580 else if (Ty->isDoubleTy() && Subtarget->hasFP64())
15791581 Opc = isSigned ? ARM::VSITOD : ARM::VUITOD;
15801582 else return false;
15811583
15881590
15891591 bool ARMFastISel::SelectFPToI(const Instruction *I, bool isSigned) {
15901592 // Make sure we have VFP.
1591 if (!Subtarget->hasVFP2()) return false;
1593 if (!Subtarget->hasVFP2Base()) return false;
15921594
15931595 MVT DstVT;
15941596 Type *RetTy = I->getType();
16011603 unsigned Opc;
16021604 Type *OpTy = I->getOperand(0)->getType();
16031605 if (OpTy->isFloatTy()) Opc = isSigned ? ARM::VTOSIZS : ARM::VTOUIZS;
1604 else if (OpTy->isDoubleTy() && !Subtarget->isFPOnlySP())
1606 else if (OpTy->isDoubleTy() && Subtarget->hasFP64())
16051607 Opc = isSigned ? ARM::VTOSIZD : ARM::VTOUIZD;
16061608 else return false;
16071609
18071809 // if we have them.
18081810 // FIXME: It'd be nice to use NEON instructions.
18091811 Type *Ty = I->getType();
1810 if (Ty->isFloatTy() && !Subtarget->hasVFP2())
1811 return false;
1812 if (Ty->isDoubleTy() && (!Subtarget->hasVFP2() || Subtarget->isFPOnlySP()))
1812 if (Ty->isFloatTy() && !Subtarget->hasVFP2Base())
1813 return false;
1814 if (Ty->isDoubleTy() && (!Subtarget->hasVFP2Base() || !Subtarget->hasFP64()))
18131815 return false;
18141816
18151817 unsigned Opc;
18511853 default:
18521854 report_fatal_error("Unsupported calling convention");
18531855 case CallingConv::Fast:
1854 if (Subtarget->hasVFP2() && !isVarArg) {
1856 if (Subtarget->hasVFP2Base() && !isVarArg) {
18551857 if (!Subtarget->isAAPCS_ABI())
18561858 return (Return ? RetFastCC_ARM_APCS : FastCC_ARM_APCS);
18571859 // For AAPCS ABI targets, just use VFP variant of the calling convention.
18621864 case CallingConv::CXX_FAST_TLS:
18631865 // Use target triple & subtarget features to do actual dispatch.
18641866 if (Subtarget->isAAPCS_ABI()) {
1865 if (Subtarget->hasVFP2() &&
1867 if (Subtarget->hasVFP2Base() &&
18661868 TM.Options.FloatABIType == FloatABI::Hard && !isVarArg)
18671869 return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP);
18681870 else
19311933 case MVT::i32:
19321934 break;
19331935 case MVT::f32:
1934 if (!Subtarget->hasVFP2())
1936 if (!Subtarget->hasVFP2Base())
19351937 return false;
19361938 break;
19371939 case MVT::f64:
1938 if (!Subtarget->hasVFP2())
1940 if (!Subtarget->hasVFP2Base())
19391941 return false;
19401942 break;
19411943 }
40424042
40434043 // If an opcode was found then we can lower the read to a VFP instruction.
40444044 if (Opcode) {
4045 if (!Subtarget->hasVFP2())
4045 if (!Subtarget->hasVFP2Base())
40464046 return false;
4047 if (Opcode == ARM::VMRS_MVFR2 && !Subtarget->hasFPARMv8())
4047 if (Opcode == ARM::VMRS_MVFR2 && !Subtarget->hasFPARMv8Base())
40484048 return false;
40494049
40504050 Ops = { getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32),
41534153 .Default(0);
41544154
41554155 if (Opcode) {
4156 if (!Subtarget->hasVFP2())
4156 if (!Subtarget->hasVFP2Base())
41574157 return false;
41584158 Ops = { N->getOperand(2), getAL(CurDAG, DL),
41594159 CurDAG->getRegister(0, MVT::i32), N->getOperand(0) };
240240
241241 if (Subtarget->isTargetMachO()) {
242242 // Uses VFP for Thumb libfuncs if available.
243 if (Subtarget->isThumb() && Subtarget->hasVFP2() &&
243 if (Subtarget->isThumb() && Subtarget->hasVFP2Base() &&
244244 Subtarget->hasARMOps() && !Subtarget->useSoftFloat()) {
245245 static const struct {
246246 const RTLIB::Libcall Op;
509509 else
510510 addRegisterClass(MVT::i32, &ARM::GPRRegClass);
511511
512 if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2() &&
512 if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2Base() &&
513513 !Subtarget->isThumb1Only()) {
514514 addRegisterClass(MVT::f32, &ARM::SPRRegClass);
515515 addRegisterClass(MVT::f64, &ARM::DPRRegClass);
697697 setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::v2i64, Custom);
698698
699699 // NEON only has FMA instructions as of VFP4.
700 if (!Subtarget->hasVFP4()) {
700 if (!Subtarget->hasVFP4Base()) {
701701 setOperationAction(ISD::FMA, MVT::v2f32, Expand);
702702 setOperationAction(ISD::FMA, MVT::v4f32, Expand);
703703 }
731731 }
732732 }
733733
734 if (Subtarget->isFPOnlySP()) {
734 if (!Subtarget->hasFP64()) {
735735 // When targeting a floating-point unit with only single-precision
736736 // operations, f64 is legal for the few double-precision instructions which
737737 // are present However, no double-precision operations other than moves,
10291029 }
10301030 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
10311031
1032 if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2() &&
1032 if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2Base() &&
10331033 !Subtarget->isThumb1Only()) {
10341034 // Turn f64->i64 into VMOVRRD, i64 -> f64 to VMOVDRR
10351035 // iff target supports vfp2.
10791079 setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
10801080 setOperationAction(ISD::FREM, MVT::f64, Expand);
10811081 setOperationAction(ISD::FREM, MVT::f32, Expand);
1082 if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2() &&
1082 if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2Base() &&
10831083 !Subtarget->isThumb1Only()) {
10841084 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom);
10851085 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom);
10871087 setOperationAction(ISD::FPOW, MVT::f64, Expand);
10881088 setOperationAction(ISD::FPOW, MVT::f32, Expand);
10891089
1090 if (!Subtarget->hasVFP4()) {
1090 if (!Subtarget->hasVFP4Base()) {
10911091 setOperationAction(ISD::FMA, MVT::f64, Expand);
10921092 setOperationAction(ISD::FMA, MVT::f32, Expand);
10931093 }
10951095 // Various VFP goodness
10961096 if (!Subtarget->useSoftFloat() && !Subtarget->isThumb1Only()) {
10971097 // FP-ARMv8 adds f64 <-> f16 conversion. Before that it should be expanded.
1098 if (!Subtarget->hasFPARMv8() || Subtarget->isFPOnlySP()) {
1098 if (!Subtarget->hasFPARMv8Base() || !Subtarget->hasFP64()) {
10991099 setOperationAction(ISD::FP16_TO_FP, MVT::f64, Expand);
11001100 setOperationAction(ISD::FP_TO_FP16, MVT::f64, Expand);
11011101 }
11151115 }
11161116
11171117 // FP-ARMv8 implements a lot of rounding-like FP operations.
1118 if (Subtarget->hasFPARMv8()) {
1118 if (Subtarget->hasFPARMv8Base()) {
11191119 setOperationAction(ISD::FFLOOR, MVT::f32, Legal);
11201120 setOperationAction(ISD::FCEIL, MVT::f32, Legal);
11211121 setOperationAction(ISD::FROUND, MVT::f32, Legal);
11291129 setOperationAction(ISD::FMINNUM, MVT::v4f32, Legal);
11301130 setOperationAction(ISD::FMAXNUM, MVT::v4f32, Legal);
11311131
1132 if (!Subtarget->isFPOnlySP()) {
1132 if (Subtarget->hasFP64()) {
11331133 setOperationAction(ISD::FFLOOR, MVT::f64, Legal);
11341134 setOperationAction(ISD::FCEIL, MVT::f64, Legal);
11351135 setOperationAction(ISD::FROUND, MVT::f64, Legal);
12011201 setStackPointerRegisterToSaveRestore(ARM::SP);
12021202
12031203 if (Subtarget->useSoftFloat() || Subtarget->isThumb1Only() ||
1204 !Subtarget->hasVFP2() || Subtarget->hasMinSize())
1204 !Subtarget->hasVFP2Base() || Subtarget->hasMinSize())
12051205 setSchedulingPreference(Sched::RegPressure);
12061206 else
12071207 setSchedulingPreference(Sched::Hybrid);
16361636 case CallingConv::C:
16371637 if (!Subtarget->isAAPCS_ABI())
16381638 return CallingConv::ARM_APCS;
1639 else if (Subtarget->hasVFP2() && !Subtarget->isThumb1Only() &&
1639 else if (Subtarget->hasVFP2Base() && !Subtarget->isThumb1Only() &&
16401640 getTargetMachine().Options.FloatABIType == FloatABI::Hard &&
16411641 !isVarArg)
16421642 return CallingConv::ARM_AAPCS_VFP;
16451645 case CallingConv::Fast:
16461646 case CallingConv::CXX_FAST_TLS:
16471647 if (!Subtarget->isAAPCS_ABI()) {
1648 if (Subtarget->hasVFP2() && !Subtarget->isThumb1Only() && !isVarArg)
1648 if (Subtarget->hasVFP2Base() && !Subtarget->isThumb1Only() && !isVarArg)
16491649 return CallingConv::Fast;
16501650 return CallingConv::ARM_APCS;
1651 } else if (Subtarget->hasVFP2() && !Subtarget->isThumb1Only() && !isVarArg)
1651 } else if (Subtarget->hasVFP2Base() &&
1652 !Subtarget->isThumb1Only() && !isVarArg)
16521653 return CallingConv::ARM_AAPCS_VFP;
16531654 else
16541655 return CallingConv::ARM_AAPCS;
39113912 SDValue ARMTargetLowering::getVFPCmp(SDValue LHS, SDValue RHS,
39123913 SelectionDAG &DAG, const SDLoc &dl,
39133914 bool InvalidOnQNaN) const {
3914 assert(!Subtarget->isFPOnlySP() || RHS.getValueType() != MVT::f64);
3915 assert(Subtarget->hasFP64() || RHS.getValueType() != MVT::f64);
39153916 SDValue Cmp;
39163917 SDValue C = DAG.getConstant(InvalidOnQNaN, dl, MVT::i32);
39173918 if (!isFloatingPointZero(RHS))
42244225 SDValue ARMTargetLowering::getCMOV(const SDLoc &dl, EVT VT, SDValue FalseVal,
42254226 SDValue TrueVal, SDValue ARMcc, SDValue CCR,
42264227 SDValue Cmp, SelectionDAG &DAG) const {
4227 if (Subtarget->isFPOnlySP() && VT == MVT::f64) {
4228 if (!Subtarget->hasFP64() && VT == MVT::f64) {
42284229 FalseVal = DAG.getNode(ARMISD::VMOVRRD, dl,
42294230 DAG.getVTList(MVT::i32, MVT::i32), FalseVal);
42304231 TrueVal = DAG.getNode(ARMISD::VMOVRRD, dl,
44734474 SDValue TrueVal = Op.getOperand(2);
44744475 SDValue FalseVal = Op.getOperand(3);
44754476
4476 if (Subtarget->isFPOnlySP() && LHS.getValueType() == MVT::f64) {
4477 if (!Subtarget->hasFP64() && LHS.getValueType() == MVT::f64) {
44774478 DAG.getTargetLoweringInfo().softenSetCCOperands(DAG, MVT::f64, LHS, RHS, CC,
44784479 dl);
44794480
44964497 // inverting the compare condition, swapping 'less' and 'greater') and
44974498 // sometimes need to swap the operands to the VSEL (which inverts the
44984499 // condition in the sense of firing whenever the previous condition didn't)
4499 if (Subtarget->hasFPARMv8() && (TrueVal.getValueType() == MVT::f16 ||
4500 TrueVal.getValueType() == MVT::f32 ||
4501 TrueVal.getValueType() == MVT::f64)) {
4500 if (Subtarget->hasFPARMv8Base() && (TrueVal.getValueType() == MVT::f16 ||
4501 TrueVal.getValueType() == MVT::f32 ||
4502 TrueVal.getValueType() == MVT::f64)) {
45024503 ARMCC::CondCodes CondCode = IntCCToARMCC(CC);
45034504 if (CondCode == ARMCC::LT || CondCode == ARMCC::LE ||
45044505 CondCode == ARMCC::VC || CondCode == ARMCC::NE) {
45214522 // match CMPFPw0 instead of CMPFP, though we don't do this for f16 because we
45224523 // must use VSEL (limited condition codes), due to not having conditional f16
45234524 // moves.
4524 if (Subtarget->hasFPARMv8() &&
4525 if (Subtarget->hasFPARMv8Base() &&
45254526 !(isFloatingPointZero(RHS) && TrueVal.getValueType() != MVT::f16) &&
45264527 (TrueVal.getValueType() == MVT::f16 ||
45274528 TrueVal.getValueType() == MVT::f32 ||
47144715 SDValue Dest = Op.getOperand(4);
47154716 SDLoc dl(Op);
47164717
4717 if (Subtarget->isFPOnlySP() && LHS.getValueType() == MVT::f64) {
4718 if (!Subtarget->hasFP64() && LHS.getValueType() == MVT::f64) {
47184719 DAG.getTargetLoweringInfo().softenSetCCOperands(DAG, MVT::f64, LHS, RHS, CC,
47194720 dl);
47204721
48614862 EVT VT = Op.getValueType();
48624863 if (VT.isVector())
48634864 return LowerVectorFP_TO_INT(Op, DAG);
4864 if (Subtarget->isFPOnlySP() && Op.getOperand(0).getValueType() == MVT::f64) {
4865 if (!Subtarget->hasFP64() && Op.getOperand(0).getValueType() == MVT::f64) {
48654866 RTLIB::Libcall LC;
48664867 if (Op.getOpcode() == ISD::FP_TO_SINT)
48674868 LC = RTLIB::getFPTOSINT(Op.getOperand(0).getValueType(),
49254926 EVT VT = Op.getValueType();
49264927 if (VT.isVector())
49274928 return LowerVectorINT_TO_FP(Op, DAG);
4928 if (Subtarget->isFPOnlySP() && Op.getValueType() == MVT::f64) {
4929 if (!Subtarget->hasFP64() && Op.getValueType() == MVT::f64) {
49294930 RTLIB::Libcall LC;
49304931 if (Op.getOpcode() == ISD::SINT_TO_FP)
49314932 LC = RTLIB::getSINTTOFP(Op.getOperand(0).getValueType(),
59085909 }
59095910 }
59105911
5911 if (!ST->hasVFP3())
5912 if (!ST->hasVFP3Base())
59125913 return SDValue();
59135914
59145915 // Use the default (constant pool) lowering for double constants when we have
59155916 // an SP-only FPU
5916 if (IsDouble && Subtarget->isFPOnlySP())
5917 if (IsDouble && !Subtarget->hasFP64())
59175918 return SDValue();
59185919
59195920 // Try splatting with a VMOV.f32...
1135511356 const ARMSubtarget *Subtarget) {
1135611357 // vmovrrd(vmovdrr x, y) -> x,y
1135711358 SDValue InDouble = N->getOperand(0);
11358 if (InDouble.getOpcode() == ARMISD::VMOVDRR && !Subtarget->isFPOnlySP())
11359 if (InDouble.getOpcode() == ARMISD::VMOVDRR && Subtarget->hasFP64())
1135911360 return DCI.CombineTo(N, InDouble.getOperand(0), InDouble.getOperand(1));
1136011361
1136111362 // vmovrrd(load f64) -> (load i32), (load i32)
1330213303 unsigned NumBytes = std::max(VT.getSizeInBits() / 8, 1U);
1330313304
1330413305 // VLDR and LDRD: 4 * imm8
13305 if ((VT.isFloatingPoint() && Subtarget->hasVFP2()) || NumBytes == 8)
13306 if ((VT.isFloatingPoint() && Subtarget->hasVFP2Base()) || NumBytes == 8)
1330613307 return isShiftedUInt<8, 2>(V);
1330713308
1330813309 if (NumBytes == 1 || NumBytes == 2 || NumBytes == 4) {
1334613347 return isUInt<8>(V);
1334713348 case MVT::f32:
1334813349 case MVT::f64:
13349 if (!Subtarget->hasVFP2()) // FIXME: NEON?
13350 if (!Subtarget->hasVFP2Base()) // FIXME: NEON?
1335013351 return false;
1335113352 return isShiftedUInt<8, 2>(V);
1335213353 }
1390913910 // Although we are correct (we are free to emit anything, without
1391013911 // constraints), we might break use cases that would expect us to be more
1391113912 // efficient and emit something else.
13912 if (!Subtarget->hasVFP2())
13913 if (!Subtarget->hasVFP2Base())
1391313914 return "r";
1391413915 if (ConstraintVT.isFloatingPoint())
1391513916 return "w";
1439114392 }
1439214393
1439314394 SDValue ARMTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
14394 assert(Op.getValueType() == MVT::f64 && Subtarget->isFPOnlySP() &&
14395 assert(Op.getValueType() == MVT::f64 && !Subtarget->hasFP64() &&
1439514396 "Unexpected type for custom-lowering FP_EXTEND");
1439614397
1439714398 RTLIB::Libcall LC;
1440314404 }
1440414405
1440514406 SDValue ARMTargetLowering::LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const {
14406 assert(Op.getOperand(0).getValueType() == MVT::f64 &&
14407 Subtarget->isFPOnlySP() &&
14407 assert(Op.getOperand(0).getValueType() == MVT::f64 && !Subtarget->hasFP64() &&
1440814408 "Unexpected type for custom-lowering FP_ROUND");
1440914409
1441014410 RTLIB::Libcall LC;
1446714467 /// materialize the FP immediate as a load from a constant pool.
1446814468 bool ARMTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
1446914469 bool ForCodeSize) const {
14470 if (!Subtarget->hasVFP3())
14470 if (!Subtarget->hasVFP3Base())
1447114471 return false;
1447214472 if (VT == MVT::f16 && Subtarget->hasFullFP16())
1447314473 return ARM_AM::getFP16Imm(Imm) != -1;
1447414474 if (VT == MVT::f32)
1447514475 return ARM_AM::getFP32Imm(Imm) != -1;
14476 if (VT == MVT::f64 && !Subtarget->isFPOnlySP())
14476 if (VT == MVT::f64 && Subtarget->hasFP64())
1447714477 return ARM_AM::getFP64Imm(Imm) != -1;
1447814478 return false;
1447914479 }
257257 AssemblerPredicate<"HasV8_4aOps", "armv8.4a">;
258258 def HasV8_5a : Predicate<"Subtarget->hasV8_5aOps()">,
259259 AssemblerPredicate<"HasV8_5aOps", "armv8.5a">;
260 def NoVFP : Predicate<"!Subtarget->hasVFP2()">;
261 def HasVFP2 : Predicate<"Subtarget->hasVFP2()">,
262 AssemblerPredicate<"FeatureVFP2", "VFP2">;
263 def HasVFP3 : Predicate<"Subtarget->hasVFP3()">,
264 AssemblerPredicate<"FeatureVFP3", "VFP3">;
265 def HasVFP4 : Predicate<"Subtarget->hasVFP4()">,
266 AssemblerPredicate<"FeatureVFP4", "VFP4">;
267 def HasDPVFP : Predicate<"!Subtarget->isFPOnlySP()">,
268 AssemblerPredicate<"!FeatureVFPOnlySP",
260 def NoVFP : Predicate<"!Subtarget->hasVFP2Base()">;
261 def HasVFP2 : Predicate<"Subtarget->hasVFP2Base()">,
262 AssemblerPredicate<"FeatureVFP2_D16_SP", "VFP2">;
263 def HasVFP3 : Predicate<"Subtarget->hasVFP3Base()">,
264 AssemblerPredicate<"FeatureVFP3_D16_SP", "VFP3">;
265 def HasVFP4 : Predicate<"Subtarget->hasVFP4Base()">,
266 AssemblerPredicate<"FeatureVFP4_D16_SP", "VFP4">;
267 def HasDPVFP : Predicate<"Subtarget->hasFP64()">,
268 AssemblerPredicate<"FeatureFP64",
269269 "double precision VFP">;
270 def HasFPARMv8 : Predicate<"Subtarget->hasFPARMv8()">,
271 AssemblerPredicate<"FeatureFPARMv8", "FPARMv8">;
270 def HasFPARMv8 : Predicate<"Subtarget->hasFPARMv8Base()">,
271 AssemblerPredicate<"FeatureFPARMv8_D16_SP", "FPARMv8">;
272272 def HasNEON : Predicate<"Subtarget->hasNEON()">,
273273 AssemblerPredicate<"FeatureNEON", "NEON">;
274274 def HasSHA2 : Predicate<"Subtarget->hasSHA2()">,
370370 // Do not use them for Darwin platforms.
371371 def UseFusedMAC : Predicate<"(TM.Options.AllowFPOpFusion =="
372372 " FPOpFusion::Fast && "
373 " Subtarget->hasVFP4()) && "
373 " Subtarget->hasVFP4Base()) && "
374374 "!Subtarget->isTargetDarwin() &&"
375375 "Subtarget->useFPVMLx()">;
376376
231231 MachineRegisterInfo &MRI,
232232 const TargetRegisterInfo &TRI,
233233 const RegisterBankInfo &RBI) {
234 assert(TII.getSubtarget().hasVFP2() && "Can't select merge without VFP");
234 assert(TII.getSubtarget().hasVFP2Base() && "Can't select merge without VFP");
235235
236236 // We only support G_MERGE_VALUES as a way to stick together two scalar GPRs
237237 // into one DPR.
262262 MachineRegisterInfo &MRI,
263263 const TargetRegisterInfo &TRI,
264264 const RegisterBankInfo &RBI) {
265 assert(TII.getSubtarget().hasVFP2() && "Can't select unmerge without VFP");
265 assert(TII.getSubtarget().hasVFP2Base() &&
266 "Can't select unmerge without VFP");
266267
267268 // We only support G_UNMERGE_VALUES as a way to break up one DPR into two
268269 // GPRs.
10351036 return selectCmp(Helper, MIB, MRI);
10361037 }
10371038 case G_FCMP: {
1038 assert(STI.hasVFP2() && "Can't select fcmp without VFP");
1039 assert(STI.hasVFP2Base() && "Can't select fcmp without VFP");
10391040
10401041 unsigned OpReg = I.getOperand(2).getReg();
10411042 unsigned Size = MRI.getType(OpReg).getSizeInBits();
10421043
1043 if (Size == 64 && STI.isFPOnlySP()) {
1044 if (Size == 64 && !STI.hasFP64()) {
10441045 LLVM_DEBUG(dbgs() << "Subtarget only supports single precision");
10451046 return false;
10461047 }
10861087 LLT ValTy = MRI.getType(Reg);
10871088 const auto ValSize = ValTy.getSizeInBits();
10881089
1089 assert((ValSize != 64 || STI.hasVFP2()) &&
1090 assert((ValSize != 64 || STI.hasVFP2Base()) &&
10901091 "Don't know how to load/store 64-bit value without VFP");
10911092
10921093 const auto NewOpc = selectLoadStoreOpCode(I.getOpcode(), RegBank, ValSize);
156156
157157 getActionDefinitionsBuilder(G_BRCOND).legalFor({s1});
158158
159 if (!ST.useSoftFloat() && ST.hasVFP2()) {
159 if (!ST.useSoftFloat() && ST.hasVFP2Base()) {
160160 getActionDefinitionsBuilder(
161161 {G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FCONSTANT, G_FNEG})
162162 .legalFor({s32, s64});
207207 .libcallForCartesianProduct({s32, s64}, {s32});
208208 }
209209
210 if (!ST.useSoftFloat() && ST.hasVFP4())
210 if (!ST.useSoftFloat() && ST.hasVFP4Base())
211211 getActionDefinitionsBuilder(G_FMA).legalFor({s32, s64});
212212 else
213213 getActionDefinitionsBuilder(G_FMA).libcallFor({s32, s64});
452452 for (const auto &Mapping : OperandsMapping[i]) {
453453 assert(
454454 (Mapping.RegBank->getID() != ARM::FPRRegBankID ||
455 MF.getSubtarget().hasVFP2()) &&
455 MF.getSubtarget().hasVFP2Base()) &&
456456 "Trying to use floating point register bank on target without vfp");
457457 }
458458 }
165165 bool HasFPARMv8 = false;
166166 bool HasNEON = false;
167167
168 /// Versions of the VFP flags restricted to single precision, or to
169 /// 16 d-registers, or both.
170 bool HasVFPv2SP = false;
171 bool HasVFPv3SP = false;
172 bool HasVFPv4SP = false;
173 bool HasFPARMv8SP = false;
174 bool HasVFPv2D16 = false;
175 bool HasVFPv3D16 = false;
176 bool HasVFPv4D16 = false;
177 bool HasFPARMv8D16 = false;
178 bool HasVFPv2D16SP = false;
179 bool HasVFPv3D16SP = false;
180 bool HasVFPv4D16SP = false;
181 bool HasFPARMv8D16SP = false;
182
168183 /// HasDotProd - True if the ARMv8.2A dot product instructions are supported.
169184 bool HasDotProd = false;
170185
231246 /// HasFP16FML - True if subtarget supports half-precision FP fml operations
232247 bool HasFP16FML = false;
233248
234 /// HasD16 - True if subtarget is limited to 16 double precision
249 /// HasD32 - True if subtarget has the full 32 double precision
235250 /// FP registers for VFPv3.
236 bool HasD16 = false;
251 bool HasD32 = false;
237252
238253 /// HasHardwareDivide - True if subtarget supports [su]div in Thumb mode
239254 bool HasHardwareDivideInThumb = false;
290305 /// extension.
291306 bool HasVirtualization = false;
292307
293 /// FPOnlySP - If true, the floating point unit only supports single
308 /// HasFP64 - If true, the floating point unit supports double
294309 /// precision.
295 bool FPOnlySP = false;
310 bool HasFP64 = false;
296311
297312 /// If true, the processor supports the Performance Monitor Extensions. These
298313 /// include a generic cycle-counter as well as more fine-grained (often
568583
569584 bool hasARMOps() const { return !NoARM; }
570585
571 bool hasVFP2() const { return HasVFPv2; }
572 bool hasVFP3() const { return HasVFPv3; }
573 bool hasVFP4() const { return HasVFPv4; }
574 bool hasFPARMv8() const { return HasFPARMv8; }
586 bool hasVFP2Base() const { return HasVFPv2D16SP; }
587 bool hasVFP3Base() const { return HasVFPv3D16SP; }
588 bool hasVFP4Base() const { return HasVFPv4D16SP; }
589 bool hasFPARMv8Base() const { return HasFPARMv8D16SP; }
575590 bool hasNEON() const { return HasNEON; }
576591 bool hasSHA2() const { return HasSHA2; }
577592 bool hasAES() const { return HasAES; }
600615 bool useFPVMLx() const { return !SlowFPVMLx; }
601616 bool hasVMLxForwarding() const { return HasVMLxForwarding; }
602617 bool isFPBrccSlow() const { return SlowFPBrcc; }
603 bool isFPOnlySP() const { return FPOnlySP; }
618 bool hasFP64() const { return HasFP64; }
604619 bool hasPerfMon() const { return HasPerfMon; }
605620 bool hasTrustZone() const { return HasTrustZone; }
606621 bool has8MSecExt() const { return Has8MSecExt; }
637652 bool genExecuteOnly() const { return GenExecuteOnly; }
638653
639654 bool hasFP16() const { return HasFP16; }
640 bool hasD16() const { return HasD16; }
655 bool hasD32() const { return HasD32; }
641656 bool hasFullFP16() const { return HasFullFP16; }
642657 bool hasFP16FML() const { return HasFP16FML; }
643658
4747 const ARMTargetLowering *TLI;
4848
4949 // Currently the following features are excluded from InlineFeatureWhitelist.
50 // ModeThumb, FeatureNoARM, ModeSoftFloat, FeatureVFPOnlySP, FeatureD16
50 // ModeThumb, FeatureNoARM, ModeSoftFloat, FeatureFP64, FeatureD32
5151 // Depending on whether they are set or unset, different
5252 // instructions/registers are available. For example, inlining a callee with
5353 // -thumb-mode in a caller with +thumb-mode, may cause the assembler to
491491 return getSTI().getFeatureBits()[ARM::FeatureDSP];
492492 }
493493
494 bool hasD16() const {
495 return getSTI().getFeatureBits()[ARM::FeatureD16];
494 bool hasD32() const {
495 return getSTI().getFeatureBits()[ARM::FeatureD32];
496496 }
497497
498498 bool hasV8_1aOps() const {
34233423 }
34243424
34253425 // Some FPUs only have 16 D registers, so D16-D31 are invalid
3426 if (hasD16() && RegNum >= ARM::D16 && RegNum <= ARM::D31)
3426 if (!hasD32() && RegNum >= ARM::D16 && RegNum <= ARM::D31)
34273427 return -1;
34283428
34293429 Parser.Lex(); // Eat identifier token.
1041410414 : "operand must be a register in range [r0, r12] or r14";
1041510415 // DPR contains 16 registers for some FPUs, and 32 for others.
1041610416 case Match_DPR:
10417 return hasD16() ? "operand must be a register in range [d0, d15]"
10418 : "operand must be a register in range [d0, d31]";
10417 return hasD32() ? "operand must be a register in range [d0, d31]"
10418 : "operand must be a register in range [d0, d15]";
1041910419 case Match_DPR_RegList:
10420 return hasD16() ? "operand must be a list of registers in range [d0, d15]"
10421 : "operand must be a list of registers in range [d0, d31]";
10420 return hasD32() ? "operand must be a list of registers in range [d0, d31]"
10421 : "operand must be a list of registers in range [d0, d15]";
1042210422
1042310423 // For all other diags, use the static string from tablegen.
1042410424 default:
1062010620 { ARM::AEK_CRC, {Feature_HasV8Bit}, {ARM::FeatureCRC} },
1062110621 { ARM::AEK_CRYPTO, {Feature_HasV8Bit},
1062210622 {ARM::FeatureCrypto, ARM::FeatureNEON, ARM::FeatureFPARMv8} },
10623 { ARM::AEK_FP, {Feature_HasV8Bit}, {ARM::FeatureFPARMv8} },
10623 { ARM::AEK_FP, {Feature_HasV8Bit},
10624 {ARM::FeatureVFP2_D16_SP, ARM::FeatureFPARMv8} },
1062410625 { (ARM::AEK_HWDIVTHUMB | ARM::AEK_HWDIVARM),
1062510626 {Feature_HasV7Bit, Feature_IsNotMClassBit},
1062610627 {ARM::FeatureHWDivThumb, ARM::FeatureHWDivARM} },
1062710628 { ARM::AEK_MP, {Feature_HasV7Bit, Feature_IsNotMClassBit},
1062810629 {ARM::FeatureMP} },
1062910630 { ARM::AEK_SIMD, {Feature_HasV8Bit},
10630 {ARM::FeatureNEON, ARM::FeatureFPARMv8} },
10631 {ARM::FeatureNEON, ARM::FeatureVFP2_D16_SP, ARM::FeatureFPARMv8} },
1063110632 { ARM::AEK_SEC, {Feature_HasV6KBit}, {ARM::FeatureTrustZone} },
1063210633 // FIXME: Only available in A-class, isel not predicated
1063310634 { ARM::AEK_VIRT, {Feature_HasV7Bit}, {ARM::FeatureVirtualization} },
1067710678 "allowed for the current base architecture");
1067810679
1067910680 MCSubtargetInfo &STI = copySTI();
10680 FeatureBitset ToggleFeatures = EnableFeature
10681 ? (~STI.getFeatureBits() & Extension.Features)
10682 : ( STI.getFeatureBits() & Extension.Features);
10683
10684 FeatureBitset Features =
10685 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
10681 if (EnableFeature) {
10682 STI.SetFeatureBitsTransitively(Extension.Features);
10683 } else {
10684 STI.ClearFeatureBitsTransitively(Extension.Features);
10685 }
10686 FeatureBitset Features = ComputeAvailableFeatures(STI.getFeatureBits());
1068610687 setAvailableFeatures(Features);
1068710688 return false;
1068810689 }
10421042 const FeatureBitset &featureBits =
10431043 ((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
10441044
1045 bool hasD16 = featureBits[ARM::FeatureD16];
1046
1047 if (RegNo > 31 || (hasD16 && RegNo > 15))
1045 bool hasD32 = featureBits[ARM::FeatureD32];
1046
1047 if (RegNo > 31 || (!hasD32 && RegNo > 15))
10481048 return MCDisassembler::Fail;
10491049
10501050 unsigned Register = DPRDecoderTable[RegNo];
221221 ? ARMBuildAttrs::AllowNeonARMv8_1a
222222 : ARMBuildAttrs::AllowNeonARMv8);
223223 } else {
224 if (STI.hasFeature(ARM::FeatureFPARMv8))
224 if (STI.hasFeature(ARM::FeatureFPARMv8_D16_SP))
225225 // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one
226226 // FPU, but there are two different names for it depending on the CPU.
227 emitFPU(STI.hasFeature(ARM::FeatureD16)
228 ? (STI.hasFeature(ARM::FeatureVFPOnlySP) ? ARM::FK_FPV5_SP_D16
229 : ARM::FK_FPV5_D16)
230 : ARM::FK_FP_ARMV8);
231 else if (STI.hasFeature(ARM::FeatureVFP4))
232 emitFPU(STI.hasFeature(ARM::FeatureD16)
233 ? (STI.hasFeature(ARM::FeatureVFPOnlySP) ? ARM::FK_FPV4_SP_D16
234 : ARM::FK_VFPV4_D16)
235 : ARM::FK_VFPV4);
236 else if (STI.hasFeature(ARM::FeatureVFP3))
227 emitFPU(STI.hasFeature(ARM::FeatureD32)
228 ? ARM::FK_FP_ARMV8
229 : (STI.hasFeature(ARM::FeatureFP64) ? ARM::FK_FPV5_D16
230 : ARM::FK_FPV5_SP_D16));
231 else if (STI.hasFeature(ARM::FeatureVFP4_D16_SP))
232 emitFPU(STI.hasFeature(ARM::FeatureD32)
233 ? ARM::FK_VFPV4
234 : (STI.hasFeature(ARM::FeatureFP64) ? ARM::FK_VFPV4_D16
235 : ARM::FK_FPV4_SP_D16));
236 else if (STI.hasFeature(ARM::FeatureVFP3_D16_SP))
237237 emitFPU(
238 STI.hasFeature(ARM::FeatureD16)
239 // +d16
240 ? (STI.hasFeature(ARM::FeatureVFPOnlySP)
241 ? (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3XD_FP16
242 : ARM::FK_VFPV3XD)
243 : (STI.hasFeature(ARM::FeatureFP16)
238 STI.hasFeature(ARM::FeatureD32)
239 // +d32
240 ? (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3_FP16
241 : ARM::FK_VFPV3)
242 // -d32
243 : (STI.hasFeature(ARM::FeatureFP64)
244 ? (STI.hasFeature(ARM::FeatureFP16)
244245 ? ARM::FK_VFPV3_D16_FP16
245 : ARM::FK_VFPV3_D16))
246 // -d16
247 : (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3_FP16
248 : ARM::FK_VFPV3));
249 else if (STI.hasFeature(ARM::FeatureVFP2))
246 : ARM::FK_VFPV3_D16)
247 : (STI.hasFeature(ARM::FeatureFP16) ? ARM::FK_VFPV3XD_FP16
248 : ARM::FK_VFPV3XD)));
249 else if (STI.hasFeature(ARM::FeatureVFP2_D16_SP))
250250 emitFPU(ARM::FK_VFPV2);
251251 }
252252
253253 // ABI_HardFP_use attribute to indicate single precision FP.
254 if (STI.hasFeature(ARM::FeatureVFPOnlySP))
254 if (STI.hasFeature(ARM::FeatureVFP2_D16_SP) && !STI.hasFeature(ARM::FeatureFP64))
255255 emitAttribute(ARMBuildAttrs::ABI_HardFP_use,
256256 ARMBuildAttrs::HardFPSinglePrecision);
257257
1010 define void @test_gep_s16() { ret void }
1111
1212 attributes #0 = { "target-features"="+vfp2" }
13 attributes #1 = { "target-features"="-vfp2" }
13 attributes #1 = { "target-features"="-vfp2d16sp" }
1414 ...
1515 ---
1616 name: test_legal_loads_stores
336336 ret void
337337 }
338338
339 attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="preserve-sign" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="true" "no-jump-tables"="false" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-m7" "target-features"="+d16,+dsp,+fp-armv8,+hwdiv,+thumb-mode,-crc,-crypto,-dotprod,-fp-only-sp,-fullfp16,-hwdiv-arm,-neon,-ras" "unsafe-fp-math"="false" "use-soft-float"="false" }
339 attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="preserve-sign" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="true" "no-jump-tables"="false" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-m7" "target-features"="-d32,+dsp,+fp-armv8,+hwdiv,+thumb-mode,-crc,-crypto,-dotprod,-fullfp16,-hwdiv-arm,-neon,-ras" "unsafe-fp-math"="false" "use-soft-float"="false" }
340340
0 ; RUN: llc < %s -mtriple=armv8-linux-gnueabihf -mattr=+fp-armv8 | FileCheck --check-prefix=CHECK --check-prefix=DP %s
1 ; RUN: llc < %s -mtriple=thumbv7em-linux-gnueabihf -mattr=+fp-armv8,+d16,+fp-only-sp | FileCheck --check-prefix=SP %s
2 ; RUN: llc < %s -mtriple=thumbv7em-linux-gnueabihf -mattr=+fp-armv8,+d16 | FileCheck --check-prefix=DP %s
1 ; RUN: llc < %s -mtriple=thumbv7em-linux-gnueabihf -mattr=+fp-armv8,-d32,-fp64 | FileCheck --check-prefix=SP %s
2 ; RUN: llc < %s -mtriple=thumbv7em-linux-gnueabihf -mattr=+fp-armv8,-d32 | FileCheck --check-prefix=DP %s
33
44 ; CHECK-LABEL: test1
55 ; CHECK: vrintm.f32
3232 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a5 | FileCheck %s --check-prefix=CORTEX-A5-DEFAULT
3333 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a5 -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A5-DEFAULT-FAST
3434 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a5 -enable-sign-dependent-rounding-fp-math | FileCheck %s --check-prefix=DYN-ROUNDING
35 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a5 -mattr=-neon,+d16 | FileCheck %s --check-prefix=CORTEX-A5-NONEON
36 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a5 -mattr=-vfp2 | FileCheck %s --check-prefix=CORTEX-A5-NOFPU
37 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a5 -mattr=-vfp2 -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A5-NOFPU-FAST
35 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a5 -mattr=-neon,-d32 | FileCheck %s --check-prefix=CORTEX-A5-NONEON
36 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a5 -mattr=-vfp2d16sp | FileCheck %s --check-prefix=CORTEX-A5-NOFPU
37 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a5 -mattr=-vfp2d16sp -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A5-NOFPU-FAST
3838 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a8 -float-abi=soft | FileCheck %s --check-prefix=CORTEX-A8-SOFT
3939 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a8 -float-abi=soft -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A8-SOFT-FAST
4040 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a8 -float-abi=hard | FileCheck %s --check-prefix=CORTEX-A8-HARD
4949 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a12 | FileCheck %s --check-prefix=CORTEX-A12-DEFAULT
5050 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a9 -float-abi=soft | FileCheck %s --check-prefix=CORTEX-A9-SOFT
5151 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a12 -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A12-DEFAULT-FAST
52 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a12 -mattr=-vfp2 | FileCheck %s --check-prefix=CORTEX-A12-NOFPU
53 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a12 -mattr=-vfp2 -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A12-NOFPU-FAST
52 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a12 -mattr=-vfp2d16sp | FileCheck %s --check-prefix=CORTEX-A12-NOFPU
53 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a12 -mattr=-vfp2d16sp -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A12-NOFPU-FAST
5454 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a12 -enable-sign-dependent-rounding-fp-math | FileCheck %s --check-prefix=DYN-ROUNDING
5555 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a15 | FileCheck %s --check-prefix=CORTEX-A15
5656 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a15 -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A15-FAST
5757 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a15 -enable-sign-dependent-rounding-fp-math | FileCheck %s --check-prefix=DYN-ROUNDING
5858 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a17 | FileCheck %s --check-prefix=CORTEX-A17-DEFAULT
5959 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a17 -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A17-FAST
60 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a17 -mattr=-vfp2 | FileCheck %s --check-prefix=CORTEX-A17-NOFPU
61 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a17 -mattr=-vfp2 -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A17-NOFPU-FAST
60 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a17 -mattr=-vfp2d16sp | FileCheck %s --check-prefix=CORTEX-A17-NOFPU
61 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a17 -mattr=-vfp2d16sp -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A17-NOFPU-FAST
6262
6363 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a15 -enable-no-trapping-fp-math | FileCheck %s --check-prefix=NO-TRAPPING-MATH
6464 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a15 -denormal-fp-math=ieee | FileCheck %s --check-prefix=DENORMAL-IEEE
6666 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a15 -denormal-fp-math=positive-zero | FileCheck %s --check-prefix=DENORMAL-POSITIVE-ZERO
6767
6868 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mattr=-neon,+vfp3,+fp16 | FileCheck %s --check-prefix=GENERIC-FPU-VFPV3-FP16
69 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mattr=-neon,+vfp3,+d16,+fp16 | FileCheck %s --check-prefix=GENERIC-FPU-VFPV3-D16-FP16
70 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mattr=-neon,+vfp3,+fp-only-sp,+d16 | FileCheck %s --check-prefix=GENERIC-FPU-VFPV3XD
71 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mattr=-neon,+vfp3,+fp-only-sp,+d16,+fp16 | FileCheck %s --check-prefix=GENERIC-FPU-VFPV3XD-FP16
69 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mattr=-neon,+vfp3,-d32,+fp16 | FileCheck %s --check-prefix=GENERIC-FPU-VFPV3-D16-FP16
70 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mattr=-neon,+vfp3,-fp64,-d32 | FileCheck %s --check-prefix=GENERIC-FPU-VFPV3XD
71 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mattr=-neon,+vfp3,-fp64,-d32,+fp16 | FileCheck %s --check-prefix=GENERIC-FPU-VFPV3XD-FP16
7272 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mattr=+neon,+fp16 | FileCheck %s --check-prefix=GENERIC-FPU-NEON-FP16
7373
7474 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -mcpu=cortex-a17 -enable-sign-dependent-rounding-fp-math | FileCheck %s --check-prefix=DYN-ROUNDING
9595 ; RUN: llc < %s -mtriple=thumbv7m-linux-gnueabi -mcpu=cortex-m4 -float-abi=hard | FileCheck %s --check-prefix=CORTEX-M4-HARD
9696 ; RUN: llc < %s -mtriple=thumbv7m-linux-gnueabi -mcpu=cortex-m4 -float-abi=hard -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-M4-HARD-FAST
9797 ; RUN: llc < %s -mtriple=thumbv7m-linux-gnueabi -mcpu=cortex-m4 -enable-sign-dependent-rounding-fp-math | FileCheck %s --check-prefix=DYN-ROUNDING
98 ; RUN: llc < %s -mtriple=thumbv7em-linux-gnueabi -mcpu=cortex-m7 -mattr=-vfp2 | FileCheck %s --check-prefix=CORTEX-M7 --check-prefix=CORTEX-M7-SOFT
99 ; RUN: llc < %s -mtriple=thumbv7em-linux-gnueabi -mcpu=cortex-m7 -mattr=-vfp2 -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-M7-NOFPU-FAST
100 ; RUN: llc < %s -mtriple=thumbv7em-linux-gnueabi -mcpu=cortex-m7 -mattr=+fp-only-sp | FileCheck %s --check-prefix=CORTEX-M7 --check-prefix=CORTEX-M7-SINGLE
101 ; RUN: llc < %s -mtriple=thumbv7em-linux-gnueabi -mcpu=cortex-m7 -mattr=+fp-only-sp -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-M7-FAST
98 ; RUN: llc < %s -mtriple=thumbv7em-linux-gnueabi -mcpu=cortex-m7 -mattr=-vfp2d16sp | FileCheck %s --check-prefix=CORTEX-M7 --check-prefix=CORTEX-M7-SOFT
99 ; RUN: llc < %s -mtriple=thumbv7em-linux-gnueabi -mcpu=cortex-m7 -mattr=-vfp2d16sp -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-M7-NOFPU-FAST
100 ; RUN: llc < %s -mtriple=thumbv7em-linux-gnueabi -mcpu=cortex-m7 -mattr=-fp64 | FileCheck %s --check-prefix=CORTEX-M7 --check-prefix=CORTEX-M7-SINGLE
101 ; RUN: llc < %s -mtriple=thumbv7em-linux-gnueabi -mcpu=cortex-m7 -mattr=-fp64 -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-M7-FAST
102102 ; RUN: llc < %s -mtriple=thumbv7em-linux-gnueabi -mcpu=cortex-m7 | FileCheck %s --check-prefix=CORTEX-M7-DOUBLE
103103 ; RUN: llc < %s -mtriple=thumbv7em-linux-gnueabi -mcpu=cortex-m7 -enable-sign-dependent-rounding-fp-math | FileCheck %s --check-prefix=DYN-ROUNDING
104104 ; RUN: llc < %s -mtriple=thumbv8-linux-gnueabi -mcpu=cortex-m23 | FileCheck %s --check-prefix=CORTEX-M23
156156 ; RUN: llc < %s -mtriple=armv8.1a-linux-gnueabi -enable-sign-dependent-rounding-fp-math | FileCheck %s --check-prefix=DYN-ROUNDING
157157 ; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi -mcpu=cortex-a7 | FileCheck %s --check-prefix=CORTEX-A7-CHECK
158158 ; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi -mcpu=cortex-a7 -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A7-CHECK-FAST
159 ; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi -mcpu=cortex-a7 -mattr=-vfp2,-vfp3,-vfp4,-neon,-fp16 | FileCheck %s --check-prefix=CORTEX-A7-NOFPU
160 ; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi -mcpu=cortex-a7 -mattr=-vfp2,-vfp3,-vfp4,-neon,-fp16 -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A7-NOFPU-FAST
159 ; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi -mcpu=cortex-a7 -mattr=-vfp2d16sp,-vfp3,-vfp4,-neon,-fp16 | FileCheck %s --check-prefix=CORTEX-A7-NOFPU
160 ; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi -mcpu=cortex-a7 -mattr=-vfp2d16sp,-vfp3,-vfp4,-neon,-fp16 -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A7-NOFPU-FAST
161161 ; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi -mcpu=cortex-a7 -mattr=+vfp4,-neon | FileCheck %s --check-prefix=CORTEX-A7-FPUV4
162162 ; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi -mcpu=cortex-a7 -enable-sign-dependent-rounding-fp-math | FileCheck %s --check-prefix=DYN-ROUNDING
163163 ; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi -mcpu=cortex-a7 -mattr=+vfp4,-neon -enable-unsafe-fp-math -frame-pointer=all -enable-no-infs-fp-math -enable-no-nans-fp-math -fp-contract=fast | FileCheck %s --check-prefix=CORTEX-A7-FPUV4-FAST
164 ; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi -mcpu=cortex-a7 -mattr=+vfp4,,+d16,-neon | FileCheck %s --check-prefix=CORTEX-A7-FPUV4
164 ; RUN: llc < %s -mtriple=armv7-none-linux-gnueabi -mcpu=cortex-a7 -mattr=+vfp4,,-d32,-neon | FileCheck %s --check-prefix=CORTEX-A7-FPUV4
165165 ; RUN: llc < %s -mtriple=arm-none-linux-gnueabi -mattr=+strict-align -relocation-model=pic | FileCheck %s --check-prefix=RELOC-PIC
166166 ; RUN: llc < %s -mtriple=arm-none-linux-gnueabi -mattr=+strict-align -relocation-model=static | FileCheck %s --check-prefix=RELOC-OTHER
167167 ; RUN: llc < %s -mtriple=arm-none-linux-gnueabi -mattr=+strict-align -relocation-model=dynamic-no-pic | FileCheck %s --check-prefix=RELOC-OTHER
229229 ; RUN: llc < %s -mtriple=armv5-none-linux-gnueabi -mcpu=arm1022e -mattr=+strict-align | FileCheck %s --check-prefix=STRICT-ALIGN
230230
231231 ; ARMv8-R
232 ; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-r52 -mattr=-vfp2,-fp16 | FileCheck %s --check-prefix=ARMv8R --check-prefix=ARMv8R-NOFPU
233 ; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-r52 -mattr=-neon,+fp-only-sp,+d16 | FileCheck %s --check-prefix=ARMv8R --check-prefix=ARMv8R-SP
232 ; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-r52 -mattr=-vfp2d16sp,-fp16 | FileCheck %s --check-prefix=ARMv8R --check-prefix=ARMv8R-NOFPU
233 ; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-r52 -mattr=-neon,-fp64,-d32 | FileCheck %s --check-prefix=ARMv8R --check-prefix=ARMv8R-SP
234234 ; RUN: llc < %s -mtriple=arm-none-none-eabi -mcpu=cortex-r52 | FileCheck %s --check-prefix=ARMv8R --check-prefix=ARMv8R-NEON
235235
236236 ; ARMv8-M
33 ; RUN: llc -fast-isel-sink-local-values < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -mattr=+long-calls | FileCheck %s --check-prefix=ARM-LONG --check-prefix=ARM-LONG-MACHO
44 ; RUN: llc -fast-isel-sink-local-values < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -mattr=+long-calls | FileCheck %s --check-prefix=ARM-LONG --check-prefix=ARM-LONG-ELF
55 ; RUN: llc -fast-isel-sink-local-values < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -mattr=+long-calls | FileCheck %s --check-prefix=THUMB-LONG
6 ; RUN: llc -fast-isel-sink-local-values < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -mattr=-vfp2 | FileCheck %s --check-prefix=ARM-NOVFP
7 ; RUN: llc -fast-isel-sink-local-values < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -mattr=-vfp2 | FileCheck %s --check-prefix=ARM-NOVFP
8 ; RUN: llc -fast-isel-sink-local-values < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -mattr=-vfp2 | FileCheck %s --check-prefix=THUMB-NOVFP
6 ; RUN: llc -fast-isel-sink-local-values < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -mattr=-vfp2d16sp | FileCheck %s --check-prefix=ARM-NOVFP
7 ; RUN: llc -fast-isel-sink-local-values < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -mattr=-vfp2d16sp | FileCheck %s --check-prefix=ARM-NOVFP
8 ; RUN: llc -fast-isel-sink-local-values < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -mattr=-vfp2d16sp | FileCheck %s --check-prefix=THUMB-NOVFP
99
1010 ; Note that some of these tests assume that relocations are either
1111 ; movw/movt or constant pool loads. Different platforms will select
44 ; RUN: llc -asm-verbose=false -mattr=+vfp3 -meabi=gnu -mtriple=arm-eabi < %s | FileCheck %s -check-prefix=CHECK-SOFTFP
55 ; RUN: llc -asm-verbose=false -mattr=+vfp3 -float-abi=hard -mtriple=arm-eabi < %s | FileCheck %s -check-prefix=CHECK-HARDFP-SP -check-prefix=CHECK-HARDFP-DP
66 ; RUN: llc -asm-verbose=false -mattr=+vfp3 -float-abi=hard -meabi=gnu -mtriple=arm-eabi < %s | FileCheck %s -check-prefix=CHECK-HARDFP-SP -check-prefix=CHECK-HARDFP-DP
7 ; RUN: llc -asm-verbose=false -mattr=+vfp3,+fp-only-sp -float-abi=hard -mtriple=arm-eabi < %s | FileCheck %s -check-prefix=CHECK-HARDFP-SP -check-prefix=CHECK-HARDFP-SPONLY
8 ; RUN: llc -asm-verbose=false -mattr=+vfp3,+fp-only-sp -float-abi=hard -mtriple=arm-eabi -meabi=gnu < %s | FileCheck %s -check-prefix=CHECK-HARDFP-SP -check-prefix=CHECK-HARDFP-SPONLY
7 ; RUN: llc -asm-verbose=false -mattr=+vfp3,-fp64 -float-abi=hard -mtriple=arm-eabi < %s | FileCheck %s -check-prefix=CHECK-HARDFP-SP -check-prefix=CHECK-HARDFP-SPONLY
8 ; RUN: llc -asm-verbose=false -mattr=+vfp3,-fp64 -float-abi=hard -mtriple=arm-eabi -meabi=gnu < %s | FileCheck %s -check-prefix=CHECK-HARDFP-SP -check-prefix=CHECK-HARDFP-SPONLY
99
1010 ; The Runtime ABI for the ARM Architecture IHI0043 section 4.1.2 The
1111 ; floating-point helper functions to always use the base AAPCS (soft-float)
0 ; RUN: llc -mtriple=thumbv7em-apple-macho -mcpu=cortex-m4 %s -o - -O0 | FileCheck %s
11 ; RUN: llc -mtriple=thumbv7em-apple-macho -mcpu=cortex-m4 %s -o - | FileCheck %s
22
3 ; Note: vldr and vstr really do have 64-bit variants even with fp-only-sp
3 ; Note: vldr and vstr really do have 64-bit variants even with -fp64
44 define void @test_load_store(double* %addr) {
55 ; CHECK-LABEL: test_load_store:
66 ; CHECK: vldr [[TMP:d[0-9]+]], [r0]
44 ; SOFTFP:
55 ; RUN: llc < %s -mtriple=arm-none-eabi -mattr=+vfp3 | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-VFP3
66 ; RUN: llc < %s -mtriple=arm-none-eabi -mattr=+vfp4 | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-FP16,CHECK-SOFTFP-FP16-A32
7 ; RUN: llc < %s -mtriple=arm-none-eabi -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-FULLFP16
7 ; RUN: llc < %s -mtriple=arm-none-eabi -mattr=+fullfp16,+fp64 | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-FULLFP16
88
99 ; RUN: llc < %s -mtriple=thumbv7-none-eabi -mattr=+vfp3 | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-VFP3
1010 ; RUN: llc < %s -mtriple=thumbv7-none-eabi -mattr=+vfp4 | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-FP16,CHECK-SOFTFP-FP16-T32
11 ; RUN: llc < %s -mtriple=thumbv7-none-eabi -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-FULLFP16
11 ; RUN: llc < %s -mtriple=thumbv7-none-eabi -mattr=+fullfp16,+fp64 | FileCheck %s --check-prefixes=CHECK,CHECK-SOFTFP-FULLFP16
1212
1313 ; Test fast-isel
14 ; RUN: llc < %s -mtriple=arm-none-eabi -mattr=+fullfp16 -O0 | FileCheck %s --check-prefixes=CHECK-SPILL-RELOAD
15 ; RUN: llc < %s -mtriple=thumbv7-none-eabi -mattr=+fullfp16 -O0 | FileCheck %s --check-prefixes=CHECK-SPILL-RELOAD
14 ; RUN: llc < %s -mtriple=arm-none-eabi -mattr=+fullfp16,+fp64 -O0 | FileCheck %s --check-prefixes=CHECK-SPILL-RELOAD
15 ; RUN: llc < %s -mtriple=thumbv7-none-eabi -mattr=+fullfp16,+fp64 -O0 | FileCheck %s --check-prefixes=CHECK-SPILL-RELOAD
1616
1717 ; HARD:
1818 ; RUN: llc < %s -mtriple=arm-none-eabihf -mattr=+vfp3 | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-VFP3
1919 ; RUN: llc < %s -mtriple=arm-none-eabihf -mattr=+vfp4 | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-FP16
20 ; RUN: llc < %s -mtriple=arm-none-eabihf -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-FULLFP16
20 ; RUN: llc < %s -mtriple=arm-none-eabihf -mattr=+fullfp16,+fp64 | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-FULLFP16
2121
2222 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mattr=+vfp3 | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-VFP3
2323 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mattr=+vfp4 | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-FP16
24 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-FULLFP16
24 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mattr=+fullfp16,fp64 | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-FULLFP16
2525
2626 ; FP-CONTRACT=FAST
27 ; RUN: llc < %s -mtriple=arm-none-eabihf -mattr=+fullfp16 -fp-contract=fast | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-FULLFP16-FAST
28 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mattr=+fullfp16 -fp-contract=fast | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-FULLFP16-FAST
27 ; RUN: llc < %s -mtriple=arm-none-eabihf -mattr=+fullfp16,+fp64 -fp-contract=fast | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-FULLFP16-FAST
28 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mattr=+fullfp16,+fp64 -fp-contract=fast | FileCheck %s --check-prefixes=CHECK,CHECK-HARDFP-FULLFP16-FAST
2929
3030 ; TODO: we can't pass half-precision arguments as "half" types yet. We do
3131 ; that for the time being by passing "float %f.coerce" and the necessary
0 ; RUN: llc -asm-verbose=false < %s -mattr=+vfp3,+fp16 | FileCheck -allow-deprecated-dag-overlap %s -check-prefix=CHECK-FP16 --check-prefix=CHECK-VFP -check-prefix=CHECK-ALL
11 ; RUN: llc -asm-verbose=false < %s | FileCheck -allow-deprecated-dag-overlap %s -check-prefix=CHECK-LIBCALL --check-prefix=CHECK-VFP -check-prefix=CHECK-ALL --check-prefix=CHECK-LIBCALL-VFP
2 ; RUN: llc -asm-verbose=false < %s -mattr=-vfp2 | FileCheck -allow-deprecated-dag-overlap %s --check-prefix=CHECK-LIBCALL -check-prefix=CHECK-NOVFP -check-prefix=CHECK-ALL
2 ; RUN: llc -asm-verbose=false < %s -mattr=-vfp2d16sp | FileCheck -allow-deprecated-dag-overlap %s --check-prefix=CHECK-LIBCALL -check-prefix=CHECK-NOVFP -check-prefix=CHECK-ALL
33
44 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32"
55 target triple = "armv7---eabihf"
0 ; RUN: llc -mtriple=arm-eabi -mattr=+vfp2 %s -o - | FileCheck %s --check-prefix=CHECK-VFP
11 ; RUN: llc -mtriple=arm-apple-darwin %s -o - | FileCheck %s
22 ; RUN: llc -mtriple=armv8r-none-none-eabi %s -o - | FileCheck %s --check-prefix=CHECK-VFP
3 ; RUN: llc -mtriple=armv8r-none-none-eabi -mattr=+fp-only-sp %s -o - | FileCheck %s --check-prefix=CHECK-VFP-SP
3 ; RUN: llc -mtriple=armv8r-none-none-eabi -mattr=-fp64 %s -o - | FileCheck %s --check-prefix=CHECK-VFP-SP
44
55 define float @f1(double %x) {
66 ;CHECK-VFP-LABEL: f1:
11 ; RUN: llc < %s -mtriple=thumbv7s-apple-ios7.0 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-F16
22 ; RUN: llc < %s -mtriple=thumbv8-apple-ios7.0 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-V8
33 ; RUN: llc < %s -mtriple=armv8r-none-none-eabi | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-V8
4 ; RUN: llc < %s -mtriple=armv8r-none-none-eabi -mattr=+fp-only-sp | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-V8-SP
4 ; RUN: llc < %s -mtriple=armv8r-none-none-eabi -mattr=-fp64 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-V8-SP
55
66 define void @test_load_store(half* %in, half* %out) {
77 ; CHECK-LABEL: test_load_store:
None ; RUN: llc -mtriple=armv7-none-eabi -mattr=-neon,-vfp2 %s -o - | FileCheck %s -check-prefixes=COMMON,NOVFP
0 ; RUN: llc -mtriple=armv7-none-eabi -mattr=-neon,-vfp2d16sp %s -o - | FileCheck %s -check-prefixes=COMMON,NOVFP
11 ; RUN: llc -mtriple=armv7-none-eabi -mattr=+neon %s -float-abi=hard -o - | FileCheck %s -check-prefixes=COMMON,VFP
22
33 ; The intent here is to test "X", which says that any operand whatsoever is allowed.
133133 ret double %add
134134 }
135135
136 attributes #0 = { nounwind "target-features"="+d16,+vfp2,+vfp3,-fp-only-sp" "use-soft-float"="true" }
136 attributes #0 = { nounwind "target-features"="-d32,+vfp2,+vfp3" "use-soft-float"="true" }
137137
138138
139139 ; Check support for returning a float in GPR with hard float ABI
303303 ret %struct.twodouble %res
304304 }
305305
306 attributes #1 = { nounwind "target-features"="+d16,+vfp2,+vfp3,-fp-only-sp" "use-soft-float"="false" }
306 attributes #1 = { nounwind "target-features"="-d32,+vfp2,+vfp3" "use-soft-float"="false" }
None ; RUN: llc < %s -mtriple=armv7-none-gnueabi -mattr=-neon,-vfp2 | FileCheck --check-prefix=NONEON-NOVFP %s
0 ; RUN: llc < %s -mtriple=armv7-none-gnueabi -mattr=-neon,-vfp2d16sp | FileCheck --check-prefix=NONEON-NOVFP %s
11 ; RUN: llc < %s -mtriple=armv7-none-gnueabi -mattr=-neon | FileCheck --check-prefix=NONEON %s
2 ; RUN: llc < %s -mtriple=armv7-none-gnueabi -mattr=-vfp2 | FileCheck --check-prefix=NOVFP %s
2 ; RUN: llc < %s -mtriple=armv7-none-gnueabi -mattr=-vfp2d16sp | FileCheck --check-prefix=NOVFP %s
33 ; RUN: llc < %s -mtriple=armv7-none-gnueabi -mattr=-neon,+vfp2 | FileCheck --check-prefix=NONEON-VFP %s
44
55 ; Check no NEON instructions are selected when feature is disabled.
0 ; RUN: llc < %s -mtriple=thumbv7-none-eabi -mcpu=cortex-m4 -mattr=-vfp2 | FileCheck %s -check-prefix=CHECK -check-prefix=SOFT
1 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-m4 -mattr=+vfp4,+fp-only-sp | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=SP
1 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-m4 -mattr=+vfp4,-fp64 | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=SP
22 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-a8 -mattr=+vfp3 | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=DP
33
44 define float @float_in_reg(float %a, float %b) {
0 ; RUN: llc < %s -mtriple=thumbv7-none-eabi -mcpu=cortex-m3 | FileCheck %s -check-prefix=CHECK -check-prefix=SOFT -check-prefix=NONE
11 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-m4 | FileCheck %s -check-prefix=CHECK -check-prefix=SOFT -check-prefix=SP
22 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-m7 | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=DP -check-prefix=VFP -check-prefix=FP-ARMv8
3 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-m7 -mattr=+fp-only-sp | FileCheck %s -check-prefix=CHECK -check-prefix=SOFT -check-prefix=SP
3 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-m7 -mattr=-fp64 | FileCheck %s -check-prefix=CHECK -check-prefix=SOFT -check-prefix=SP
44 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-a7 | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=DP -check-prefix=NEON -check-prefix=VFP4
55 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-a57 | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=DP -check-prefix=NEON -check-prefix=FP-ARMv8
66
11 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-m4 | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=SP -check-prefix=NO-VMLA
22 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-m33 | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=SP -check-prefix=NO-VMLA
33 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-m7 | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=DP -check-prefix=VFP -check-prefix=FP-ARMv8 -check-prefix=VMLA
4 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-m7 -mattr=+fp-only-sp | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=SP -check-prefix=FP-ARMv8 -check-prefix=VMLA
4 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-m7 -mattr=-fp64 | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=SP -check-prefix=FP-ARMv8 -check-prefix=VMLA
55 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-a7 | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=DP -check-prefix=NEON -check-prefix=VFP4 -check-prefix=NO-VMLA
66 ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-a57 | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=DP -check-prefix=NEON -check-prefix=FP-ARMv8 -check-prefix=VMLA
77
2828 br i1 %exitcond, label %for.cond.cleanup, label %for.body
2929 }
3030
31 attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="cortex-m7" "target-features"="+d16,+dsp,+fp-armv8,+fp-only-sp,+hwdiv,+strict-align,+thumb-mode,-crc,-dotprod,-hwdiv-arm,-ras" "unsafe-fp-math"="false" "use-soft-float"="false" }
31 attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="cortex-m7" "target-features"="-d32,+dsp,+fp-armv8,-fp64,+hwdiv,+strict-align,+thumb-mode,-crc,-dotprod,-hwdiv-arm,-ras" "unsafe-fp-math"="false" "use-soft-float"="false" }
3232
3333 ...
3434 ---
0 // RUN: llvm-mc -triple arm-none-none-eabi -show-encoding -mattr=+v8.3a,+fp-armv8 < %s 2>&1 | FileCheck %s --check-prefix=ARM
11 // RUN: llvm-mc -triple thumb-none-none-eabi -show-encoding -mattr=+v8.3a,+fp-armv8 < %s 2>&1 | FileCheck %s --check-prefix=THUMB
22 // RUN: not llvm-mc -triple arm-none-none-eabi -show-encoding -mattr=+v8.2a,+fp-armv8 < %s 2>&1 | FileCheck --check-prefix=REQ-V83 %s
3 // RUN: not llvm-mc -triple arm-none-none-eabi -show-encoding -mattr=+v8.3a,-fp-armv8 < %s 2>&1 | FileCheck --check-prefix=REQ-FP %s
3 // RUN: not llvm-mc -triple arm-none-none-eabi -show-encoding -mattr=+v8.3a,-fp-armv8d16fp < %s 2>&1 | FileCheck --check-prefix=REQ-FP %s
44
55 vjcvt.s32.f64 s1, d2
66 // ARM: vjcvt.s32.f64 s1, d2 @ encoding: [0xc2,0x0b,0xf9,0xee]
1212 // ARM: vjcvt.s32.f64 s17, d18 @ encoding: [0xe2,0x8b,0xf9,0xee]
1313 // THUMB: vjcvt.s32.f64 s17, d18 @ encoding: [0xf9,0xee,0xe2,0x8b]
1414 // REQ-V83: error: instruction requires: armv8.3a
15 // REQ-FP: error: instruction requires: FPARMv8
15 // REQ-FP: error: invalid instruction
None @ RUN: llvm-mc < %s -triple thumbv7-unknown-unknown -show-encoding -mattr=+vfp4,-d16 2>&1 | FileCheck %s --check-prefix=D32
1 @ RUN: not llvm-mc < %s -triple thumbv7-unknown-unknown -show-encoding -mattr=+vfp4,+d16 2>&1 | FileCheck %s --check-prefix=D16
0 @ RUN: llvm-mc < %s -triple thumbv7-unknown-unknown -show-encoding -mattr=+vfp4,+d32 2>&1 | FileCheck %s --check-prefix=D32
1 @ RUN: not llvm-mc < %s -triple thumbv7-unknown-unknown -show-encoding -mattr=+vfp4,-d32 2>&1 | FileCheck %s --check-prefix=D16
22
33 @ D32-NOT: error:
44
None @ RUN: not llvm-mc -triple armv8 -mattr=-fp-armv8 -show-encoding < %s 2>&1 | FileCheck %s
0 @ RUN: not llvm-mc -triple armv8 -mattr=-fp-armv8d16sp -show-encoding < %s 2>&1 | FileCheck %s
11
22 vmaxnm.f32 s4, d5, q1
33 @ CHECK: error: invalid instruction
None @ RUN: not llvm-mc < %s -triple thumbv8-unknown-unknown -show-encoding -mattr=+fp-only-sp,-neon 2> %t > %t2
0 @ RUN: not llvm-mc < %s -triple thumbv8-unknown-unknown -show-encoding -mattr=-fp64,-neon 2> %t > %t2
11 @ RUN: FileCheck %s < %t --check-prefix=CHECK-ERRORS
22 @ RUN: FileCheck %s < %t2
33
0 @ RUN: not llvm-mc -triple armv7-eabi -filetype asm -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-D32
1 @ RUN: not llvm-mc -triple armv7-eabi -filetype asm -o /dev/null -mattr=+d16 %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-D16
1 @ RUN: not llvm-mc -triple armv7-eabi -filetype asm -o /dev/null -mattr=-d32 %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-D16
22
33 // First operand must be a GPR
44 vldm s0, {s1, s2}
0 ; RUN: opt -S -inline -mtriple=arm-eabi -pass-remarks=.* -pass-remarks-missed=.* < %s 2>&1 | FileCheck %s -check-prefix=NOFP
11 ; RUN: opt -S -inline -mtriple=arm-eabi -mattr=+vfp2 -pass-remarks=.* -pass-remarks-missed=.* < %s 2>&1 | FileCheck %s -check-prefix=FULLFP
2 ; RUN: opt -S -inline -mtriple=arm-eabi -mattr=+vfp2,+fp-only-sp -pass-remarks=.* -pass-remarks-missed=.* < %s 2>&1 | FileCheck %s -check-prefix=SINGLEFP
2 ; RUN: opt -S -inline -mtriple=arm-eabi -mattr=+vfp2,-fp64 -pass-remarks=.* -pass-remarks-missed=.* < %s 2>&1 | FileCheck %s -check-prefix=SINGLEFP
33 ; Make sure that soft float implementations are calculated as being more expensive
44 ; to the inliner.
55
6565 ; Function Attrs: nounwind readnone
6666 declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1
6767
68 attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="arm7tdmi" "target-features"="+neon,+strict-align,+vfp3,-crypto,-d16,-fp-armv8,-fp-only-sp,-fp16,-vfp4" "unsafe-fp-math"="false" "use-soft-float"="false" }
68 attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="arm7tdmi" "target-features"="+neon,+strict-align,+vfp3,-crypto,-fp-armv8,-fp16,-vfp4" "unsafe-fp-math"="false" "use-soft-float"="false" }
6969 attributes #1 = { nounwind readnone }
7070
7171 !llvm.dbg.cu = !{!0}