LLVM: lib/Target/AMDGPU/AMDGPUMCInstLower.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

37#include

38

39using namespace llvm;

40

41#include "AMDGPUGenMCPseudoLowering.inc"

42

46 Ctx(ctx), ST(st), AP(ap) { }

47

49 switch (MOFlags) {

50 default:

71 }

72}

73

77 default:

78 break;

81 return true;

84 return true;

88 return true;

92 AP.getNameWithPrefix(SymbolName, GV);

93 MCSymbol *Sym = Ctx.getOrCreateSymbol(SymbolName);

100 }

102 return true;

103 }

108 return true;

109 }

111

112 return false;

117 return true;

118 }

119 break;

120 }

122}

123

124

125

127 MCInst &OutMI) const {

128 unsigned Opcode = MI->getOpcode();

129 const auto *TII = static_cast<const SIInstrInfo*>(ST.getInstrInfo());

131 const auto *Info = AMDGPU::getT16D16Helper(Opcode);

132

133 llvm::AMDGPU::OpName OpName;

134 if (TII->isDS(Opcode)) {

135 if (MI->mayLoad())

136 OpName = llvm::AMDGPU::OpName::vdst;

137 else if (MI->mayStore())

138 OpName = llvm::AMDGPU::OpName::data0;

139 else

141 } else {

143 ? llvm::AMDGPU::OpName::vdata

144 : llvm::AMDGPU::OpName::vdst;

145 }

146

147

148 int VDstOrVDataIdx = AMDGPU::getNamedOperandIdx(Opcode, OpName);

149 const MachineOperand &MIVDstOrVData = MI->getOperand(VDstOrVDataIdx);

150

151

153 Opcode = IsHi ? Info->HiOp : Info->LoOp;

154

155 int MCOpcode = TII->pseudoToMCOpcode(Opcode);

156 assert(MCOpcode != -1 &&

157 "Pseudo instruction doesn't have a target-specific version");

159

160

161 for (int I = 0, E = MI->getNumExplicitOperands(); I < E; I++) {

164 if (I == VDstOrVDataIdx)

166 else

169 }

170

175 }

176}

177

179 MCInst &OutMI) const {

180 unsigned Opcode = MI->getOpcode();

181 const auto *TII = static_cast<const SIInstrInfo *>(ST.getInstrInfo());

183

184 int VDstIdx = AMDGPU::getNamedOperandIdx(Opcode, llvm::AMDGPU::OpName::vdst);

187 switch (Opcode) {

188 case AMDGPU::V_FMA_MIX_F16_t16:

189 Opcode = IsHi ? AMDGPU::V_FMA_MIXHI_F16 : AMDGPU::V_FMA_MIXLO_F16;

190 break;

191 case AMDGPU::V_FMA_MIX_BF16_t16:

192 Opcode = IsHi ? AMDGPU::V_FMA_MIXHI_BF16 : AMDGPU::V_FMA_MIXLO_BF16;

193 break;

194 }

195 int MCOpcode = TII->pseudoToMCOpcode(Opcode);

196 assert(MCOpcode != -1 &&

197 "Pseudo instruction doesn't have a target-specific version");

199

200

201 for (int I = 0, E = MI->getNumExplicitOperands(); I < E; I++) {

204 if (I == VDstIdx)

206 else

209 }

210}

211

213 unsigned Opcode = MI->getOpcode();

214 const auto *TII = static_cast<const SIInstrInfo *>(ST.getInstrInfo());

215

216

217

218

219 if (Opcode == AMDGPU::S_SETPC_B64_return)

220 Opcode = AMDGPU::S_SETPC_B64;

221 else if (Opcode == AMDGPU::SI_CALL) {

222

223

224 OutMI.setOpcode(TII->pseudoToMCOpcode(AMDGPU::S_SWAPPC_B64));

230 return;

231 } else if (Opcode == AMDGPU::SI_TCRETURN ||

232 Opcode == AMDGPU::SI_TCRETURN_GFX ||

233 Opcode == AMDGPU::SI_TCRETURN_CHAIN) {

234

235 Opcode = AMDGPU::S_SETPC_B64;

236 } else if (AMDGPU::getT16D16Helper(Opcode)) {

238 return;

239 } else if (Opcode == AMDGPU::V_FMA_MIX_F16_t16 ||

240 Opcode == AMDGPU::V_FMA_MIX_BF16_t16) {

242 return;

243 }

244

245 int MCOpcode = TII->pseudoToMCOpcode(Opcode);

246 if (MCOpcode == -1) {

247 LLVMContext &C = MI->getMF()->getFunction().getContext();

248 C.emitError("AMDGPUMCInstLower::lower - Pseudo instruction doesn't have "

249 "a target-specific version: " + Twine(MI->getOpcode()));

250 }

251

253

258 }

259

260 int FIIdx = AMDGPU::getNamedOperandIdx(MCOpcode, AMDGPU::OpName::fi);

263}

264

269 return MCInstLowering.lowerOperand(MO, MCOp);

270}

271

275

276

278 if (std::optional<uint32_t> Address =

283 }

284 }

285

287 return E;

289}

290

295

296

297

298

299

301 TII->getNamedOperand(*MI, MI->mayLoad() ? AMDGPU::OpName::vdst

302 : AMDGPU::OpName::vdata)

303 ->getReg();

304 Register FirstRegInBlock = TRI->getSubReg(RegBlock, AMDGPU::sub0);

306

307 if (!Mask)

308 return;

309

311 for (unsigned I = 0; I < sizeof(Mask) * 8; ++I) {

312 if (Mask & (1 << I)) {

313 (llvm::Twine(" ") + TRI->getRegAsmName(FirstRegInBlock + I))

314 .toVector(TransferredRegs);

315 }

316 }

317

318 OS.emitRawComment(" transferring at most " + TransferredRegs);

319}

320

322

323

324

325

328 return;

329 }

330

333

336 LLVMContext &C = MI->getMF()->getFunction().getContext();

337 C.emitError("Illegal instruction detected: " + Err);

339 }

340

341 if (MI->isBundle()) {

344 while (I != MBB->instr_end() && I->isInsideBundle()) {

346 ++I;

347 }

348 } else {

349

350

351

352 if (MI->getOpcode() == AMDGPU::SI_RETURN_TO_EPILOG) {

354 OutStreamer->emitRawComment(" return to shader part epilog");

355 return;

356 }

357

358 if (MI->getOpcode() == AMDGPU::WAVE_BARRIER) {

360 OutStreamer->emitRawComment(" wave barrier");

361 return;

362 }

363

364 if (MI->getOpcode() == AMDGPU::SCHED_BARRIER) {

366 std::string HexString;

368 HexStream << format_hex(MI->getOperand(0).getImm(), 10, true);

369 OutStreamer->emitRawComment(" sched_barrier mask(" + HexString + ")");

370 }

371 return;

372 }

373

374 if (MI->getOpcode() == AMDGPU::SCHED_GROUP_BARRIER) {

376 std::string HexString;

378 HexStream << format_hex(MI->getOperand(0).getImm(), 10, true);

380 " sched_group_barrier mask(" + HexString + ") size(" +

381 Twine(MI->getOperand(1).getImm()) + ") SyncID(" +

382 Twine(MI->getOperand(2).getImm()) + ")");

383 }

384 return;

385 }

386

387 if (MI->getOpcode() == AMDGPU::IGLP_OPT) {

389 std::string HexString;

391 HexStream << format_hex(MI->getOperand(0).getImm(), 10, true);

392 OutStreamer->emitRawComment(" iglp_opt mask(" + HexString + ")");

393 }

394 return;

395 }

396

397 if (MI->getOpcode() == AMDGPU::SI_MASKED_UNREACHABLE) {

399 OutStreamer->emitRawComment(" divergent unreachable");

400 return;

401 }

402

403 if (MI->isMetaInstruction()) {

405 OutStreamer->emitRawComment(" meta instruction");

406 return;

407 }

408

414

415 if (isVerbose() && MI->getOpcode() == AMDGPU::S_SET_VGPR_MSB) {

416 unsigned V = MI->getOperand(0).getImm() & 0xff;

418 " msbs: dst=" + Twine(V >> 6) + " src0=" + Twine(V & 3) +

419 " src1=" + Twine((V >> 2) & 3) + " src2=" + Twine((V >> 4) & 3));

420 }

421

423 MCInstLowering.lower(MI, TmpInst);

425

426#ifdef EXPENSIVE_CHECKS

427

428

429

430

431

432

433

434

435 if (MI->isPseudo() && STI.isCPUStringValid(STI.getCPU()) &&

439

442 InstEmitter->encodeInstruction(TmpInst, CodeBytes, Fixups, STI);

443

445 }

446#endif

447

448 if (DumpCodeInstEmitter) {

449

451 std::string &DisasmLine = DisasmLines.back();

453

457

458

461

462 DumpCodeInstEmitter->encodeInstruction(

463 TmpInst, CodeBytes, Fixups, MF->getSubtarget<MCSubtargetInfo>());

465 std::string &HexLine = HexLines.back();

467

468 for (size_t i = 0; i < CodeBytes.size(); i += 4) {

469 unsigned int CodeDWord =

471 HexStream << format("%s%08X", (i > 0 ? " " : ""), CodeDWord);

472 }

473

475 }

476 }

477}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

const TargetInstrInfo & TII

AMDGPU Assembly printer class.

static void emitVGPRBlockComment(const MachineInstr *MI, const SIInstrInfo *TII, const TargetRegisterInfo *TRI, const SIMachineFunctionInfo *MFI, MCStreamer &OS)

Definition AMDGPUMCInstLower.cpp:291

Header of lower AMDGPU MachineInstrs to their corresponding MCInst.

Provides AMDGPU specific target descriptions.

This file contains the declarations for the subclasses of Constant, which represent the different fla...

Register const TargetRegisterInfo * TRI

static SDValue lowerAddrSpaceCast(SDValue Op, SelectionDAG &DAG)

std::vector< std::string > DisasmLines

std::vector< std::string > HexLines

bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const

Wrapper for MCInstLowering.lowerOperand() for the tblgen'erated pseudo lowering.

Definition AMDGPUMCInstLower.cpp:265

bool lowerPseudoInstExpansion(const MachineInstr *MI, MCInst &Inst)

tblgen'erated driver function for lowering simple MI->MC pseudo instructions.

const MCExpr * lowerConstant(const Constant *CV, const Constant *BaseCV, uint64_t Offset) override

Lower the specified LLVM Constant to an MCExpr.

Definition AMDGPUMCInstLower.cpp:272

void emitInstruction(const MachineInstr *MI) override

Implemented in AMDGPUMCInstLower.cpp.

Definition AMDGPUMCInstLower.cpp:321

void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override

Print the specified MCInst to the specified raw_ostream.

void lowerT16FmaMixFP16(const MachineInstr *MI, MCInst &OutMI) const

Definition AMDGPUMCInstLower.cpp:178

bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const

Definition AMDGPUMCInstLower.cpp:74

void lowerT16D16Helper(const MachineInstr *MI, MCInst &OutMI) const

Definition AMDGPUMCInstLower.cpp:126

AMDGPUMCInstLower(MCContext &ctx, const TargetSubtargetInfo &ST, const AsmPrinter &AP)

Definition AMDGPUMCInstLower.cpp:43

void lower(const MachineInstr *MI, MCInst &OutMI) const

Lower a MachineInstr to an MCInst.

Definition AMDGPUMCInstLower.cpp:212

static std::optional< uint32_t > getLDSAbsoluteAddress(const GlobalValue &GV)

This class is intended to be used as a driving class for all asm writers.

void EmitToStreamer(MCStreamer &S, const MCInst &Inst)

TargetMachine & TM

Target machine description.

MachineFunction * MF

The current machine function.

virtual const MCExpr * lowerConstant(const Constant *CV, const Constant *BaseCV=nullptr, uint64_t Offset=0)

Lower the specified LLVM Constant to an MCExpr.

MCContext & OutContext

This is the context for the output file that we are streaming.

std::unique_ptr< MCStreamer > OutStreamer

This is the MCStreamer object for the file we are generating.

bool isVerbose() const

Return true if assembly output should contain comments.

This is an important base class in LLVM.

const SIInstrInfo * getInstrInfo() const override

bool hasOffset3fBug() const

const SIRegisterInfo * getRegisterInfo() const override

This is an important class for using LLVM in a threaded context.

static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())

static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

Base class for the full range of assembler expressions which are needed for parsing.

Instances of this class represent a single low-level machine instruction.

unsigned getNumOperands() const

void addOperand(const MCOperand Op)

void setOpcode(unsigned Op)

Instances of this class represent operands of the MCInst class.

static MCOperand createExpr(const MCExpr *Val)

static MCOperand createReg(MCRegister Reg)

static MCOperand createImm(int64_t Val)

Streaming machine code generation interface.

virtual void emitRawComment(const Twine &T, bool TabPrefix=true)

Print T and prefix it with the comment string (normally #) and optionally a tab.

Generic base class for all target subtargets.

Represent a reference to a symbol from inside an expression.

static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

const MCExpr * getVariableValue() const

Get the expression of the variable symbol.

LLVM_ABI MCSymbol * getSymbol() const

Return the MCSymbol for this basic block.

Instructions::const_iterator const_instr_iterator

Representation of each machine instruction.

MachineOperand class - Representation of each machine instruction operand.

const GlobalValue * getGlobal() const

MachineBasicBlock * getMBB() const

unsigned getTargetFlags() const

MachineOperandType getType() const

getType - Returns the MachineOperandType for this operand.

const char * getSymbolName() const

Register getReg() const

getReg - Returns the register number.

MCSymbol * getMCSymbol() const

@ MO_Immediate

Immediate operand.

@ MO_MCSymbol

MCSymbol reference (for debug/eh info)

@ MO_GlobalAddress

Address of a global value.

@ MO_RegisterMask

Mask of preserved registers.

@ MO_MachineBasicBlock

MachineBasicBlock reference.

@ MO_Register

Register operand.

@ MO_ExternalSymbol

Name of external global symbol.

int64_t getOffset() const

Return the offset from the symbol in this operand.

Wrapper class representing virtual and physical registers.

unsigned getInstSizeInBytes(const MachineInstr &MI) const override

static bool isBlockLoadStore(uint16_t Opcode)

bool verifyInstruction(const MachineInstr &MI, StringRef &ErrInfo) const override

This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...

uint32_t getMaskForVGPRBlockOps(Register RegisterBlock) const

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

pointer data()

Return a pointer to the vector's buffer, even if empty().

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

TargetSubtargetInfo - Generic base class for all target subtargets.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)

LLVM_ABI LLVMContext & getContext() const

All values hold a context through their type.

A raw_ostream that writes to an std::string.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

MCRegister getMCReg(MCRegister Reg, const MCSubtargetInfo &STI)

If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg.

bool isHi16Reg(MCRegister Reg, const MCRegisterInfo &MRI)

LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, OpName NamedIdx)

@ C

The default llvm calling convention, compatible with C.

uint32_t read32le(const void *P)

This is an optimization pass for GlobalISel generic memory operations.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)

format_hex - Output N as a fixed width hexadecimal.

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

static uint16_t getSpecifier(const MCSymbolRefExpr *SRE)

MCCodeEmitter * createAMDGPUMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)