14 #define DEBUG_TYPE "asm-printer"
39 struct SrcMgrDiagInfo {
50 SrcMgrDiagInfo *DiagInfo =
static_cast<SrcMgrDiagInfo *
>(diagInfo);
51 assert(DiagInfo &&
"Diagnostic context not passed down?");
55 unsigned LocCookie = 0;
56 if (
const MDNode *LocInfo = DiagInfo->LocInfo) {
58 if (ErrorLine >= LocInfo->getNumOperands())
61 if (LocInfo->getNumOperands() != 0)
63 dyn_cast<ConstantInt>(LocInfo->getOperand(ErrorLine)))
64 LocCookie = CI->getZExtValue();
67 DiagInfo->DiagHandler(Diag, DiagInfo->DiagContext, LocCookie);
73 assert(!Str.
empty() &&
"Can't emit empty inline asm block");
76 bool isNullTerminated = Str.
back() == 0;
89 SrcMgrDiagInfo DiagInfo;
93 bool HasDiagHandler =
false;
97 DiagInfo.LocInfo = LocMDNode;
101 HasDiagHandler =
true;
105 if (isNullTerminated)
129 " we don't have an asm parser for this target\n");
130 Parser->setAssemblerDialect(Dialect);
131 Parser->setTargetParser(*TAP.get());
134 int Res = Parser->Run(
true,
136 if (Res && !HasDiagHandler)
145 OS <<
"\t.intel_syntax\n\t";
147 const char *LastEmitted = AsmStr;
150 while (*LastEmitted) {
151 switch (*LastEmitted) {
154 const char *LiteralEnd = LastEmitted+1;
155 while (*LiteralEnd && *LiteralEnd !=
'{' && *LiteralEnd !=
'|' &&
156 *LiteralEnd !=
'}' && *LiteralEnd !=
'$' && *LiteralEnd !=
'\n')
159 OS.
write(LastEmitted, LiteralEnd-LastEmitted);
160 LastEmitted = LiteralEnd;
172 switch (*LastEmitted) {
173 default: Done =
false;
break;
180 const char *IDStart = LastEmitted;
181 const char *IDEnd = IDStart;
182 while (*IDEnd >=
'0' && *IDEnd <=
'9') ++IDEnd;
185 if (
StringRef(IDStart, IDEnd-IDStart).getAsInteger(10, Val))
187 Twine(AsmStr) +
"'");
190 if (Val >= NumOperands-1)
192 Twine(AsmStr) +
"'");
196 unsigned OpNo = InlineAsm::MIOp_FirstOperand;
228 Msg <<
"invalid operand in inline asm: '" << AsmStr <<
"'";
235 OS <<
"\n\t.att_syntax\n" << (char)0;
243 const char *LastEmitted = AsmStr;
248 while (*LastEmitted) {
249 switch (*LastEmitted) {
252 const char *LiteralEnd = LastEmitted+1;
253 while (*LiteralEnd && *LiteralEnd !=
'{' && *LiteralEnd !=
'|' &&
254 *LiteralEnd !=
'}' && *LiteralEnd !=
'$' && *LiteralEnd !=
'\n')
256 if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
257 OS.
write(LastEmitted, LiteralEnd-LastEmitted);
258 LastEmitted = LiteralEnd;
270 switch (*LastEmitted) {
271 default: Done =
false;
break;
273 if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
279 if (CurVariant != -1)
281 Twine(AsmStr) +
"'");
286 if (CurVariant == -1)
293 if (CurVariant == -1)
301 bool HasCurlyBraces =
false;
302 if (*LastEmitted ==
'{') {
304 HasCurlyBraces =
true;
310 if (HasCurlyBraces && *LastEmitted ==
':') {
312 const char *StrStart = LastEmitted;
313 const char *StrEnd =
strchr(StrStart,
'}');
316 " string: '" +
Twine(AsmStr) +
"'");
318 std::string Val(StrStart, StrEnd);
320 LastEmitted = StrEnd+1;
324 const char *IDStart = LastEmitted;
325 const char *IDEnd = IDStart;
326 while (*IDEnd >=
'0' && *IDEnd <=
'9') ++IDEnd;
331 Twine(AsmStr) +
"'");
334 char Modifier[2] = { 0, 0 };
336 if (HasCurlyBraces) {
339 if (*LastEmitted ==
':') {
341 if (*LastEmitted == 0)
343 Twine(AsmStr) +
"'");
345 Modifier[0] = *LastEmitted;
349 if (*LastEmitted !=
'}')
351 Twine(AsmStr) +
"'");
355 if (Val >= NumOperands-1)
357 Twine(AsmStr) +
"'");
361 if (CurVariant == -1 || CurVariant == AsmPrinterVariant) {
362 unsigned OpNo = InlineAsm::MIOp_FirstOperand;
383 if (Modifier[0] ==
'l')
389 Modifier[0] ? Modifier : 0,
393 Modifier[0] ? Modifier : 0, OS);
400 Msg <<
"invalid operand in inline asm: '" << AsmStr <<
"'";
408 OS <<
'\n' << (char)0;
414 assert(MI->
isInlineAsm() &&
"printInlineAsm only works on inline asms");
417 unsigned NumDefs = 0;
429 if (AsmStr[0] == 0) {
448 unsigned LocCookie = 0;
455 LocCookie = CI->getZExtValue();
493 const char *
Code)
const {
494 if (!
strcmp(Code,
"private")) {
496 }
else if (!
strcmp(Code,
"comment")) {
498 }
else if (!
strcmp(Code,
"uid")) {
512 Msg <<
"Unknown special formatter '" << Code
513 <<
"' for machine instr: " << *
MI;
522 unsigned AsmVariant,
const char *ExtraCode,
525 if (ExtraCode && ExtraCode[0]) {
526 if (ExtraCode[1] != 0)
return true;
529 switch (ExtraCode[0]) {
static MemoryBuffer * getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
int strcmp(const char *s1, const char *s2);
unsigned getAssemblerDialect() const
void EmitRawText(const Twine &String)
size_t size() const
size - Get the string size.
MachineBasicBlock * getMBB() const
InlineAsmDiagHandlerTy getInlineAsmDiagnosticHandler() const
unsigned getNumOperands() const
getNumOperands - Return number of MDNode operands.
const char * getPrivateGlobalPrefix() const
const StringRef getTargetFeatureString() const
const StringRef getTargetCPU() const
StringRef substr(size_t Start, size_t N=npos) const
virtual bool hasRawTextSupport() const
unsigned getFunctionNumber() const
const char * getSymbolName() const
MDNode - a tuple of other values.
const MDNode * getMetadata() const
bool isMetadata() const
isMetadata - Tests if this is a MO_Metadata operand.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Value * getOperand(unsigned i) const LLVM_READONLY
getOperand - Return specified operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
const Module * getModule() const
virtual void PrintSpecial(const MachineInstr *MI, raw_ostream &OS, const char *Code) const
char *strchr(const char *s, int c);
const char * getInlineAsmEnd() const
unsigned getNumOperands() const
void emitError(unsigned LocCookie, const Twine &ErrorStr)
virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS)
MachineModuleInfo * MMI
MMI - This is a pointer to the current MachineModuleInfo.
const MachineOperand & getOperand(unsigned i) const
char back() const
back - Get the last character in the string.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS)
static unsigned getNumOperandRegisters(unsigned Flag)
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
MCAsmParser * createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &)
Create an MCAsmParser instance.
static void srcMgrDiagHandler(const SMDiagnostic &Diag, void *diagInfo)
static bool isMemKind(unsigned Flag)
enable_if_c< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
MCSymbol * getSymbol() const
MCSubtargetInfo * createMCSubtargetInfo(StringRef Triple, StringRef CPU, StringRef Features) const
raw_ostream & write(unsigned char C)
static MemoryBuffer * getMemBufferCopy(StringRef InputData, StringRef BufferName="")
Class for constant integers.
MCTargetAsmParser * createMCAsmParser(MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII) const
void(* InlineAsmDiagHandlerTy)(const SMDiagnostic &, void *Context, unsigned LocCookie)
const StringRef getTargetTriple() const
void * getInlineAsmDiagnosticContext() const
MachineOperandType getType() const
static void EmitGCCInlineAsmStr(const char *AsmStr, const MachineInstr *MI, MachineModuleInfo *MMI, int InlineAsmVariant, int AsmPrinterVariant, AsmPrinter *AP, unsigned LocCookie, raw_ostream &OS)
void setDiagHandler(DiagHandlerTy DH, void *Ctx=0)
const Target & getTarget() const
static void EmitMSInlineAsmStr(const char *AsmStr, const MachineInstr *MI, MachineModuleInfo *MMI, int InlineAsmVariant, AsmPrinter *AP, unsigned LocCookie, raw_ostream &OS)
const char * getInlineAsmStart() const
Represents a location in source code.
size_t AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc)
const char * getCommentString() const
InlineAsm::AsmDialect getInlineAsmDialect() const
LLVMContext & getContext() const
bool empty() const
empty - Check if the string is empty.