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 @@ -1787,9 +1787,24 @@ if (getParser().parseIdentifier(Identifier)) return MatchOperand_ParseFail; - auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier); - if (!SysReg) - SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier); + auto SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier); + + // Accept a Alternate named Sys Reg if the alternate required features are present. + if (SysReg) { + if (!SysReg->haveAltRequiredFeatures(getSTI().getFeatureBits())) { + Error(S, "system register use requires an option to be enabled"); + return MatchOperand_ParseFail; + } + Operands.push_back( + RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding)); + return MatchOperand_Success; + } + + SysReg = RISCVSysReg::lookupSysRegByName(Identifier); + if(SysReg && SysReg->AltName && SysReg->haveAltRequiredFeatures(getSTI().getFeatureBits())){ + Warning(S, "'" + Identifier + "' CSR is not available on the current subtarget. Instead '" + + SysReg->AltName + "' CSR will be used."); + } if (!SysReg) if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier))) Warning(S, "'" + Identifier + "' is a deprecated alias for '" + diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -381,6 +381,16 @@ return true; return (FeaturesRequired & ActiveFeatures) == FeaturesRequired; } + + bool haveAltRequiredFeatures(const FeatureBitset &ActiveFeatures) const { + // Not in 32-bit mode. + if (isRV32Only && ActiveFeatures[RISCV::Feature64Bit]) + return false; + // No Alternate required feature associated with the system register. + if (AltFeaturesRequired.none()) + return false; + return (AltFeaturesRequired & ActiveFeatures) == AltFeaturesRequired; + } }; #define GET_SysRegsList_DECL diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp @@ -121,10 +121,17 @@ raw_ostream &O) { unsigned Imm = MI->getOperand(OpNo).getImm(); auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm); - if (SysReg && SysReg->haveRequiredFeatures(STI.getFeatureBits())) - O << SysReg->Name; - else - O << Imm; + if (SysReg) { + if (SysReg->AltName && + SysReg->haveAltRequiredFeatures(STI.getFeatureBits())) + O << SysReg->AltName; + else if (SysReg->haveRequiredFeatures(STI.getFeatureBits())) + O << SysReg->Name; + else + O << Imm; + return; + } + O << Imm; } void RISCVInstPrinter::printFenceArg(const MCInst *MI, unsigned OpNo, diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -767,6 +767,13 @@ AssemblerPredicate<(all_of FeatureVendorXCVmac), "'XCVmac' (Multiply-Accumulate)">; +def FeatureVendorXSfcie + : SubtargetFeature<"xsfcie", "HasVendorXSfcie", "true", + "'XSfcie' (SiFive Custom Instruction Extension SFCIE for S76.)">; +def HasVendorXSfcie : Predicate<"Subtarget->hasVendorXSfcie()">, + AssemblerPredicate<(all_of FeatureVendorXSfcie), + "'XSfcie' (SiFive Custom Instruction Extension SFCIE for S76.)">; + //===----------------------------------------------------------------------===// // LLVM specific features and extensions //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVProcessors.td b/llvm/lib/Target/RISCV/RISCVProcessors.td --- a/llvm/lib/Target/RISCV/RISCVProcessors.td +++ b/llvm/lib/Target/RISCV/RISCVProcessors.td @@ -142,7 +142,8 @@ FeatureStdExtA, FeatureStdExtF, FeatureStdExtD, - FeatureStdExtC], + FeatureStdExtC, + FeatureVendorXSfcie], [TuneSiFive7]>; def SIFIVE_U54 : RISCVProcessorModel<"sifive-u54", diff --git a/llvm/lib/Target/RISCV/RISCVSystemOperands.td b/llvm/lib/Target/RISCV/RISCVSystemOperands.td --- a/llvm/lib/Target/RISCV/RISCVSystemOperands.td +++ b/llvm/lib/Target/RISCV/RISCVSystemOperands.td @@ -19,8 +19,8 @@ class SysReg op> { string Name = name; - // A maximum of one alias is supported right now. - string AltName = name; + // AltName to be used by Vendors for Custom Vendor Extension. + string AltName = ""; // A maximum of one deprecated name is supported right now. Unlike the // `AltName` alias, a `DeprecatedName` generates a diagnostic when the name is // used to encourage software to migrate away from the name. @@ -36,6 +36,7 @@ // Register number without the privilege bits. // bits<6> Number = op{5 - 0}; code FeaturesRequired = [{ {} }]; + code AltFeaturesRequired = [{ {} }]; bit isRV32Only = 0; } @@ -44,7 +45,7 @@ // FIXME: add "ReadWrite", "Mode", "Extra", "Number" fields when needed. let Fields = [ "Name", "AltName", "DeprecatedName", "Encoding", "FeaturesRequired", - "isRV32Only", + "AltFeaturesRequired", "isRV32Only", ]; let PrimaryKey = [ "Encoding" ]; @@ -292,7 +293,7 @@ //===----------------------------------------------------------------------===// // Machine Counter Setup //===----------------------------------------------------------------------===// -let AltName = "mucounteren" in // Privileged spec v1.9.1 Name +let DeprecatedName = "mucounteren" in // Privileged spec v1.9.1 Name def : SysReg<"mcountinhibit", 0x320>; // mhpmevent3-mhpmevent31 at 0x323-0x33F. @@ -305,6 +306,18 @@ def : SysReg<"mhpmevent"#i#"h", !add(0x723, !sub(i, 3))>; } +//===----------------------------------------------------------------------===// +// Sifive S76 Custom Machine Mode Registers +//===----------------------------------------------------------------------===// + +let FeaturesRequired = [{ {RISCV::FeatureVendorXSfcie} }] in { +def : SysReg<"mncause", 0x352>; +def : SysReg<"mnstatus", 0x353>; +def : SysReg<"mbpm", 0x7C0>; +def : SysReg<"mfd", 0x7C1>; +def : SysReg<"mpd", 0x7C8>; +} + //===----------------------------------------------------------------------===// // Debug/ Trace Registers (shared with Debug Mode) //===----------------------------------------------------------------------===// @@ -322,7 +335,7 @@ // "dscratch" is an alternative name for "dscratch0" which appeared in earlier // drafts of the RISC-V debug spec -let AltName = "dscratch" in +let DeprecatedName = "dscratch" in def : SysReg<"dscratch0", 0x7B2>; def : SysReg<"dscratch1", 0x7B3>; @@ -365,8 +378,14 @@ //===----------------------------------------------- // Machine-level CSRs -def : SysReg<"miselect", 0x350>; -def : SysReg<"mireg", 0x351>; +def : SysReg<"miselect", 0x350> { + let AltName = "mnscratch"; + let AltFeaturesRequired = [{ {RISCV::FeatureVendorXSfcie} }]; +} +def : SysReg<"mireg", 0x351> { + let AltName = "mnepc"; + let AltFeaturesRequired = [{ {RISCV::FeatureVendorXSfcie} }]; +} def : SysReg<"mtopei", 0x35C>; def : SysReg<"mtopi", 0xFB0>; def : SysReg<"mvien", 0x308>; diff --git a/llvm/test/MC/RISCV/xsfcie-invalid.s b/llvm/test/MC/RISCV/xsfcie-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/xsfcie-invalid.s @@ -0,0 +1,20 @@ +# SFCIE - SiFive S76 Custom Instructions and CSRs. +# RUN: not llvm-mc -triple riscv64 -mattr=-xsfcie < %s 2>&1 | FileCheck %s + +csrr t1, mbpm # CHECK: :[[@LINE]]:10: error: system register use requires an option to be enabled + +csrr t1, mfd # CHECK: :[[@LINE]]:10: error: system register use requires an option to be enabled + +csrr t1, mpd # CHECK: :[[@LINE]]:10: error: system register use requires an option to be enabled + +csrr t1, mnscratch # CHECK-NEED-CLIC: :[[@LINE]]:10: error: system register use requires an option to be enabled + +csrr t1, mnepc # CHECK-NEED-CLIC: :[[@LINE]]:10: error: system register use requires an option to be enabled + +csrr t1, mncause # CHECK-NEED-CLIC: :[[@LINE]]:10: error: system register use requires an option to be enabled + +csrr t1, mnstatus # CHECK-NEED-CLIC: :[[@LINE]]:10: error: system register use requires an option to be enabled + +csrr t1, miselect # CHECK-ERROR: :[[@LINE]]:11: warning: 'miselect' CSR is not available on the current subtarget. Instead 'mnscratch' CSR will be used. + +csrr t1, mireg # CHECK-ERROR: :[[@LINE]]:11: warning: 'mireg' CSR is not available on the current subtarget. Instead 'mnepc' CSR will be used. diff --git a/llvm/test/MC/RISCV/xsfcie-valid.s b/llvm/test/MC/RISCV/xsfcie-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/xsfcie-valid.s @@ -0,0 +1,97 @@ +# SFCIE - SiFive S76 Custom Instructions and CSRs. +# RUN: llvm-mc %s -triple=riscv64 -mcpu=sifive-s76 -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+xsfcie -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ENC,CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mcpu=sifive-s76 < %s \ +# RUN: | llvm-objdump --mcpu=sifive-s76 -M no-aliases -d - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+xsfcie < %s \ +# RUN: | llvm-objdump --mattr=+xsfcie -M no-aliases -d - \ +# RUN: | FileCheck -check-prefix=CHECK-INST %s + +# mbpm +# name +# CHECK-INST: csrrs t2, mbpm, zero +# CHECK-ENC: encoding: [0xf3,0x23,0x00,0x7c] +# uimm12 +# CHECK-INST: csrrs t2, mbpm, zero +# CHECK-ENC: encoding: [0xf3,0x23,0x00,0x7c] +# name +csrrs t2, mbpm, zero +# uimm12 +csrrs t2, 0x7C0, zero + +# mfd +# name +# CHECK-INST: csrrs t2, mfd, zero +# CHECK-ENC: encoding: [0xf3,0x23,0x10,0x7c] +# uimm12 +# CHECK-INST: csrrs t2, mfd, zero +# CHECK-ENC: encoding: [0xf3,0x23,0x10,0x7c] +# name +csrrs t2, mfd, zero +# uimm12 +csrrs t2, 0x7C1, zero + +# mpd +# name +# CHECK-INST: csrrs t2, mpd, zero +# CHECK-ENC: encoding: [0xf3,0x23,0x80,0x7c] +# uimm12 +# CHECK-INST: csrrs t2, mpd, zero +# CHECK-ENC: encoding: [0xf3,0x23,0x80,0x7c] +# name +csrrs t2, mpd, zero +# uimm12 +csrrs t2, 0x7C8, zero + +# mnscratch +# name +# CHECK-INST: csrrs t1, mnscratch, zero +# CHECK-ENC: encoding: [0x73,0x23,0x00,0x35] +# uimm12 +# CHECK-INST: csrrs t2, mnscratch, zero +# CHECK-ENC: encoding: [0xf3,0x23,0x00,0x35] +# name +csrrs t1, mnscratch, zero +csrrs t1, miselect, zero +# uimm12 +csrrs t2, 0x350, zero + +# mnepc +# name +# CHECK-INST: csrrs t1, mnepc, zero +# CHECK-ENC: encoding: [0x73,0x23,0x10,0x35] +# uimm12 +# CHECK-INST: csrrs t2, mnepc, zero +# CHECK-ENC: encoding: [0xf3,0x23,0x10,0x35] +# name +csrrs t1, mnepc, zero +csrrs t1, mireg, zero +# uimm12 +csrrs t2, 0x351, zero + +# mncause +# name +# CHECK-INST: csrrs t1, mncause, zero +# CHECK-ENC: encoding: [0x73,0x23,0x20,0x35] +# uimm12 +# CHECK-INST: csrrs t2, mncause, zero +# CHECK-ENC: encoding: [0xf3,0x23,0x20,0x35] +# name +csrrs t1, mncause, zero +# uimm12 +csrrs t2, 0x352, zero + +# mnstatus +# name +# CHECK-INST: csrrs t1, mnstatus, zero +# CHECK-ENC: encoding: [0x73,0x23,0x30,0x35] +# uimm12 +# CHECK-INST: csrrs t2, mnstatus, zero +# CHECK-ENC: encoding: [0xf3,0x23,0x30,0x35] +# name +csrrs t1, mnstatus, zero +# uimm12 +csrrs t2, 0x353, zero