29#define DEBUG_TYPE "asm-printer"
32#include "SPIRVGenAsmWriter.inc"
38 bool SkipImmediates) {
39 const unsigned NumOps =
MI->getNumOperands();
40 for (
unsigned i = StartIndex; i < NumOps; ++i) {
41 if (!SkipImmediates || !
MI->getOperand(i).isImm()) {
42 if (!SkipFirstSpace || i != StartIndex)
53 if (
MI->getNumOperands() - StartIndex == 2) {
54 uint64_t Imm =
MI->getOperand(StartIndex).getImm();
55 Imm |= (
MI->getOperand(StartIndex + 1).getImm() << 32);
62void SPIRVInstPrinter::recordOpExtInstImport(
const MCInst *
MI) {
66 ExtInstSetIDs.
insert({Reg, Set});
72 const unsigned OpCode =
MI->getOpcode();
75 if (OpCode == SPIRV::OpDecorate) {
77 }
else if (OpCode == SPIRV::OpExtInstImport) {
78 recordOpExtInstImport(
MI);
79 }
else if (OpCode == SPIRV::OpExtInst) {
86 const unsigned LastFixedIndex = NumFixedOps - 1;
87 const int FirstVariableIndex = NumFixedOps;
88 if (NumFixedOps > 0 && MCDesc.
operands()[LastFixedIndex].OperandType ==
94 case SPIRV::OpTypeImage:
96 printSymbolicOperand<OperandCategory::AccessQualifierOperand>(
97 MI, FirstVariableIndex,
OS);
99 case SPIRV::OpVariable:
103 case SPIRV::OpEntryPoint: {
109 case SPIRV::OpExecutionMode:
110 case SPIRV::OpExecutionModeId:
111 case SPIRV::OpLoopMerge: {
127 printSymbolicOperand<OperandCategory::MemoryOperandOperand>(
128 MI, FirstVariableIndex,
OS);
131 case SPIRV::OpImageSampleImplicitLod:
132 case SPIRV::OpImageSampleDrefImplicitLod:
133 case SPIRV::OpImageSampleProjImplicitLod:
134 case SPIRV::OpImageSampleProjDrefImplicitLod:
135 case SPIRV::OpImageFetch:
136 case SPIRV::OpImageGather:
137 case SPIRV::OpImageDrefGather:
138 case SPIRV::OpImageRead:
139 case SPIRV::OpImageWrite:
140 case SPIRV::OpImageSparseSampleImplicitLod:
141 case SPIRV::OpImageSparseSampleDrefImplicitLod:
142 case SPIRV::OpImageSparseSampleProjImplicitLod:
143 case SPIRV::OpImageSparseSampleProjDrefImplicitLod:
144 case SPIRV::OpImageSparseFetch:
145 case SPIRV::OpImageSparseGather:
146 case SPIRV::OpImageSparseDrefGather:
147 case SPIRV::OpImageSparseRead:
148 case SPIRV::OpImageSampleFootprintNV:
150 printSymbolicOperand<OperandCategory::ImageOperandOperand>(
151 MI, FirstVariableIndex,
OS);
154 case SPIRV::OpCopyMemory:
155 case SPIRV::OpCopyMemorySized: {
156 const unsigned NumOps =
MI->getNumOperands();
157 for (
unsigned i = NumFixedOps; i < NumOps; ++i) {
159 printSymbolicOperand<OperandCategory::MemoryOperandOperand>(
MI, i,
161 if (
MI->getOperand(i).getImm() & MemoryOperand::Aligned) {
162 assert(i + 1 < NumOps &&
"Missing alignment operand");
170 case SPIRV::OpConstantI:
171 case SPIRV::OpConstantF:
192 const auto NumOps =
MI->getNumOperands();
193 if (NumOps == NumFixedOps)
208 if (NumFixedOps !=
MI->getNumOperands()) {
209 auto DecOp =
MI->getOperand(NumFixedOps - 1);
210 auto Dec =
static_cast<Decoration::Decoration
>(DecOp.getImm());
215 case Decoration::BuiltIn:
216 printSymbolicOperand<OperandCategory::BuiltInOperand>(
MI, NumFixedOps, O);
218 case Decoration::UniformId:
219 printSymbolicOperand<OperandCategory::ScopeOperand>(
MI, NumFixedOps, O);
221 case Decoration::FuncParamAttr:
222 printSymbolicOperand<OperandCategory::FunctionParameterAttributeOperand>(
225 case Decoration::FPRoundingMode:
226 printSymbolicOperand<OperandCategory::FPRoundingModeOperand>(
229 case Decoration::FPFastMathMode:
230 printSymbolicOperand<OperandCategory::FPFastMathModeOperand>(
233 case Decoration::LinkageAttributes:
234 case Decoration::UserSemantic:
248 if (
const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr))
249 SRE = cast<MCSymbolRefExpr>(BE->getLHS());
251 SRE = cast<MCSymbolRefExpr>(Expr);
262 assert((Modifier == 0 || Modifier[0] == 0) &&
"No modifiers supported");
263 if (OpNo < MI->getNumOperands()) {
269 else if (
Op.isDFPImm())
271 else if (
Op.isExpr())
280 const unsigned NumOps =
MI->getNumOperands();
281 unsigned StrStartIndex = OpNo;
282 while (StrStartIndex < NumOps) {
283 if (
MI->getOperand(StrStartIndex).isReg())
287 if (StrStartIndex != OpNo)
297 unsigned numOpsInString = (Str.size() / 4) + 1;
298 StrStartIndex += numOpsInString;
301 if (
MI->getOpcode() == SPIRV::OpDecorate &&
302 MI->getOperand(1).getImm() ==
303 static_cast<unsigned>(Decoration::LinkageAttributes)) {
305 printSymbolicOperand<OperandCategory::LinkageTypeOperand>(
306 MI, StrStartIndex, O);
314 auto SetReg =
MI->getOperand(2).getReg();
315 auto Set = ExtInstSetIDs[SetReg];
316 auto Op =
MI->getOperand(OpNo).getImm();
320template <OperandCategory::OperandCategory category>
323 if (OpNo < MI->getNumOperands()) {
static void printExpr(const MCExpr *Expr, const MCAsmInfo *MAI, raw_ostream &OS)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class represents an Operation in the Expression.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Binary assembler expressions.
Base class for the full range of assembler expressions which are needed for parsing.
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.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Instances of this class represent operands of the MCInst class.
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
VariantKind getKind() const
Wrapper class representing virtual and physical registers.
static unsigned virtReg2Index(Register Reg)
Convert a virtual register number to a 0-based index.
void printExtension(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printStringImm(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O, const char *Modifier=nullptr)
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.
void printOpExtInst(const MCInst *MI, raw_ostream &O)
void printOpConstantVarOps(const MCInst *MI, unsigned StartIndex, raw_ostream &O)
void printSymbolicOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
void printRemainingVariableOps(const MCInst *MI, unsigned StartIndex, raw_ostream &O, bool SkipFirstSpace=false, bool SkipImmediates=false)
void printOpDecorate(const MCInst *MI, raw_ostream &O)
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.
Lowers a builtin funtion call using the provided DemangledCall skeleton and external instruction Set.
This is an optimization pass for GlobalISel generic memory operations.
std::string getExtInstName(SPIRV::InstructionSet::InstructionSet Set, uint32_t InstructionNumber)
std::string getSPIRVStringOperand(const InstType &MI, unsigned StartIndex)
SPIRV::InstructionSet::InstructionSet getExtInstSetFromString(std::string SetName)
std::string getSymbolicOperandMnemonic(SPIRV::OperandCategory::OperandCategory Category, int32_t Value)