llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-sparc Author: Koakuma (koachan) <details> <summary>Changes</summary> This adds named tag constants (such as `#one_write` and `#one_read`) for the prefetch instruction. --- Full diff: https://github.com/llvm/llvm-project/pull/94249.diff 11 Files Affected: - (modified) llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp (+56-1) - (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp (+11) - (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h (+2) - (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp (+5) - (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h (+11) - (modified) llvm/lib/Target/Sparc/Sparc.td (+2) - (modified) llvm/lib/Target/Sparc/SparcASITags.td (-2) - (modified) llvm/lib/Target/Sparc/SparcInstrInfo.td (+12-2) - (added) llvm/lib/Target/Sparc/SparcPrefetchTags.td (+41) - (modified) llvm/test/MC/Disassembler/Sparc/sparc-v9.txt (+2-2) - (modified) llvm/test/MC/Sparc/sparcv9-instructions.s (+14-4) ``````````diff diff --git a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp index e4f5c64f9d00e..a0dec24e3200a 100644 --- a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp +++ b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp @@ -91,6 +91,8 @@ class SparcAsmParser : public MCTargetAsmParser { ParseStatus parseASITag(OperandVector &Operands); + ParseStatus parsePrefetchTag(OperandVector &Operands); + template <TailRelocKind Kind> ParseStatus parseTailRelocSym(OperandVector &Operands); @@ -209,7 +211,8 @@ class SparcOperand : public MCParsedAsmOperand { k_Immediate, k_MemoryReg, k_MemoryImm, - k_ASITag + k_ASITag, + k_PrefetchTag, } Kind; SMLoc StartLoc, EndLoc; @@ -240,6 +243,7 @@ class SparcOperand : public MCParsedAsmOperand { struct ImmOp Imm; struct MemOp Mem; unsigned ASI; + unsigned Prefetch; }; public: @@ -253,6 +257,7 @@ class SparcOperand : public MCParsedAsmOperand { bool isMEMri() const { return Kind == k_MemoryImm; } bool isMembarTag() const { return Kind == k_Immediate; } bool isASITag() const { return Kind == k_ASITag; } + bool isPrefetchTag() const { return Kind == k_PrefetchTag; } bool isTailRelocSym() const { return Kind == k_Immediate; } bool isCallTarget() const { @@ -337,6 +342,11 @@ class SparcOperand : public MCParsedAsmOperand { return ASI; } + unsigned getPrefetchTag() const { + assert((Kind == k_PrefetchTag) && "Invalid access!"); + return Prefetch; + } + /// getStartLoc - Get the location of the first token of this operand. SMLoc getStartLoc() const override { return StartLoc; @@ -360,6 +370,9 @@ class SparcOperand : public MCParsedAsmOperand { case k_ASITag: OS << "ASI tag: " << getASITag() << "\n"; break; + case k_PrefetchTag: + OS << "Prefetch tag: " << getPrefetchTag() << "\n"; + break; } } @@ -416,6 +429,11 @@ class SparcOperand : public MCParsedAsmOperand { Inst.addOperand(MCOperand::createImm(getASITag())); } + void addPrefetchTagOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::createImm(getPrefetchTag())); + } + void addMembarTagOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); const MCExpr *Expr = getImm(); @@ -469,6 +487,15 @@ class SparcOperand : public MCParsedAsmOperand { return Op; } + static std::unique_ptr<SparcOperand> CreatePrefetchTag(unsigned Val, SMLoc S, + SMLoc E) { + auto Op = std::make_unique<SparcOperand>(k_PrefetchTag); + Op->Prefetch = Val; + Op->StartLoc = S; + Op->EndLoc = E; + return Op; + } + static bool MorphToIntPairReg(SparcOperand &Op) { unsigned Reg = Op.getReg(); assert(Op.Reg.Kind == rk_IntReg); @@ -1088,6 +1115,34 @@ ParseStatus SparcAsmParser::parseASITag(OperandVector &Operands) { return ParseStatus::Success; } +ParseStatus SparcAsmParser::parsePrefetchTag(OperandVector &Operands) { + SMLoc S = Parser.getTok().getLoc(); + SMLoc E = Parser.getTok().getEndLoc(); + int64_t PrefetchVal = 0; + + if (getLexer().getKind() == AsmToken::Hash) { + SMLoc TagStart = getLexer().peekTok(false).getLoc(); + Parser.Lex(); // Eat the '#'. + auto PrefetchName = Parser.getTok().getString(); + auto PrefetchTag = SparcPrefetchTag::lookupPrefetchTagByName(PrefetchName); + Parser.Lex(); // Eat the identifier token. + + if (!PrefetchTag) + return Error(TagStart, "unknown prefetch tag"); + + PrefetchVal = PrefetchTag->Encoding; + } else if (!getParser().parseAbsoluteExpression(PrefetchVal)) { + if (!isUInt<5>(PrefetchVal)) + return Error(S, "invalid prefetch number, must be between 0 and 31"); + } else { + return Error(S, "malformed prefetch tag, must be a constant integer " + "expression, or a named tag"); + } + + Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E)); + return ParseStatus::Success; +} + ParseStatus SparcAsmParser::parseCallTarget(OperandVector &Operands) { SMLoc S = Parser.getTok().getLoc(); SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp index ef77648504716..5b407a8b6f54a 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.cpp @@ -253,3 +253,14 @@ void SparcInstPrinter::printASITag(const MCInst *MI, int opNum, else O << Imm; } + +void SparcInstPrinter::printPrefetchTag(const MCInst *MI, int opNum, + const MCSubtargetInfo &STI, + raw_ostream &O) { + unsigned Imm = MI->getOperand(opNum).getImm(); + auto PrefetchTag = SparcPrefetchTag::lookupPrefetchTagByEncoding(Imm); + if (PrefetchTag) + O << '#' << PrefetchTag->Name; + else + O << Imm; +} diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h index cb691a3420da7..207a970228058 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h @@ -56,6 +56,8 @@ class SparcInstPrinter : public MCInstPrinter { raw_ostream &O); void printASITag(const MCInst *MI, int opNum, const MCSubtargetInfo &STI, raw_ostream &O); + void printPrefetchTag(const MCInst *MI, int opNum, const MCSubtargetInfo &STI, + raw_ostream &O); }; } // end namespace llvm diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp index fb634ccb280df..ad6ca0911adb9 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp @@ -26,6 +26,11 @@ namespace SparcASITag { #define GET_ASITagsList_IMPL #include "SparcGenSearchableTables.inc" } // end namespace SparcASITag + +namespace SparcPrefetchTag { +#define GET_PrefetchTagsList_IMPL +#include "SparcGenSearchableTables.inc" +} // end namespace SparcPrefetchTag } // end namespace llvm using namespace llvm; diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h index fd76627aa0675..a2a9f7474c3f9 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h @@ -48,6 +48,17 @@ struct ASITag { #define GET_ASITagsList_DECL #include "SparcGenSearchableTables.inc" } // end namespace SparcASITag + +// Defines symbolic names for Sparc v9 prefetch tag names. +namespace SparcPrefetchTag { +struct PrefetchTag { + const char *Name; + unsigned Encoding; +}; + +#define GET_PrefetchTagsList_DECL +#include "SparcGenSearchableTables.inc" +} // end namespace SparcPrefetchTag } // End llvm namespace // Defines symbolic names for Sparc registers. This defines a mapping from diff --git a/llvm/lib/Target/Sparc/Sparc.td b/llvm/lib/Target/Sparc/Sparc.td index 45cf985cfa062..65f372f4376b1 100644 --- a/llvm/lib/Target/Sparc/Sparc.td +++ b/llvm/lib/Target/Sparc/Sparc.td @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// include "llvm/Target/Target.td" +include "llvm/TableGen/SearchableTable.td" //===----------------------------------------------------------------------===// // SPARC Subtarget features. @@ -91,6 +92,7 @@ foreach i = 0 ... 5 in //===----------------------------------------------------------------------===// include "SparcASITags.td" +include "SparcPrefetchTags.td" include "SparcRegisterInfo.td" include "SparcCallingConv.td" include "SparcSchedule.td" diff --git a/llvm/lib/Target/Sparc/SparcASITags.td b/llvm/lib/Target/Sparc/SparcASITags.td index 115e41bfe0333..4b2d17b77ee59 100644 --- a/llvm/lib/Target/Sparc/SparcASITags.td +++ b/llvm/lib/Target/Sparc/SparcASITags.td @@ -11,8 +11,6 @@ // //===----------------------------------------------------------------------===// -include "llvm/TableGen/SearchableTable.td" - class ASITag<string name, string alt_name, bits<8> op> { string Name = name; // A maximum of one alias is supported right now. diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td index 4d68f93efeac1..f1778f2162f8c 100644 --- a/llvm/lib/Target/Sparc/SparcInstrInfo.td +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td @@ -197,6 +197,16 @@ def ASITag : Operand<i32> { let ParserMatchClass = SparcASITagAsmOperand; } +def SparcPrefetchTagAsmOperand : AsmOperandClass { + let Name = "PrefetchTag"; + let ParserMethod = "parsePrefetchTag"; +} + +def PrefetchTag : Operand<i32> { + let PrintMethod = "printPrefetchTag"; + let ParserMatchClass = SparcPrefetchTagAsmOperand; +} + // Branch targets have OtherVT type. def brtarget : Operand<OtherVT> { let EncoderMethod = "getBranchTargetOpValue"; @@ -1767,10 +1777,10 @@ let Predicates = [HasV9], rs1 = 0, rs2 = 0 in { // Section A.42 - Prefetch Data let Predicates = [HasV9] in { def PREFETCHr : F3_1<3, 0b101101, - (outs), (ins (MEMrr $rs1, $rs2):$addr, shift_imm5:$rd), + (outs), (ins (MEMrr $rs1, $rs2):$addr, PrefetchTag:$rd), "prefetch [$addr], $rd", []>; def PREFETCHi : F3_2<3, 0b101101, - (outs), (ins (MEMri $rs1, $simm13):$addr, shift_imm5:$rd), + (outs), (ins (MEMri $rs1, $simm13):$addr, PrefetchTag:$rd), "prefetch [$addr], $rd", []>; } diff --git a/llvm/lib/Target/Sparc/SparcPrefetchTags.td b/llvm/lib/Target/Sparc/SparcPrefetchTags.td new file mode 100644 index 0000000000000..0104f47472b00 --- /dev/null +++ b/llvm/lib/Target/Sparc/SparcPrefetchTags.td @@ -0,0 +1,41 @@ +//===- SparcPrefetchTags.td --------------------------------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the symbolic operands permitted for various kinds of +// SPARCv9 prefetches. +// +//===----------------------------------------------------------------------===// + +class PrefetchTag<string name, bits<8> op> { + string Name = name; + bits<8> Encoding = op; +} + +def PrefetchTagsList : GenericTable { + let FilterClass = "PrefetchTag"; + let Fields = ["Name", "Encoding"]; + + let PrimaryKey = [ "Encoding" ]; + let PrimaryKeyName = "lookupPrefetchTagByEncoding"; +} + +def lookupPrefetchTagByName : SearchIndex { + let Table = PrefetchTagsList; + let Key = [ "Name" ]; +} + +def : PrefetchTag<"n_reads", 0x0>; +def : PrefetchTag<"one_read", 0x1>; +def : PrefetchTag<"n_writes", 0x2>; +def : PrefetchTag<"one_write", 0x3>; +def : PrefetchTag<"page", 0x4>; +def : PrefetchTag<"unified", 0x11>; +def : PrefetchTag<"n_reads_strong", 0x14>; +def : PrefetchTag<"one_read_strong", 0x15>; +def : PrefetchTag<"n_writes_strong", 0x16>; +def : PrefetchTag<"one_write_strong", 0x17>; diff --git a/llvm/test/MC/Disassembler/Sparc/sparc-v9.txt b/llvm/test/MC/Disassembler/Sparc/sparc-v9.txt index da278e1832767..49b6e339435f1 100644 --- a/llvm/test/MC/Disassembler/Sparc/sparc-v9.txt +++ b/llvm/test/MC/Disassembler/Sparc/sparc-v9.txt @@ -132,10 +132,10 @@ # CHECK: membar #LoadLoad | #StoreLoad | #LoadStore | #StoreStore | #Lookaside | #MemIssue | #Sync 0x81 0x43 0xe0 0x7f -# CHECK: prefetch [%i1+3968], 1 +# CHECK: prefetch [%i1+3968], #one_read 0xc3,0x6e,0x6f,0x80 -# CHECK: prefetch [%i1+%i2], 1 +# CHECK: prefetch [%i1+%i2], #one_read 0xc3,0x6e,0x40,0x1a # CHECK: done diff --git a/llvm/test/MC/Sparc/sparcv9-instructions.s b/llvm/test/MC/Sparc/sparcv9-instructions.s index d461c82467471..f0348eb70f1c5 100644 --- a/llvm/test/MC/Sparc/sparcv9-instructions.s +++ b/llvm/test/MC/Sparc/sparcv9-instructions.s @@ -537,16 +537,26 @@ ! V9: stxa %g0, [%g2+%i5] #ASI_SNF ! encoding: [0xc0,0xf0,0x90,0x7d] stxa %g0, [%g2 + %i5] #ASI_SNF - ! V8: error: instruction requires a CPU feature not currently enabled + ! V8: error: invalid operand for instruction ! V8-NEXT: prefetch [ %i1 + 0xf80 ], 1 - ! V9: prefetch [%i1+3968], 1 ! encoding: [0xc3,0x6e,0x6f,0x80] + ! V9: prefetch [%i1+3968], #one_read ! encoding: [0xc3,0x6e,0x6f,0x80] prefetch [ %i1 + 0xf80 ], 1 - ! V8: error: instruction requires a CPU feature not currently enabled + ! V8: error: unexpected token + ! V8-NEXT: prefetch [ %i1 + 0xf80 ], #one_read + ! V9: prefetch [%i1+3968], #one_read ! encoding: [0xc3,0x6e,0x6f,0x80] + prefetch [ %i1 + 0xf80 ], #one_read + + ! V8: error: invalid operand for instruction ! V8-NEXT: prefetch [ %i1 + %i2 ], 1 - ! V9: prefetch [%i1+%i2], 1 ! encoding: [0xc3,0x6e,0x40,0x1a] + ! V9: prefetch [%i1+%i2], #one_read ! encoding: [0xc3,0x6e,0x40,0x1a] prefetch [ %i1 + %i2 ], 1 + ! V8: error: unexpected token + ! V8-NEXT: prefetch [ %i1 + %i2 ], #one_read + ! V9: prefetch [%i1+%i2], #one_read ! encoding: [0xc3,0x6e,0x40,0x1a] + prefetch [ %i1 + %i2 ], #one_read + ! V8: error: instruction requires a CPU feature not currently enabled ! V8-NEXT: done ! V9: done ! encoding: [0x81,0xf0,0x00,0x00] `````````` </details> https://github.com/llvm/llvm-project/pull/94249 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits