41#include "AMDGPUGenMCPseudoLowering.inc"
46 Ctx(ctx), ST(st), AP(ap) { }
92 AP.getNameWithPrefix(SymbolName, GV);
93 MCSymbol *Sym = Ctx.getOrCreateSymbol(SymbolName);
137 unsigned Opcode =
MI->getOpcode();
138 const auto *
TII =
static_cast<const SIInstrInfo*
>(ST.getInstrInfo());
140 const auto *Info = AMDGPU::getT16D16Helper(Opcode);
142 llvm::AMDGPU::OpName
OpName;
143 if (
TII->isDS(Opcode)) {
145 OpName = llvm::AMDGPU::OpName::vdst;
146 else if (
MI->mayStore())
147 OpName = llvm::AMDGPU::OpName::data0;
152 ? llvm::AMDGPU::OpName::vdata
153 : llvm::AMDGPU::OpName::vdst;
157 int VDstOrVDataIdx = AMDGPU::getNamedOperandIdx(Opcode,
OpName);
162 Opcode = IsHi ? Info->HiOp : Info->LoOp;
164 int MCOpcode =
TII->pseudoToMCOpcode(Opcode);
166 "Pseudo instruction doesn't have a target-specific version");
170 for (
int I = 0, E =
MI->getNumExplicitOperands();
I < E;
I++) {
173 if (
I == VDstOrVDataIdx)
189 unsigned Opcode =
MI->getOpcode();
190 const auto *
TII =
static_cast<const SIInstrInfo *
>(ST.getInstrInfo());
193 int VDstIdx = AMDGPU::getNamedOperandIdx(Opcode, llvm::AMDGPU::OpName::vdst);
197 case AMDGPU::V_FMA_MIX_F16_t16:
198 Opcode = IsHi ? AMDGPU::V_FMA_MIXHI_F16 : AMDGPU::V_FMA_MIXLO_F16;
200 case AMDGPU::V_FMA_MIX_BF16_t16:
201 Opcode = IsHi ? AMDGPU::V_FMA_MIXHI_BF16 : AMDGPU::V_FMA_MIXLO_BF16;
204 int MCOpcode =
TII->pseudoToMCOpcode(Opcode);
206 "Pseudo instruction doesn't have a target-specific version");
210 for (
int I = 0, E =
MI->getNumExplicitOperands();
I < E;
I++) {
222 unsigned Opcode =
MI->getOpcode();
223 const auto *
TII =
static_cast<const SIInstrInfo *
>(ST.getInstrInfo());
228 if (Opcode == AMDGPU::S_SETPC_B64_return)
229 Opcode = AMDGPU::S_SETPC_B64;
230 else if (Opcode == AMDGPU::SI_CALL) {
233 OutMI.
setOpcode(
TII->pseudoToMCOpcode(AMDGPU::S_SWAPPC_B64));
240 }
else if (Opcode == AMDGPU::SI_TCRETURN ||
241 Opcode == AMDGPU::SI_TCRETURN_GFX ||
242 Opcode == AMDGPU::SI_TCRETURN_CHAIN) {
244 Opcode = AMDGPU::S_SETPC_B64;
245 }
else if (AMDGPU::getT16D16Helper(Opcode)) {
248 }
else if (Opcode == AMDGPU::V_FMA_MIX_F16_t16 ||
249 Opcode == AMDGPU::V_FMA_MIX_BF16_t16) {
254 int MCOpcode =
TII->pseudoToMCOpcode(Opcode);
255 if (MCOpcode == -1) {
257 C.emitError(
"AMDGPUMCInstLower::lower - Pseudo instruction doesn't have "
258 "a target-specific version: " +
Twine(
MI->getOpcode()));
270 int FIIdx = AMDGPU::getNamedOperandIdx(MCOpcode, AMDGPU::OpName::fi);
279 return MCInstLowering.lowerOperand(MO, MCOp);
288 if (std::optional<uint32_t>
Address =
312 TII->getNamedOperand(*
MI,
MI->mayLoad() ? AMDGPU::OpName::vdst
313 : AMDGPU::OpName::vdata)
315 Register FirstRegInBlock =
TRI->getSubReg(RegBlock, AMDGPU::sub0);
322 for (
unsigned I = 0;
I <
sizeof(Mask) * 8; ++
I) {
323 if (Mask & (1 <<
I)) {
325 .toVector(TransferredRegs);
334 collectCallEdge(*
MI);
351 C.emitError(
"Illegal instruction detected: " + Err);
355 if (
MI->isBundle()) {
358 while (
I !=
MBB->instr_end() &&
I->isInsideBundle()) {
366 if (
MI->getOpcode() == AMDGPU::SI_RETURN_TO_EPILOG) {
368 OutStreamer->emitRawComment(
" return to shader part epilog");
372 if (
MI->getOpcode() == AMDGPU::WAVE_BARRIER) {
378 if (
MI->getOpcode() == AMDGPU::ASYNCMARK) {
382 OS <<
" asyncmark(stages="
390 if (
MI->getOpcode() == AMDGPU::WAIT_ASYNCMARK) {
394 OS <<
" wait_asyncmark(" <<
MI->getOperand(0).getImm() <<
", stages="
402 if (
MI->getOpcode() == AMDGPU::SCHED_BARRIER) {
404 std::string HexString;
406 HexStream <<
format_hex(
MI->getOperand(0).getImm(), 10,
true);
407 OutStreamer->emitRawComment(
" sched_barrier mask(" + HexString +
")");
412 if (
MI->getOpcode() == AMDGPU::SCHED_GROUP_BARRIER) {
414 std::string HexString;
416 HexStream <<
format_hex(
MI->getOperand(0).getImm(), 10,
true);
418 " sched_group_barrier mask(" + HexString +
") size(" +
419 Twine(
MI->getOperand(1).getImm()) +
") SyncID(" +
420 Twine(
MI->getOperand(2).getImm()) +
")");
425 if (
MI->getOpcode() == AMDGPU::IGLP_OPT) {
427 std::string HexString;
429 HexStream <<
format_hex(
MI->getOperand(0).getImm(), 10,
true);
430 OutStreamer->emitRawComment(
" iglp_opt mask(" + HexString +
")");
435 if (
MI->getOpcode() == AMDGPU::SI_MASKED_UNREACHABLE) {
437 OutStreamer->emitRawComment(
" divergent unreachable");
441 if (
MI->isMetaInstruction()) {
447 unsigned Opc =
MI->getOpcode();
449 Opc == TargetOpcode::STACKMAP ||
450 Opc == TargetOpcode::PATCHPOINT)) {
452 Ctx.emitError(
"unhandled statepoint-like instruction");
453 OutStreamer->emitRawComment(
"unsupported statepoint/stackmap/patchpoint");
463 if (
isVerbose() && (
MI->getOpcode() == AMDGPU::S_SET_VGPR_MSB ||
464 (
MI->getOpcode() == AMDGPU::S_SETREG_IMM32_B32 &&
465 STI.hasVGPRMSBs()))) {
466 std::optional<unsigned> V;
467 if (
MI->getOpcode() == AMDGPU::S_SETREG_IMM32_B32)
469 STI.hasSetregVGPRMSBFixup());
471 V =
MI->getOperand(0).getImm() & 0xff;
474 " msbs: dst=" +
Twine(*V >> 6) +
" src0=" +
Twine(*V & 3) +
475 " src1=" +
Twine((*V >> 2) & 3) +
" src2=" +
Twine((*V >> 4) & 3));
479 MCInstLowering.lower(
MI, TmpInst);
482 if (DumpCodeInstEmitter) {
496 DumpCodeInstEmitter->encodeInstruction(
499 std::string &HexLine =
HexLines.back();
502 for (
size_t i = 0; i < CodeBytes.
size(); i += 4) {
503 unsigned int CodeDWord =
505 HexStream <<
format(
"%s%08X", (i > 0 ?
" " :
""), CodeDWord);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU address space definition.
AMDGPU Assembly printer class.
Shared AMDGPU asyncmark stage definitions.
static void emitVGPRBlockComment(const MachineInstr *MI, const SIInstrInfo *TII, const TargetRegisterInfo *TRI, const SIMachineFunctionInfo *MFI, MCStreamer &OS)
Header of lower AMDGPU MachineInstrs to their corresponding MCInst.
Provides AMDGPU specific target descriptions.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
#define LLVM_UNLIKELY(EXPR)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const HexagonInstrInfo * TII
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.
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.
void emitInstruction(const MachineInstr *MI) override
Implemented in AMDGPUMCInstLower.cpp.
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
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const
void lowerT16D16Helper(const MachineInstr *MI, MCInst &OutMI) const
AMDGPUMCInstLower(MCContext &ctx, const TargetSubtargetInfo &ST, const AsmPrinter &AP)
void lower(const MachineInstr *MI, MCInst &OutMI) const
Lower a MachineInstr to an MCInst.
static std::optional< uint32_t > get32BitAbsoluteAddress(const GlobalValue &GV, unsigned AS)
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
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
const BlockAddress * getBlockAddress() 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_BlockAddress
Address of a basic block.
@ 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.
bool verifyInstruction(const MachineInstr &MI, StringRef &ErrInfo) const override
static bool isBlockLoadStore(uint32_t Opcode)
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.
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)
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.
@ LOCAL_ADDRESS
Address space for local memory.
MCRegister getMCReg(MCRegister Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg.
constexpr AsyncStages asyncStagesFromMaskOperand(int64_t Mask)
bool isHi16Reg(MCRegister Reg, const MCRegisterInfo &MRI)
static std::optional< unsigned > convertSetRegImmToVgprMSBs(uint64_t Imm, uint64_t Simm16, bool HasSetregVGPRMSBFixup)
LLVM_READONLY bool hasNamedOperand(uint32_t Opcode, OpName NamedIdx)
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<X> - 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)