[llvm-branch-commits] [SPARC][IAS] Add named prefetch tag constants (PR #94249)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Jun 3 09:29:41 PDT 2024


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


More information about the llvm-branch-commits mailing list