@@ -73,14 +73,15 @@ static unsigned getARMFPUFeatures(const Driver &D, const Arg *A,
73
73
}
74
74
75
75
// Decode ARM features from string like +[no]featureA+[no]featureB+...
76
- static bool DecodeARMFeatures (const Driver &D, StringRef text,
77
- StringRef CPU, llvm::ARM::ArchKind ArchKind,
78
- std::vector<StringRef> &Features) {
76
+ static bool DecodeARMFeatures (const Driver &D, StringRef text, StringRef CPU,
77
+ llvm::ARM::ArchKind ArchKind,
78
+ std::vector<StringRef> &Features,
79
+ unsigned &ArgFPUID) {
79
80
SmallVector<StringRef, 8 > Split;
80
81
text.split (Split, StringRef (" +" ), -1 , false );
81
82
82
83
for (StringRef Feature : Split) {
83
- if (!appendArchExtFeatures (CPU, ArchKind, Feature, Features))
84
+ if (!appendArchExtFeatures (CPU, ArchKind, Feature, Features, ArgFPUID ))
84
85
return false ;
85
86
}
86
87
return true ;
@@ -102,30 +103,30 @@ static void DecodeARMFeaturesFromCPU(const Driver &D, StringRef CPU,
102
103
static void checkARMArchName (const Driver &D, const Arg *A, const ArgList &Args,
103
104
llvm::StringRef ArchName, llvm::StringRef CPUName,
104
105
std::vector<StringRef> &Features,
105
- const llvm::Triple &Triple) {
106
+ const llvm::Triple &Triple, unsigned &ArgFPUID ) {
106
107
std::pair<StringRef, StringRef> Split = ArchName.split (" +" );
107
108
108
109
std::string MArch = arm::getARMArch (ArchName, Triple);
109
110
llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch (MArch);
110
111
if (ArchKind == llvm::ARM::ArchKind::INVALID ||
111
- (Split.second .size () && !DecodeARMFeatures (
112
- D, Split. second , CPUName, ArchKind, Features)))
112
+ (Split.second .size () && !DecodeARMFeatures (D, Split. second , CPUName,
113
+ ArchKind, Features, ArgFPUID )))
113
114
D.Diag (clang::diag::err_drv_clang_unsupported) << A->getAsString (Args);
114
115
}
115
116
116
117
// Check -mcpu=. Needs ArchName to handle -mcpu=generic.
117
118
static void checkARMCPUName (const Driver &D, const Arg *A, const ArgList &Args,
118
119
llvm::StringRef CPUName, llvm::StringRef ArchName,
119
120
std::vector<StringRef> &Features,
120
- const llvm::Triple &Triple) {
121
+ const llvm::Triple &Triple, unsigned &ArgFPUID ) {
121
122
std::pair<StringRef, StringRef> Split = CPUName.split (" +" );
122
123
123
124
std::string CPU = arm::getARMTargetCPU (CPUName, ArchName, Triple);
124
125
llvm::ARM::ArchKind ArchKind =
125
126
arm::getLLVMArchKindForARM (CPU, ArchName, Triple);
126
127
if (ArchKind == llvm::ARM::ArchKind::INVALID ||
127
- (Split.second .size () && ! DecodeARMFeatures (
128
- D, Split.second , CPU, ArchKind, Features)))
128
+ (Split.second .size () &&
129
+ ! DecodeARMFeatures ( D, Split.second , CPU, ArchKind, Features, ArgFPUID )))
129
130
D.Diag (clang::diag::err_drv_clang_unsupported) << A->getAsString (Args);
130
131
}
131
132
@@ -347,6 +348,8 @@ void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
347
348
const Arg *CPUArg = Args.getLastArg (options::OPT_mcpu_EQ);
348
349
StringRef ArchName;
349
350
StringRef CPUName;
351
+ unsigned ArchArgFPUID = llvm::ARM::FK_INVALID;
352
+ unsigned CPUArgFPUID = llvm::ARM::FK_INVALID;
350
353
351
354
// Check -mcpu. ClangAs gives preference to -Wa,-mcpu=.
352
355
if (WaCPU) {
@@ -364,14 +367,14 @@ void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
364
367
D.Diag (clang::diag::warn_drv_unused_argument)
365
368
<< ArchArg->getAsString (Args);
366
369
ArchName = StringRef (WaArch->getValue ()).substr (7 );
367
- checkARMArchName (D, WaArch, Args, ArchName, CPUName,
368
- ExtensionFeatures, Triple );
370
+ checkARMArchName (D, WaArch, Args, ArchName, CPUName, ExtensionFeatures,
371
+ Triple, ArchArgFPUID );
369
372
// FIXME: Set Arch.
370
373
D.Diag (clang::diag::warn_drv_unused_argument) << WaArch->getAsString (Args);
371
374
} else if (ArchArg) {
372
375
ArchName = ArchArg->getValue ();
373
- checkARMArchName (D, ArchArg, Args, ArchName, CPUName,
374
- ExtensionFeatures, Triple );
376
+ checkARMArchName (D, ArchArg, Args, ArchName, CPUName, ExtensionFeatures,
377
+ Triple, ArchArgFPUID );
375
378
}
376
379
377
380
// Add CPU features for generic CPUs
@@ -390,8 +393,8 @@ void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
390
393
}
391
394
392
395
if (CPUArg)
393
- checkARMCPUName (D, CPUArg, Args, CPUName, ArchName,
394
- ExtensionFeatures, Triple );
396
+ checkARMCPUName (D, CPUArg, Args, CPUName, ArchName, ExtensionFeatures,
397
+ Triple, CPUArgFPUID );
395
398
// Honor -mfpu=. ClangAs gives preference to -Wa,-mfpu=.
396
399
unsigned FPUID = llvm::ARM::FK_INVALID;
397
400
const Arg *FPUArg = Args.getLastArg (options::OPT_mfpu_EQ);
@@ -455,20 +458,26 @@ void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
455
458
Features.push_back (" +fullfp16" );
456
459
}
457
460
458
- // Setting -msoft-float/-mfloat-abi=soft effectively disables the FPU (GCC
459
- // ignores the -mfpu options in this case).
460
- // Note that the ABI can also be set implicitly by the target selected.
461
+ // Setting -msoft-float/-mfloat-abi=soft, -mfpu=none, or adding +nofp to
462
+ // -march/-mcpu effectively disables the FPU (GCC ignores the -mfpu options in
463
+ // this case). Note that the ABI can also be set implicitly by the target
464
+ // selected.
461
465
if (ABI == arm::FloatABI::Soft) {
462
466
llvm::ARM::getFPUFeatures (llvm::ARM::FK_NONE, Features);
463
467
464
468
// Disable all features relating to hardware FP, not already disabled by the
465
469
// above call.
470
+ Features.insert (Features.end (), {" -dotprod" , " -fp16fml" , " -bf16" , " -mve" ,
471
+ " -mve.fp" , " -fpregs" });
472
+ } else if (FPUID == llvm::ARM::FK_NONE ||
473
+ ArchArgFPUID == llvm::ARM::FK_NONE ||
474
+ CPUArgFPUID == llvm::ARM::FK_NONE) {
475
+ // -mfpu=none, -march=armvX+nofp or -mcpu=X+nofp is *very* similar to
476
+ // -mfloat-abi=soft, only that it should not disable MVE-I. They disable the
477
+ // FPU, but not the FPU registers, thus MVE-I, which depends only on the
478
+ // latter, is still supported.
466
479
Features.insert (Features.end (),
467
- {" -dotprod" , " -fp16fml" , " -mve" , " -mve.fp" , " -fpregs" });
468
- } else if (FPUID == llvm::ARM::FK_NONE) {
469
- // -mfpu=none is *very* similar to -mfloat-abi=soft, only that it should not
470
- // disable MVE-I.
471
- Features.insert (Features.end (), {" -dotprod" , " -fp16fml" , " -mve.fp" });
480
+ {" -dotprod" , " -fp16fml" , " -bf16" , " -mve.fp" });
472
481
if (!hasIntegerMVE (Features))
473
482
Features.emplace_back (" -fpregs" );
474
483
}
0 commit comments