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 || MI->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 if (MI->getOpcode() == SPIRV::OpConstantI && NumVarOps > 2) {

54

55

56 for (unsigned I = StartIndex; I != MI->getNumOperands(); ++I)

57 O << ' ' << MI->getOperand(I).getImm();

58 return;

59 }

60

61 assert((NumVarOps == 1 || NumVarOps == 2) &&

62 "Unsupported number of bits for literal variable");

63

64 O << ' ';

65

66 uint64_t Imm = MI->getOperand(StartIndex).getImm();

67

68

69 if (NumVarOps == 2) {

70 Imm |= (MI->getOperand(StartIndex + 1).getImm() << 32);

71 }

72

73

74 if (MI->getOpcode() == SPIRV::OpConstantF && IsBitwidth16 == 0) {

77

78

79

80

81 if (FP.isInfinity()) {

82 if (FP.isNegative())

83 O << '-';

84 O << "0x1p+128";

85 return;

86 }

87 if (FP.isNaN()) {

88 O << "0x1.8p+128";

89 return;

90 }

91

92

93

94 O << format("%.*g", std::numeric_limits::max_digits10,

95 FP.convertToDouble());

96

97 return;

98 }

99

100

101 O << Imm;

102}

103

104void SPIRVInstPrinter::recordOpExtInstImport(const MCInst *MI) {

108 ExtInstSetIDs.insert({Reg, Set});

109}

110

114 const unsigned OpCode = MI->getOpcode();

116

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) {

125 } else {

126

129 const unsigned NumFixedOps = MCDesc.getNumOperands();

130 const unsigned LastFixedIndex = NumFixedOps - 1;

131 const int FirstVariableIndex = NumFixedOps;

132 if (NumFixedOps > 0 && MCDesc.operands()[LastFixedIndex].OperandType ==

134

135

136

137 switch (OpCode) {

138 case SPIRV::OpTypeImage:

139 OS << ' ';

141 MI, FirstVariableIndex, OS);

142 break;

143 case SPIRV::OpVariable:

144 OS << ' ';

146 break;

147 case SPIRV::OpEntryPoint: {

148

149

151 break;

152 }

153 case SPIRV::OpMemberDecorate:

155 break;

156 case SPIRV::OpExecutionMode:

157 case SPIRV::OpExecutionModeId:

158 case SPIRV::OpLoopMerge: {

159

161 break;

162 }

163 default:

164 break;

165 }

166 } else {

167

168

169

170 switch (OpCode) {

171 case SPIRV::OpLoad:

172 case SPIRV::OpStore:

173 OS << ' ';

175 MI, FirstVariableIndex, OS);

177 break;

178 case SPIRV::OpSwitch:

180

181

182

183 const unsigned NumOps = MI->getNumOperands();

186 MI->getOperand(OpIdx + 1).isImm()) {

188 continue;

189 }

190 OS << ' ';

193 uint64_t CombinedValue = (HighBits << 32) | LowBits;

196

197

199 OS << ' ';

202 }

203 }

204 } else {

206 }

207 break;

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:

226 OS << ' ';

228 MI, FirstVariableIndex, OS);

230 break;

231 case SPIRV::OpCopyMemory:

232 case SPIRV::OpCopyMemorySized: {

233 const unsigned NumOps = MI->getNumOperands();

234 for (unsigned i = NumFixedOps; i < NumOps; ++i) {

235 OS << ' ';

237 OS);

238 if (MI->getOperand(i).getImm() & MemoryOperand::Aligned) {

239 assert(i + 1 < NumOps && "Missing alignment operand");

240 OS << ' ';

242 i += 1;

243 }

244 }

245 break;

246 }

247 case SPIRV::OpConstantI:

248 case SPIRV::OpConstantF:

249

250

251 assert(NumFixedOps > 0 && "Expected at least one fixed operand");

253 break;

254 case SPIRV::OpCooperativeMatrixMulAddKHR: {

255 const unsigned NumOps = MI->getNumOperands();

256 if (NumFixedOps == NumOps)

257 break;

258

259 OS << ' ';

260 const unsigned MulAddOp = MI->getOperand(FirstVariableIndex).getImm();

261 if (MulAddOp == 0) {

263 OperandCategory::CooperativeMatrixOperandsOperand>(

264 MI, FirstVariableIndex, OS);

265 } else {

266 std::string Buffer;

267 for (unsigned Mask = 0x1;

268 Mask != SPIRV::CooperativeMatrixOperands::

269 MatrixResultBFloat16ComponentsINTEL;

270 Mask <<= 1) {

271 if (MulAddOp & Mask) {

272 if (!Buffer.empty())

273 Buffer += '|';

275 OperandCategory::CooperativeMatrixOperandsOperand, Mask);

276 }

277 }

278 OS << Buffer;

279 }

280 break;

281 }

282 case SPIRV::OpSubgroupMatrixMultiplyAccumulateINTEL: {

283 const unsigned NumOps = MI->getNumOperands();

284 if (NumFixedOps >= NumOps)

285 break;

286 OS << ' ';

287 const unsigned Flags = MI->getOperand(NumOps - 1).getImm();

288 if (Flags == 0) {

290 OperandCategory::MatrixMultiplyAccumulateOperandsOperand>(

292 } else {

293 std::string Buffer;

294 for (unsigned Mask = 0x1;

295 Mask <= SPIRV::MatrixMultiplyAccumulateOperands::

296 MatrixBPackedBFloat16INTEL;

297 Mask <<= 1) {

298 if (Flags & Mask) {

299 if (!Buffer.empty())

300 Buffer += '|';

302 OperandCategory::MatrixMultiplyAccumulateOperandsOperand,

303 Mask);

304 }

305 }

306 OS << Buffer;

307 }

308 break;

309 }

310 case SPIRV::OpSDot:

311 case SPIRV::OpUDot:

312 case SPIRV::OpSUDot:

313 case SPIRV::OpSDotAccSat:

314 case SPIRV::OpUDotAccSat:

315 case SPIRV::OpSUDotAccSat: {

316 const unsigned NumOps = MI->getNumOperands();

317 if (NumOps > NumFixedOps) {

318 OS << ' ';

321 break;

322 }

323 break;

324 }

325 case SPIRV::OpPredicatedLoadINTEL:

326 case SPIRV::OpPredicatedStoreINTEL: {

327 const unsigned NumOps = MI->getNumOperands();

328 if (NumOps > NumFixedOps) {

329 OS << ' ';

332 break;

333 }

334 break;

335 }

336 default:

338 break;

339 }

340 }

341 }

342 }

343

345}

346

348

349

352 const auto NumOps = MI->getNumOperands();

353 if (NumOps == NumFixedOps)

354 return;

355

356 O << ' ';

357

358

360}

361

363

364

367

368 if (NumFixedOps != MI->getNumOperands()) {

369 auto DecOp = MI->getOperand(NumFixedOps - 1);

370 auto Dec = static_castDecoration::Decoration\(DecOp.getImm());

371

372 O << ' ';

373

374 switch (Dec) {

375 case Decoration::BuiltIn:

377 break;

378 case Decoration::UniformId:

380 break;

381 case Decoration::FuncParamAttr:

383 MI, NumFixedOps, O);

384 break;

385 case Decoration::FPRoundingMode:

387 MI, NumFixedOps, O);

388 break;

389 case Decoration::FPFastMathMode:

391 MI, NumFixedOps, O);

392 break;

393 case Decoration::LinkageAttributes:

394 case Decoration::UserSemantic:

396 break;

397 case Decoration::HostAccessINTEL:

399 if (NumFixedOps + 1 < MI->getNumOperands()) {

400 O << ' ';

402 }

403 break;

404 default:

406 break;

407 }

408 }

409}

410

412 const auto EnumOperand = MI->getOperand(1);

413 assert(EnumOperand.isImm() &&

414 "second operand of UNKNOWN_type must be opcode!");

415

416 const auto Enumerant = EnumOperand.getImm();

417 const auto NumOps = MI->getNumOperands();

418

419

420 O << "OpUnknown(" << Enumerant << ", " << NumOps << ") ";

421

422

424

425 O << " ";

426

429 if (NumOps == NumFixedOps)

430 return;

431

432

434}

435

438 if (OpNo < MI->getNumOperands()) {

440 if (Op.isReg())

442 else if (Op.isImm()) {

443 int64_t Imm = Op.getImm();

444

445

446

447

448 if (MI->getOpcode() == SPIRV::OpVectorShuffle && Imm == -1)

449 O << "0xFFFFFFFF";

450 else

452 } else if (Op.isDFPImm())

454 else if (Op.isExpr())

455 MAI.printExpr(O, *Op.getExpr());

456 else

458 }

459}

460

463 const unsigned NumOps = MI->getNumOperands();

464 unsigned StrStartIndex = OpNo;

465 while (StrStartIndex < NumOps) {

466 if (MI->getOperand(StrStartIndex).isReg())

467 break;

468

470 if (StrStartIndex != OpNo)

471 O << ' ';

472 O << '"';

473 for (char c : Str) {

474

475 if (c == '\n') {

476 O.write("\\n", 2);

477 } else {

478 if (c == '"')

479 O.write('\\');

480 O.write(c);

481 }

482 }

483 O << '"';

484

485 unsigned numOpsInString = (Str.size() / 4) + 1;

486 StrStartIndex += numOpsInString;

487

488

489 if (MI->getOpcode() == SPIRV::OpDecorate &&

490 MI->getOperand(1).getImm() ==

491 static_cast<unsigned>(Decoration::LinkageAttributes)) {

492 O << ' ';

494 MI, StrStartIndex, O);

495 break;

496 }

497 }

498}

499

502 auto SetReg = MI->getOperand(2).getReg();

503 auto Set = ExtInstSetIDs[SetReg];

504 auto Op = MI->getOperand(OpNo).getImm();

506}

507

508template <OperandCategory::OperandCategory category>

511 if (OpNo < MI->getNumOperands()) {

513 }

514}

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:500

void printStringImm(const MCInst *MI, unsigned OpNo, raw_ostream &O)

Definition SPIRVInstPrinter.cpp:461

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:111

void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)

Definition SPIRVInstPrinter.cpp:436

void printOpExtInst(const MCInst *MI, raw_ostream &O)

Definition SPIRVInstPrinter.cpp:347

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:509

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:362

void printUnknownType(const MCInst *MI, raw_ostream &O)

Definition SPIRVInstPrinter.cpp:411

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