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 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 MI->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