zixuan-wu updated this revision to Diff 396147.
zixuan-wu edited the summary of this revision.
zixuan-wu added a comment.
Address all comments.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D115921/new/
https://reviews.llvm.org/D115921
Files:
clang/lib/Basic/Targets/RISCV.cpp
clang/lib/Driver/ToolChains/Arch/RISCV.cpp
clang/test/Driver/riscv-arch-version.c
llvm/include/llvm/Support/RISCVISAInfo.h
llvm/lib/Object/ELFObjectFile.cpp
llvm/lib/Support/RISCVISAInfo.cpp
llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
llvm/lib/Target/RISCV/RISCV.td
llvm/lib/Target/RISCV/RISCVSubtarget.cpp
llvm/lib/Target/RISCV/RISCVSubtarget.h
llvm/test/CodeGen/RISCV/attributes-version.ll
llvm/test/tools/llvm-objdump/ELF/RISCV/unknown-arch-attr.test
Index: llvm/test/tools/llvm-objdump/ELF/RISCV/unknown-arch-attr.test
===================================================================
--- llvm/test/tools/llvm-objdump/ELF/RISCV/unknown-arch-attr.test
+++ llvm/test/tools/llvm-objdump/ELF/RISCV/unknown-arch-attr.test
@@ -3,7 +3,7 @@
## The expected behavior is to ignore the unrecognized arch feature and
## continue to process the following arch features.
##
-## The object file has the "rv32i2p0_x1p0_m2p0" arch feature. "x1p0" is an
+## The object file has the "rv32i2p0_y1p0_m2p0" arch feature. "y1p0" is an
## unrecognized architecture extension. llvm-objdump will ignore it and decode
## "mul" instruction correctly according to "m2p0" in the arch feature.
##
@@ -34,5 +34,5 @@
Content: 3385C502
- Name: .riscv.attributes
Type: SHT_RISCV_ATTRIBUTES
-## The content is the encoding of the arch feature "rv32i2p0_x1p0_m2p0"
- Content: 412300000072697363760001190000000572763332693270305F783170305F6D32703000
+## The content is the encoding of the arch feature "rv32i2p0_y1p0_m2p0"
+ Content: 412300000072697363760001190000000572763332693270305F793170305F6D32703000
Index: llvm/test/CodeGen/RISCV/attributes-version.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/RISCV/attributes-version.ll
@@ -0,0 +1,81 @@
+; Generate ELF attributes from llc.
+
+; RUN: llc -mtriple=riscv32 -mattr=+m %s -o - | FileCheck --check-prefix=RV32M %s
+; RUN: llc -mtriple=riscv32 -mattr=+a %s -o - | FileCheck --check-prefix=RV32A %s
+; RUN: llc -mtriple=riscv32 -mattr=+f %s -o - | FileCheck --check-prefix=RV32F %s
+; RUN: llc -mtriple=riscv32 -mattr=+d %s -o - | FileCheck --check-prefix=RV32D %s
+; RUN: llc -mtriple=riscv32 -mattr=+c %s -o - | FileCheck --check-prefix=RV32C %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zfhmin %s -o - | FileCheck --check-prefix=RV32ZFHMIN %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zfh %s -o - | FileCheck --check-prefix=RV32ZFH %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zba %s -o - | FileCheck --check-prefix=RV32ZBA %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbb %s -o - | FileCheck --check-prefix=RV32ZBB %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbc %s -o - | FileCheck --check-prefix=RV32ZBC %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbe %s -o - | FileCheck --check-prefix=RV32ZBE %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbf %s -o - | FileCheck --check-prefix=RV32ZBF %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbm %s -o - | FileCheck --check-prefix=RV32ZBM %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbp %s -o - | FileCheck --check-prefix=RV32ZBP %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbr %s -o - | FileCheck --check-prefix=RV32ZBR %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbs %s -o - | FileCheck --check-prefix=RV32ZBS %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbt %s -o - | FileCheck --check-prefix=RV32ZBT %s
+
+
+; RV32M: .attribute 5, "rv32i2p0_m2p0"
+; RV32A: .attribute 5, "rv32i2p0_a2p0"
+; RV32F: .attribute 5, "rv32i2p0_f2p0"
+; RV32D: .attribute 5, "rv32i2p0_f2p0_d2p0"
+; RV32C: .attribute 5, "rv32i2p0_c2p0"
+; RV32V: .attribute 5, "rv32i2p0_v0p10_zvlsseg0p10"
+; RV32ZFHMIN: .attribute 5, "rv32i2p0_f2p0_zfhmin0p1"
+; RV32ZFH: .attribute 5, "rv32i2p0_f2p0_zfh0p1_zfhmin0p1"
+; RV32ZBA: .attribute 5, "rv32i2p0_zba1p0"
+; RV32ZBB: .attribute 5, "rv32i2p0_zbb1p0"
+; RV32ZBC: .attribute 5, "rv32i2p0_zbc1p0"
+; RV32ZBE: .attribute 5, "rv32i2p0_zbe0p93"
+; RV32ZBF: .attribute 5, "rv32i2p0_zbf0p93"
+; RV32ZBM: .attribute 5, "rv32i2p0_zbm0p93"
+; RV32ZBP: .attribute 5, "rv32i2p0_zbp0p93"
+; RV32ZBR: .attribute 5, "rv32i2p0_zbr0p93"
+; RV32ZBS: .attribute 5, "rv32i2p0_zbs1p0"
+; RV32ZBT: .attribute 5, "rv32i2p0_zbt0p93"
+
+
+; RUN: llc -mtriple=riscv32 -mattr=+m0p7 < %s 2>&1 | FileCheck --check-prefix=RV32M0P7 %s
+; RUN: llc -mtriple=riscv32 -mattr=+a0p7 < %s 2>&1 | FileCheck --check-prefix=RV32A0P7 %s
+; RUN: llc -mtriple=riscv32 -mattr=+f0p7 < %s 2>&1 | FileCheck --check-prefix=RV32F0P7 %s
+; RUN: llc -mtriple=riscv32 -mattr=+d0p7 < %s 2>&1 | FileCheck --check-prefix=RV32D0P7 %s
+; RUN: llc -mtriple=riscv32 -mattr=+c0p7 < %s 2>&1 | FileCheck --check-prefix=RV32C0P7 %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zfhmin0p7 < %s 2>&1 | FileCheck --check-prefix=RV32ZFHMIN0P7 %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zfh0p7 < %s 2>&1 | FileCheck --check-prefix=RV32ZFH0P7 %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zba0p7 < %s 2>&1 | FileCheck --check-prefix=RV32ZBA0P7 %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbb0p7 < %s 2>&1 | FileCheck --check-prefix=RV32ZBB0P7 %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbc0p7 < %s 2>&1 | FileCheck --check-prefix=RV32ZBC0P7 %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbe0p7 < %s 2>&1 | FileCheck --check-prefix=RV32ZBE0P7 %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbf0p7 < %s 2>&1 | FileCheck --check-prefix=RV32ZBF0P7 %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbm0p7 < %s 2>&1 | FileCheck --check-prefix=RV32ZBM0P7 %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbp0p7 < %s 2>&1 | FileCheck --check-prefix=RV32ZBP0P7 %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbr0p7 < %s 2>&1 | FileCheck --check-prefix=RV32ZBR0P7 %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbs0p7 < %s 2>&1 | FileCheck --check-prefix=RV32ZBS0P7 %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbt0p7 < %s 2>&1 | FileCheck --check-prefix=RV32ZBT0P7 %s
+
+; RV32M0P7: '+m0p7' is not a recognized feature for this target
+; RV32A0P7: '+a0p7' is not a recognized feature for this target
+; RV32F0P7: '+f0p7' is not a recognized feature for this target
+; RV32D0P7: '+d0p7' is not a recognized feature for this target
+; RV32C0P7: '+c0p7' is not a recognized feature for this target
+; RV32ZFHMIN0P7: '+experimental-zfhmin0p7' is not a recognized feature for this target
+; RV32ZFH0P7: '+experimental-zfh0p7' is not a recognized feature for this target
+; RV32ZBA0P7: '+experimental-zba0p7' is not a recognized feature for this target
+; RV32ZBB0P7: '+experimental-zbb0p7' is not a recognized feature for this target
+; RV32ZBC0P7: '+experimental-zbc0p7' is not a recognized feature for this target
+; RV32ZBE0P7: '+experimental-zbe0p7' is not a recognized feature for this target
+; RV32ZBF0P7: '+experimental-zbf0p7' is not a recognized feature for this target
+; RV32ZBM0P7: '+experimental-zbm0p7' is not a recognized feature for this target
+; RV32ZBP0P7: '+experimental-zbp0p7' is not a recognized feature for this target
+; RV32ZBR0P7: '+experimental-zbr0p7' is not a recognized feature for this target
+; RV32ZBS0P7: '+experimental-zbs0p7' is not a recognized feature for this target
+; RV32ZBT0P7: '+experimental-zbt0p7' is not a recognized feature for this target
+
+define i32 @addi(i32 %a) {
+ %1 = add i32 %a, 1
+ ret i32 %1
+}
Index: llvm/lib/Target/RISCV/RISCVSubtarget.h
===================================================================
--- llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -24,6 +24,7 @@
#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/Support/RISCVISAInfo.h"
#include "llvm/Target/TargetMachine.h"
#define GET_SUBTARGETINFO_HEADER
@@ -34,27 +35,28 @@
class RISCVSubtarget : public RISCVGenSubtargetInfo {
virtual void anchor();
- bool HasStdExtM = false;
- bool HasStdExtA = false;
- bool HasStdExtF = false;
- bool HasStdExtD = false;
- bool HasStdExtC = false;
- bool HasStdExtZba = false;
- bool HasStdExtZbb = false;
- bool HasStdExtZbc = false;
- bool HasStdExtZbe = false;
- bool HasStdExtZbf = false;
- bool HasStdExtZbm = false;
- bool HasStdExtZbp = false;
- bool HasStdExtZbr = false;
- bool HasStdExtZbs = false;
- bool HasStdExtZbt = false;
- bool HasStdExtV = false;
- bool HasStdExtZvlsseg = false;
- bool HasStdExtZfhmin = false;
- bool HasStdExtZfh = false;
+ RISCVExtensionVersion StdExtM;
+ RISCVExtensionVersion StdExtA;
+ RISCVExtensionVersion StdExtF;
+ RISCVExtensionVersion StdExtD;
+ RISCVExtensionVersion StdExtC;
+ RISCVExtensionVersion StdExtZba;
+ RISCVExtensionVersion StdExtZbb;
+ RISCVExtensionVersion StdExtZbc;
+ RISCVExtensionVersion StdExtZbe;
+ RISCVExtensionVersion StdExtZbf;
+ RISCVExtensionVersion StdExtZbm;
+ RISCVExtensionVersion StdExtZbp;
+ RISCVExtensionVersion StdExtZbr;
+ RISCVExtensionVersion StdExtZbs;
+ RISCVExtensionVersion StdExtZbt;
+ RISCVExtensionVersion StdExtV;
+ RISCVExtensionVersion StdExtZvlsseg;
+ RISCVExtensionVersion StdExtZvamo;
+ RISCVExtensionVersion StdExtZfhmin;
+ RISCVExtensionVersion StdExtZfh;
+ RISCVExtensionVersion StdExtE;
bool HasRV64 = false;
- bool IsRV32E = false;
bool EnableLinkerRelax = false;
bool EnableRVCHintInstrs = true;
bool EnableSaveRestore = false;
@@ -100,27 +102,27 @@
return &TSInfo;
}
bool enableMachineScheduler() const override { return true; }
- bool hasStdExtM() const { return HasStdExtM; }
- bool hasStdExtA() const { return HasStdExtA; }
- bool hasStdExtF() const { return HasStdExtF; }
- bool hasStdExtD() const { return HasStdExtD; }
- bool hasStdExtC() const { return HasStdExtC; }
- bool hasStdExtZba() const { return HasStdExtZba; }
- bool hasStdExtZbb() const { return HasStdExtZbb; }
- bool hasStdExtZbc() const { return HasStdExtZbc; }
- bool hasStdExtZbe() const { return HasStdExtZbe; }
- bool hasStdExtZbf() const { return HasStdExtZbf; }
- bool hasStdExtZbm() const { return HasStdExtZbm; }
- bool hasStdExtZbp() const { return HasStdExtZbp; }
- bool hasStdExtZbr() const { return HasStdExtZbr; }
- bool hasStdExtZbs() const { return HasStdExtZbs; }
- bool hasStdExtZbt() const { return HasStdExtZbt; }
- bool hasStdExtV() const { return HasStdExtV; }
- bool hasStdExtZvlsseg() const { return HasStdExtZvlsseg; }
- bool hasStdExtZfhmin() const { return HasStdExtZfhmin; }
- bool hasStdExtZfh() const { return HasStdExtZfh; }
+ bool hasStdExtM() const { return StdExtM; }
+ bool hasStdExtA() const { return StdExtA; }
+ bool hasStdExtF() const { return StdExtF; }
+ bool hasStdExtD() const { return StdExtD; }
+ bool hasStdExtC() const { return StdExtC; }
+ bool hasStdExtZba() const { return StdExtZba; }
+ bool hasStdExtZbb() const { return StdExtZbb; }
+ bool hasStdExtZbc() const { return StdExtZbc; }
+ bool hasStdExtZbe() const { return StdExtZbe; }
+ bool hasStdExtZbf() const { return StdExtZbf; }
+ bool hasStdExtZbm() const { return StdExtZbm; }
+ bool hasStdExtZbp() const { return StdExtZbp; }
+ bool hasStdExtZbr() const { return StdExtZbr; }
+ bool hasStdExtZbs() const { return StdExtZbs; }
+ bool hasStdExtZbt() const { return StdExtZbt; }
+ bool hasStdExtV() const { return StdExtV; }
+ bool hasStdExtZvlsseg() const { return StdExtZvlsseg; }
+ bool hasStdExtZfhmin() const { return StdExtZfhmin; }
+ bool hasStdExtZfh() const { return StdExtZfh; }
bool is64Bit() const { return HasRV64; }
- bool isRV32E() const { return IsRV32E; }
+ bool isRV32E() const { return StdExtE; }
bool enableLinkerRelax() const { return EnableLinkerRelax; }
bool enableRVCHintInstrs() const { return EnableRVCHintInstrs; }
bool enableSaveRestore() const { return EnableSaveRestore; }
@@ -133,11 +135,11 @@
}
// Vector codegen related methods.
- bool hasVInstructions() const { return HasStdExtV; }
- bool hasVInstructionsI64() const { return HasStdExtV; }
- bool hasVInstructionsF16() const { return HasStdExtV && hasStdExtZfh(); }
- bool hasVInstructionsF32() const { return HasStdExtV && hasStdExtF(); }
- bool hasVInstructionsF64() const { return HasStdExtV && hasStdExtD(); }
+ bool hasVInstructions() const { return StdExtV; }
+ bool hasVInstructionsI64() const { return StdExtV; }
+ bool hasVInstructionsF16() const { return StdExtV && hasStdExtZfh(); }
+ bool hasVInstructionsF32() const { return StdExtV && hasStdExtF(); }
+ bool hasVInstructionsF64() const { return StdExtV && hasStdExtD(); }
// F16 and F64 both require F32.
bool hasVInstructionsAnyF() const { return hasVInstructionsF32(); }
unsigned getMaxInterleaveFactor() const {
Index: llvm/lib/Target/RISCV/RISCVSubtarget.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVSubtarget.cpp
+++ llvm/lib/Target/RISCV/RISCVSubtarget.cpp
@@ -66,7 +66,6 @@
if (TuneCPU.empty())
TuneCPU = CPU;
-
ParseSubtargetFeatures(CPU, TuneCPU, FS);
if (Is64Bit) {
XLenVT = MVT::i64;
Index: llvm/lib/Target/RISCV/RISCV.td
===================================================================
--- llvm/lib/Target/RISCV/RISCV.td
+++ llvm/lib/Target/RISCV/RISCV.td
@@ -13,28 +13,28 @@
//===----------------------------------------------------------------------===//
def FeatureStdExtM
- : SubtargetFeature<"m", "HasStdExtM", "true",
+ : SubtargetFeature<"m", "StdExtM", "RISCVExtensionVersion{2, 0}",
"'M' (Integer Multiplication and Division)">;
def HasStdExtM : Predicate<"Subtarget->hasStdExtM()">,
AssemblerPredicate<(all_of FeatureStdExtM),
"'M' (Integer Multiplication and Division)">;
def FeatureStdExtA
- : SubtargetFeature<"a", "HasStdExtA", "true",
+ : SubtargetFeature<"a", "StdExtA", "RISCVExtensionVersion{2, 0}",
"'A' (Atomic Instructions)">;
def HasStdExtA : Predicate<"Subtarget->hasStdExtA()">,
AssemblerPredicate<(all_of FeatureStdExtA),
"'A' (Atomic Instructions)">;
def FeatureStdExtF
- : SubtargetFeature<"f", "HasStdExtF", "true",
+ : SubtargetFeature<"f", "StdExtF", "RISCVExtensionVersion{2, 0}",
"'F' (Single-Precision Floating-Point)">;
def HasStdExtF : Predicate<"Subtarget->hasStdExtF()">,
AssemblerPredicate<(all_of FeatureStdExtF),
"'F' (Single-Precision Floating-Point)">;
def FeatureStdExtD
- : SubtargetFeature<"d", "HasStdExtD", "true",
+ : SubtargetFeature<"d", "StdExtD", "RISCVExtensionVersion{2, 0}",
"'D' (Double-Precision Floating-Point)",
[FeatureStdExtF]>;
def HasStdExtD : Predicate<"Subtarget->hasStdExtD()">,
@@ -42,7 +42,8 @@
"'D' (Double-Precision Floating-Point)">;
def FeatureStdExtZfhmin
- : SubtargetFeature<"experimental-zfhmin", "HasStdExtZfhmin", "true",
+ : SubtargetFeature<"experimental-zfhmin", "StdExtZfhmin",
+ "RISCVExtensionVersion{0, 1}",
"'Zfhmin' (Half-Precision Floating-Point Minimal)",
[FeatureStdExtF]>;
def HasStdExtZfhmin : Predicate<"Subtarget->hasStdExtZfhmin()">,
@@ -50,7 +51,8 @@
"'Zfhmin' (Half-Precision Floating-Point Minimal)">;
def FeatureStdExtZfh
- : SubtargetFeature<"experimental-zfh", "HasStdExtZfh", "true",
+ : SubtargetFeature<"experimental-zfh", "StdExtZfh",
+ "RISCVExtensionVersion{0, 1}",
"'Zfh' (Half-Precision Floating-Point)",
[FeatureStdExtZfhmin, FeatureStdExtF]>;
def HasStdExtZfh : Predicate<"Subtarget->hasStdExtZfh()">,
@@ -58,14 +60,15 @@
"'Zfh' (Half-Precision Floating-Point)">;
def FeatureStdExtC
- : SubtargetFeature<"c", "HasStdExtC", "true",
+ : SubtargetFeature<"c", "StdExtC", "RISCVExtensionVersion{2, 0}",
"'C' (Compressed Instructions)">;
def HasStdExtC : Predicate<"Subtarget->hasStdExtC()">,
AssemblerPredicate<(all_of FeatureStdExtC),
"'C' (Compressed Instructions)">;
def FeatureStdExtZba
- : SubtargetFeature<"experimental-zba", "HasStdExtZba", "true",
+ : SubtargetFeature<"experimental-zba", "StdExtZba",
+ "RISCVExtensionVersion{1, 0}",
"'Zba' (Address calculation 'B' Instructions)">;
def HasStdExtZba : Predicate<"Subtarget->hasStdExtZba()">,
AssemblerPredicate<(all_of FeatureStdExtZba),
@@ -73,63 +76,72 @@
def NotHasStdExtZba : Predicate<"!Subtarget->hasStdExtZba()">;
def FeatureStdExtZbb
- : SubtargetFeature<"experimental-zbb", "HasStdExtZbb", "true",
+ : SubtargetFeature<"experimental-zbb", "StdExtZbb",
+ "RISCVExtensionVersion{1, 0}",
"'Zbb' (Base 'B' Instructions)">;
def HasStdExtZbb : Predicate<"Subtarget->hasStdExtZbb()">,
AssemblerPredicate<(all_of FeatureStdExtZbb),
"'Zbb' (Base 'B' Instructions)">;
def FeatureStdExtZbc
- : SubtargetFeature<"experimental-zbc", "HasStdExtZbc", "true",
+ : SubtargetFeature<"experimental-zbc", "StdExtZbc",
+ "RISCVExtensionVersion{1, 0}",
"'Zbc' (Carry-Less 'B' Instructions)">;
def HasStdExtZbc : Predicate<"Subtarget->hasStdExtZbc()">,
AssemblerPredicate<(all_of FeatureStdExtZbc),
"'Zbc' (Carry-Less 'B' Instructions)">;
def FeatureStdExtZbe
- : SubtargetFeature<"experimental-zbe", "HasStdExtZbe", "true",
+ : SubtargetFeature<"experimental-zbe", "StdExtZbe",
+ "RISCVExtensionVersion{0, 93}",
"'Zbe' (Extract-Deposit 'B' Instructions)">;
def HasStdExtZbe : Predicate<"Subtarget->hasStdExtZbe()">,
AssemblerPredicate<(all_of FeatureStdExtZbe),
"'Zbe' (Extract-Deposit 'B' Instructions)">;
def FeatureStdExtZbf
- : SubtargetFeature<"experimental-zbf", "HasStdExtZbf", "true",
+ : SubtargetFeature<"experimental-zbf", "StdExtZbf",
+ "RISCVExtensionVersion{0, 93}",
"'Zbf' (Bit-Field 'B' Instructions)">;
def HasStdExtZbf : Predicate<"Subtarget->hasStdExtZbf()">,
AssemblerPredicate<(all_of FeatureStdExtZbf),
"'Zbf' (Bit-Field 'B' Instructions)">;
def FeatureStdExtZbm
- : SubtargetFeature<"experimental-zbm", "HasStdExtZbm", "true",
+ : SubtargetFeature<"experimental-zbm", "StdExtZbm",
+ "RISCVExtensionVersion{0, 93}",
"'Zbm' (Matrix 'B' Instructions)">;
def HasStdExtZbm : Predicate<"Subtarget->hasStdExtZbm()">,
AssemblerPredicate<(all_of FeatureStdExtZbm),
"'Zbm' (Matrix 'B' Instructions)">;
def FeatureStdExtZbp
- : SubtargetFeature<"experimental-zbp", "HasStdExtZbp", "true",
+ : SubtargetFeature<"experimental-zbp", "StdExtZbp",
+ "RISCVExtensionVersion{0, 93}",
"'Zbp' (Permutation 'B' Instructions)">;
def HasStdExtZbp : Predicate<"Subtarget->hasStdExtZbp()">,
AssemblerPredicate<(all_of FeatureStdExtZbp),
"'Zbp' (Permutation 'B' Instructions)">;
def FeatureStdExtZbr
- : SubtargetFeature<"experimental-zbr", "HasStdExtZbr", "true",
+ : SubtargetFeature<"experimental-zbr", "StdExtZbr",
+ "RISCVExtensionVersion{0, 93}",
"'Zbr' (Polynomial Reduction 'B' Instructions)">;
def HasStdExtZbr : Predicate<"Subtarget->hasStdExtZbr()">,
AssemblerPredicate<(all_of FeatureStdExtZbr),
"'Zbr' (Polynomial Reduction 'B' Instructions)">;
def FeatureStdExtZbs
- : SubtargetFeature<"experimental-zbs", "HasStdExtZbs", "true",
+ : SubtargetFeature<"experimental-zbs", "StdExtZbs",
+ "RISCVExtensionVersion{1, 0}",
"'Zbs' (Single-Bit 'B' Instructions)">;
def HasStdExtZbs : Predicate<"Subtarget->hasStdExtZbs()">,
AssemblerPredicate<(all_of FeatureStdExtZbs),
"'Zbs' (Single-Bit 'B' Instructions)">;
def FeatureStdExtZbt
- : SubtargetFeature<"experimental-zbt", "HasStdExtZbt", "true",
+ : SubtargetFeature<"experimental-zbt", "StdExtZbt",
+ "RISCVExtensionVersion{0, 93}",
"'Zbt' (Ternary 'B' Instructions)">;
def HasStdExtZbt : Predicate<"Subtarget->hasStdExtZbt()">,
AssemblerPredicate<(all_of FeatureStdExtZbt),
@@ -151,22 +163,26 @@
"RVC Hint Instructions">;
def FeatureStdExtV
- : SubtargetFeature<"experimental-v", "HasStdExtV", "true",
+ : SubtargetFeature<"experimental-v", "StdExtV",
+ "RISCVExtensionVersion{0, 10}",
"'V' (Vector Instructions)">;
-def HasStdExtV : Predicate<"Subtarget->hasStdExtV()">,
- AssemblerPredicate<(all_of FeatureStdExtV),
- "'V' (Vector Instructions)">;
+def HasStdExtV
+ : Predicate<"Subtarget->hasStdExtV()">,
+ AssemblerPredicate<(all_of FeatureStdExtV),
+ "'V' (Vector Instructions)">;
def HasVInstructions : Predicate<"Subtarget->hasVInstructions()">;
def HasVInstructionsAnyF : Predicate<"Subtarget->hasVInstructionsAnyF()">;
def FeatureStdExtZvlsseg
- : SubtargetFeature<"experimental-zvlsseg", "HasStdExtZvlsseg", "true",
+ : SubtargetFeature<"experimental-zvlsseg", "StdExtZvlsseg",
+ "RISCVExtensionVersion{0, 10}",
"'Zvlsseg' (Vector segment load/store instructions)",
[FeatureStdExtV]>;
-def HasStdExtZvlsseg : Predicate<"Subtarget->hasStdExtZvlsseg()">,
- AssemblerPredicate<(all_of FeatureStdExtZvlsseg),
- "'Zvlsseg' (Vector segment load/store instructions)">;
+def HasStdExtZvlsseg
+ : Predicate<"Subtarget->hasStdExtZvlsseg()">,
+ AssemblerPredicate<(all_of FeatureStdExtZvlsseg),
+ "'Zvlsseg' (Vector segment load/store instructions)">;
def Feature64Bit
: SubtargetFeature<"64bit", "HasRV64", "true", "Implements RV64">;
@@ -181,7 +197,7 @@
def RV64 : HwMode<"+64bit">;
def FeatureRV32E
- : SubtargetFeature<"e", "IsRV32E", "true",
+ : SubtargetFeature<"e", "StdExtE", "RISCVExtensionVersion{1, 9}",
"Implements RV32E (provides 16 rather than 32 GPRs)">;
def IsRV32E : Predicate<"Subtarget->isRV32E()">,
AssemblerPredicate<(all_of FeatureRV32E)>;
Index: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
===================================================================
--- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -2153,9 +2153,10 @@
}
auto &ISAInfo = *ParseResult;
- for (auto Feature : RISCVFeatureKV)
- if (ISAInfo->hasExtension(Feature.Key))
+ for (auto Feature : RISCVFeatureKV) {
+ if (ISAInfo->hasExtensionWithVersion(Feature.Key))
setFeatureBits(Feature.Value, Feature.Key);
+ }
if (ISAInfo->getXLen() == 32)
clearFeatureBits(RISCV::Feature64Bit, "64bit");
Index: llvm/lib/Support/RISCVISAInfo.cpp
===================================================================
--- llvm/lib/Support/RISCVISAInfo.cpp
+++ llvm/lib/Support/RISCVISAInfo.cpp
@@ -22,11 +22,6 @@
using namespace llvm;
namespace {
-/// Represents the major and version number components of a RISC-V extension
-struct RISCVExtensionVersion {
- unsigned Major;
- unsigned Minor;
-};
struct RISCVSupportedExtension {
const char *Name;
@@ -50,6 +45,7 @@
static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
{"v", RISCVExtensionVersion{0, 10}},
+ //{"v", RISCVExtensionVersion{0, 7}},
{"zba", RISCVExtensionVersion{1, 0}},
{"zbb", RISCVExtensionVersion{1, 0}},
{"zbc", RISCVExtensionVersion{1, 0}},
@@ -62,11 +58,17 @@
{"zbt", RISCVExtensionVersion{0, 93}},
{"zvlsseg", RISCVExtensionVersion{0, 10}},
+ //{"zvlsseg", RISCVExtensionVersion{0, 7}},
{"zfhmin", RISCVExtensionVersion{0, 1}},
{"zfh", RISCVExtensionVersion{0, 1}},
};
+static Error getExtensionVersion(StringRef Ext, StringRef In, unsigned &Major,
+ unsigned &Minor, unsigned &ConsumeLength,
+ bool EnableExperimentalExtension,
+ bool ExperimentalExtensionVersionCheck);
+
static bool stripExperimentalPrefix(StringRef &Ext) {
return Ext.consume_front("experimental-");
}
@@ -120,8 +122,8 @@
unsigned MinorVersion) {
RISCVExtensionInfo Ext;
Ext.ExtName = ExtName.str();
- Ext.MajorVersion = MajorVersion;
- Ext.MinorVersion = MinorVersion;
+ Ext.Version.Major = MajorVersion;
+ Ext.Version.Minor = MinorVersion;
Exts[ExtName.str()] = Ext;
}
@@ -149,22 +151,47 @@
return StringRef();
}
-static Optional<RISCVExtensionVersion> isExperimentalExtension(StringRef Ext) {
- auto ExtIterator =
- llvm::find_if(SupportedExperimentalExtensions, FindByName(Ext));
- if (ExtIterator == std::end(SupportedExperimentalExtensions))
- return None;
+static std::vector<RISCVExtensionVersion>
+getExperimentalExtensionVersions(StringRef Ext) {
+ std::vector<RISCVExtensionVersion> Result;
- return ExtIterator->Version;
+ for (auto &Extension : SupportedExperimentalExtensions) {
+ if (Extension.Name == Ext)
+ Result.push_back(Extension.Version);
+ }
+
+ return Result;
}
-bool RISCVISAInfo::isSupportedExtensionFeature(StringRef Ext) {
- bool IsExperimental = stripExperimentalPrefix(Ext);
+Optional<RISCVExtensionInfo>
+RISCVISAInfo::isSupportedExtensionFeature(StringRef Ext) {
+ stripExperimentalPrefix(Ext);
- if (IsExperimental)
- return llvm::any_of(SupportedExperimentalExtensions, FindByName(Ext));
- else
- return llvm::any_of(SupportedExtensions, FindByName(Ext));
+ auto Pos = findFirstNonVersionCharacter(Ext) + 1;
+ StringRef Name(Ext.substr(0, Pos));
+ StringRef Vers(Ext.substr(Pos));
+
+ unsigned Major, Minor, ConsumeLength;
+ if (Vers.empty()) {
+ auto Version = findDefaultVersion(Name);
+ if (!Version)
+ return None;
+
+ Major = Version->Major;
+ Minor = Version->Minor;
+
+ } else if (auto E = getExtensionVersion(Name, Vers, Major, Minor,
+ ConsumeLength, true, false)) {
+ // Not all features is related to ISA extension, like `relax` or
+ // `save-restore`, skip those feature.
+ consumeError(std::move(E));
+ return None;
+ }
+
+ if (!isSupportedExtension(Name, Major, Minor))
+ return None;
+
+ return RISCVExtensionInfo{Name.str(), {Major, Minor}};
}
bool RISCVISAInfo::isSupportedExtension(StringRef Ext) {
@@ -191,6 +218,20 @@
return Exts.count(Ext.str()) != 0;
}
+bool RISCVISAInfo::hasExtensionWithVersion(StringRef Ext) const {
+ auto Info = isSupportedExtensionFeature(Ext);
+ if (!Info)
+ return false;
+
+ auto ExtInfoIt = Exts.find(Info->ExtName);
+
+ if (ExtInfoIt == Exts.end())
+ return false;
+
+ return ExtInfoIt->second.Version.Major == Info->Version.Major &&
+ ExtInfoIt->second.Version.Minor == Info->Version.Minor;
+}
+
// Get the rank for single-letter extension, lower value meaning higher
// priority.
static int singleLetterExtensionRank(char Ext) {
@@ -273,22 +314,35 @@
return LHS < RHS;
}
-void RISCVISAInfo::toFeatures(
- std::vector<StringRef> &Features,
- std::function<StringRef(const Twine &)> StrAlloc) const {
+static std::string addVersionSuffix(StringRef Suffix, StringRef ExtName,
+ unsigned Major, unsigned Minor) {
+ if (auto DefaultVersion = findDefaultVersion(ExtName))
+ if (DefaultVersion->Major == Major && DefaultVersion->Minor == Minor)
+ return (Twine(Suffix) + ExtName).str();
+
+ return (Suffix + ExtName + Twine(Major) + "p" + Twine(Minor)).str();
+}
+
+void RISCVISAInfo::toFeatures(std::vector<std::string> &Features) const {
+
for (auto &Ext : Exts) {
StringRef ExtName = Ext.first;
+ auto Extension = Ext.second;
+ unsigned Major = Ext.second.Version.Major;
+ unsigned Minor = Ext.second.Version.Minor;
if (ExtName == "i")
continue;
if (ExtName == "zvlsseg") {
- Features.push_back("+experimental-v");
- Features.push_back("+experimental-zvlsseg");
- } else if (isExperimentalExtension(ExtName)) {
- Features.push_back(StrAlloc("+experimental-" + ExtName));
+ Features.push_back(addVersionSuffix("experimental-", "v", Major, Minor));
+ Features.push_back(
+ addVersionSuffix("experimental-", "zvlsseg", Major, Minor));
+ } else if (!getExperimentalExtensionVersions(ExtName).empty()) {
+ Features.push_back(
+ addVersionSuffix("experimental-", ExtName, Major, Minor));
} else {
- Features.push_back(StrAlloc("+" + ExtName));
+ Features.push_back(addVersionSuffix("", ExtName, Major, Minor));
}
}
}
@@ -346,7 +400,8 @@
}
// If experimental extension, require use of current version number number
- if (auto ExperimentalExtension = isExperimentalExtension(Ext)) {
+ auto ExperimentalExtension = getExperimentalExtensionVersions(Ext);
+ if (!ExperimentalExtension.empty()) {
if (!EnableExperimentalExtension) {
std::string Error = "requires '-menable-experimental-extensions' for "
"experimental extension '" +
@@ -362,18 +417,27 @@
return createStringError(errc::invalid_argument, Error);
}
- auto SupportedVers = *ExperimentalExtension;
- if (ExperimentalExtensionVersionCheck &&
- (Major != SupportedVers.Major || Minor != SupportedVers.Minor)) {
- std::string Error = "unsupported version number " + MajorStr.str();
- if (!MinorStr.empty())
- Error += "." + MinorStr.str();
- Error += " for experimental extension '" + Ext.str() +
- "'(this compiler supports " + utostr(SupportedVers.Major) + "." +
- utostr(SupportedVers.Minor) + ")";
- return createStringError(errc::invalid_argument, Error);
+ for (auto Version : ExperimentalExtension) {
+ if (Major == Version.Major && Minor == Version.Minor)
+ return Error::success();
}
- return Error::success();
+
+ if (!ExperimentalExtensionVersionCheck)
+ return Error::success();
+
+ std::string Error = "unsupported version number " + MajorStr.str();
+ if (!MinorStr.empty())
+ Error += "." + MinorStr.str();
+ Error += " for experimental extension '" + Ext.str() +
+ "'(this compiler supports ";
+
+ ListSeparator LS;
+ for (auto Version : ExperimentalExtension) {
+ Error += LS;
+ Error += (utostr(Version.Major) + "." + utostr(Version.Minor));
+ }
+ Error += ")";
+ return createStringError(errc::invalid_argument, Error);
}
// Exception rule for `g`, we don't have clear version scheme for that on
@@ -409,27 +473,19 @@
for (auto &Feature : Features) {
StringRef ExtName = Feature;
- bool Experimental = false;
assert(ExtName.size() > 1 && (ExtName[0] == '+' || ExtName[0] == '-'));
bool Add = ExtName[0] == '+';
ExtName = ExtName.drop_front(1); // Drop '+' or '-'
- Experimental = stripExperimentalPrefix(ExtName);
- auto ExtensionInfos = Experimental
- ? makeArrayRef(SupportedExperimentalExtensions)
- : makeArrayRef(SupportedExtensions);
- auto ExtensionInfoIterator =
- llvm::find_if(ExtensionInfos, FindByName(ExtName));
- // Not all features is related to ISA extension, like `relax` or
- // `save-restore`, skip those feature.
- if (ExtensionInfoIterator == ExtensionInfos.end())
+ auto Info = isSupportedExtensionFeature(ExtName);
+ if (!Info)
continue;
if (Add)
- ISAInfo->addExtension(ExtName, ExtensionInfoIterator->Version.Major,
- ExtensionInfoIterator->Version.Minor);
+ ISAInfo->addExtension(Info->ExtName, Info->Version.Major,
+ Info->Version.Minor);
else
- ISAInfo->Exts.erase(ExtName.str());
+ ISAInfo->Exts.erase(Info->ExtName);
}
ISAInfo->updateImplication();
@@ -443,7 +499,8 @@
llvm::Expected<std::unique_ptr<RISCVISAInfo>>
RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
- bool ExperimentalExtensionVersionCheck) {
+ bool ExperimentalExtensionVersionCheck,
+ bool IgnoreUnknownExtension) {
// RISC-V ISA strings must be lowercase.
if (llvm::any_of(Arch, isupper)) {
return createStringError(errc::invalid_argument,
@@ -544,9 +601,10 @@
"standard user-level extension not given in canonical order '%c'",
C);
}
-
- return createStringError(errc::invalid_argument,
- "invalid standard user-level extension '%c'", C);
+ if (!IgnoreUnknownExtension)
+ return createStringError(errc::invalid_argument,
+ "invalid standard user-level extension '%c'",
+ C);
}
// Move to next char to prevent repeated letter.
@@ -558,18 +616,23 @@
Next = std::string(std::next(I), E);
if (auto E = getExtensionVersion(std::string(1, C), Next, Major, Minor,
ConsumeLength, EnableExperimentalExtension,
- ExperimentalExtensionVersionCheck))
- return std::move(E);
-
- // The order is OK, then push it into features.
- // TODO: Use version number when setting target features
- // Currently LLVM supports only "mafdcbv".
- StringRef SupportedStandardExtension = "mafdcbv";
- if (SupportedStandardExtension.find(C) == StringRef::npos)
- return createStringError(errc::invalid_argument,
- "unsupported standard user-level extension '%c'",
- C);
- ISAInfo->addExtension(std::string(1, C), Major, Minor);
+ ExperimentalExtensionVersionCheck)) {
+ if (IgnoreUnknownExtension)
+ consumeError(std::move(E));
+ else
+ return std::move(E);
+ } else {
+ // The order is OK, then push it into features.
+ // TODO: Use version number when setting target features
+ // Currently LLVM supports only "mafdcbv".
+ StringRef SupportedStandardExtension = "mafdcbv";
+ if (SupportedStandardExtension.find(C) != StringRef::npos)
+ ISAInfo->addExtension(std::string(1, C), Major, Minor);
+ else if (!IgnoreUnknownExtension)
+ return createStringError(
+ errc::invalid_argument,
+ "unsupported standard user-level extension '%c'", C);
+ }
// Consume full extension name and version, including any optional '_'
// between this extension and the next
@@ -724,10 +787,9 @@
for (auto &Ext : Exts) {
auto I = llvm::lower_bound(ImpliedExts, Ext.first);
if (I != std::end(ImpliedExts) && I->Name == Ext.first) {
- for (auto &ImpliedExt : I->Exts) {
- auto Version = findDefaultVersion(ImpliedExt);
- addExtension(ImpliedExt, Version->Major, Version->Minor);
- }
+ for (auto &ImpliedExt : I->Exts)
+ addExtension(ImpliedExt, Ext.second.Version.Major,
+ Ext.second.Version.Minor);
}
}
}
@@ -752,7 +814,7 @@
StringRef ExtName = Ext.first;
auto ExtInfo = Ext.second;
Arch << LS << ExtName;
- Arch << ExtInfo.MajorVersion << "p" << ExtInfo.MinorVersion;
+ Arch << ExtInfo.Version.Major << "p" << ExtInfo.Version.Minor;
}
return Arch.str();
Index: llvm/lib/Object/ELFObjectFile.cpp
===================================================================
--- llvm/lib/Object/ELFObjectFile.cpp
+++ llvm/lib/Object/ELFObjectFile.cpp
@@ -26,6 +26,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/RISCVAttributeParser.h"
#include "llvm/Support/RISCVAttributes.h"
+#include "llvm/Support/RISCVISAInfo.h"
#include <algorithm>
#include <cstddef>
#include <cstdint>
@@ -309,35 +310,27 @@
// The Arch pattern is [rv32|rv64][i|e]version(_[m|a|f|d|c]version)*
// Version string pattern is (major)p(minor). Major and minor are optional.
// For example, a version number could be 2p0, 2, or p92.
- StringRef Arch = Attr.getValue();
- if (Arch.consume_front("rv32"))
+ auto ParseResult =
+ llvm::RISCVISAInfo::parseArchString(Attr.getValue(), true, true, true);
+ if (!ParseResult)
+ return Features;
+
+ auto &ISAInfo = *ParseResult;
+
+ if (ISAInfo->getXLen() == 32)
Features.AddFeature("64bit", false);
- else if (Arch.consume_front("rv64"))
+ else if (ISAInfo->getXLen() == 64)
Features.AddFeature("64bit");
- while (!Arch.empty()) {
- switch (Arch[0]) {
- default:
- break; // Ignore unexpected features.
- case 'i':
- Features.AddFeature("e", false);
- break;
- case 'd':
- Features.AddFeature("f"); // D-ext will imply F-ext.
- LLVM_FALLTHROUGH;
- case 'e':
- case 'm':
- case 'a':
- case 'f':
- case 'c':
- Features.AddFeature(Arch.take_front());
- break;
- }
-
- // FIXME: Handle version numbers.
- Arch = Arch.drop_until([](char c) { return c == '_' || c == '\0'; });
- Arch = Arch.drop_while([](char c) { return c == '_'; });
+ if (PlatformFlags & ELF::EF_RISCV_RVC) {
+ Features.AddFeature("c", false);
}
+
+ std::vector<std::string> ToFeatures;
+ ISAInfo->toFeatures(ToFeatures);
+
+ for (const auto &Feature : ToFeatures)
+ Features.AddFeature(Feature);
}
return Features;
Index: llvm/include/llvm/Support/RISCVISAInfo.h
===================================================================
--- llvm/include/llvm/Support/RISCVISAInfo.h
+++ llvm/include/llvm/Support/RISCVISAInfo.h
@@ -19,10 +19,34 @@
#include <vector>
namespace llvm {
+
+/// Represents the major and version number components of a RISC-V extension
+struct RISCVExtensionVersion {
+ unsigned Major;
+ unsigned Minor;
+
+ RISCVExtensionVersion() : Major(0), Minor(0) {}
+ RISCVExtensionVersion(unsigned Maj, unsigned Min) : Major(Maj), Minor(Min) {}
+
+ bool operator==(const RISCVExtensionVersion &Version) const {
+ return Major == Version.Major && Minor == Version.Minor;
+ }
+
+ bool operator!=(const RISCVExtensionVersion &Version) const {
+ return !(*this == Version);
+ }
+
+ bool operator<(const RISCVExtensionVersion &Version) const {
+ return (Major < Version.Major) ||
+ (Major == Version.Major && Minor < Version.Minor);
+ }
+
+ operator bool() const { return Major != 0 || Minor != 0; }
+};
+
struct RISCVExtensionInfo {
std::string ExtName;
- unsigned MajorVersion;
- unsigned MinorVersion;
+ RISCVExtensionVersion Version;
};
class RISCVISAInfo {
@@ -47,15 +71,15 @@
/// Parse RISCV ISA info from arch string.
static llvm::Expected<std::unique_ptr<RISCVISAInfo>>
parseArchString(StringRef Arch, bool EnableExperimentalExtension,
- bool ExperimentalExtensionVersionCheck = true);
+ bool ExperimentalExtensionVersionCheck = true,
+ bool IgnoreUnknownExtension = false);
/// Parse RISCV ISA info from feature vector.
static llvm::Expected<std::unique_ptr<RISCVISAInfo>>
parseFeatures(unsigned XLen, const std::vector<std::string> &Features);
/// Convert RISCV ISA info to a feature vector.
- void toFeatures(std::vector<StringRef> &Features,
- std::function<StringRef(const Twine &)> StrAlloc) const;
+ void toFeatures(std::vector<std::string> &Features) const;
const OrderedExtensionMap &getExtensions() const { return Exts; };
@@ -63,9 +87,11 @@
unsigned getFLen() const { return FLen; };
bool hasExtension(StringRef Ext) const;
+ bool hasExtensionWithVersion(StringRef Ext) const;
std::string toString() const;
- static bool isSupportedExtensionFeature(StringRef Ext);
+ static Optional<RISCVExtensionInfo>
+ isSupportedExtensionFeature(StringRef Ext);
static bool isSupportedExtension(StringRef Ext);
static bool isSupportedExtension(StringRef Ext, unsigned MajorVersion,
unsigned MinorVersion);
Index: clang/test/Driver/riscv-arch-version.c
===================================================================
--- /dev/null
+++ clang/test/Driver/riscv-arch-version.c
@@ -0,0 +1,181 @@
+// RUN: %clang -target riscv32-unknown-elf -march=rv32e1p9 -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-E1P9 %s
+// RV32-E1P9: "-target-feature" "+e"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32im2p0 -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-M2P0 %s
+// RV32-M2P0: "-target-feature" "+m"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32ia2p0 -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-A2P0 %s
+// RV32-A2P0: "-target-feature" "+a"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32if2p0 -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-F2P0 %s
+// RV32-F2P0: "-target-feature" "+f"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32ifd2p0 -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-D2P0 %s
+// RV32-D2P0: "-target-feature" "+f" "-target-feature" "+d"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32ic2p0 -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-C2P0 %s
+// RV32-C2P0: "-target-feature" "+c"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32iv0p10 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-V0P10 %s
+// RV32-EXPERIMENTAL-V0P10: "-target-feature" "+experimental-v"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izba1p0 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBA1P0 %s
+// RV32-EXPERIMENTAL-ZBA1P0: "-target-feature" "+experimental-zba"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbb1p0 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBB1P0 %s
+// RV32-EXPERIMENTAL-ZBB1P0: "-target-feature" "+experimental-zbb"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbc1p0 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBC1P0 %s
+// RV32-EXPERIMENTAL-ZBC1P0: "-target-feature" "+experimental-zbc"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbe0p93 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBE0P93 %s
+// RV32-EXPERIMENTAL-ZBE0P93: "-target-feature" "+experimental-zbe"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbf0p93 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBF0P93 %s
+// RV32-EXPERIMENTAL-ZBF0P93: "-target-feature" "+experimental-zbf"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbm0p93 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBM0P93 %s
+// RV32-EXPERIMENTAL-ZBM0P93: "-target-feature" "+experimental-zbm"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbp0p93 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBP0P93 %s
+// RV32-EXPERIMENTAL-ZBP0P93: "-target-feature" "+experimental-zbp"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbr0p93 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBR0P93 %s
+// RV32-EXPERIMENTAL-ZBR0P93: "-target-feature" "+experimental-zbr"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbs1p0 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBS1P0 %s
+// RV32-EXPERIMENTAL-ZBS1P0: "-target-feature" "+experimental-zbs"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbt0p93 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBT0P93 %s
+// RV32-EXPERIMENTAL-ZBT0P93: "-target-feature" "+experimental-zbt"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izvlsseg0p10 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZVLSSEG0P10 %s
+// RV32-EXPERIMENTAL-ZVLSSEG0P10: "-target-feature" "+experimental-zvlsseg"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izfhmin0p1 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZFHMIN0P1 %s
+// RV32-EXPERIMENTAL-ZFHMIN0P1: "-target-feature" "+experimental-zfhmin"
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izfh0p1 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZFH0P1 %s
+// RV32-EXPERIMENTAL-ZFH0P1: "-target-feature" "+experimental-zfh"
+
+// Error Check Blow.
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32e2p0 -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-E2P0 %s
+// RV32-E2P0: error: invalid arch name 'rv32e2p0'
+// RV32-E2P0: unsupported version number 2.0 for extension 'e'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32im2p1 -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-M2P1 %s
+// RV32-M2P1: error: invalid arch name 'rv32im2p1'
+// RV32-M2P1: unsupported version number 2.1 for extension 'm'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32ia2p1 -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-A2P1 %s
+// RV32-A2P1: error: invalid arch name 'rv32ia2p1'
+// RV32-A2P1: unsupported version number 2.1 for extension 'a'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32if2p1 -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-F2P1 %s
+// RV32-F2P1: error: invalid arch name 'rv32if2p1'
+// RV32-F2P1: unsupported version number 2.1 for extension 'f'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32id2p1 -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-D2P1 %s
+// RV32-D2P1: error: invalid arch name 'rv32id2p1'
+// RV32-D2P1: unsupported version number 2.1 for extension 'd'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32ic2p1 -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-C2P1 %s
+// RV32-C2P1: error: invalid arch name 'rv32ic2p1'
+// RV32-C2P1: unsupported version number 2.1 for extension 'c'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32iv0p7 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-V0P7 %s
+// RV32-EXPERIMENTAL-V0P7: error: invalid arch name 'rv32iv0p7'
+// RV32-EXPERIMENTAL-V0P7: unsupported version number 0.7 for experimental extension 'v'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izba0p7 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBA0P7 %s
+// RV32-EXPERIMENTAL-ZBA0P7: error: invalid arch name 'rv32izba0p7'
+// RV32-EXPERIMENTAL-ZBA0P7: unsupported version number 0.7 for experimental extension 'zba'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbb0p7 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBB0P7 %s
+// RV32-EXPERIMENTAL-ZBB0P7: error: invalid arch name 'rv32izbb0p7'
+// RV32-EXPERIMENTAL-ZBB0P7: unsupported version number 0.7 for experimental extension 'zbb'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbc0p7 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBC0P7 %s
+// RV32-EXPERIMENTAL-ZBC0P7: error: invalid arch name 'rv32izbc0p7'
+// RV32-EXPERIMENTAL-ZBC0P7: unsupported version number 0.7 for experimental extension 'zbc'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbe0p7 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBE0P7 %s
+// RV32-EXPERIMENTAL-ZBE0P7: error: invalid arch name 'rv32izbe0p7'
+// RV32-EXPERIMENTAL-ZBE0P7: unsupported version number 0.7 for experimental extension 'zbe'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbf0p7 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBF0P7 %s
+// RV32-EXPERIMENTAL-ZBF0P7: error: invalid arch name 'rv32izbf0p7'
+// RV32-EXPERIMENTAL-ZBF0P7: unsupported version number 0.7 for experimental extension 'zbf'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbm0p7 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBM0P7 %s
+// RV32-EXPERIMENTAL-ZBM0P7: error: invalid arch name 'rv32izbm0p7'
+// RV32-EXPERIMENTAL-ZBM0P7: unsupported version number 0.7 for experimental extension 'zbm'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbp0p7 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBP0P7 %s
+// RV32-EXPERIMENTAL-ZBP0P7: error: invalid arch name 'rv32izbp0p7'
+// RV32-EXPERIMENTAL-ZBP0P7: unsupported version number 0.7 for experimental extension 'zbp'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbr0p7 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBR0P7 %s
+// RV32-EXPERIMENTAL-ZBR0P7: error: invalid arch name 'rv32izbr0p7'
+// RV32-EXPERIMENTAL-ZBR0P7: unsupported version number 0.7 for experimental extension 'zbr'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbs0p7 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBS0P7 %s
+// RV32-EXPERIMENTAL-ZBS0P7: error: invalid arch name 'rv32izbs0p7'
+// RV32-EXPERIMENTAL-ZBS0P7: unsupported version number 0.7 for experimental extension 'zbs'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izbt0p7 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBT0P7 %s
+// RV32-EXPERIMENTAL-ZBT0P7: error: invalid arch name 'rv32izbt0p7'
+// RV32-EXPERIMENTAL-ZBT0P7: unsupported version number 0.7 for experimental extension 'zbt'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izvlsseg0p1 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZVLSSEG0P1 %s
+// RV32-EXPERIMENTAL-ZVLSSEG0P1: error: invalid arch name 'rv32izvlsseg0p1'
+// RV32-EXPERIMENTAL-ZVLSSEG0P1: unsupported version number 0.1 for experimental extension 'zvlsseg'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izfhmin0p7 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZFHMIN0P7 %s
+// RV32-EXPERIMENTAL-ZFHMIN0P7: error: invalid arch name 'rv32izfhmin0p7'
+// RV32-EXPERIMENTAL-ZFHMIN0P7: unsupported version number 0.7 for experimental extension 'zfhmin'
+
+// RUN: %clang -target riscv32-unknown-elf -march=rv32izfh0p7 -menable-experimental-extensions -### %s -c 2>&1 | \
+// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZFH0P7 %s
+// RV32-EXPERIMENTAL-ZFH0P7: error: invalid arch name 'rv32izfh0p7'
+// RV32-EXPERIMENTAL-ZFH0P7: unsupported version number 0.7 for experimental extension 'zfh'
Index: clang/lib/Driver/ToolChains/Arch/RISCV.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Arch/RISCV.cpp
+++ clang/lib/Driver/ToolChains/Arch/RISCV.cpp
@@ -41,8 +41,12 @@
return false;
}
- (*ISAInfo)->toFeatures(
- Features, [&Args](const Twine &Str) { return Args.MakeArgString(Str); });
+ std::vector<std::string> ToFeatures;
+ (*ISAInfo)->toFeatures(ToFeatures);
+
+ for (const auto &Feature : ToFeatures)
+ Features.push_back(Args.MakeArgString("+" + Feature));
+
return true;
}
Index: clang/lib/Basic/Targets/RISCV.cpp
===================================================================
--- clang/lib/Basic/Targets/RISCV.cpp
+++ clang/lib/Basic/Targets/RISCV.cpp
@@ -150,7 +150,7 @@
auto ExtName = Extension.first;
auto ExtInfo = Extension.second;
unsigned Version =
- (ExtInfo.MajorVersion * 1000000) + (ExtInfo.MinorVersion * 1000);
+ (ExtInfo.Version.Major * 1000000) + (ExtInfo.Version.Minor * 1000);
Builder.defineMacro(Twine("__riscv_", ExtName), Twine(Version));
}
@@ -223,10 +223,7 @@
if (Result.hasValue())
return Result.getValue();
- if (ISAInfo->isSupportedExtensionFeature(Feature))
- return ISAInfo->hasExtension(Feature);
-
- return false;
+ return ISAInfo->hasExtensionWithVersion(Feature);
}
/// Perform initialization based on the user configured set of features.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits