@@ -446,6 +446,19 @@ static bool getArchFeatures(const Driver &D, StringRef MArch,
446
446
return true ;
447
447
}
448
448
449
+ // Get features except standard extension feature
450
+ void getRISCFeaturesFromMcpu (const Driver &D, const llvm::Triple &Triple,
451
+ const llvm::opt::ArgList &Args,
452
+ const llvm::opt::Arg *A, StringRef Mcpu,
453
+ std::vector<StringRef> &Features) {
454
+ bool Is64Bit = (Triple.getArch () == llvm::Triple::riscv64);
455
+ llvm::RISCV::CPUKind CPUKind = llvm::RISCV::parseCPUKind (Mcpu);
456
+ if (!llvm::RISCV::checkCPUKind (CPUKind, Is64Bit) ||
457
+ !llvm::RISCV::getCPUFeaturesExceptStdExt (CPUKind, Features)) {
458
+ D.Diag (clang::diag::err_drv_clang_unsupported) << A->getAsString (Args);
459
+ }
460
+ }
461
+
449
462
void riscv::getRISCVTargetFeatures (const Driver &D, const llvm::Triple &Triple,
450
463
const ArgList &Args,
451
464
std::vector<StringRef> &Features) {
@@ -454,6 +467,11 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const llvm::Triple &Triple,
454
467
if (!getArchFeatures (D, MArch, Features, Args))
455
468
return ;
456
469
470
+ // If users give march and mcpu, get std extension feature from MArch
471
+ // and other features (ex. mirco architecture feature) from mcpu
472
+ if (Arg *A = Args.getLastArg (options::OPT_mcpu_EQ))
473
+ getRISCFeaturesFromMcpu (D, Triple, Args, A, A->getValue (), Features);
474
+
457
475
// Handle features corresponding to "-ffixed-X" options
458
476
if (Args.hasArg (options::OPT_ffixed_x1))
459
477
Features.push_back (" +reserve-x1" );
@@ -543,11 +561,9 @@ StringRef riscv::getRISCVABI(const ArgList &Args, const llvm::Triple &Triple) {
543
561
544
562
// GCC's logic around choosing a default `-mabi=` is complex. If GCC is not
545
563
// configured using `--with-abi=`, then the logic for the default choice is
546
- // defined in config.gcc. This function is based on the logic in GCC 9.2.0. We
547
- // deviate from GCC's default only on baremetal targets (UnknownOS) where
548
- // neither `-march` nor `-mabi` is specified.
564
+ // defined in config.gcc. This function is based on the logic in GCC 9.2.0.
549
565
//
550
- // The logic uses the following, in order:
566
+ // The logic used in GCC 9.2.0 is the following, in order:
551
567
// 1. Explicit choices using `--with-abi=`
552
568
// 2. A default based on `--with-arch=`, if provided
553
569
// 3. A default based on the target triple's arch
@@ -556,38 +572,40 @@ StringRef riscv::getRISCVABI(const ArgList &Args, const llvm::Triple &Triple) {
556
572
//
557
573
// Clang does not have `--with-arch=` or `--with-abi=`, so we use `-march=`
558
574
// and `-mabi=` respectively instead.
575
+ //
576
+ // In order to make chosing logic more clear, Clang uses the following logic,
577
+ // in order:
578
+ // 1. Explicit choices using `-mabi=`
579
+ // 2. A default based on the architecture as determined by getRISCVArch
580
+ // 3. Choose a default based on the triple
559
581
560
582
// 1. If `-mabi=` is specified, use it.
561
583
if (const Arg *A = Args.getLastArg (options::OPT_mabi_EQ))
562
584
return A->getValue ();
563
585
564
- // 2. Choose a default based on `-march=`
586
+ // 2. Choose a default based on the target architecture.
565
587
//
566
588
// rv32g | rv32*d -> ilp32d
567
589
// rv32e -> ilp32e
568
590
// rv32* -> ilp32
569
591
// rv64g | rv64*d -> lp64d
570
592
// rv64* -> lp64
571
- if (const Arg *A = Args.getLastArg (options::OPT_march_EQ)) {
572
- StringRef MArch = A->getValue ();
573
-
574
- if (MArch.startswith_lower (" rv32" )) {
575
- // FIXME: parse `March` to find `D` extension properly
576
- if (MArch.substr (4 ).contains_lower (" d" ) ||
577
- MArch.startswith_lower (" rv32g" ))
578
- return " ilp32d" ;
579
- else if (MArch.startswith_lower (" rv32e" ))
580
- return " ilp32e" ;
581
- else
582
- return " ilp32" ;
583
- } else if (MArch.startswith_lower (" rv64" )) {
584
- // FIXME: parse `March` to find `D` extension properly
585
- if (MArch.substr (4 ).contains_lower (" d" ) ||
586
- MArch.startswith_lower (" rv64g" ))
587
- return " lp64d" ;
588
- else
589
- return " lp64" ;
590
- }
593
+ StringRef MArch = getRISCVArch (Args, Triple);
594
+
595
+ if (MArch.startswith_lower (" rv32" )) {
596
+ // FIXME: parse `March` to find `D` extension properly
597
+ if (MArch.substr (4 ).contains_lower (" d" ) || MArch.startswith_lower (" rv32g" ))
598
+ return " ilp32d" ;
599
+ else if (MArch.startswith_lower (" rv32e" ))
600
+ return " ilp32e" ;
601
+ else
602
+ return " ilp32" ;
603
+ } else if (MArch.startswith_lower (" rv64" )) {
604
+ // FIXME: parse `March` to find `D` extension properly
605
+ if (MArch.substr (4 ).contains_lower (" d" ) || MArch.startswith_lower (" rv64g" ))
606
+ return " lp64d" ;
607
+ else
608
+ return " lp64" ;
591
609
}
592
610
593
611
// 3. Choose a default based on the triple
@@ -617,10 +635,11 @@ StringRef riscv::getRISCVArch(const llvm::opt::ArgList &Args,
617
635
// GCC's logic around choosing a default `-march=` is complex. If GCC is not
618
636
// configured using `--with-arch=`, then the logic for the default choice is
619
637
// defined in config.gcc. This function is based on the logic in GCC 9.2.0. We
620
- // deviate from GCC's default only on baremetal targets (UnknownOS) where
621
- // neither `-march` nor `-mabi` is specified.
638
+ // deviate from GCC's default on additional `-mcpu` option (GCC does not
639
+ // support `-mcpu`) and baremetal targets (UnknownOS) where neither `-march`
640
+ // nor `-mabi` is specified.
622
641
//
623
- // The logic uses the following, in order:
642
+ // The logic used in GCC 9.2.0 is the following, in order:
624
643
// 1. Explicit choices using `--with-arch=`
625
644
// 2. A default based on `--with-abi=`, if provided
626
645
// 3. A default based on the target triple's arch
@@ -630,14 +649,28 @@ StringRef riscv::getRISCVArch(const llvm::opt::ArgList &Args,
630
649
// Clang does not have `--with-arch=` or `--with-abi=`, so we use `-march=`
631
650
// and `-mabi=` respectively instead.
632
651
//
652
+ // Clang uses the following logic, in order:
653
+ // 1. Explicit choices using `-march=`
654
+ // 2. Based on `-mcpu` if the target CPU has a default ISA string
655
+ // 3. A default based on `-mabi`, if provided
656
+ // 4. A default based on the target triple's arch
657
+ //
633
658
// Clang does not yet support MULTILIB_REUSE, so we use `rv{XLEN}imafdc`
634
659
// instead of `rv{XLEN}gc` though they are (currently) equivalent.
635
660
636
661
// 1. If `-march=` is specified, use it.
637
662
if (const Arg *A = Args.getLastArg (options::OPT_march_EQ))
638
663
return A->getValue ();
639
664
640
- // 2. Choose a default based on `-mabi=`
665
+ // 2. Get march (isa string) based on `-mcpu=`
666
+ if (const Arg *A = Args.getLastArg (options::OPT_mcpu_EQ)) {
667
+ StringRef MArch = llvm::RISCV::getMArchFromMcpu (A->getValue ());
668
+ // Bypass if target cpu's default march is empty.
669
+ if (MArch != " " )
670
+ return MArch;
671
+ }
672
+
673
+ // 3. Choose a default based on `-mabi=`
641
674
//
642
675
// ilp32e -> rv32e
643
676
// ilp32 | ilp32f | ilp32d -> rv32imafdc
@@ -653,7 +686,7 @@ StringRef riscv::getRISCVArch(const llvm::opt::ArgList &Args,
653
686
return " rv64imafdc" ;
654
687
}
655
688
656
- // 3 . Choose a default based on the triple
689
+ // 4 . Choose a default based on the triple
657
690
//
658
691
// We deviate from GCC's defaults here:
659
692
// - On `riscv{XLEN}-unknown-elf` we default to `rv{XLEN}imac`
0 commit comments