31#define DEBUG_TYPE "asm-printer"
34#include "SPIRVGenAsmWriter.inc"
40 bool SkipImmediates) {
41 const unsigned NumOps =
MI->getNumOperands();
42 for (
unsigned i = StartIndex; i < NumOps; ++i) {
43 if (!SkipImmediates || !
MI->getOperand(i).isImm()) {
44 if (!SkipFirstSpace || i != StartIndex)
55 const unsigned NumVarOps =
MI->getNumOperands() - StartIndex;
57 assert((NumVarOps == 1 || NumVarOps == 2) &&
58 "Unsupported number of bits for literal variable");
62 uint64_t Imm =
MI->getOperand(StartIndex).getImm();
66 Imm |= (
MI->getOperand(StartIndex + 1).getImm() << 32);
70 if (
MI->getOpcode() == SPIRV::OpConstantF && IsBitwidth16 == 0) {
77 if (
FP.isInfinity()) {
90 O <<
format(
"%.*g", std::numeric_limits<double>::max_digits10,
91 FP.convertToDouble());
100void SPIRVInstPrinter::recordOpExtInstImport(
const MCInst *
MI) {
104 ExtInstSetIDs.
insert({Reg, Set});
110 const unsigned OpCode =
MI->getOpcode();
113 if (OpCode == SPIRV::OpDecorate) {
115 }
else if (OpCode == SPIRV::OpExtInstImport) {
116 recordOpExtInstImport(
MI);
117 }
else if (OpCode == SPIRV::OpExtInst) {
124 const unsigned LastFixedIndex = NumFixedOps - 1;
125 const int FirstVariableIndex = NumFixedOps;
126 if (NumFixedOps > 0 && MCDesc.
operands()[LastFixedIndex].OperandType ==
132 case SPIRV::OpTypeImage:
134 printSymbolicOperand<OperandCategory::AccessQualifierOperand>(
135 MI, FirstVariableIndex,
OS);
137 case SPIRV::OpVariable:
141 case SPIRV::OpEntryPoint: {
147 case SPIRV::OpExecutionMode:
148 case SPIRV::OpExecutionModeId:
149 case SPIRV::OpLoopMerge: {
165 printSymbolicOperand<OperandCategory::MemoryOperandOperand>(
166 MI, FirstVariableIndex,
OS);
169 case SPIRV::OpImageSampleImplicitLod:
170 case SPIRV::OpImageSampleDrefImplicitLod:
171 case SPIRV::OpImageSampleProjImplicitLod:
172 case SPIRV::OpImageSampleProjDrefImplicitLod:
173 case SPIRV::OpImageFetch:
174 case SPIRV::OpImageGather:
175 case SPIRV::OpImageDrefGather:
176 case SPIRV::OpImageRead:
177 case SPIRV::OpImageWrite:
178 case SPIRV::OpImageSparseSampleImplicitLod:
179 case SPIRV::OpImageSparseSampleDrefImplicitLod:
180 case SPIRV::OpImageSparseSampleProjImplicitLod:
181 case SPIRV::OpImageSparseSampleProjDrefImplicitLod:
182 case SPIRV::OpImageSparseFetch:
183 case SPIRV::OpImageSparseGather:
184 case SPIRV::OpImageSparseDrefGather:
185 case SPIRV::OpImageSparseRead:
186 case SPIRV::OpImageSampleFootprintNV:
188 printSymbolicOperand<OperandCategory::ImageOperandOperand>(
189 MI, FirstVariableIndex,
OS);
192 case SPIRV::OpCopyMemory:
193 case SPIRV::OpCopyMemorySized: {
194 const unsigned NumOps =
MI->getNumOperands();
195 for (
unsigned i = NumFixedOps; i < NumOps; ++i) {
197 printSymbolicOperand<OperandCategory::MemoryOperandOperand>(
MI, i,
199 if (
MI->getOperand(i).getImm() & MemoryOperand::Aligned) {
200 assert(i + 1 < NumOps &&
"Missing alignment operand");
208 case SPIRV::OpConstantI:
209 case SPIRV::OpConstantF:
214 case SPIRV::OpCooperativeMatrixMulAddKHR: {
215 const unsigned NumOps =
MI->getNumOperands();
216 if (NumFixedOps == NumOps)
220 const unsigned MulAddOp =
MI->getOperand(FirstVariableIndex).getImm();
223 OperandCategory::CooperativeMatrixOperandsOperand>(
224 MI, FirstVariableIndex,
OS);
227 for (
unsigned Mask = 0x1;
228 Mask != SPIRV::CooperativeMatrixOperands::
229 MatrixResultBFloat16ComponentsINTEL;
231 if (MulAddOp & Mask) {
235 OperandCategory::CooperativeMatrixOperandsOperand, Mask);
258 const auto NumOps =
MI->getNumOperands();
259 if (NumOps == NumFixedOps)
274 if (NumFixedOps !=
MI->getNumOperands()) {
275 auto DecOp =
MI->getOperand(NumFixedOps - 1);
276 auto Dec =
static_cast<Decoration::Decoration
>(DecOp.getImm());
281 case Decoration::BuiltIn:
282 printSymbolicOperand<OperandCategory::BuiltInOperand>(
MI, NumFixedOps, O);
284 case Decoration::UniformId:
285 printSymbolicOperand<OperandCategory::ScopeOperand>(
MI, NumFixedOps, O);
287 case Decoration::FuncParamAttr:
288 printSymbolicOperand<OperandCategory::FunctionParameterAttributeOperand>(
291 case Decoration::FPRoundingMode:
292 printSymbolicOperand<OperandCategory::FPRoundingModeOperand>(
295 case Decoration::FPFastMathMode:
296 printSymbolicOperand<OperandCategory::FPFastMathModeOperand>(
299 case Decoration::LinkageAttributes:
300 case Decoration::UserSemantic:
303 case Decoration::HostAccessINTEL:
305 if (NumFixedOps + 1 <
MI->getNumOperands()) {
321 if (
const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr))
322 SRE = cast<MCSymbolRefExpr>(BE->getLHS());
324 SRE = cast<MCSymbolRefExpr>(Expr);
335 assert((Modifier == 0 || Modifier[0] == 0) &&
"No modifiers supported");
336 if (OpNo < MI->getNumOperands()) {
342 else if (
Op.isDFPImm())
344 else if (
Op.isExpr())
353 const unsigned NumOps =
MI->getNumOperands();
354 unsigned StrStartIndex = OpNo;
355 while (StrStartIndex < NumOps) {
356 if (
MI->getOperand(StrStartIndex).isReg())
360 if (StrStartIndex != OpNo)
375 unsigned numOpsInString = (Str.size() / 4) + 1;
376 StrStartIndex += numOpsInString;
379 if (
MI->getOpcode() == SPIRV::OpDecorate &&
380 MI->getOperand(1).getImm() ==
381 static_cast<unsigned>(Decoration::LinkageAttributes)) {
383 printSymbolicOperand<OperandCategory::LinkageTypeOperand>(
384 MI, StrStartIndex, O);
392 auto SetReg =
MI->getOperand(2).getReg();
393 auto Set = ExtInstSetIDs[SetReg];
394 auto Op =
MI->getOperand(OpNo).getImm();
398template <OperandCategory::OperandCategory category>
401 if (OpNo < MI->getNumOperands()) {
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static void printExpr(const MCExpr *Expr, const MCAsmInfo *MAI, raw_ostream &OS)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
This class represents an Operation in the Expression.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Binary assembler expressions.
Base class for the full range of assembler expressions which are needed for parsing.
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
format_object< int64_t > formatImm(int64_t Value) const
Utility function to print immediates in decimal or hex.
Instances of this class represent a single low-level machine instruction.
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
bool isVariadic() const
Return true if this instruction can have a variable number of operands.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Instances of this class represent operands of the MCInst class.
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
VariantKind getKind() const
Wrapper class representing virtual and physical registers.
static unsigned virtReg2Index(Register Reg)
Convert a virtual register number to a 0-based index.
void printExtension(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printStringImm(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O, const char *Modifier=nullptr)
void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O)
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &OS) override
Print the specified MCInst to the specified raw_ostream.
void printOpExtInst(const MCInst *MI, raw_ostream &O)
void printOpConstantVarOps(const MCInst *MI, unsigned StartIndex, raw_ostream &O)
void printSymbolicOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printRemainingVariableOps(const MCInst *MI, unsigned StartIndex, raw_ostream &O, bool SkipFirstSpace=false, bool SkipImmediates=false)
void printOpDecorate(const MCInst *MI, raw_ostream &O)
StringRef - Represent a constant reference to a string, i.e.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
std::string getExtInstName(SPIRV::InstructionSet::InstructionSet Set, uint32_t InstructionNumber)
std::string getSPIRVStringOperand(const InstType &MI, unsigned StartIndex)
SPIRV::InstructionSet::InstructionSet getExtInstSetFromString(std::string SetName)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
std::string getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category, int32_t Value)