Fix up formatting.
[oota-llvm.git] / lib / CodeGen / AsmPrinter / AsmPrinterInlineAsm.cpp
1 //===-- AsmPrinterInlineAsm.cpp - AsmPrinter Inline Asm Handling ----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the inline assembler pieces of the AsmPrinter class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #define DEBUG_TYPE "asm-printer"
15 #include "llvm/CodeGen/AsmPrinter.h"
16 #include "llvm/ADT/SmallString.h"
17 #include "llvm/ADT/Twine.h"
18 #include "llvm/CodeGen/MachineBasicBlock.h"
19 #include "llvm/CodeGen/MachineModuleInfo.h"
20 #include "llvm/IR/Constants.h"
21 #include "llvm/IR/DataLayout.h"
22 #include "llvm/IR/InlineAsm.h"
23 #include "llvm/IR/LLVMContext.h"
24 #include "llvm/IR/Module.h"
25 #include "llvm/MC/MCAsmInfo.h"
26 #include "llvm/MC/MCStreamer.h"
27 #include "llvm/MC/MCSubtargetInfo.h"
28 #include "llvm/MC/MCSymbol.h"
29 #include "llvm/MC/MCTargetAsmParser.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Support/MemoryBuffer.h"
32 #include "llvm/Support/SourceMgr.h"
33 #include "llvm/Support/TargetRegistry.h"
34 #include "llvm/Support/raw_ostream.h"
35 #include "llvm/Target/TargetMachine.h"
36 #include "llvm/Target/TargetSubtargetInfo.h"
37 using namespace llvm;
38
39 namespace {
40   struct SrcMgrDiagInfo {
41     const MDNode *LocInfo;
42     LLVMContext::InlineAsmDiagHandlerTy DiagHandler;
43     void *DiagContext;
44   };
45 }
46
47 /// srcMgrDiagHandler - This callback is invoked when the SourceMgr for an
48 /// inline asm has an error in it.  diagInfo is a pointer to the SrcMgrDiagInfo
49 /// struct above.
50 static void srcMgrDiagHandler(const SMDiagnostic &Diag, void *diagInfo) {
51   SrcMgrDiagInfo *DiagInfo = static_cast<SrcMgrDiagInfo *>(diagInfo);
52   assert(DiagInfo && "Diagnostic context not passed down?");
53
54   // If the inline asm had metadata associated with it, pull out a location
55   // cookie corresponding to which line the error occurred on.
56   unsigned LocCookie = 0;
57   if (const MDNode *LocInfo = DiagInfo->LocInfo) {
58     unsigned ErrorLine = Diag.getLineNo()-1;
59     if (ErrorLine >= LocInfo->getNumOperands())
60       ErrorLine = 0;
61
62     if (LocInfo->getNumOperands() != 0)
63       if (const ConstantInt *CI =
64           dyn_cast<ConstantInt>(LocInfo->getOperand(ErrorLine)))
65         LocCookie = CI->getZExtValue();
66   }
67
68   DiagInfo->DiagHandler(Diag, DiagInfo->DiagContext, LocCookie);
69 }
70
71 /// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
72 void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode,
73                                InlineAsm::AsmDialect Dialect) const {
74   assert(!Str.empty() && "Can't emit empty inline asm block");
75
76   // Remember if the buffer is nul terminated or not so we can avoid a copy.
77   bool isNullTerminated = Str.back() == 0;
78   if (isNullTerminated)
79     Str = Str.substr(0, Str.size()-1);
80
81   // If the output streamer does not have mature MC support or the integrated
82   // assembler has been disabled, just emit the blob textually.
83   // Otherwise parse the asm and emit it via MC support.
84   // This is useful in case the asm parser doesn't handle something but the
85   // system assembler does.
86   const MCAsmInfo *MCAI = TM.getMCAsmInfo();
87   assert(MCAI && "No MCAsmInfo");
88   if (!MCAI->useIntegratedAssembler() &&
89       !OutStreamer.isIntegratedAssemblerRequired()) {
90     OutStreamer.EmitRawText(Str);
91     emitInlineAsmEnd(TM.getSubtarget<MCSubtargetInfo>(), 0);
92     return;
93   }
94
95   SourceMgr SrcMgr;
96   SrcMgrDiagInfo DiagInfo;
97
98   // If the current LLVMContext has an inline asm handler, set it in SourceMgr.
99   LLVMContext &LLVMCtx = MMI->getModule()->getContext();
100   bool HasDiagHandler = false;
101   if (LLVMCtx.getInlineAsmDiagnosticHandler() != 0) {
102     // If the source manager has an issue, we arrange for srcMgrDiagHandler
103     // to be invoked, getting DiagInfo passed into it.
104     DiagInfo.LocInfo = LocMDNode;
105     DiagInfo.DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler();
106     DiagInfo.DiagContext = LLVMCtx.getInlineAsmDiagnosticContext();
107     SrcMgr.setDiagHandler(srcMgrDiagHandler, &DiagInfo);
108     HasDiagHandler = true;
109   }
110
111   MemoryBuffer *Buffer;
112   if (isNullTerminated)
113     Buffer = MemoryBuffer::getMemBuffer(Str, "<inline asm>");
114   else
115     Buffer = MemoryBuffer::getMemBufferCopy(Str, "<inline asm>");
116
117   // Tell SrcMgr about this buffer, it takes ownership of the buffer.
118   SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
119
120   std::unique_ptr<MCAsmParser> Parser(
121       createMCAsmParser(SrcMgr, OutContext, OutStreamer, *MAI));
122
123   // Initialize the parser with a fresh subtarget info. It is better to use a
124   // new STI here because the parser may modify it and we do not want those
125   // modifications to persist after parsing the inlineasm. The modifications
126   // made by the parser will be seen by the code emitters because it passes
127   // the current STI down to the EncodeInstruction() method.
128   std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo(
129       TM.getTargetTriple(), TM.getTargetCPU(), TM.getTargetFeatureString()));
130
131   // Preserve a copy of the original STI because the parser may modify it.  For
132   // example, when switching between arm and thumb mode. If the target needs to
133   // emit code to return to the original state it can do so in
134   // emitInlineAsmEnd().
135   MCSubtargetInfo STIOrig = *STI;
136
137   std::unique_ptr<MCTargetAsmParser> TAP(
138       TM.getTarget().createMCAsmParser(*STI, *Parser, *MII));
139   if (!TAP)
140     report_fatal_error("Inline asm not supported by this streamer because"
141                        " we don't have an asm parser for this target\n");
142   Parser->setAssemblerDialect(Dialect);
143   Parser->setTargetParser(*TAP.get());
144
145   // Don't implicitly switch to the text section before the asm.
146   int Res = Parser->Run(/*NoInitialTextSection*/ true,
147                         /*NoFinalize*/ true);
148   emitInlineAsmEnd(STIOrig, STI.get());
149   if (Res && !HasDiagHandler)
150     report_fatal_error("Error parsing inline asm\n");
151 }
152
153 static void EmitMSInlineAsmStr(const char *AsmStr, const MachineInstr *MI,
154                                MachineModuleInfo *MMI, int InlineAsmVariant,
155                                AsmPrinter *AP, unsigned LocCookie,
156                                raw_ostream &OS) {
157   // Switch to the inline assembly variant.
158   OS << "\t.intel_syntax\n\t";
159
160   const char *LastEmitted = AsmStr; // One past the last character emitted.
161   unsigned NumOperands = MI->getNumOperands();
162
163   while (*LastEmitted) {
164     switch (*LastEmitted) {
165     default: {
166       // Not a special case, emit the string section literally.
167       const char *LiteralEnd = LastEmitted+1;
168       while (*LiteralEnd && *LiteralEnd != '{' && *LiteralEnd != '|' &&
169              *LiteralEnd != '}' && *LiteralEnd != '$' && *LiteralEnd != '\n')
170         ++LiteralEnd;
171
172       OS.write(LastEmitted, LiteralEnd-LastEmitted);
173       LastEmitted = LiteralEnd;
174       break;
175     }
176     case '\n':
177       ++LastEmitted;   // Consume newline character.
178       OS << '\n';      // Indent code with newline.
179       break;
180     case '$': {
181       ++LastEmitted;   // Consume '$' character.
182       bool Done = true;
183
184       // Handle escapes.
185       switch (*LastEmitted) {
186       default: Done = false; break;
187       case '$':
188         ++LastEmitted;  // Consume second '$' character.
189         break;
190       }
191       if (Done) break;
192
193       const char *IDStart = LastEmitted;
194       const char *IDEnd = IDStart;
195       while (*IDEnd >= '0' && *IDEnd <= '9') ++IDEnd;
196
197       unsigned Val;
198       if (StringRef(IDStart, IDEnd-IDStart).getAsInteger(10, Val))
199         report_fatal_error("Bad $ operand number in inline asm string: '" +
200                            Twine(AsmStr) + "'");
201       LastEmitted = IDEnd;
202
203       if (Val >= NumOperands-1)
204         report_fatal_error("Invalid $ operand number in inline asm string: '" +
205                            Twine(AsmStr) + "'");
206
207       // Okay, we finally have a value number.  Ask the target to print this
208       // operand!
209       unsigned OpNo = InlineAsm::MIOp_FirstOperand;
210
211       bool Error = false;
212
213       // Scan to find the machine operand number for the operand.
214       for (; Val; --Val) {
215         if (OpNo >= MI->getNumOperands()) break;
216         unsigned OpFlags = MI->getOperand(OpNo).getImm();
217         OpNo += InlineAsm::getNumOperandRegisters(OpFlags) + 1;
218       }
219
220       // We may have a location metadata attached to the end of the
221       // instruction, and at no point should see metadata at any
222       // other point while processing. It's an error if so.
223       if (OpNo >= MI->getNumOperands() ||
224           MI->getOperand(OpNo).isMetadata()) {
225         Error = true;
226       } else {
227         unsigned OpFlags = MI->getOperand(OpNo).getImm();
228         ++OpNo;  // Skip over the ID number.
229
230         if (InlineAsm::isMemKind(OpFlags)) {
231           Error = AP->PrintAsmMemoryOperand(MI, OpNo, InlineAsmVariant,
232                                             /*Modifier*/ 0, OS);
233         } else {
234           Error = AP->PrintAsmOperand(MI, OpNo, InlineAsmVariant,
235                                       /*Modifier*/ 0, OS);
236         }
237       }
238       if (Error) {
239         std::string msg;
240         raw_string_ostream Msg(msg);
241         Msg << "invalid operand in inline asm: '" << AsmStr << "'";
242         MMI->getModule()->getContext().emitError(LocCookie, Msg.str());
243       }
244       break;
245     }
246     }
247   }
248   OS << "\n\t.att_syntax\n" << (char)0;  // null terminate string.
249 }
250
251 static void EmitGCCInlineAsmStr(const char *AsmStr, const MachineInstr *MI,
252                                 MachineModuleInfo *MMI, int InlineAsmVariant,
253                                 int AsmPrinterVariant, AsmPrinter *AP,
254                                 unsigned LocCookie, raw_ostream &OS) {
255   int CurVariant = -1;            // The number of the {.|.|.} region we are in.
256   const char *LastEmitted = AsmStr; // One past the last character emitted.
257   unsigned NumOperands = MI->getNumOperands();
258
259   OS << '\t';
260
261   while (*LastEmitted) {
262     switch (*LastEmitted) {
263     default: {
264       // Not a special case, emit the string section literally.
265       const char *LiteralEnd = LastEmitted+1;
266       while (*LiteralEnd && *LiteralEnd != '{' && *LiteralEnd != '|' &&
267              *LiteralEnd != '}' && *LiteralEnd != '$' && *LiteralEnd != '\n')
268         ++LiteralEnd;
269       if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
270         OS.write(LastEmitted, LiteralEnd-LastEmitted);
271       LastEmitted = LiteralEnd;
272       break;
273     }
274     case '\n':
275       ++LastEmitted;   // Consume newline character.
276       OS << '\n';      // Indent code with newline.
277       break;
278     case '$': {
279       ++LastEmitted;   // Consume '$' character.
280       bool Done = true;
281
282       // Handle escapes.
283       switch (*LastEmitted) {
284       default: Done = false; break;
285       case '$':     // $$ -> $
286         if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
287           OS << '$';
288         ++LastEmitted;  // Consume second '$' character.
289         break;
290       case '(':             // $( -> same as GCC's { character.
291         ++LastEmitted;      // Consume '(' character.
292         if (CurVariant != -1)
293           report_fatal_error("Nested variants found in inline asm string: '" +
294                              Twine(AsmStr) + "'");
295         CurVariant = 0;     // We're in the first variant now.
296         break;
297       case '|':
298         ++LastEmitted;  // consume '|' character.
299         if (CurVariant == -1)
300           OS << '|';       // this is gcc's behavior for | outside a variant
301         else
302           ++CurVariant;   // We're in the next variant.
303         break;
304       case ')':         // $) -> same as GCC's } char.
305         ++LastEmitted;  // consume ')' character.
306         if (CurVariant == -1)
307           OS << '}';     // this is gcc's behavior for } outside a variant
308         else
309           CurVariant = -1;
310         break;
311       }
312       if (Done) break;
313
314       bool HasCurlyBraces = false;
315       if (*LastEmitted == '{') {     // ${variable}
316         ++LastEmitted;               // Consume '{' character.
317         HasCurlyBraces = true;
318       }
319
320       // If we have ${:foo}, then this is not a real operand reference, it is a
321       // "magic" string reference, just like in .td files.  Arrange to call
322       // PrintSpecial.
323       if (HasCurlyBraces && *LastEmitted == ':') {
324         ++LastEmitted;
325         const char *StrStart = LastEmitted;
326         const char *StrEnd = strchr(StrStart, '}');
327         if (StrEnd == 0)
328           report_fatal_error("Unterminated ${:foo} operand in inline asm"
329                              " string: '" + Twine(AsmStr) + "'");
330
331         std::string Val(StrStart, StrEnd);
332         AP->PrintSpecial(MI, OS, Val.c_str());
333         LastEmitted = StrEnd+1;
334         break;
335       }
336
337       const char *IDStart = LastEmitted;
338       const char *IDEnd = IDStart;
339       while (*IDEnd >= '0' && *IDEnd <= '9') ++IDEnd;
340
341       unsigned Val;
342       if (StringRef(IDStart, IDEnd-IDStart).getAsInteger(10, Val))
343         report_fatal_error("Bad $ operand number in inline asm string: '" +
344                            Twine(AsmStr) + "'");
345       LastEmitted = IDEnd;
346
347       char Modifier[2] = { 0, 0 };
348
349       if (HasCurlyBraces) {
350         // If we have curly braces, check for a modifier character.  This
351         // supports syntax like ${0:u}, which correspond to "%u0" in GCC asm.
352         if (*LastEmitted == ':') {
353           ++LastEmitted;    // Consume ':' character.
354           if (*LastEmitted == 0)
355             report_fatal_error("Bad ${:} expression in inline asm string: '" +
356                                Twine(AsmStr) + "'");
357
358           Modifier[0] = *LastEmitted;
359           ++LastEmitted;    // Consume modifier character.
360         }
361
362         if (*LastEmitted != '}')
363           report_fatal_error("Bad ${} expression in inline asm string: '" +
364                              Twine(AsmStr) + "'");
365         ++LastEmitted;    // Consume '}' character.
366       }
367
368       if (Val >= NumOperands-1)
369         report_fatal_error("Invalid $ operand number in inline asm string: '" +
370                            Twine(AsmStr) + "'");
371
372       // Okay, we finally have a value number.  Ask the target to print this
373       // operand!
374       if (CurVariant == -1 || CurVariant == AsmPrinterVariant) {
375         unsigned OpNo = InlineAsm::MIOp_FirstOperand;
376
377         bool Error = false;
378
379         // Scan to find the machine operand number for the operand.
380         for (; Val; --Val) {
381           if (OpNo >= MI->getNumOperands()) break;
382           unsigned OpFlags = MI->getOperand(OpNo).getImm();
383           OpNo += InlineAsm::getNumOperandRegisters(OpFlags) + 1;
384         }
385
386         // We may have a location metadata attached to the end of the
387         // instruction, and at no point should see metadata at any
388         // other point while processing. It's an error if so.
389         if (OpNo >= MI->getNumOperands() ||
390             MI->getOperand(OpNo).isMetadata()) {
391           Error = true;
392         } else {
393           unsigned OpFlags = MI->getOperand(OpNo).getImm();
394           ++OpNo;  // Skip over the ID number.
395
396           if (Modifier[0] == 'l')  // labels are target independent
397             // FIXME: What if the operand isn't an MBB, report error?
398             OS << *MI->getOperand(OpNo).getMBB()->getSymbol();
399           else {
400             if (InlineAsm::isMemKind(OpFlags)) {
401               Error = AP->PrintAsmMemoryOperand(MI, OpNo, InlineAsmVariant,
402                                                 Modifier[0] ? Modifier : 0,
403                                                 OS);
404             } else {
405               Error = AP->PrintAsmOperand(MI, OpNo, InlineAsmVariant,
406                                           Modifier[0] ? Modifier : 0, OS);
407             }
408           }
409         }
410         if (Error) {
411           std::string msg;
412           raw_string_ostream Msg(msg);
413           Msg << "invalid operand in inline asm: '" << AsmStr << "'";
414           MMI->getModule()->getContext().emitError(LocCookie, Msg.str());
415         }
416       }
417       break;
418     }
419     }
420   }
421   OS << '\n' << (char)0;  // null terminate string.
422 }
423
424 /// EmitInlineAsm - This method formats and emits the specified machine
425 /// instruction that is an inline asm.
426 void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const {
427   assert(MI->isInlineAsm() && "printInlineAsm only works on inline asms");
428
429   // Count the number of register definitions to find the asm string.
430   unsigned NumDefs = 0;
431   for (; MI->getOperand(NumDefs).isReg() && MI->getOperand(NumDefs).isDef();
432        ++NumDefs)
433     assert(NumDefs != MI->getNumOperands()-2 && "No asm string?");
434
435   assert(MI->getOperand(NumDefs).isSymbol() && "No asm string?");
436
437   // Disassemble the AsmStr, printing out the literal pieces, the operands, etc.
438   const char *AsmStr = MI->getOperand(NumDefs).getSymbolName();
439
440   // If this asmstr is empty, just print the #APP/#NOAPP markers.
441   // These are useful to see where empty asm's wound up.
442   if (AsmStr[0] == 0) {
443     OutStreamer.emitRawComment(MAI->getInlineAsmStart());
444     OutStreamer.emitRawComment(MAI->getInlineAsmEnd());
445     return;
446   }
447
448   // Emit the #APP start marker.  This has to happen even if verbose-asm isn't
449   // enabled, so we use emitRawComment.
450   OutStreamer.emitRawComment(MAI->getInlineAsmStart());
451
452   // Get the !srcloc metadata node if we have it, and decode the loc cookie from
453   // it.
454   unsigned LocCookie = 0;
455   const MDNode *LocMD = 0;
456   for (unsigned i = MI->getNumOperands(); i != 0; --i) {
457     if (MI->getOperand(i-1).isMetadata() &&
458         (LocMD = MI->getOperand(i-1).getMetadata()) &&
459         LocMD->getNumOperands() != 0) {
460       if (const ConstantInt *CI = dyn_cast<ConstantInt>(LocMD->getOperand(0))) {
461         LocCookie = CI->getZExtValue();
462         break;
463       }
464     }
465   }
466
467   // Emit the inline asm to a temporary string so we can emit it through
468   // EmitInlineAsm.
469   SmallString<256> StringData;
470   raw_svector_ostream OS(StringData);
471
472   // The variant of the current asmprinter.
473   int AsmPrinterVariant = MAI->getAssemblerDialect();
474   InlineAsm::AsmDialect InlineAsmVariant = MI->getInlineAsmDialect();
475   AsmPrinter *AP = const_cast<AsmPrinter*>(this);
476   if (InlineAsmVariant == InlineAsm::AD_ATT)
477     EmitGCCInlineAsmStr(AsmStr, MI, MMI, InlineAsmVariant, AsmPrinterVariant,
478                         AP, LocCookie, OS);
479   else
480     EmitMSInlineAsmStr(AsmStr, MI, MMI, InlineAsmVariant, AP, LocCookie, OS);
481
482   EmitInlineAsm(OS.str(), LocMD, MI->getInlineAsmDialect());
483
484   // Emit the #NOAPP end marker.  This has to happen even if verbose-asm isn't
485   // enabled, so we use emitRawComment.
486   OutStreamer.emitRawComment(MAI->getInlineAsmEnd());
487 }
488
489
490 /// PrintSpecial - Print information related to the specified machine instr
491 /// that is independent of the operand, and may be independent of the instr
492 /// itself.  This can be useful for portably encoding the comment character
493 /// or other bits of target-specific knowledge into the asmstrings.  The
494 /// syntax used is ${:comment}.  Targets can override this to add support
495 /// for their own strange codes.
496 void AsmPrinter::PrintSpecial(const MachineInstr *MI, raw_ostream &OS,
497                               const char *Code) const {
498   const DataLayout *DL = TM.getDataLayout();
499   if (!strcmp(Code, "private")) {
500     OS << DL->getPrivateGlobalPrefix();
501   } else if (!strcmp(Code, "comment")) {
502     OS << MAI->getCommentString();
503   } else if (!strcmp(Code, "uid")) {
504     // Comparing the address of MI isn't sufficient, because machineinstrs may
505     // be allocated to the same address across functions.
506
507     // If this is a new LastFn instruction, bump the counter.
508     if (LastMI != MI || LastFn != getFunctionNumber()) {
509       ++Counter;
510       LastMI = MI;
511       LastFn = getFunctionNumber();
512     }
513     OS << Counter;
514   } else {
515     std::string msg;
516     raw_string_ostream Msg(msg);
517     Msg << "Unknown special formatter '" << Code
518          << "' for machine instr: " << *MI;
519     report_fatal_error(Msg.str());
520   }
521 }
522
523 /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
524 /// instruction, using the specified assembler variant.  Targets should
525 /// override this to format as appropriate.
526 bool AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
527                                  unsigned AsmVariant, const char *ExtraCode,
528                                  raw_ostream &O) {
529   // Does this asm operand have a single letter operand modifier?
530   if (ExtraCode && ExtraCode[0]) {
531     if (ExtraCode[1] != 0) return true; // Unknown modifier.
532
533     const MachineOperand &MO = MI->getOperand(OpNo);
534     switch (ExtraCode[0]) {
535     default:
536       return true;  // Unknown modifier.
537     case 'c': // Substitute immediate value without immediate syntax
538       if (MO.getType() != MachineOperand::MO_Immediate)
539         return true;
540       O << MO.getImm();
541       return false;
542     case 'n':  // Negate the immediate constant.
543       if (MO.getType() != MachineOperand::MO_Immediate)
544         return true;
545       O << -MO.getImm();
546       return false;
547     }
548   }
549   return true;
550 }
551
552 bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
553                                        unsigned AsmVariant,
554                                        const char *ExtraCode, raw_ostream &O) {
555   // Target doesn't support this yet!
556   return true;
557 }
558
559 void AsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
560                                   const MCSubtargetInfo *EndInfo) const {}