brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.0 KiB · 75e3d8c Raw
182 lines · cpp
1//===- AMDGPUMIRFormatter.cpp ---------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9/// \file10/// Implementation of AMDGPU overrides of MIRFormatter.11//12//===----------------------------------------------------------------------===//13 14#include "AMDGPUMIRFormatter.h"15#include "SIMachineFunctionInfo.h"16 17using namespace llvm;18 19void AMDGPUMIRFormatter::printImm(raw_ostream &OS, const MachineInstr &MI,20                      std::optional<unsigned int> OpIdx, int64_t Imm) const {21 22  switch (MI.getOpcode()) {23  case AMDGPU::S_DELAY_ALU:24    assert(OpIdx == 0);25    printSDelayAluImm(Imm, OS);26    break;27  default:28    MIRFormatter::printImm(OS, MI, OpIdx, Imm);29    break;30  }31}32 33/// Implement target specific parsing of immediate mnemonics. The mnemonic is34/// a string with a leading dot.35bool AMDGPUMIRFormatter::parseImmMnemonic(const unsigned OpCode,36                              const unsigned OpIdx,37                              StringRef Src, int64_t &Imm,38                              ErrorCallbackType ErrorCallback) const39{40 41  switch (OpCode) {42  case AMDGPU::S_DELAY_ALU:43    return parseSDelayAluImmMnemonic(OpIdx, Imm, Src, ErrorCallback);44  default:45    break;46  }47  return true; // Don't know what this is48}49 50void AMDGPUMIRFormatter::printSDelayAluImm(int64_t Imm,51                                           llvm::raw_ostream &OS) const {52  // Construct an immediate string to represent the information encoded in the53  // s_delay_alu immediate.54  // .id0_<dep>[_skip_<count>_id1<dep>]55  constexpr int64_t None = 0;56  constexpr int64_t Same = 0;57 58  uint64_t Id0 = (Imm & 0xF);59  uint64_t Skip = ((Imm >> 4) & 0x7);60  uint64_t Id1 = ((Imm >> 7) & 0xF);61  auto Outdep = [&](uint64_t Id) {62    if (Id == None)63      OS << "NONE";64    else if (Id < 5)65      OS << "VALU_DEP_" << Id;66    else if (Id < 8)67      OS << "TRANS32_DEP_" << Id - 4;68    else69      OS << "SALU_CYCLE_" << Id - 8;70  };71 72  OS << ".id0_";73  Outdep(Id0);74 75  // If the second inst is "same" and "none", no need to print the rest of the76  // string.77  if (Skip == Same && Id1 == None)78    return;79 80  // Encode the second delay specification.81  OS << "_skip_";82  if (Skip == 0)83    OS << "SAME";84  else if (Skip == 1)85    OS << "NEXT";86  else87    OS << "SKIP_" << Skip - 1;88 89  OS << "_id1_";90  Outdep(Id1);91}92 93bool AMDGPUMIRFormatter::parseSDelayAluImmMnemonic(94    const unsigned int OpIdx, int64_t &Imm, llvm::StringRef &Src,95    llvm::MIRFormatter::ErrorCallbackType &ErrorCallback) const96{97  assert(OpIdx == 0);98 99  Imm = 0;100  bool Expected = Src.consume_front(".id0_");101  if (!Expected)102    return ErrorCallback(Src.begin(), "Expected .id0_");103 104  auto ExpectInt = [&](StringRef &Src, int64_t Offset) -> int64_t {105    int64_t Dep;106    if (!Src.consumeInteger(10, Dep))107      return Dep + Offset;108 109    return -1;110  };111 112  auto DecodeDelay = [&](StringRef &Src) -> int64_t {113    if (Src.consume_front("NONE"))114      return 0;115    if (Src.consume_front("VALU_DEP_"))116      return ExpectInt(Src, 0);117    if (Src.consume_front("TRANS32_DEP_"))118      return ExpectInt(Src, 4);119    if (Src.consume_front("SALU_CYCLE_"))120      return ExpectInt(Src, 8);121 122    return -1;123  };124 125  int64_t Delay0 = DecodeDelay(Src);126  int64_t Skip = 0;127  int64_t Delay1 = 0;128  if (Delay0 == -1)129    return ErrorCallback(Src.begin(), "Could not decode delay0");130 131 132  // Set the Imm so far, to that early return has the correct value.133  Imm = Delay0;134 135  // If that was the end of the string, the second instruction is "same" and136  // "none"137  if (Src.begin() == Src.end())138    return false;139 140  Expected = Src.consume_front("_skip_");141  if (!Expected)142    return ErrorCallback(Src.begin(), "Expected _skip_");143 144 145  if (Src.consume_front("SAME")) {146    Skip = 0;147  } else if (Src.consume_front("NEXT")) {148    Skip = 1;149  } else if (Src.consume_front("SKIP_")) {150    if (Src.consumeInteger(10, Skip)) {151      return ErrorCallback(Src.begin(), "Expected integer Skip value");152    }153    Skip += 1;154  } else {155    ErrorCallback(Src.begin(), "Unexpected Skip Value");156  }157 158  Expected = Src.consume_front("_id1_");159  if (!Expected)160    return ErrorCallback(Src.begin(), "Expected _id1_");161 162  Delay1 = DecodeDelay(Src);163  if (Delay1 == -1)164    return ErrorCallback(Src.begin(), "Could not decode delay1");165 166  Imm = Imm | (Skip << 4) | (Delay1 << 7);167  return false;168}169 170bool AMDGPUMIRFormatter::parseCustomPseudoSourceValue(171    StringRef Src, MachineFunction &MF, PerFunctionMIParsingState &PFS,172    const PseudoSourceValue *&PSV, ErrorCallbackType ErrorCallback) const {173  SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();174  const AMDGPUTargetMachine &TM =175      static_cast<const AMDGPUTargetMachine &>(MF.getTarget());176  if (Src == "GWSResource") {177    PSV = MFI->getGWSPSV(TM);178    return false;179  }180  llvm_unreachable("unknown MIR custom pseudo source value");181}182