diff options
author | Ana Pazos <apazos@codeaurora.org> | 2018-10-04 21:50:54 +0000 |
---|---|---|
committer | Ana Pazos <apazos@codeaurora.org> | 2018-10-04 21:50:54 +0000 |
commit | 9d6c55323f1ce36c18f9b0f7042d44228c6edda0 (patch) | |
tree | 6f57ad7fc9dca1f429fd083bfcc6d990ae08e4ee /llvm/lib/Target/RISCV | |
parent | ab358bfd0994b6c2b57e37be26869a611dc8fdd5 (diff) | |
download | bcm5719-llvm-9d6c55323f1ce36c18f9b0f7042d44228c6edda0.tar.gz bcm5719-llvm-9d6c55323f1ce36c18f9b0f7042d44228c6edda0.zip |
[RISCV] Support named operands for CSR instructions.
Reviewers: asb, mgrang
Reviewed By: asb
Subscribers: jocewei, mgorny, jfb, PkmX, MartinMosbeck, brucehoult, the_o, rkruppe, rogfer01, rbar, johnrusso, simoncook, jordy.potman.lists, sabuasal, niosHD, kito-cheng, shiva0217, zzheng, edward-jones
Differential Revision: https://reviews.llvm.org/D46759
llvm-svn: 343822
Diffstat (limited to 'llvm/lib/Target/RISCV')
17 files changed, 637 insertions, 88 deletions
diff --git a/llvm/lib/Target/RISCV/AsmParser/LLVMBuild.txt b/llvm/lib/Target/RISCV/AsmParser/LLVMBuild.txt index a9ad92c872e..205d1248f92 100644 --- a/llvm/lib/Target/RISCV/AsmParser/LLVMBuild.txt +++ b/llvm/lib/Target/RISCV/AsmParser/LLVMBuild.txt @@ -19,5 +19,5 @@ type = Library name = RISCVAsmParser parent = RISCV -required_libraries = MC MCParser RISCVDesc RISCVInfo Support +required_libraries = MC MCParser RISCVDesc RISCVInfo RISCVUtils Support add_to_library_groups = RISCV diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 2e80dca4540..b1f1eb40401 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -7,10 +7,10 @@ // //===----------------------------------------------------------------------===// -#include "MCTargetDesc/RISCVBaseInfo.h" #include "MCTargetDesc/RISCVMCExpr.h" #include "MCTargetDesc/RISCVMCTargetDesc.h" #include "MCTargetDesc/RISCVTargetStreamer.h" +#include "Utils/RISCVBaseInfo.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/MC/MCContext.h" @@ -86,6 +86,7 @@ class RISCVAsmParser : public MCTargetAsmParser { #define GET_ASSEMBLER_HEADER #include "RISCVGenAsmMatcher.inc" + OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands); OperandMatchResultTy parseImmediate(OperandVector &Operands); OperandMatchResultTy parseRegister(OperandVector &Operands, bool AllowParens = false); @@ -113,6 +114,7 @@ class RISCVAsmParser : public MCTargetAsmParser { ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); } } + public: enum RISCVMatchResultTy { Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, @@ -144,6 +146,7 @@ struct RISCVOperand : public MCParsedAsmOperand { Token, Register, Immediate, + SystemRegister } Kind; bool IsRV64; @@ -156,11 +159,20 @@ struct RISCVOperand : public MCParsedAsmOperand { const MCExpr *Val; }; + struct SysRegOp { + const char *Data; + unsigned Length; + unsigned Encoding; + // FIXME: Add the Encoding parsed fields as needed for checks, + // e.g.: read/write or user/supervisor/machine privileges. + }; + SMLoc StartLoc, EndLoc; union { StringRef Tok; RegOp Reg; ImmOp Imm; + struct SysRegOp SysReg; }; RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} @@ -181,6 +193,9 @@ public: case Token: Tok = o.Tok; break; + case SystemRegister: + SysReg = o.SysReg; + break; } } @@ -188,6 +203,7 @@ public: bool isReg() const override { return Kind == Register; } bool isImm() const override { return Kind == Immediate; } bool isMem() const override { return false; } + bool isSystemRegister() const { return Kind == SystemRegister; } static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm, RISCVMCExpr::VariantKind &VK) { @@ -233,6 +249,8 @@ public: VK == RISCVMCExpr::VK_RISCV_None; } + bool isCSRSystemRegister() const { return isSystemRegister(); } + /// Return true if the operand is a valid for the fence instruction e.g. /// ('iorw'). bool isFenceArg() const { @@ -355,7 +373,7 @@ public: bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); return IsConstantImm && (Imm != 0) && (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) && - VK == RISCVMCExpr::VK_RISCV_None; + VK == RISCVMCExpr::VK_RISCV_None; } bool isUImm7Lsb00() const { @@ -428,15 +446,6 @@ public: bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); } - bool isUImm12() const { - int64_t Imm; - RISCVMCExpr::VariantKind VK; - if (!isImm()) - return false; - bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); - return IsConstantImm && isUInt<12>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; - } - bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); } bool isSImm10Lsb0000NonZero() const { @@ -495,6 +504,11 @@ public: return Reg.RegNum; } + StringRef getSysReg() const { + assert(Kind == SystemRegister && "Invalid access!"); + return StringRef(SysReg.Data, SysReg.Length); + } + const MCExpr *getImm() const { assert(Kind == Immediate && "Invalid type access!"); return Imm.Val; @@ -517,6 +531,9 @@ public: case Token: OS << "'" << getToken() << "'"; break; + case SystemRegister: + OS << "<sysreg: " << getSysReg() << '>'; + break; } } @@ -550,6 +567,17 @@ public: return Op; } + static std::unique_ptr<RISCVOperand> + createSysReg(StringRef Str, SMLoc S, unsigned Encoding, bool IsRV64) { + auto Op = make_unique<RISCVOperand>(SystemRegister); + Op->SysReg.Data = Str.data(); + Op->SysReg.Length = Str.size(); + Op->SysReg.Encoding = Encoding; + Op->StartLoc = S; + Op->IsRV64 = IsRV64; + return Op; + } + void addExpr(MCInst &Inst, const MCExpr *Expr) const { assert(Expr && "Expr shouldn't be null!"); int64_t Imm = 0; @@ -581,16 +609,22 @@ public: unsigned Imm = 0; for (char c : SE->getSymbol().getName()) { switch (c) { - default: llvm_unreachable("FenceArg must contain only [iorw]"); - case 'i': Imm |= RISCVFenceField::I; break; - case 'o': Imm |= RISCVFenceField::O; break; - case 'r': Imm |= RISCVFenceField::R; break; - case 'w': Imm |= RISCVFenceField::W; break; + default: + llvm_unreachable("FenceArg must contain only [iorw]"); + case 'i': Imm |= RISCVFenceField::I; break; + case 'o': Imm |= RISCVFenceField::O; break; + case 'r': Imm |= RISCVFenceField::R; break; + case 'w': Imm |= RISCVFenceField::W; break; } } Inst.addOperand(MCOperand::createImm(Imm)); } + void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::createImm(SysReg.Encoding)); + } + // Returns the rounding mode represented by this RISCVOperand. Should only // be called after checking isFRMArg. RISCVFPRndMode::RoundingMode getRoundingMode() const { @@ -618,40 +652,40 @@ public: // information from TableGen. unsigned convertFPR32ToFPR64(unsigned Reg) { switch (Reg) { - default: - llvm_unreachable("Not a recognised FPR32 register"); - case RISCV::F0_32: return RISCV::F0_64; - case RISCV::F1_32: return RISCV::F1_64; - case RISCV::F2_32: return RISCV::F2_64; - case RISCV::F3_32: return RISCV::F3_64; - case RISCV::F4_32: return RISCV::F4_64; - case RISCV::F5_32: return RISCV::F5_64; - case RISCV::F6_32: return RISCV::F6_64; - case RISCV::F7_32: return RISCV::F7_64; - case RISCV::F8_32: return RISCV::F8_64; - case RISCV::F9_32: return RISCV::F9_64; - case RISCV::F10_32: return RISCV::F10_64; - case RISCV::F11_32: return RISCV::F11_64; - case RISCV::F12_32: return RISCV::F12_64; - case RISCV::F13_32: return RISCV::F13_64; - case RISCV::F14_32: return RISCV::F14_64; - case RISCV::F15_32: return RISCV::F15_64; - case RISCV::F16_32: return RISCV::F16_64; - case RISCV::F17_32: return RISCV::F17_64; - case RISCV::F18_32: return RISCV::F18_64; - case RISCV::F19_32: return RISCV::F19_64; - case RISCV::F20_32: return RISCV::F20_64; - case RISCV::F21_32: return RISCV::F21_64; - case RISCV::F22_32: return RISCV::F22_64; - case RISCV::F23_32: return RISCV::F23_64; - case RISCV::F24_32: return RISCV::F24_64; - case RISCV::F25_32: return RISCV::F25_64; - case RISCV::F26_32: return RISCV::F26_64; - case RISCV::F27_32: return RISCV::F27_64; - case RISCV::F28_32: return RISCV::F28_64; - case RISCV::F29_32: return RISCV::F29_64; - case RISCV::F30_32: return RISCV::F30_64; - case RISCV::F31_32: return RISCV::F31_64; + default: + llvm_unreachable("Not a recognised FPR32 register"); + case RISCV::F0_32: return RISCV::F0_64; + case RISCV::F1_32: return RISCV::F1_64; + case RISCV::F2_32: return RISCV::F2_64; + case RISCV::F3_32: return RISCV::F3_64; + case RISCV::F4_32: return RISCV::F4_64; + case RISCV::F5_32: return RISCV::F5_64; + case RISCV::F6_32: return RISCV::F6_64; + case RISCV::F7_32: return RISCV::F7_64; + case RISCV::F8_32: return RISCV::F8_64; + case RISCV::F9_32: return RISCV::F9_64; + case RISCV::F10_32: return RISCV::F10_64; + case RISCV::F11_32: return RISCV::F11_64; + case RISCV::F12_32: return RISCV::F12_64; + case RISCV::F13_32: return RISCV::F13_64; + case RISCV::F14_32: return RISCV::F14_64; + case RISCV::F15_32: return RISCV::F15_64; + case RISCV::F16_32: return RISCV::F16_64; + case RISCV::F17_32: return RISCV::F17_64; + case RISCV::F18_32: return RISCV::F18_64; + case RISCV::F19_32: return RISCV::F19_64; + case RISCV::F20_32: return RISCV::F20_64; + case RISCV::F21_32: return RISCV::F21_64; + case RISCV::F22_32: return RISCV::F22_64; + case RISCV::F23_32: return RISCV::F23_64; + case RISCV::F24_32: return RISCV::F24_64; + case RISCV::F25_32: return RISCV::F25_64; + case RISCV::F26_32: return RISCV::F26_64; + case RISCV::F27_32: return RISCV::F27_64; + case RISCV::F28_32: return RISCV::F28_64; + case RISCV::F29_32: return RISCV::F29_64; + case RISCV::F30_32: return RISCV::F30_64; + case RISCV::F31_32: return RISCV::F31_64; } } @@ -750,8 +784,8 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1); case Match_InvalidSImm6NonZero: - return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), - (1 << 5) - 1, + return generateImmOutOfRangeError( + Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1, "immediate must be non-zero in the range"); case Match_InvalidCLUIImm: return generateImmOutOfRangeError( @@ -794,8 +828,6 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2, "immediate must be a multiple of 2 bytes in the range"); - case Match_InvalidUImm12: - return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1); case Match_InvalidSImm13Lsb0: return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2, @@ -813,6 +845,11 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return generateImmOutOfRangeError( Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2, "immediate must be a multiple of 2 bytes in the range"); + case Match_InvalidCSRSystemRegister: { + return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1, + "operand must be a valid system register " + "name or an integer in the range"); + } case Match_InvalidFenceArg: { SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); return Error( @@ -895,6 +932,72 @@ OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands, return MatchOperand_Success; } +OperandMatchResultTy +RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) { + SMLoc S = getLoc(); + const MCExpr *Res; + + switch (getLexer().getKind()) { + default: + return MatchOperand_NoMatch; + case AsmToken::LParen: + case AsmToken::Minus: + case AsmToken::Plus: + case AsmToken::Integer: + case AsmToken::String: { + if (getParser().parseExpression(Res)) + return MatchOperand_ParseFail; + + auto *CE = dyn_cast<MCConstantExpr>(Res); + if (CE) { + int64_t Imm = CE->getValue(); + if (isUInt<12>(Imm)) { + auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm); + // Accept an immediate representing a named or un-named Sys Reg + // if the range is valid, regardless of the required features. + Operands.push_back(RISCVOperand::createSysReg( + SysReg ? SysReg->Name : "", S, Imm, isRV64())); + return MatchOperand_Success; + } + } + + Twine Msg = "immediate must be an integer in the range"; + Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); + return MatchOperand_ParseFail; + } + case AsmToken::Identifier: { + StringRef Identifier; + if (getParser().parseIdentifier(Identifier)) + return MatchOperand_ParseFail; + + auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier); + // Accept a named Sys Reg if the required features are present. + if (SysReg) { + if (!SysReg->haveRequiredFeatures(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, isRV64())); + return MatchOperand_Success; + } + + Twine Msg = "operand must be a valid system register name " + "or an integer in the range"; + Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); + return MatchOperand_ParseFail; + } + case AsmToken::Percent: { + // Discard operand with modifier. + Twine Msg = "immediate must be an integer in the range"; + Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); + return MatchOperand_ParseFail; + } + } + + return MatchOperand_NoMatch; +} + OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { SMLoc S = getLoc(); SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt index ee5ed625f12..07c32cb315d 100644 --- a/llvm/lib/Target/RISCV/CMakeLists.txt +++ b/llvm/lib/Target/RISCV/CMakeLists.txt @@ -10,6 +10,7 @@ tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter) tablegen(LLVM RISCVGenMCPseudoLowering.inc -gen-pseudo-lowering) tablegen(LLVM RISCVGenRegisterInfo.inc -gen-register-info) tablegen(LLVM RISCVGenSubtargetInfo.inc -gen-subtarget) +tablegen(LLVM RISCVGenSystemOperands.inc -gen-searchable-tables) add_public_tablegen_target(RISCVCommonTableGen) @@ -33,3 +34,4 @@ add_subdirectory(Disassembler) add_subdirectory(InstPrinter) add_subdirectory(MCTargetDesc) add_subdirectory(TargetInfo) +add_subdirectory(Utils) diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index d5b8b389ae3..eafa09d5631 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#include "MCTargetDesc/RISCVBaseInfo.h" #include "MCTargetDesc/RISCVMCTargetDesc.h" +#include "Utils/RISCVBaseInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" #include "llvm/MC/MCFixedLenDisassembler.h" diff --git a/llvm/lib/Target/RISCV/InstPrinter/LLVMBuild.txt b/llvm/lib/Target/RISCV/InstPrinter/LLVMBuild.txt index 5f4545e3d67..5a28372a302 100644 --- a/llvm/lib/Target/RISCV/InstPrinter/LLVMBuild.txt +++ b/llvm/lib/Target/RISCV/InstPrinter/LLVMBuild.txt @@ -19,5 +19,5 @@ type = Library name = RISCVAsmPrinter parent = RISCV -required_libraries = MC Support +required_libraries = MC RISCVUtils Support add_to_library_groups = RISCV diff --git a/llvm/lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp index 300e6fd9750..aa21cf0e6b4 100644 --- a/llvm/lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp +++ b/llvm/lib/Target/RISCV/InstPrinter/RISCVInstPrinter.cpp @@ -12,8 +12,8 @@ //===----------------------------------------------------------------------===// #include "RISCVInstPrinter.h" -#include "MCTargetDesc/RISCVBaseInfo.h" #include "MCTargetDesc/RISCVMCExpr.h" +#include "Utils/RISCVBaseInfo.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" @@ -36,10 +36,9 @@ using namespace llvm; #include "RISCVGenCompressInstEmitter.inc" static cl::opt<bool> -NoAliases("riscv-no-aliases", - cl::desc("Disable the emission of assembler pseudo instructions"), - cl::init(false), - cl::Hidden); + NoAliases("riscv-no-aliases", + cl::desc("Disable the emission of assembler pseudo instructions"), + cl::init(false), cl::Hidden); void RISCVInstPrinter::printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, const MCSubtargetInfo &STI) { @@ -49,7 +48,7 @@ void RISCVInstPrinter::printInst(const MCInst *MI, raw_ostream &O, if (!NoAliases) Res = uncompressInst(UncompressedMI, *MI, MRI, STI); if (Res) - NewMI = const_cast<MCInst*>(&UncompressedMI); + NewMI = const_cast<MCInst *>(&UncompressedMI); if (NoAliases || !printAliasInstr(NewMI, STI, O)) printInstruction(NewMI, STI, O); printAnnotation(O, Annot); @@ -60,8 +59,8 @@ void RISCVInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const { } void RISCVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, - const MCSubtargetInfo &STI, - raw_ostream &O, const char *Modifier) { + const MCSubtargetInfo &STI, raw_ostream &O, + const char *Modifier) { assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported"); const MCOperand &MO = MI->getOperand(OpNo); @@ -79,6 +78,17 @@ void RISCVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, MO.getExpr()->print(O, &MAI); } +void RISCVInstPrinter::printCSRSystemRegister(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, + 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; +} + void RISCVInstPrinter::printFenceArg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O) { @@ -94,8 +104,7 @@ void RISCVInstPrinter::printFenceArg(const MCInst *MI, unsigned OpNo, } void RISCVInstPrinter::printFRMArg(const MCInst *MI, unsigned OpNo, - const MCSubtargetInfo &STI, - raw_ostream &O) { + const MCSubtargetInfo &STI, raw_ostream &O) { auto FRMArg = static_cast<RISCVFPRndMode::RoundingMode>(MI->getOperand(OpNo).getImm()); O << RISCVFPRndMode::roundingModeToString(FRMArg); diff --git a/llvm/lib/Target/RISCV/InstPrinter/RISCVInstPrinter.h b/llvm/lib/Target/RISCV/InstPrinter/RISCVInstPrinter.h index 241be8daf11..0f9bed18499 100644 --- a/llvm/lib/Target/RISCV/InstPrinter/RISCVInstPrinter.h +++ b/llvm/lib/Target/RISCV/InstPrinter/RISCVInstPrinter.h @@ -32,6 +32,8 @@ public: void printOperand(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O, const char *Modifier = nullptr); + void printCSRSystemRegister(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, raw_ostream &O); void printFenceArg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); void printFRMArg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, @@ -48,6 +50,6 @@ public: static const char *getRegisterName(unsigned RegNo, unsigned AltIdx = RISCV::ABIRegAltName); }; -} +} // namespace llvm #endif diff --git a/llvm/lib/Target/RISCV/LLVMBuild.txt b/llvm/lib/Target/RISCV/LLVMBuild.txt index ab21565b0c2..7af605e6954 100644 --- a/llvm/lib/Target/RISCV/LLVMBuild.txt +++ b/llvm/lib/Target/RISCV/LLVMBuild.txt @@ -16,7 +16,7 @@ ;===------------------------------------------------------------------------===; [common] -subdirectories = AsmParser Disassembler InstPrinter TargetInfo MCTargetDesc +subdirectories = AsmParser Disassembler InstPrinter TargetInfo MCTargetDesc Utils [component_0] type = TargetGroup @@ -31,5 +31,5 @@ type = Library name = RISCVCodeGen parent = RISCV required_libraries = AsmPrinter Core CodeGen MC RISCVAsmPrinter RISCVDesc - RISCVInfo SelectionDAG Support Target + RISCVInfo RISCVUtils SelectionDAG Support Target add_to_library_groups = RISCV diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp index 6a57e0e3aa5..c5a4ffc0e36 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp @@ -11,10 +11,10 @@ // //===----------------------------------------------------------------------===// -#include "MCTargetDesc/RISCVBaseInfo.h" #include "MCTargetDesc/RISCVFixupKinds.h" #include "MCTargetDesc/RISCVMCExpr.h" #include "MCTargetDesc/RISCVMCTargetDesc.h" +#include "Utils/RISCVBaseInfo.h" #include "llvm/ADT/Statistic.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCCodeEmitter.h" diff --git a/llvm/lib/Target/RISCV/RISCV.h b/llvm/lib/Target/RISCV/RISCV.h index b48a68f76eb..b25aee46200 100644 --- a/llvm/lib/Target/RISCV/RISCV.h +++ b/llvm/lib/Target/RISCV/RISCV.h @@ -15,7 +15,7 @@ #ifndef LLVM_LIB_TARGET_RISCV_RISCV_H #define LLVM_LIB_TARGET_RISCV_RISCV_H -#include "MCTargetDesc/RISCVBaseInfo.h" +#include "Utils/RISCVBaseInfo.h" #include "llvm/Target/TargetMachine.h" namespace llvm { diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td index 281378cb2ee..0e86e2bc5e9 100644 --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -68,6 +68,12 @@ include "RISCVCallingConv.td" include "RISCVInstrInfo.td" //===----------------------------------------------------------------------===// +// Named operands for CSR instructions. +//===----------------------------------------------------------------------===// + +include "RISCVSystemOperands.td" + +//===----------------------------------------------------------------------===// // RISC-V processors supported. //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index e9244ac64c3..5ca1cbd165d 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -125,11 +125,6 @@ def simm12 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<12>(Imm);}]> { }]; } -def uimm12 : Operand<XLenVT> { - let ParserMatchClass = UImmAsmOperand<12>; - let DecoderMethod = "decodeUImmOperand<12>"; -} - // A 13-bit signed immediate where the least significant bit is zero. def simm13_lsb0 : Operand<OtherVT> { let ParserMatchClass = SImmAsmOperand<13, "Lsb0">; @@ -190,6 +185,18 @@ def bare_symbol : Operand<XLenVT> { let ParserMatchClass = BareSymbol; } +def CSRSystemRegister : AsmOperandClass { + let Name = "CSRSystemRegister"; + let ParserMethod = "parseCSRSystemRegister"; + let DiagnosticType = "InvalidCSRSystemRegister"; +} + +def csr_sysreg : Operand<XLenVT> { + let ParserMatchClass = CSRSystemRegister; + let PrintMethod = "printCSRSystemRegister"; + let DecoderMethod = "decodeUImmOperand<12>"; +} + // A parameterized register class alternative to i32imm/i64imm from Target.td. def ixlenimm : Operand<XLenVT> { let ParserMatchClass = ImmXLenAsmOperand<"">; @@ -263,13 +270,13 @@ class ALU_rr<bits<7> funct7, bits<3> funct3, string opcodestr> let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in class CSR_ir<bits<3> funct3, string opcodestr> - : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), (ins uimm12:$imm12, GPR:$rs1), + : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), (ins csr_sysreg:$imm12, GPR:$rs1), opcodestr, "$rd, $imm12, $rs1">; let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in class CSR_ii<bits<3> funct3, string opcodestr> : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), - (ins uimm12:$imm12, uimm5:$rs1), + (ins csr_sysreg:$imm12, uimm5:$rs1), opcodestr, "$rd, $imm12, $rs1">; let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in @@ -546,14 +553,14 @@ def : InstAlias<"rdcycleh $rd", (CSRRS GPR:$rd, 0xC80, X0)>; def : InstAlias<"rdtimeh $rd", (CSRRS GPR:$rd, 0xC81, X0)>; } // Predicates = [IsRV32] -def : InstAlias<"csrr $rd, $csr", (CSRRS GPR:$rd, uimm12:$csr, X0)>; -def : InstAlias<"csrw $csr, $rs", (CSRRW X0, uimm12:$csr, GPR:$rs)>; -def : InstAlias<"csrs $csr, $rs", (CSRRS X0, uimm12:$csr, GPR:$rs)>; -def : InstAlias<"csrc $csr, $rs", (CSRRC X0, uimm12:$csr, GPR:$rs)>; +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)>; +def : InstAlias<"csrc $csr, $rs", (CSRRC X0, csr_sysreg:$csr, GPR:$rs)>; -def : InstAlias<"csrwi $csr, $imm", (CSRRWI X0, uimm12:$csr, uimm5:$imm)>; -def : InstAlias<"csrsi $csr, $imm", (CSRRSI X0, uimm12:$csr, uimm5:$imm)>; -def : InstAlias<"csrci $csr, $imm", (CSRRCI X0, uimm12:$csr, uimm5:$imm)>; +def : InstAlias<"csrwi $csr, $imm", (CSRRWI X0, csr_sysreg:$csr, uimm5:$imm)>; +def : InstAlias<"csrsi $csr, $imm", (CSRRSI X0, csr_sysreg:$csr, uimm5:$imm)>; +def : InstAlias<"csrci $csr, $imm", (CSRRCI X0, csr_sysreg:$csr, uimm5:$imm)>; 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/RISCVSystemOperands.td b/llvm/lib/Target/RISCV/RISCVSystemOperands.td new file mode 100644 index 00000000000..f1b7984ffe6 --- /dev/null +++ b/llvm/lib/Target/RISCV/RISCVSystemOperands.td @@ -0,0 +1,352 @@ +//===- RISCVSystemOperands.td ----------------------------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the symbolic operands permitted for various kinds of +// RISC-V system instruction. +// +//===----------------------------------------------------------------------===// + +include "llvm/TableGen/SearchableTable.td" + +//===----------------------------------------------------------------------===// +// CSR (control and status register read/write) instruction options. +//===----------------------------------------------------------------------===// + +class SysReg<string name, bits<12> op> { + string Name = name; + bits<12> Encoding = op; + // FIXME: add these additional fields when needed. + // Privilege Access: Read and Write = 0, 1, 2; Read-Only = 3. + // Privilege Mode: User = 0, System = 1 or Machine = 3. + // bits<2> ReadWrite = op{11 - 10}; + // bits<2> XMode = op{9 - 8}; + // Check Extra field name and what bits 7-6 correspond to. + // bits<2> Extra = op{7 - 6}; + // Register number without the privilege bits. + // bits<6> Number = op{5 - 0}; + code FeaturesRequired = [{ {} }]; + bit isRV32Only = 0; +} + +def SysRegsList : GenericTable { + let FilterClass = "SysReg"; + // FIXME: add "ReadWrite", "Mode", "Extra", "Number" fields when needed. + let Fields = [ "Name", "Encoding", "FeaturesRequired", "isRV32Only" ]; + + let PrimaryKey = [ "Encoding" ]; + let PrimaryKeyName = "lookupSysRegByEncoding"; +} + +def lookupSysRegByName : SearchIndex { + let Table = SysRegsList; + let Key = [ "Name" ]; +} + +// The following CSR encodings match those given in Tables 2.2, +// 2.3, 2.4 and 2.5 in the RISC-V Instruction Set Manual +// Volume II: Privileged Architecture. + +//===-------------------------- +// User Trap Setup +//===-------------------------- +def : SysReg<"ustatus", 0x000>; +def : SysReg<"uie", 0x004>; +def : SysReg<"utvec", 0x005>; + +//===-------------------------- +// User Trap Handling +//===-------------------------- +def : SysReg<"uscratch", 0x040>; +def : SysReg<"uepc", 0x041>; +def : SysReg<"ucause", 0x042>; +def : SysReg<"utval", 0x043>; +def : SysReg<"uip", 0x044>; + +//===-------------------------- +// User Floating-Point CSRs +//===-------------------------- + +let FeaturesRequired = [{ {RISCV::FeatureStdExtF} }] in { +def : SysReg<"fflags", 0x001>; +def : SysReg<"frm", 0x002>; +def : SysReg<"fcsr", 0x003>; +} + +//===-------------------------- +// User Counter/Timers +//===-------------------------- +def : SysReg<"cycle", 0xC00>; +def : SysReg<"time", 0xC01>; +def : SysReg<"instret", 0xC02>; + +def : SysReg<"hpmcounter3", 0xC03>; +def : SysReg<"hpmcounter4", 0xC04>; +def : SysReg<"hpmcounter5", 0xC05>; +def : SysReg<"hpmcounter6", 0xC06>; +def : SysReg<"hpmcounter7", 0xC07>; +def : SysReg<"hpmcounter8", 0xC08>; +def : SysReg<"hpmcounter9", 0xC09>; +def : SysReg<"hpmcounter10", 0xC0A>; +def : SysReg<"hpmcounter11", 0xC0B>; +def : SysReg<"hpmcounter12", 0xC0C>; +def : SysReg<"hpmcounter13", 0xC0D>; +def : SysReg<"hpmcounter14", 0xC0E>; +def : SysReg<"hpmcounter15", 0xC0F>; +def : SysReg<"hpmcounter16", 0xC10>; +def : SysReg<"hpmcounter17", 0xC11>; +def : SysReg<"hpmcounter18", 0xC12>; +def : SysReg<"hpmcounter19", 0xC13>; +def : SysReg<"hpmcounter20", 0xC14>; +def : SysReg<"hpmcounter21", 0xC15>; +def : SysReg<"hpmcounter22", 0xC16>; +def : SysReg<"hpmcounter23", 0xC17>; +def : SysReg<"hpmcounter24", 0xC18>; +def : SysReg<"hpmcounter25", 0xC19>; +def : SysReg<"hpmcounter26", 0xC1A>; +def : SysReg<"hpmcounter27", 0xC1B>; +def : SysReg<"hpmcounter28", 0xC1C>; +def : SysReg<"hpmcounter29", 0xC1D>; +def : SysReg<"hpmcounter30", 0xC1E>; +def : SysReg<"hpmcounter31", 0xC1F>; + +let isRV32Only = 1 in { +def: SysReg<"cycleh", 0xC80>; +def: SysReg<"timeh", 0xC81>; +def: SysReg<"instreth", 0xC82>; + +def: SysReg<"hpmcounter3h", 0xC83>; +def: SysReg<"hpmcounter4h", 0xC84>; +def: SysReg<"hpmcounter5h", 0xC85>; +def: SysReg<"hpmcounter6h", 0xC86>; +def: SysReg<"hpmcounter7h", 0xC87>; +def: SysReg<"hpmcounter8h", 0xC88>; +def: SysReg<"hpmcounter9h", 0xC89>; +def: SysReg<"hpmcounter10h", 0xC8A>; +def: SysReg<"hpmcounter11h", 0xC8B>; +def: SysReg<"hpmcounter12h", 0xC8C>; +def: SysReg<"hpmcounter13h", 0xC8D>; +def: SysReg<"hpmcounter14h", 0xC8E>; +def: SysReg<"hpmcounter15h", 0xC8F>; +def: SysReg<"hpmcounter16h", 0xC90>; +def: SysReg<"hpmcounter17h", 0xC91>; +def: SysReg<"hpmcounter18h", 0xC92>; +def: SysReg<"hpmcounter19h", 0xC93>; +def: SysReg<"hpmcounter20h", 0xC94>; +def: SysReg<"hpmcounter21h", 0xC95>; +def: SysReg<"hpmcounter22h", 0xC96>; +def: SysReg<"hpmcounter23h", 0xC97>; +def: SysReg<"hpmcounter24h", 0xC98>; +def: SysReg<"hpmcounter25h", 0xC99>; +def: SysReg<"hpmcounter26h", 0xC9A>; +def: SysReg<"hpmcounter27h", 0xC9B>; +def: SysReg<"hpmcounter28h", 0xC9C>; +def: SysReg<"hpmcounter29h", 0xC9D>; +def: SysReg<"hpmcounter30h", 0xC9E>; +def: SysReg<"hpmcounter31h", 0xC9F>; +} + +//===-------------------------- +// Supervisor Trap Setup +//===-------------------------- +def : SysReg<"sstatus", 0x100>; +def : SysReg<"sedeleg", 0x102>; +def : SysReg<"sideleg", 0x103>; +def : SysReg<"sie", 0x104>; +def : SysReg<"stvec", 0x105>; +def : SysReg<"scounteren", 0x106>; + +//===-------------------------- +// Supervisor Trap Handling +//===-------------------------- +def : SysReg<"sscratch", 0x140>; +def : SysReg<"sepc", 0x141>; +def : SysReg<"scause", 0x142>; +def : SysReg<"stval", 0x143>; +def : SysReg<"sip", 0x144>; + +//===------------------------------------- +// Supervisor Protection and Translation +//===------------------------------------- +def : SysReg<"satp", 0x180>; + +//===----------------------------- +// Machine Information Registers +//===----------------------------- + +def : SysReg<"mvendorid", 0xF11>; +def : SysReg<"marchid", 0xF12>; +def : SysReg<"mimpid", 0xF13>; +def : SysReg<"mhartid", 0xF14>; + +//===----------------------------- +// Machine Trap Setup +//===----------------------------- +def : SysReg<"mstatus", 0x300>; +def : SysReg<"misa", 0x301>; +def : SysReg<"medeleg", 0x302>; +def : SysReg<"mideleg", 0x303>; +def : SysReg<"mie", 0x304>; +def : SysReg<"mtvec", 0x305>; +def : SysReg<"mcounteren", 0x306>; + +//===----------------------------- +// Machine Trap Handling +//===----------------------------- +def : SysReg<"mscratch", 0x340>; +def : SysReg<"mepc", 0x341>; +def : SysReg<"mcause", 0x342>; +def : SysReg<"mtval", 0x343>; +def : SysReg<"mip", 0x344>; + +//===---------------------------------- +// Machine Protection and Translation +//===---------------------------------- +def : SysReg<"pmpcfg0", 0x3A0>; +def : SysReg<"pmpcfg2", 0x3A2>; +let isRV32Only = 1 in { +def : SysReg<"pmpcfg1", 0x3A1>; +def : SysReg<"pmpcfg3", 0x3A3>; +} + +def : SysReg<"pmpaddr0", 0x3B0>; +def : SysReg<"pmpaddr1", 0x3B1>; +def : SysReg<"pmpaddr2", 0x3B2>; +def : SysReg<"pmpaddr3", 0x3B3>; +def : SysReg<"pmpaddr4", 0x3B4>; +def : SysReg<"pmpaddr5", 0x3B5>; +def : SysReg<"pmpaddr6", 0x3B6>; +def : SysReg<"pmpaddr7", 0x3B7>; +def : SysReg<"pmpaddr8", 0x3B8>; +def : SysReg<"pmpaddr9", 0x3B9>; +def : SysReg<"pmpaddr10", 0x3BA>; +def : SysReg<"pmpaddr11", 0x3BB>; +def : SysReg<"pmpaddr12", 0x3BC>; +def : SysReg<"pmpaddr13", 0x3BD>; +def : SysReg<"pmpaddr14", 0x3BE>; +def : SysReg<"pmpaddr15", 0x3BF>; + + +//===-------------------------- +// Machine Counter and Timers +//===-------------------------- +def : SysReg<"mcycle", 0xB00>; +def : SysReg<"minstret", 0xB02>; + +def : SysReg<"mhpmcounter3", 0xB03>; +def : SysReg<"mhpmcounter4", 0xB04>; +def : SysReg<"mhpmcounter5", 0xB05>; +def : SysReg<"mhpmcounter6", 0xB06>; +def : SysReg<"mhpmcounter7", 0xB07>; +def : SysReg<"mhpmcounter8", 0xB08>; +def : SysReg<"mhpmcounter9", 0xB09>; +def : SysReg<"mhpmcounter10", 0xB0A>; +def : SysReg<"mhpmcounter11", 0xB0B>; +def : SysReg<"mhpmcounter12", 0xB0C>; +def : SysReg<"mhpmcounter13", 0xB0D>; +def : SysReg<"mhpmcounter14", 0xB0E>; +def : SysReg<"mhpmcounter15", 0xB0F>; +def : SysReg<"mhpmcounter16", 0xB10>; +def : SysReg<"mhpmcounter17", 0xB11>; +def : SysReg<"mhpmcounter18", 0xB12>; +def : SysReg<"mhpmcounter19", 0xB13>; +def : SysReg<"mhpmcounter20", 0xB14>; +def : SysReg<"mhpmcounter21", 0xB15>; +def : SysReg<"mhpmcounter22", 0xB16>; +def : SysReg<"mhpmcounter23", 0xB17>; +def : SysReg<"mhpmcounter24", 0xB18>; +def : SysReg<"mhpmcounter25", 0xB19>; +def : SysReg<"mhpmcounter26", 0xB1A>; +def : SysReg<"mhpmcounter27", 0xB1B>; +def : SysReg<"mhpmcounter28", 0xB1C>; +def : SysReg<"mhpmcounter29", 0xB1D>; +def : SysReg<"mhpmcounter30", 0xB1E>; +def : SysReg<"mhpmcounter31", 0xB1F>; + +let isRV32Only = 1 in { +def: SysReg<"mcycleh", 0xB80>; +def: SysReg<"minstreth", 0xB82>; + +def: SysReg<"mhpmcounter3h", 0xB83>; +def: SysReg<"mhpmcounter4h", 0xB84>; +def: SysReg<"mhpmcounter5h", 0xB85>; +def: SysReg<"mhpmcounter6h", 0xB86>; +def: SysReg<"mhpmcounter7h", 0xB87>; +def: SysReg<"mhpmcounter8h", 0xB88>; +def: SysReg<"mhpmcounter9h", 0xB89>; +def: SysReg<"mhpmcounter10h", 0xB8A>; +def: SysReg<"mhpmcounter11h", 0xB8B>; +def: SysReg<"mhpmcounter12h", 0xB8C>; +def: SysReg<"mhpmcounter13h", 0xB8D>; +def: SysReg<"mhpmcounter14h", 0xB8E>; +def: SysReg<"mhpmcounter15h", 0xB8F>; +def: SysReg<"mhpmcounter16h", 0xB90>; +def: SysReg<"mhpmcounter17h", 0xB91>; +def: SysReg<"mhpmcounter18h", 0xB92>; +def: SysReg<"mhpmcounter19h", 0xB93>; +def: SysReg<"mhpmcounter20h", 0xB94>; +def: SysReg<"mhpmcounter21h", 0xB95>; +def: SysReg<"mhpmcounter22h", 0xB96>; +def: SysReg<"mhpmcounter23h", 0xB97>; +def: SysReg<"mhpmcounter24h", 0xB98>; +def: SysReg<"mhpmcounter25h", 0xB99>; +def: SysReg<"mhpmcounter26h", 0xB9A>; +def: SysReg<"mhpmcounter27h", 0xB9B>; +def: SysReg<"mhpmcounter28h", 0xB9C>; +def: SysReg<"mhpmcounter29h", 0xB9D>; +def: SysReg<"mhpmcounter30h", 0xB9E>; +def: SysReg<"mhpmcounter31h", 0xB9F>; +} + +//===-------------------------- +// Machine Counter Setup +//===-------------------------- +def : SysReg<"mhpmevent3", 0x323>; +def : SysReg<"mhpmevent4", 0x324>; +def : SysReg<"mhpmevent5", 0x325>; +def : SysReg<"mhpmevent6", 0x326>; +def : SysReg<"mhpmevent7", 0x327>; +def : SysReg<"mhpmevent8", 0x328>; +def : SysReg<"mhpmevent9", 0x329>; +def : SysReg<"mhpmevent10", 0x32A>; +def : SysReg<"mhpmevent11", 0x32B>; +def : SysReg<"mhpmevent12", 0x32C>; +def : SysReg<"mhpmevent13", 0x32D>; +def : SysReg<"mhpmevent14", 0x32E>; +def : SysReg<"mhpmevent15", 0x32F>; +def : SysReg<"mhpmevent16", 0x330>; +def : SysReg<"mhpmevent17", 0x331>; +def : SysReg<"mhpmevent18", 0x332>; +def : SysReg<"mhpmevent19", 0x333>; +def : SysReg<"mhpmevent20", 0x334>; +def : SysReg<"mhpmevent21", 0x335>; +def : SysReg<"mhpmevent22", 0x336>; +def : SysReg<"mhpmevent23", 0x337>; +def : SysReg<"mhpmevent24", 0x338>; +def : SysReg<"mhpmevent25", 0x339>; +def : SysReg<"mhpmevent26", 0x33A>; +def : SysReg<"mhpmevent27", 0x33B>; +def : SysReg<"mhpmevent28", 0x33C>; +def : SysReg<"mhpmevent29", 0x33D>; +def : SysReg<"mhpmevent30", 0x33E>; +def : SysReg<"mhpmevent31", 0x33F>; + +//===----------------------------------------------- +// Debug/ Trace Registers (shared with Debug Mode) +//===----------------------------------------------- +def : SysReg<"tselect", 0x7A0>; +def : SysReg<"tdata1", 0x7A1>; +def : SysReg<"tdata2", 0x7A2>; +def : SysReg<"tdata3", 0x7A3>; + +//===----------------------------------------------- +// Debug Mode Registers +//===----------------------------------------------- +def : SysReg<"dcsr", 0x7B0>; +def : SysReg<"dpc", 0x7B1>; +def : SysReg<"dscratch", 0x7B2>; diff --git a/llvm/lib/Target/RISCV/Utils/CMakeLists.txt b/llvm/lib/Target/RISCV/Utils/CMakeLists.txt new file mode 100644 index 00000000000..b7869f69630 --- /dev/null +++ b/llvm/lib/Target/RISCV/Utils/CMakeLists.txt @@ -0,0 +1,3 @@ +add_llvm_library(LLVMRISCVUtils + RISCVBaseInfo.cpp + ) diff --git a/llvm/lib/Target/RISCV/Utils/LLVMBuild.txt b/llvm/lib/Target/RISCV/Utils/LLVMBuild.txt new file mode 100644 index 00000000000..ec75b930366 --- /dev/null +++ b/llvm/lib/Target/RISCV/Utils/LLVMBuild.txt @@ -0,0 +1,24 @@ +;===- ./lib/Target/RISCV/Utils/LLVMBuild.txt ----------------*- Conf -*--===; +; +; The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = RISCVUtils +parent = RISCV +required_libraries = Support +add_to_library_groups = RISCV + diff --git a/llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.cpp b/llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.cpp new file mode 100644 index 00000000000..964af1f74ce --- /dev/null +++ b/llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.cpp @@ -0,0 +1,9 @@ +#include "RISCVBaseInfo.h" +#include "llvm/ADT/ArrayRef.h" + +namespace llvm { +namespace RISCVSysReg { +#define GET_SysRegsList_IMPL +#include "RISCVGenSystemOperands.inc" +} // namespace RISCVSysReg +} // namespace llvm diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.h index d6b4687c346..86cd2d6e58a 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ b/llvm/lib/Target/RISCV/Utils/RISCVBaseInfo.h @@ -14,9 +14,10 @@ #ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVBASEINFO_H #define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVBASEINFO_H -#include "RISCVMCTargetDesc.h" +#include "MCTargetDesc/RISCVMCTargetDesc.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/MC/SubtargetFeature.h" namespace llvm { @@ -118,8 +119,39 @@ inline static bool isValidRoundingMode(unsigned Mode) { return true; } } - } // namespace RISCVFPRndMode + +namespace RISCVSysReg { +struct SysReg { + const char *Name; + unsigned Encoding; + // FIXME: add these additional fields when needed. + // Privilege Access: Read, Write, Read-Only. + // unsigned ReadWrite; + // Privilege Mode: User, System or Machine. + // unsigned Mode; + // Check field name. + // unsigned Extra; + // Register number without the privilege bits. + // unsigned Number; + FeatureBitset FeaturesRequired; + bool isRV32Only; + + bool haveRequiredFeatures(FeatureBitset ActiveFeatures) const { + // Not in 32-bit mode. + if (isRV32Only && ActiveFeatures[RISCV::Feature64Bit]) + return false; + // No required feature associated with the system register. + if (FeaturesRequired.none()) + return true; + return (FeaturesRequired & ActiveFeatures) == FeaturesRequired; + } +}; + +#define GET_SysRegsList_DECL +#include "RISCVGenSystemOperands.inc" +} // end namespace RISCVSysReg + } // namespace llvm #endif |