diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -233,7 +233,7 @@ bool RISCVTargetInfo::handleTargetFeatures(std::vector &Features, DiagnosticsEngine &Diags) { unsigned XLen = getTriple().isArch64Bit() ? 64 : 32; - auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, Features); + auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, false, Features); if (!ParseResult) { std::string Buffer; llvm::raw_string_ostream OutputErrMsg(Buffer); diff --git a/clang/test/Driver/riscv-arch.c b/clang/test/Driver/riscv-arch.c --- a/clang/test/Driver/riscv-arch.c +++ b/clang/test/Driver/riscv-arch.c @@ -307,10 +307,10 @@ // RV32-IMINOR-MISS: error: invalid arch name 'rv32i2p', // RV32-IMINOR-MISS: minor version number missing after 'p' for extension 'i' -// RUN: %clang -target riscv32-unknown-elf -march=rv32i2p1 -### %s \ +// RUN: %clang -target riscv32-unknown-elf -march=rv32i2p2 -### %s \ // RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-IMINOR1 %s -// RV32-IMINOR1: error: invalid arch name 'rv32i2p1', unsupported -// RV32-IMINOR1: version number 2.1 for extension 'i' +// RV32-IMINOR1: error: invalid arch name 'rv32i2p2', unsupported +// RV32-IMINOR1: version number 2.2 for extension 'i' // RUN: %clang -target riscv32-unknown-elf -march=rv32ixt2p -### %s \ // RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-XMINOR-MISS %s diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c --- a/clang/test/Driver/riscv-cpus.c +++ b/clang/test/Driver/riscv-cpus.c @@ -129,7 +129,8 @@ // march overwrite mcpu's default march // RUN: %clang -target riscv32 -### -c %s 2>&1 -mcpu=sifive-e31 -march=rv32imc | FileCheck -check-prefix=MCPU-MARCH %s -// MCPU-MARCH: "-nostdsysteminc" "-target-cpu" "sifive-e31" "-target-feature" "+m" "-target-feature" "+c" +// MCPU-MARCH: "-nostdsysteminc" "-target-cpu" "sifive-e31" +// MCPU-MARCH: "-target-feature" "+m" "-target-feature" "+c" // MCPU-MARCH: "-target-abi" "ilp32" // Check interaction between mcpu and mtune, mtune won't affect arch related diff --git a/llvm/include/llvm/Support/RISCVISAInfo.h b/llvm/include/llvm/Support/RISCVISAInfo.h --- a/llvm/include/llvm/Support/RISCVISAInfo.h +++ b/llvm/include/llvm/Support/RISCVISAInfo.h @@ -51,7 +51,8 @@ /// Parse RISCV ISA info from feature vector. static llvm::Expected> - parseFeatures(unsigned XLen, const std::vector &Features); + parseFeatures(unsigned XLen, bool IsI2p1, + const std::vector &Features); /// Convert RISCV ISA info to a feature vector. void toFeatures(std::vector &Features, @@ -61,6 +62,7 @@ unsigned getXLen() const { return XLen; }; unsigned getFLen() const { return FLen; }; + bool getIsI2p1() const { return IsI2p1; }; bool hasExtension(StringRef Ext) const; std::string toString() const; @@ -75,6 +77,7 @@ unsigned XLen; unsigned FLen; + bool IsI2p1; OrderedExtensionMap Exts; diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -30,42 +30,45 @@ struct RISCVSupportedExtension { const char *Name; - /// Supported version. - RISCVExtensionVersion Version; + /// Supported versions. + std::array Versions; }; } // end anonymous namespace static constexpr StringLiteral AllStdExts = "mafdqlcbjtpvn"; -static const RISCVSupportedExtension SupportedExtensions[] = { - {"i", RISCVExtensionVersion{2, 0}}, - {"e", RISCVExtensionVersion{1, 9}}, - {"m", RISCVExtensionVersion{2, 0}}, - {"a", RISCVExtensionVersion{2, 0}}, - {"f", RISCVExtensionVersion{2, 0}}, - {"d", RISCVExtensionVersion{2, 0}}, - {"c", RISCVExtensionVersion{2, 0}}, +const RISCVSupportedExtension SupportedExtensions[] = { + {"i", {RISCVExtensionVersion{2, 0}, RISCVExtensionVersion{2, 1}}}, + {"e", {RISCVExtensionVersion{1, 9}}}, + {"m", {RISCVExtensionVersion{2, 0}}}, + {"a", {RISCVExtensionVersion{2, 0}}}, + {"f", {RISCVExtensionVersion{2, 0}}}, + {"d", {RISCVExtensionVersion{2, 0}}}, + {"c", {RISCVExtensionVersion{2, 0}}}, + + {"zicsr", {RISCVExtensionVersion{2, 0}}}, + {"zifencei", {RISCVExtensionVersion{2, 0}}}, }; -static const RISCVSupportedExtension SupportedExperimentalExtensions[] = { - {"v", RISCVExtensionVersion{0, 10}}, - {"zba", RISCVExtensionVersion{1, 0}}, - {"zbb", RISCVExtensionVersion{1, 0}}, - {"zbc", RISCVExtensionVersion{1, 0}}, - {"zbe", RISCVExtensionVersion{0, 93}}, - {"zbf", RISCVExtensionVersion{0, 93}}, - {"zbm", RISCVExtensionVersion{0, 93}}, - {"zbp", RISCVExtensionVersion{0, 93}}, - {"zbr", RISCVExtensionVersion{0, 93}}, - {"zbs", RISCVExtensionVersion{1, 0}}, - {"zbt", RISCVExtensionVersion{0, 93}}, - - {"zvamo", RISCVExtensionVersion{0, 10}}, - {"zvlsseg", RISCVExtensionVersion{0, 10}}, - - {"zfhmin", RISCVExtensionVersion{0, 1}}, - {"zfh", RISCVExtensionVersion{0, 1}}, +const RISCVSupportedExtension SupportedExperimentalExtensions[] = { + {"v", {RISCVExtensionVersion{0, 10}}}, + {"zba", {RISCVExtensionVersion{1, 0}}}, + {"zbb", {RISCVExtensionVersion{1, 0}}}, + {"zbc", {RISCVExtensionVersion{1, 0}}}, + {"zbe", {RISCVExtensionVersion{0, 93}}}, + {"zbf", {RISCVExtensionVersion{0, 93}}}, + {"zbm", {RISCVExtensionVersion{0, 93}}}, + {"zbp", {RISCVExtensionVersion{0, 93}}}, + {"zbr", {RISCVExtensionVersion{0, 93}}}, + {"zbs", {RISCVExtensionVersion{1, 0}}}, + {"zbt", {RISCVExtensionVersion{0, 93}}}, + + {"zvamo", {RISCVExtensionVersion{0, 10}}}, + {"zvlsseg", {RISCVExtensionVersion{0, 10}}}, + + {"zfhmin", {RISCVExtensionVersion{0, 1}}}, + {"zfh", {RISCVExtensionVersion{0, 1}}}, }; static bool stripExperimentalPrefix(StringRef &Ext) { @@ -112,7 +115,7 @@ if (ExtensionInfoIterator == ExtInfo.end()) { continue; } - return ExtensionInfoIterator->Version; + return ExtensionInfoIterator->Versions.front(); } return None; } @@ -156,7 +159,7 @@ if (ExtIterator == std::end(SupportedExperimentalExtensions)) return None; - return ExtIterator->Version; + return ExtIterator->Versions.front(); } bool RISCVISAInfo::isSupportedExtensionFeature(StringRef Ext) { @@ -176,8 +179,11 @@ bool RISCVISAInfo::isSupportedExtension(StringRef Ext, unsigned MajorVersion, unsigned MinorVersion) { auto FindByNameAndVersion = [=](const RISCVSupportedExtension &ExtInfo) { - return ExtInfo.Name == Ext && (MajorVersion == ExtInfo.Version.Major) && - (MinorVersion == ExtInfo.Version.Minor); + for (const auto &Version : ExtInfo.Versions) + if (ExtInfo.Name == Ext && (MajorVersion == Version.Major) && + (MinorVersion == Version.Minor)) + return true; + return false; }; return llvm::any_of(SupportedExtensions, FindByNameAndVersion) || llvm::any_of(SupportedExperimentalExtensions, FindByNameAndVersion); @@ -279,9 +285,16 @@ std::function StrAlloc) const { for (auto &Ext : Exts) { StringRef ExtName = Ext.first; + unsigned Major = Ext.second.MajorVersion; + unsigned Minor = Ext.second.MinorVersion; - if (ExtName == "i") + if (ExtName == "i") { + if (Major == 2 && Minor == 0) { + Features.push_back("+zicsr"); + Features.push_back("+zifencei"); + } continue; + } if (ExtName == "zvlsseg") { Features.push_back("+experimental-v"); @@ -407,7 +420,7 @@ } llvm::Expected> -RISCVISAInfo::parseFeatures(unsigned XLen, +RISCVISAInfo::parseFeatures(unsigned XLen, bool IsI2p1, const std::vector &Features) { assert(XLen == 32 || XLen == 64); std::unique_ptr ISAInfo(new RISCVISAInfo(XLen)); @@ -431,12 +444,16 @@ continue; if (Add) - ISAInfo->addExtension(ExtName, ExtensionInfoIterator->Version.Major, - ExtensionInfoIterator->Version.Minor); + ISAInfo->addExtension(ExtName, + ExtensionInfoIterator->Versions.front().Major, + ExtensionInfoIterator->Versions.front().Minor); else ISAInfo->Exts.erase(ExtName.str()); } + if (IsI2p1) + ISAInfo->addExtension("i", 2, 1); + ISAInfo->updateImplication(); ISAInfo->updateFLen(); @@ -520,9 +537,12 @@ ISAInfo->addExtension(Ext, Version->Major, Version->Minor); else llvm_unreachable("Default extension version not found?"); - } else + } else { // Baseline is `i` or `e` ISAInfo->addExtension(std::string(1, Baseline), Major, Minor); + if (Baseline == 'i' && Major == 2 && Minor == 1) + ISAInfo->IsI2p1 = true; + } // Consume the base ISA version number and any '_' between rvxxx and the // first extension diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -2157,6 +2157,9 @@ if (ISAInfo->hasExtension(Feature.Key)) setFeatureBits(Feature.Value, Feature.Key); + if (ISAInfo->getIsI2p1()) + setFeatureBits(RISCV::FeatureI2p1, "i2p1"); + if (ISAInfo->getXLen() == 32) clearFeatureBits(RISCV::Feature64Bit, "64bit"); else if (ISAInfo->getXLen() == 64) diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp @@ -49,7 +49,9 @@ std::vector FeatureVector; RISCVFeatures::toFeatureVector(FeatureVector, STI.getFeatureBits()); - auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeatureVector); + bool IsI2p1 = STI.hasFeature(RISCV::FeatureI2p1); + auto ParseResult = + llvm::RISCVISAInfo::parseFeatures(XLen, false, FeatureVector); if (!ParseResult) { /* Assume any error about features should handled earlier. */ consumeError(ParseResult.takeError()); diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -176,6 +176,26 @@ AssemblerPredicate<(all_of FeatureStdExtZvamo), "'Zvamo' (Vector AMO Operations)">; +def FeatureI2p1 + : SubtargetFeature<"i2p1", "IsI2p1", "true", "Implements I 2.1">; + +def FeatureStdExtZicsr + : SubtargetFeature<"zicsr", "HasStdExtZicsr", "true", + "'Zicsr' (Control and Status Register)">; +def HasStdExtZicsr : Predicate<"Subtarget->hasStdExtZicsr()">, + AssemblerPredicate<(all_of FeatureStdExtZicsr), + "'Zicsr' (Control and Status Register)">; + +def FeatureStdExtZifencei + : SubtargetFeature<"zifencei", "HasStdExtZifencei", "true", + "'Zifencei' (Instruction-Fetch Fence)">; +def HasStdExtZifencei : Predicate<"Subtarget->hasStdExtZifencei()">, + AssemblerPredicate<(all_of FeatureStdExtZifencei), + "'Zifencei' (Instruction-Fetch Fence)">; + +def HasI2p0OrZicsr : Predicate<"Subtarget->HasI2p0OrZicsr()">; +def HasI2p0OrZifencei : Predicate<"Subtarget->HasI2p0OrZifencei()">; + def Feature64Bit : SubtargetFeature<"64bit", "HasRV64", "true", "Implements RV64">; def IsRV64 : Predicate<"Subtarget->is64Bit()">, diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -572,6 +572,7 @@ let imm12 = {0b1000,0b0011,0b0011}; } +let Predicates = [HasI2p0OrZifencei] in def FENCE_I : RVInstI<0b001, OPC_MISC_MEM, (outs), (ins), "fence.i", "">, Sched<[]> { let rs1 = 0; let rd = 0; @@ -602,6 +603,7 @@ } } // hasSideEffects = 1, mayLoad = 0, mayStore = 0 +let Predicates = [HasI2p0OrZicsr] in { def CSRRW : CSR_ir<0b001, "csrrw">; def CSRRS : CSR_ir<0b010, "csrrs">; def CSRRC : CSR_ir<0b011, "csrrc">; @@ -609,6 +611,7 @@ def CSRRWI : CSR_ii<0b101, "csrrwi">; def CSRRSI : CSR_ii<0b110, "csrrsi">; def CSRRCI : CSR_ii<0b111, "csrrci">; +} // Predicates = [HasI2p0OrZicsr] /// RV64I instructions @@ -794,6 +797,7 @@ def : InstAlias<"rdtimeh $rd", (CSRRS GPR:$rd, TIMEH.Encoding, X0)>; } // Predicates = [IsRV32] +let Predicates = [HasI2p0OrZicsr] in { def : InstAlias<"csrr $rd, $csr", (CSRRS GPR:$rd, csr_sysreg:$csr, X0)>; def : InstAlias<"csrw $csr, $rs", (CSRRW X0, csr_sysreg:$csr, GPR:$rs)>; def : InstAlias<"csrs $csr, $rs", (CSRRS X0, csr_sysreg:$csr, GPR:$rs)>; @@ -812,6 +816,7 @@ def : InstAlias<"csrrs $rd, $csr, $imm", (CSRRSI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>; def : InstAlias<"csrrc $rd, $csr, $imm", (CSRRCI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>; } +} // Predicates = [HasI2p0OrZicsr] def : InstAlias<"sfence.vma", (SFENCE_VMA X0, X0)>; def : InstAlias<"sfence.vma $rs", (SFENCE_VMA GPR:$rs, X0)>; diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h --- a/llvm/lib/Target/RISCV/RISCVSubtarget.h +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -52,6 +52,9 @@ bool HasStdExtV = false; bool HasStdExtZvlsseg = false; bool HasStdExtZvamo = false; + bool IsI2p1 = false; + bool HasStdExtZicsr = false; + bool HasStdExtZifencei = false; bool HasStdExtZfhmin = false; bool HasStdExtZfh = false; bool HasRV64 = false; @@ -119,6 +122,8 @@ bool hasStdExtV() const { return HasStdExtV; } bool hasStdExtZvlsseg() const { return HasStdExtZvlsseg; } bool hasStdExtZvamo() const { return HasStdExtZvamo; } + bool hasStdExtZicsr() const { return HasStdExtZicsr; } + bool hasStdExtZifencei() const { return HasStdExtZifencei; } bool hasStdExtZfhmin() const { return HasStdExtZfhmin; } bool hasStdExtZfh() const { return HasStdExtZfh; } bool is64Bit() const { return HasRV64; } @@ -146,6 +151,13 @@ return hasVInstructions() ? MaxInterleaveFactor : 1; } + bool HasI2p0OrZicsr() { + return (IsI2p1 && HasStdExtZicsr) || (!IsI2p1 && !HasStdExtZicsr); + } + bool HasI2p0OrZifencei() { + return (IsI2p1 && HasStdExtZifencei) || (!IsI2p1 && !HasStdExtZifencei); + } + protected: // GlobalISel related APIs. std::unique_ptr CallLoweringInfo; diff --git a/llvm/test/MC/RISCV/attribute-arch.s b/llvm/test/MC/RISCV/attribute-arch.s --- a/llvm/test/MC/RISCV/attribute-arch.s +++ b/llvm/test/MC/RISCV/attribute-arch.s @@ -12,6 +12,9 @@ .attribute arch, "rv32i2p0" # CHECK: attribute 5, "rv32i2p0" +.attribute arch, "rv32i2p1" +# CHECK: attribute 5, "rv32i2p1" + .attribute arch, "rv32i2_m2" # CHECK: attribute 5, "rv32i2p0_m2p0" diff --git a/llvm/test/MC/RISCV/rv32zicsr-invalid.s b/llvm/test/MC/RISCV/rv32zicsr-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zicsr-invalid.s @@ -0,0 +1,44 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+zicsr < %s 2>&1 | FileCheck %s + +# Out of range immediates +## uimm5 +csrrwi a1, 0x1, -1 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31] +csrrsi t1, 999, 32 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31] +csrrci x0, 43, -90 # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31] + +## uimm12 +csrrw a0, -1, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095] +csrrs a0, 4096, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095] +csrrs a0, -0xf, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095] +csrrc a0, 0x1000, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095] +csrrwi a0, -50, 0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095] +csrrsi a0, 4097, a0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095] +csrrci a0, 0xffff, a0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095] + +# Illegal operand modifier +## uimm5 +csrrwi a1, 0x1, %hi(b) # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31] +csrrsi t1, 999, %pcrel_hi(3) # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31] +csrrci x0, 43, %pcrel_hi(c) # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31] +csrrsi t1, 999, %pcrel_lo(4) # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31] +csrrci x0, 43, %pcrel_lo(d) # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31] + +## uimm12 +csrrw a0, %lo(1), a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095] +csrrs a0, %lo(a), a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095] +csrrs a0, %hi(2), a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095] +csrrc a0, %hi(b), a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095] +csrrwi a0, %pcrel_hi(3), 0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095] +csrrsi a0, %pcrel_hi(c), a0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095] +csrrwi a0, %pcrel_lo(4), 0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095] +csrrsi a0, %pcrel_lo(d), a0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095] + +## named csr in place of uimm12 +csrrw a0, foos, a0 # CHECK: :[[@LINE]]:11: error: operand must be a valid system register name or an integer in the range [0, 4095] +csrrs a0, mstatusx, a0 # CHECK: :[[@LINE]]:11: error: operand must be a valid system register name or an integer in the range [0, 4095] +csrrs a0, xmstatus, a0 # CHECK: :[[@LINE]]:11: error: operand must be a valid system register name or an integer in the range [0, 4095] +csrrc a0, m12status, a0 # CHECK: :[[@LINE]]:11: error: operand must be a valid system register name or an integer in the range [0, 4095] +csrrwi a0, mstatus12, 0 # CHECK: :[[@LINE]]:12: error: operand must be a valid system register name or an integer in the range [0, 4095] +csrrsi a0, mhpm12counter, a0 # CHECK: :[[@LINE]]:12: error: operand must be a valid system register name or an integer in the range [0, 4095] +csrrwi a0, mhpmcounter32, 0 # CHECK: :[[@LINE]]:12: error: operand must be a valid system register name or an integer in the range [0, 4095] +csrrsi a0, A, a0 # CHECK: :[[@LINE]]:12: error: operand must be a valid system register name or an integer in the range [0, 4095] diff --git a/llvm/test/MC/RISCV/rv32zicsr-valid.s b/llvm/test/MC/RISCV/rv32zicsr-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zicsr-valid.s @@ -0,0 +1,32 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+zicsr -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple riscv64 -mattr=+zicsr -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: csrrw t0, 4095, t1 +# CHECK-ASM: encoding: [0xf3,0x12,0xf3,0xff] +csrrw t0, 0xfff, t1 +# CHECK-ASM-AND-OBJ: csrrw s0, 4095, s1 +# CHECK-ASM: encoding: [0x73,0x94,0xf4,0xff] +csrrw s0, ~(-4096), s1 +# CHECK-ASM-AND-OBJ: csrrw s0, fflags, s1 +# CHECK-ASM: encoding: [0x73,0x94,0x14,0x00] +csrrw s0, !0, s1 +# CHECK-ASM-AND-OBJ: csrrs s0, cycle, zero +# CHECK-ASM: encoding: [0x73,0x24,0x00,0xc0] +csrrs s0, 0xc00, x0 +# CHECK-ASM-AND-OBJ: csrrs s3, fflags, s5 +# CHECK-ASM: encoding: [0xf3,0xa9,0x1a,0x00] +csrrs s3, 0x001, s5 +# CHECK-ASM-AND-OBJ: csrrc sp, ustatus, ra +# CHECK-ASM: encoding: [0x73,0xb1,0x00,0x00] +csrrc sp, 0x000, ra +# CHECK-ASM-AND-OBJ: csrrwi a5, ustatus, 0 +# CHECK-ASM: encoding: [0xf3,0x57,0x00,0x00] +csrrwi a5, 0x000, 0 +# CHECK-ASM-AND-OBJ: csrrsi t2, 4095, 31 +# CHECK-ASM: encoding: [0xf3,0xe3,0xff,0xff] +csrrsi t2, 0xfff, 31 +# CHECK-ASM-AND-OBJ: csrrci t1, sscratch, 5 +# CHECK-ASM: encoding: [0x73,0xf3,0x02,0x14] +csrrci t1, 0x140, 5 diff --git a/llvm/test/MC/RISCV/rv32zifencei-valid.s b/llvm/test/MC/RISCV/rv32zifencei-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zifencei-valid.s @@ -0,0 +1,8 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+zifencei -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple riscv64 -mattr=+zifencei -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: fence.i +# CHECK-ASM: encoding: [0x0f,0x10,0x00,0x00] +fence.i