[llvm] [AMDGPU] Introduce a pseudo mnemonic for S_DELAY_ALU in MIR. (PR #96004)

Jay Foad via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 20 01:35:34 PDT 2024


================
@@ -17,6 +17,157 @@
 
 using namespace llvm;
 
+void AMDGPUMIRFormatter::printImm(raw_ostream &OS, const MachineInstr &MI,
+                      std::optional<unsigned int> OpIdx, int64_t Imm) const {
+
+  switch(MI.getOpcode()) {
+  case AMDGPU::S_DELAY_ALU:
+    assert(OpIdx == 0);
+    printSDelayAluImm(Imm, OS);
+    break;
+  default:
+    MIRFormatter::printImm(OS, MI, OpIdx, Imm);
+    break;
+  }
+}
+
+/// Implement target specific parsing of immediate mnemonics. The mnemonic is
+/// dot seperated strings.
+bool AMDGPUMIRFormatter::parseImmMnemonic(const unsigned OpCode,
+                              const unsigned OpIdx,
+                              StringRef Src, int64_t &Imm,
+                              ErrorCallbackType ErrorCallback) const
+{
+
+  switch(OpCode) {
+  case AMDGPU::S_DELAY_ALU:
+    return parseSDelayAluImmMnemonic(OpIdx, Imm, Src, ErrorCallback);
+  default:
+    break;
+  }
+  return true; // Don't know what this is
+}
+
+void AMDGPUMIRFormatter::printSDelayAluImm(int64_t Imm,
+                                           llvm::raw_ostream &OS) const {
+  // Construct an immediate string to represent the information encoded in the
+  // s_delay_alu immediate.
+  // .id0_<dep>[_skip_<count>_id1<dep>]
+  constexpr int64_t None = 0;
+  constexpr int64_t Same = 0;
+
+  uint64_t Id0 = (Imm & 0xF);
+  uint64_t Skip = ((Imm >> 4) & 0x7);
+  uint64_t Id1 = ((Imm >> 7) & 0xF);
+  auto Outdep = [&](uint64_t Id) {
+    if (Id == None)
+      OS << "NONE";
+    else if (Id < 5)
+      OS << "VALU_DEP_" << Id;
+    else if (Id < 8)
+      OS << "TRANS32_DEP_" << Id - 4;
+    else
+      OS << "SALU_CYCLE_" << Id - 8;
+  };
+
+  OS << ".id0_";
+  Outdep(Id0);
+
+  // If the second inst is "same" and "none", no need to print the rest of the
+  // string.
+  if (Skip == Same && Id1 == None)
+    return;
+
+  // Encode the second delay specification.
+  OS << "_skip_";
+  if (Skip == 0)
+    OS << "SAME";
+  else if (Skip == 1)
+    OS << "NEXT";
+  else
+    OS << "SKIP_" << Skip - 1;
+
+  OS << "_id1_";
+  Outdep(Id1);
+}
+
+bool AMDGPUMIRFormatter::parseSDelayAluImmMnemonic(
+    const unsigned int OpIdx, int64_t &Imm, llvm::StringRef &Src,
+    llvm::MIRFormatter::ErrorCallbackType &ErrorCallback) const
+{
+  assert(OpIdx == 0);
+
+  Imm = 0;
+  bool Expected = Src.consume_front(".id0_");
+  if (!Expected)
+    return ErrorCallback(Src.begin(), "Expected .id0_");
+
+  auto ExpectInt = [&](StringRef &Src, int64_t Offset) -> int64_t {
+    int64_t Dep;
+    if (!Src.consumeInteger(10, Dep))
+      return Dep + Offset;
+    else
+      return -1;
+  };
+
+  auto DecodeDelay = [&](StringRef &Src) -> int64_t {
+    if (Src.consume_front("NONE"))
+      return 0;
+    else if (Src.consume_front("VALU_DEP_"))
----------------
jayfoad wrote:

Don't use "else" after "return".

https://github.com/llvm/llvm-project/pull/96004


More information about the llvm-commits mailing list