30#define DEBUG_TYPE "asm-printer"
33#include "SPIRVGenAsmWriter.inc"
39 bool SkipImmediates) {
40 const unsigned NumOps =
MI->getNumOperands();
41 for (
unsigned i = StartIndex; i < NumOps; ++i) {
42 if (!SkipImmediates || !
MI->getOperand(i).isImm()) {
43 if (!SkipFirstSpace || i != StartIndex)
53 const unsigned NumVarOps =
MI->getNumOperands() - StartIndex;
55 assert((NumVarOps == 1 || NumVarOps == 2) &&
56 "Unsupported number of bits for literal variable");
60 uint64_t Imm =
MI->getOperand(StartIndex).getImm();
64 Imm |= (
MI->getOperand(StartIndex + 1).getImm() << 32);
68 if (
MI->getOpcode() == SPIRV::OpConstantF) {
75 if (
FP.isInfinity()) {
88 O <<
format(
"%.*g", std::numeric_limits<double>::max_digits10,
89 FP.convertToDouble());
98void SPIRVInstPrinter::recordOpExtInstImport(
const MCInst *
MI) {
102 ExtInstSetIDs.
insert({Reg, Set});
108 const unsigned OpCode =
MI->getOpcode();
111 if (OpCode == SPIRV::OpDecorate) {
113 }
else if (OpCode == SPIRV::OpExtInstImport) {
114 recordOpExtInstImport(
MI);
115 }
else if (OpCode == SPIRV::OpExtInst) {
122 const unsigned LastFixedIndex = NumFixedOps - 1;
123 const int FirstVariableIndex = NumFixedOps;
124 if (NumFixedOps > 0 && MCDesc.
operands()[LastFixedIndex].OperandType ==
130 case SPIRV::OpTypeImage:
132 printSymbolicOperand<OperandCategory::AccessQualifierOperand>(
133 MI, FirstVariableIndex,
OS);
135 case SPIRV::OpVariable:
139 case SPIRV::OpEntryPoint: {
145 case SPIRV::OpExecutionMode:
146 case SPIRV::OpExecutionModeId:
147 case SPIRV::OpLoopMerge: {
163 printSymbolicOperand<OperandCategory::MemoryOperandOperand>(
164 MI, FirstVariableIndex,
OS);
167 case SPIRV::OpImageSampleImplicitLod:
168 case SPIRV::OpImageSampleDrefImplicitLod:
169 case SPIRV::OpImageSampleProjImplicitLod:
170 case SPIRV::OpImageSampleProjDrefImplicitLod:
171 case SPIRV::OpImageFetch:
172 case SPIRV::OpImageGather:
173 case SPIRV::OpImageDrefGather:
174 case SPIRV::OpImageRead:
175 case SPIRV::OpImageWrite:
176 case SPIRV::OpImageSparseSampleImplicitLod:
177 case SPIRV::OpImageSparseSampleDrefImplicitLod:
178 case SPIRV::OpImageSparseSampleProjImplicitLod:
179 case SPIRV::OpImageSparseSampleProjDrefImplicitLod:
180 case SPIRV::OpImageSparseFetch:
181 case SPIRV::OpImageSparseGather:
182 case SPIRV::OpImageSparseDrefGather:
183 case SPIRV::OpImageSparseRead:
184 case SPIRV::OpImageSampleFootprintNV:
186 printSymbolicOperand<OperandCategory::ImageOperandOperand>(
187 MI, FirstVariableIndex,
OS);
190 case SPIRV::OpCopyMemory:
191 case SPIRV::OpCopyMemorySized: {
192 const unsigned NumOps =
MI->getNumOperands();
193 for (
unsigned i = NumFixedOps; i < NumOps; ++i) {
195 printSymbolicOperand<OperandCategory::MemoryOperandOperand>(
MI, i,
197 if (
MI->getOperand(i).getImm() & MemoryOperand::Aligned) {
198 assert(i + 1 < NumOps &&
"Missing alignment operand");
206 case SPIRV::OpConstantI:
207 case SPIRV::OpConstantF:
228 const auto NumOps =
MI->getNumOperands();
229 if (NumOps == NumFixedOps)
244 if (NumFixedOps !=
MI->getNumOperands()) {
245 auto DecOp =
MI->getOperand(NumFixedOps - 1);
246 auto Dec =
static_cast<Decoration::Decoration
>(DecOp.getImm());
251 case Decoration::BuiltIn:
252 printSymbolicOperand<OperandCategory::BuiltInOperand>(
MI, NumFixedOps, O);
254 case Decoration::UniformId:
255 printSymbolicOperand<OperandCategory::ScopeOperand>(
MI, NumFixedOps, O);
257 case Decoration::FuncParamAttr:
258 printSymbolicOperand<OperandCategory::FunctionParameterAttributeOperand>(
261 case Decoration::FPRoundingMode:
262 printSymbolicOperand<OperandCategory::FPRoundingModeOperand>(
265 case Decoration::FPFastMathMode:
266 printSymbolicOperand<OperandCategory::FPFastMathModeOperand>(
269 case Decoration::LinkageAttributes:
270 case Decoration::UserSemantic:
284 if (
const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr))
285 SRE = cast<MCSymbolRefExpr>(BE->getLHS());
287 SRE = cast<MCSymbolRefExpr>(Expr);
298 assert((Modifier == 0 || Modifier[0] == 0) &&
"No modifiers supported");
299 if (OpNo < MI->getNumOperands()) {
305 else if (
Op.isDFPImm())
307 else if (
Op.isExpr())
316 const unsigned NumOps =
MI->getNumOperands();
317 unsigned StrStartIndex = OpNo;
318 while (StrStartIndex < NumOps) {
319 if (
MI->getOperand(StrStartIndex).isReg())
323 if (StrStartIndex != OpNo)
333 unsigned numOpsInString = (Str.size() / 4) + 1;
334 StrStartIndex += numOpsInString;
337 if (
MI->getOpcode() == SPIRV::OpDecorate &&
338 MI->getOperand(1).getImm() ==
339 static_cast<unsigned>(Decoration::LinkageAttributes)) {
341 printSymbolicOperand<OperandCategory::LinkageTypeOperand>(
342 MI, StrStartIndex, O);
350 auto SetReg =
MI->getOperand(2).getReg();
351 auto Set = ExtInstSetIDs[SetReg];
352 auto Op =
MI->getOperand(OpNo).getImm();
356template <OperandCategory::OperandCategory category>
359 if (OpNo < MI->getNumOperands()) {
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static void printExpr(const MCExpr *Expr, const MCAsmInfo *MAI, raw_ostream &OS)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
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)
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)