27#define DEBUG_TYPE "asm-printer"
30#include "SPIRVGenAsmWriter.inc"
36 bool SkipImmediates) {
37 const unsigned NumOps =
MI->getNumOperands();
38 for (
unsigned i = StartIndex; i <
NumOps; ++i) {
39 if (!SkipImmediates || !
MI->getOperand(i).isImm()) {
40 if (!SkipFirstSpace || i != StartIndex)
51 const unsigned NumVarOps =
MI->getNumOperands() - StartIndex;
53 if (
MI->getOpcode() == SPIRV::OpConstantI && NumVarOps > 2) {
56 for (
unsigned I = StartIndex;
I !=
MI->getNumOperands(); ++
I)
57 O <<
' ' <<
MI->getOperand(
I).getImm();
61 assert((NumVarOps == 1 || NumVarOps == 2) &&
62 "Unsupported number of bits for literal variable");
66 uint64_t Imm =
MI->getOperand(StartIndex).getImm();
70 Imm |= (
MI->getOperand(StartIndex + 1).
getImm() << 32);
74 if (
MI->getOpcode() == SPIRV::OpConstantF && IsBitwidth16 == 0) {
81 if (
FP.isInfinity()) {
94 O <<
format(
"%.*g", std::numeric_limits<double>::max_digits10,
95 FP.convertToDouble());
104void SPIRVInstPrinter::recordOpExtInstImport(
const MCInst *
MI) {
108 ExtInstSetIDs.insert({Reg, Set});
114 const unsigned OpCode =
MI->getOpcode();
117 if (OpCode == SPIRV::OpDecorate) {
119 }
else if (OpCode == SPIRV::OpExtInstImport) {
120 recordOpExtInstImport(
MI);
121 }
else if (OpCode == SPIRV::OpExtInst) {
123 }
else if (OpCode == SPIRV::UNKNOWN_type) {
130 const unsigned LastFixedIndex = NumFixedOps - 1;
131 const int FirstVariableIndex = NumFixedOps;
132 if (NumFixedOps > 0 && MCDesc.
operands()[LastFixedIndex].OperandType ==
138 case SPIRV::OpTypeImage:
141 MI, FirstVariableIndex, OS);
143 case SPIRV::OpVariable:
147 case SPIRV::OpEntryPoint: {
153 case SPIRV::OpMemberDecorate:
156 case SPIRV::OpExecutionMode:
157 case SPIRV::OpExecutionModeId:
158 case SPIRV::OpLoopMerge: {
175 MI, FirstVariableIndex, OS);
178 case SPIRV::OpSwitch:
183 const unsigned NumOps =
MI->getNumOperands();
186 !
MI->getOperand(
OpIdx + 1).isImm()) {
193 uint64_t CombinedValue = (HighBits << 32) | LowBits;
208 case SPIRV::OpImageSampleImplicitLod:
209 case SPIRV::OpImageSampleDrefImplicitLod:
210 case SPIRV::OpImageSampleProjImplicitLod:
211 case SPIRV::OpImageSampleProjDrefImplicitLod:
212 case SPIRV::OpImageFetch:
213 case SPIRV::OpImageGather:
214 case SPIRV::OpImageDrefGather:
215 case SPIRV::OpImageRead:
216 case SPIRV::OpImageWrite:
217 case SPIRV::OpImageSparseSampleImplicitLod:
218 case SPIRV::OpImageSparseSampleDrefImplicitLod:
219 case SPIRV::OpImageSparseSampleProjImplicitLod:
220 case SPIRV::OpImageSparseSampleProjDrefImplicitLod:
221 case SPIRV::OpImageSparseFetch:
222 case SPIRV::OpImageSparseGather:
223 case SPIRV::OpImageSparseDrefGather:
224 case SPIRV::OpImageSparseRead:
225 case SPIRV::OpImageSampleFootprintNV:
228 MI, FirstVariableIndex, OS);
231 case SPIRV::OpCopyMemory:
232 case SPIRV::OpCopyMemorySized: {
233 const unsigned NumOps =
MI->getNumOperands();
234 for (
unsigned i = NumFixedOps; i <
NumOps; ++i) {
238 if (
MI->getOperand(i).getImm() & MemoryOperand::Aligned) {
247 case SPIRV::OpConstantI:
248 case SPIRV::OpConstantF:
251 assert(NumFixedOps > 0 &&
"Expected at least one fixed operand");
254 case SPIRV::OpCooperativeMatrixMulAddKHR: {
255 const unsigned NumOps =
MI->getNumOperands();
256 if (NumFixedOps ==
NumOps)
260 const unsigned MulAddOp =
MI->getOperand(FirstVariableIndex).getImm();
263 OperandCategory::CooperativeMatrixOperandsOperand>(
264 MI, FirstVariableIndex, OS);
267 for (
unsigned Mask = 0x1;
268 Mask != SPIRV::CooperativeMatrixOperands::
269 MatrixResultBFloat16ComponentsINTEL;
271 if (MulAddOp & Mask) {
275 OperandCategory::CooperativeMatrixOperandsOperand, Mask);
282 case SPIRV::OpSubgroupMatrixMultiplyAccumulateINTEL: {
283 const unsigned NumOps =
MI->getNumOperands();
284 if (NumFixedOps >=
NumOps)
287 const unsigned Flags =
MI->getOperand(
NumOps - 1).getImm();
290 OperandCategory::MatrixMultiplyAccumulateOperandsOperand>(
294 for (
unsigned Mask = 0x1;
295 Mask <= SPIRV::MatrixMultiplyAccumulateOperands::
296 MatrixBPackedBFloat16INTEL;
302 OperandCategory::MatrixMultiplyAccumulateOperandsOperand,
313 case SPIRV::OpSDotAccSat:
314 case SPIRV::OpUDotAccSat:
315 case SPIRV::OpSUDotAccSat: {
316 const unsigned NumOps =
MI->getNumOperands();
317 if (
NumOps > NumFixedOps) {
325 case SPIRV::OpPredicatedLoadINTEL:
326 case SPIRV::OpPredicatedStoreINTEL: {
327 const unsigned NumOps =
MI->getNumOperands();
328 if (
NumOps > NumFixedOps) {
352 const auto NumOps =
MI->getNumOperands();
353 if (
NumOps == NumFixedOps)
368 if (NumFixedOps !=
MI->getNumOperands()) {
369 auto DecOp =
MI->getOperand(NumFixedOps - 1);
370 auto Dec =
static_cast<Decoration::Decoration
>(DecOp.getImm());
375 case Decoration::BuiltIn:
378 case Decoration::UniformId:
381 case Decoration::FuncParamAttr:
385 case Decoration::FPRoundingMode:
389 case Decoration::FPFastMathMode:
393 case Decoration::LinkageAttributes:
394 case Decoration::UserSemantic:
397 case Decoration::HostAccessINTEL:
399 if (NumFixedOps + 1 <
MI->getNumOperands()) {
412 const auto EnumOperand =
MI->getOperand(1);
413 assert(EnumOperand.isImm() &&
414 "second operand of UNKNOWN_type must be opcode!");
416 const auto Enumerant = EnumOperand.getImm();
417 const auto NumOps =
MI->getNumOperands();
420 O <<
"OpUnknown(" << Enumerant <<
", " <<
NumOps <<
") ";
429 if (
NumOps == NumFixedOps)
438 if (OpNo < MI->getNumOperands()) {
442 else if (
Op.isImm()) {
443 int64_t Imm =
Op.getImm();
448 if (
MI->getOpcode() == SPIRV::OpVectorShuffle && Imm == -1)
452 }
else if (
Op.isDFPImm())
454 else if (
Op.isExpr())
455 MAI.printExpr(O, *
Op.getExpr());
463 const unsigned NumOps =
MI->getNumOperands();
464 unsigned StrStartIndex = OpNo;
465 while (StrStartIndex <
NumOps) {
466 if (
MI->getOperand(StrStartIndex).isReg())
470 if (StrStartIndex != OpNo)
485 unsigned numOpsInString = (Str.size() / 4) + 1;
486 StrStartIndex += numOpsInString;
489 if (
MI->getOpcode() == SPIRV::OpDecorate &&
490 MI->getOperand(1).getImm() ==
491 static_cast<unsigned>(Decoration::LinkageAttributes)) {
494 MI, StrStartIndex, O);
502 auto SetReg =
MI->getOperand(2).getReg();
503 auto Set = ExtInstSetIDs[SetReg];
504 auto Op =
MI->getOperand(OpNo).getImm();
508template <OperandCategory::OperandCategory category>
511 if (OpNo < MI->getNumOperands()) {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares a class to represent arbitrary precision floating point values and provide a varie...
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
MachineInstr unsigned OpIdx
Class for arbitrary precision integers.
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.
Instances of this class represent operands of the MCInst class.
Wrapper class representing physical registers. Should be passed by value.
Generic base class for all target subtargets.
void printExtension(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printStringImm(const MCInst *MI, unsigned OpNo, raw_ostream &O)
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 printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
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)
void printUnknownType(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.
unsigned getIDFromRegister(unsigned Reg)
This is an optimization pass for GlobalISel generic memory operations.
std::string getExtInstName(SPIRV::InstructionSet::InstructionSet Set, uint32_t InstructionNumber)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
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)
DWARFExpression::Operation Op