LLVM: lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
23
24using namespace llvm;
26
27#define DEBUG_TYPE "asm-printer"
28
29
30#include "SPIRVGenAsmWriter.inc"
31
33 unsigned StartIndex,
35 bool SkipFirstSpace,
36 bool SkipImmediates) {
37 const unsigned NumOps = MI->getNumOperands();
38 for (unsigned i = StartIndex; i < NumOps; ++i) {
39 if (!SkipImmediates || ->getOperand(i).isImm()) {
40 if (!SkipFirstSpace || i != StartIndex)
41 O << ' ';
43 }
44 }
45}
46
48 unsigned StartIndex,
51 const unsigned NumVarOps = MI->getNumOperands() - StartIndex;
52
53 assert((NumVarOps == 1 || NumVarOps == 2) &&
54 "Unsupported number of bits for literal variable");
55
56 O << ' ';
57
58 uint64_t Imm = MI->getOperand(StartIndex).getImm();
59
60
61 if (NumVarOps == 2) {
62 Imm |= (MI->getOperand(StartIndex + 1).getImm() << 32);
63 }
64
65
66 if (MI->getOpcode() == SPIRV::OpConstantF && IsBitwidth16 == 0) {
69
70
71
72
73 if (FP.isInfinity()) {
74 if (FP.isNegative())
75 O << '-';
76 O << "0x1p+128";
77 return;
78 }
79 if (FP.isNaN()) {
80 O << "0x1.8p+128";
81 return;
82 }
83
84
85
86 O << format("%.*g", std::numeric_limits::max_digits10,
87 FP.convertToDouble());
88
89 return;
90 }
91
92
93 O << Imm;
94}
95
96void SPIRVInstPrinter::recordOpExtInstImport(const MCInst *MI) {
100 ExtInstSetIDs.insert({Reg, Set});
101}
102
106 const unsigned OpCode = MI->getOpcode();
108
109 if (OpCode == SPIRV::OpDecorate) {
111 } else if (OpCode == SPIRV::OpExtInstImport) {
112 recordOpExtInstImport(MI);
113 } else if (OpCode == SPIRV::OpExtInst) {
115 } else if (OpCode == SPIRV::UNKNOWN_type) {
117 } else {
118
121 const unsigned NumFixedOps = MCDesc.getNumOperands();
122 const unsigned LastFixedIndex = NumFixedOps - 1;
123 const int FirstVariableIndex = NumFixedOps;
124 if (NumFixedOps > 0 && MCDesc.operands()[LastFixedIndex].OperandType ==
126
127
128
129 switch (OpCode) {
130 case SPIRV::OpTypeImage:
131 OS << ' ';
133 MI, FirstVariableIndex, OS);
134 break;
135 case SPIRV::OpVariable:
136 OS << ' ';
138 break;
139 case SPIRV::OpEntryPoint: {
140
141
143 break;
144 }
145 case SPIRV::OpMemberDecorate:
147 break;
148 case SPIRV::OpExecutionMode:
149 case SPIRV::OpExecutionModeId:
150 case SPIRV::OpLoopMerge: {
151
153 break;
154 }
155 default:
156 break;
157 }
158 } else {
159
160
161
162 switch (OpCode) {
163 case SPIRV::OpLoad:
164 case SPIRV::OpStore:
165 OS << ' ';
167 MI, FirstVariableIndex, OS);
169 break;
170 case SPIRV::OpSwitch:
172
173
174
175 const unsigned NumOps = MI->getNumOperands();
178 ->getOperand(OpIdx + 1).isImm()) {
180 continue;
181 }
182 OS << ' ';
185 uint64_t CombinedValue = (HighBits << 32) | LowBits;
188
189
191 OS << ' ';
194 }
195 }
196 } else {
198 }
199 break;
200 case SPIRV::OpImageSampleImplicitLod:
201 case SPIRV::OpImageSampleDrefImplicitLod:
202 case SPIRV::OpImageSampleProjImplicitLod:
203 case SPIRV::OpImageSampleProjDrefImplicitLod:
204 case SPIRV::OpImageFetch:
205 case SPIRV::OpImageGather:
206 case SPIRV::OpImageDrefGather:
207 case SPIRV::OpImageRead:
208 case SPIRV::OpImageWrite:
209 case SPIRV::OpImageSparseSampleImplicitLod:
210 case SPIRV::OpImageSparseSampleDrefImplicitLod:
211 case SPIRV::OpImageSparseSampleProjImplicitLod:
212 case SPIRV::OpImageSparseSampleProjDrefImplicitLod:
213 case SPIRV::OpImageSparseFetch:
214 case SPIRV::OpImageSparseGather:
215 case SPIRV::OpImageSparseDrefGather:
216 case SPIRV::OpImageSparseRead:
217 case SPIRV::OpImageSampleFootprintNV:
218 OS << ' ';
220 MI, FirstVariableIndex, OS);
222 break;
223 case SPIRV::OpCopyMemory:
224 case SPIRV::OpCopyMemorySized: {
225 const unsigned NumOps = MI->getNumOperands();
226 for (unsigned i = NumFixedOps; i < NumOps; ++i) {
227 OS << ' ';
229 OS);
230 if (MI->getOperand(i).getImm() & MemoryOperand::Aligned) {
231 assert(i + 1 < NumOps && "Missing alignment operand");
232 OS << ' ';
234 i += 1;
235 }
236 }
237 break;
238 }
239 case SPIRV::OpConstantI:
240 case SPIRV::OpConstantF:
241
242
243 assert(NumFixedOps > 0 && "Expected at least one fixed operand");
245 break;
246 case SPIRV::OpCooperativeMatrixMulAddKHR: {
247 const unsigned NumOps = MI->getNumOperands();
248 if (NumFixedOps == NumOps)
249 break;
250
251 OS << ' ';
252 const unsigned MulAddOp = MI->getOperand(FirstVariableIndex).getImm();
253 if (MulAddOp == 0) {
255 OperandCategory::CooperativeMatrixOperandsOperand>(
256 MI, FirstVariableIndex, OS);
257 } else {
258 std::string Buffer;
259 for (unsigned Mask = 0x1;
260 Mask != SPIRV::CooperativeMatrixOperands::
261 MatrixResultBFloat16ComponentsINTEL;
262 Mask <<= 1) {
263 if (MulAddOp & Mask) {
264 if (!Buffer.empty())
265 Buffer += '|';
267 OperandCategory::CooperativeMatrixOperandsOperand, Mask);
268 }
269 }
270 OS << Buffer;
271 }
272 break;
273 }
274 case SPIRV::OpSubgroupMatrixMultiplyAccumulateINTEL: {
275 const unsigned NumOps = MI->getNumOperands();
276 if (NumFixedOps >= NumOps)
277 break;
278 OS << ' ';
279 const unsigned Flags = MI->getOperand(NumOps - 1).getImm();
280 if (Flags == 0) {
282 OperandCategory::MatrixMultiplyAccumulateOperandsOperand>(
284 } else {
285 std::string Buffer;
286 for (unsigned Mask = 0x1;
287 Mask <= SPIRV::MatrixMultiplyAccumulateOperands::
288 MatrixBPackedBFloat16INTEL;
289 Mask <<= 1) {
290 if (Flags & Mask) {
291 if (!Buffer.empty())
292 Buffer += '|';
294 OperandCategory::MatrixMultiplyAccumulateOperandsOperand,
295 Mask);
296 }
297 }
298 OS << Buffer;
299 }
300 break;
301 }
302 case SPIRV::OpSDot:
303 case SPIRV::OpUDot:
304 case SPIRV::OpSUDot:
305 case SPIRV::OpSDotAccSat:
306 case SPIRV::OpUDotAccSat:
307 case SPIRV::OpSUDotAccSat: {
308 const unsigned NumOps = MI->getNumOperands();
309 if (NumOps > NumFixedOps) {
310 OS << ' ';
313 break;
314 }
315 break;
316 }
317 case SPIRV::OpPredicatedLoadINTEL:
318 case SPIRV::OpPredicatedStoreINTEL: {
319 const unsigned NumOps = MI->getNumOperands();
320 if (NumOps > NumFixedOps) {
321 OS << ' ';
324 break;
325 }
326 break;
327 }
328 default:
330 break;
331 }
332 }
333 }
334 }
335
337}
338
340
341
344 const auto NumOps = MI->getNumOperands();
345 if (NumOps == NumFixedOps)
346 return;
347
348 O << ' ';
349
350
352}
353
355
356
359
360 if (NumFixedOps != MI->getNumOperands()) {
361 auto DecOp = MI->getOperand(NumFixedOps - 1);
362 auto Dec = static_castDecoration::Decoration\(DecOp.getImm());
363
364 O << ' ';
365
366 switch (Dec) {
367 case Decoration::BuiltIn:
369 break;
370 case Decoration::UniformId:
372 break;
373 case Decoration::FuncParamAttr:
375 MI, NumFixedOps, O);
376 break;
377 case Decoration::FPRoundingMode:
379 MI, NumFixedOps, O);
380 break;
381 case Decoration::FPFastMathMode:
383 MI, NumFixedOps, O);
384 break;
385 case Decoration::LinkageAttributes:
386 case Decoration::UserSemantic:
388 break;
389 case Decoration::HostAccessINTEL:
391 if (NumFixedOps + 1 < MI->getNumOperands()) {
392 O << ' ';
394 }
395 break;
396 default:
398 break;
399 }
400 }
401}
402
404 const auto EnumOperand = MI->getOperand(1);
405 assert(EnumOperand.isImm() &&
406 "second operand of UNKNOWN_type must be opcode!");
407
408 const auto Enumerant = EnumOperand.getImm();
409 const auto NumOps = MI->getNumOperands();
410
411
412 O << "OpUnknown(" << Enumerant << ", " << NumOps << ") ";
413
414
416
417 O << " ";
418
421 if (NumOps == NumFixedOps)
422 return;
423
424
426}
427
430 if (OpNo < MI->getNumOperands()) {
432 if (Op.isReg())
434 else if (Op.isImm()) {
435 int64_t Imm = Op.getImm();
436
437
438
439
440 if (MI->getOpcode() == SPIRV::OpVectorShuffle && Imm == -1)
441 O << "0xFFFFFFFF";
442 else
444 } else if (Op.isDFPImm())
446 else if (Op.isExpr())
447 MAI.printExpr(O, *Op.getExpr());
448 else
450 }
451}
452
455 const unsigned NumOps = MI->getNumOperands();
456 unsigned StrStartIndex = OpNo;
457 while (StrStartIndex < NumOps) {
458 if (MI->getOperand(StrStartIndex).isReg())
459 break;
460
462 if (StrStartIndex != OpNo)
463 O << ' ';
464 O << '"';
465 for (char c : Str) {
466
467 if (c == '\n') {
468 O.write("\\n", 2);
469 } else {
470 if (c == '"')
471 O.write('\\');
472 O.write(c);
473 }
474 }
475 O << '"';
476
477 unsigned numOpsInString = (Str.size() / 4) + 1;
478 StrStartIndex += numOpsInString;
479
480
481 if (MI->getOpcode() == SPIRV::OpDecorate &&
482 MI->getOperand(1).getImm() ==
483 static_cast<unsigned>(Decoration::LinkageAttributes)) {
484 O << ' ';
486 MI, StrStartIndex, O);
487 break;
488 }
489 }
490}
491
494 auto SetReg = MI->getOperand(2).getReg();
495 auto Set = ExtInstSetIDs[SetReg];
496 auto Op = MI->getOperand(OpNo).getImm();
498}
499
500template <OperandCategory::OperandCategory category>
503 if (OpNo < MI->getNumOperands()) {
505 }
506}
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)
Definition SPIRVInstPrinter.cpp:492
void printStringImm(const MCInst *MI, unsigned OpNo, raw_ostream &O)
Definition SPIRVInstPrinter.cpp:453
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.
Definition SPIRVInstPrinter.cpp:103
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
Definition SPIRVInstPrinter.cpp:428
void printOpExtInst(const MCInst *MI, raw_ostream &O)
Definition SPIRVInstPrinter.cpp:339
void printOpConstantVarOps(const MCInst *MI, unsigned StartIndex, raw_ostream &O)
Definition SPIRVInstPrinter.cpp:47
void printSymbolicOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
Definition SPIRVInstPrinter.cpp:501
void printRemainingVariableOps(const MCInst *MI, unsigned StartIndex, raw_ostream &O, bool SkipFirstSpace=false, bool SkipImmediates=false)
Definition SPIRVInstPrinter.cpp:32
void printOpDecorate(const MCInst *MI, raw_ostream &O)
Definition SPIRVInstPrinter.cpp:354
void printUnknownType(const MCInst *MI, raw_ostream &O)
Definition SPIRVInstPrinter.cpp:403
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