1 //===-- AsmPrinter.cpp - Common AsmPrinter code ---------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the AsmPrinter class.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/CodeGen/AsmPrinter.h"
15 #include "llvm/Assembly/Writer.h"
16 #include "llvm/DerivedTypes.h"
17 #include "llvm/Constants.h"
18 #include "llvm/Module.h"
19 #include "llvm/CodeGen/MachineConstantPool.h"
20 #include "llvm/CodeGen/MachineJumpTableInfo.h"
21 #include "llvm/Support/Mangler.h"
22 #include "llvm/Support/MathExtras.h"
23 #include "llvm/Target/TargetData.h"
24 #include "llvm/Target/TargetMachine.h"
29 AsmPrinter::AsmPrinter(std::ostream
&o
, TargetMachine
&tm
)
30 : FunctionNumber(0), O(o
), TM(tm
),
33 PrivateGlobalPrefix("."),
34 GlobalVarAddrPrefix(""),
35 GlobalVarAddrSuffix(""),
36 FunctionAddrPrefix(""),
37 FunctionAddrSuffix(""),
38 InlineAsmStart("#APP"),
39 InlineAsmEnd("#NO_APP"),
40 ZeroDirective("\t.zero\t"),
41 ZeroDirectiveSuffix(0),
42 AsciiDirective("\t.ascii\t"),
43 AscizDirective("\t.asciz\t"),
44 Data8bitsDirective("\t.byte\t"),
45 Data16bitsDirective("\t.short\t"),
46 Data32bitsDirective("\t.long\t"),
47 Data64bitsDirective("\t.quad\t"),
48 AlignDirective("\t.align\t"),
49 AlignmentIsInBytes(true),
50 SwitchToSectionDirective("\t.section\t"),
51 TextSectionStartSuffix(""),
52 DataSectionStartSuffix(""),
53 SectionEndDirectiveSuffix(0),
54 ConstantPoolSection("\t.section .rodata\n"),
55 JumpTableDataSection("\t.section .rodata\n"),
56 JumpTableTextSection("\t.text\n"),
57 StaticCtorsSection("\t.section .ctors,\"aw\",@progbits"),
58 StaticDtorsSection("\t.section .dtors,\"aw\",@progbits"),
59 FourByteConstantSection(0),
60 EightByteConstantSection(0),
61 SixteenByteConstantSection(0),
63 COMMDirective("\t.comm\t"),
64 COMMDirectiveTakesAlignment(true),
65 HasDotTypeDotSizeDirective(true) {
69 /// SwitchToTextSection - Switch to the specified text section of the executable
70 /// if we are not already in it!
72 void AsmPrinter::SwitchToTextSection(const char *NewSection
,
73 const GlobalValue
*GV
) {
75 if (GV
&& GV
->hasSection())
76 NS
= SwitchToSectionDirective
+ GV
->getSection();
80 // If we're already in this section, we're done.
81 if (CurrentSection
== NS
) return;
83 // Close the current section, if applicable.
84 if (SectionEndDirectiveSuffix
&& !CurrentSection
.empty())
85 O
<< CurrentSection
<< SectionEndDirectiveSuffix
<< "\n";
89 if (!CurrentSection
.empty())
90 O
<< CurrentSection
<< TextSectionStartSuffix
<< '\n';
93 /// SwitchToDataSection - Switch to the specified data section of the executable
94 /// if we are not already in it!
96 void AsmPrinter::SwitchToDataSection(const char *NewSection
,
97 const GlobalValue
*GV
) {
99 if (GV
&& GV
->hasSection())
100 NS
= SwitchToSectionDirective
+ GV
->getSection();
104 // If we're already in this section, we're done.
105 if (CurrentSection
== NS
) return;
107 // Close the current section, if applicable.
108 if (SectionEndDirectiveSuffix
&& !CurrentSection
.empty())
109 O
<< CurrentSection
<< SectionEndDirectiveSuffix
<< "\n";
113 if (!CurrentSection
.empty())
114 O
<< CurrentSection
<< DataSectionStartSuffix
<< '\n';
118 bool AsmPrinter::doInitialization(Module
&M
) {
119 Mang
= new Mangler(M
, GlobalPrefix
);
121 if (!M
.getModuleInlineAsm().empty())
122 O
<< CommentString
<< " Start of file scope inline assembly\n"
123 << M
.getModuleInlineAsm()
124 << "\n" << CommentString
<< " End of file scope inline assembly\n";
126 SwitchToDataSection("", 0); // Reset back to no section.
128 if (MachineDebugInfo
*DebugInfo
= getAnalysisToUpdate
<MachineDebugInfo
>()) {
129 DebugInfo
->AnalyzeModule(M
);
135 bool AsmPrinter::doFinalization(Module
&M
) {
136 delete Mang
; Mang
= 0;
140 void AsmPrinter::SetupMachineFunction(MachineFunction
&MF
) {
141 // What's my mangled name?
142 CurrentFnName
= Mang
->getValueName(MF
.getFunction());
143 IncrementFunctionNumber();
146 /// EmitConstantPool - Print to the current output stream assembly
147 /// representations of the constants in the constant pool MCP. This is
148 /// used to print out constants which have been "spilled to memory" by
149 /// the code generator.
151 void AsmPrinter::EmitConstantPool(MachineConstantPool
*MCP
) {
152 const std::vector
<MachineConstantPoolEntry
> &CP
= MCP
->getConstants();
153 if (CP
.empty()) return;
155 // Some targets require 4-, 8-, and 16- byte constant literals to be placed
156 // in special sections.
157 std::vector
<std::pair
<MachineConstantPoolEntry
,unsigned> > FourByteCPs
;
158 std::vector
<std::pair
<MachineConstantPoolEntry
,unsigned> > EightByteCPs
;
159 std::vector
<std::pair
<MachineConstantPoolEntry
,unsigned> > SixteenByteCPs
;
160 std::vector
<std::pair
<MachineConstantPoolEntry
,unsigned> > OtherCPs
;
161 for (unsigned i
= 0, e
= CP
.size(); i
!= e
; ++i
) {
162 MachineConstantPoolEntry CPE
= CP
[i
];
163 const Constant
*CV
= CPE
.Val
;
164 const Type
*Ty
= CV
->getType();
165 if (FourByteConstantSection
&&
166 TM
.getTargetData()->getTypeSize(Ty
) == 4)
167 FourByteCPs
.push_back(std::make_pair(CPE
, i
));
168 else if (EightByteConstantSection
&&
169 TM
.getTargetData()->getTypeSize(Ty
) == 8)
170 EightByteCPs
.push_back(std::make_pair(CPE
, i
));
171 else if (SixteenByteConstantSection
&&
172 TM
.getTargetData()->getTypeSize(Ty
) == 16)
173 SixteenByteCPs
.push_back(std::make_pair(CPE
, i
));
175 OtherCPs
.push_back(std::make_pair(CPE
, i
));
178 unsigned Alignment
= MCP
->getConstantPoolAlignment();
179 EmitConstantPool(Alignment
, FourByteConstantSection
, FourByteCPs
);
180 EmitConstantPool(Alignment
, EightByteConstantSection
, EightByteCPs
);
181 EmitConstantPool(Alignment
, SixteenByteConstantSection
, SixteenByteCPs
);
182 EmitConstantPool(Alignment
, ConstantPoolSection
, OtherCPs
);
185 void AsmPrinter::EmitConstantPool(unsigned Alignment
, const char *Section
,
186 std::vector
<std::pair
<MachineConstantPoolEntry
,unsigned> > &CP
) {
187 if (CP
.empty()) return;
189 SwitchToDataSection(Section
, 0);
190 EmitAlignment(Alignment
);
191 for (unsigned i
= 0, e
= CP
.size(); i
!= e
; ++i
) {
192 O
<< PrivateGlobalPrefix
<< "CPI" << getFunctionNumber() << '_'
193 << CP
[i
].second
<< ":\t\t\t\t\t" << CommentString
<< " ";
194 WriteTypeSymbolic(O
, CP
[i
].first
.Val
->getType(), 0) << '\n';
195 EmitGlobalConstant(CP
[i
].first
.Val
);
198 TM
.getTargetData()->getTypeSize(CP
[i
].first
.Val
->getType());
199 unsigned ValEnd
= CP
[i
].first
.Offset
+ EntSize
;
200 // Emit inter-object padding for alignment.
201 EmitZeros(CP
[i
+1].first
.Offset
-ValEnd
);
206 /// EmitJumpTableInfo - Print assembly representations of the jump tables used
207 /// by the current function to the current output stream.
209 void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo
*MJTI
) {
210 const std::vector
<MachineJumpTableEntry
> &JT
= MJTI
->getJumpTables();
211 if (JT
.empty()) return;
212 const TargetData
*TD
= TM
.getTargetData();
214 // JTEntryDirective is a string to print sizeof(ptr) for non-PIC jump tables,
215 // and 32 bits for PIC since PIC jump table entries are differences, not
216 // pointers to blocks.
217 const char *JTEntryDirective
= Data32bitsDirective
;
219 // Pick the directive to use to print the jump table entries, and switch to
220 // the appropriate section.
221 if (TM
.getRelocationModel() == Reloc::PIC_
) {
222 SwitchToTextSection(JumpTableTextSection
, 0);
224 SwitchToDataSection(JumpTableDataSection
, 0);
225 if (TD
->getPointerSize() == 8)
226 JTEntryDirective
= Data64bitsDirective
;
228 EmitAlignment(Log2_32(TD
->getPointerAlignment()));
230 for (unsigned i
= 0, e
= JT
.size(); i
!= e
; ++i
) {
231 O
<< PrivateGlobalPrefix
<< "JTI" << getFunctionNumber() << '_' << i
233 const std::vector
<MachineBasicBlock
*> &JTBBs
= JT
[i
].MBBs
;
234 for (unsigned ii
= 0, ee
= JTBBs
.size(); ii
!= ee
; ++ii
) {
235 O
<< JTEntryDirective
<< ' ';
236 printBasicBlockLabel(JTBBs
[ii
], false, false);
237 if (TM
.getRelocationModel() == Reloc::PIC_
) {
238 O
<< '-' << PrivateGlobalPrefix
<< "JTI" << getFunctionNumber()
246 /// EmitSpecialLLVMGlobal - Check to see if the specified global is a
247 /// special global used by LLVM. If so, emit it and return true, otherwise
248 /// do nothing and return false.
249 bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable
*GV
) {
250 // Ignore debug and non-emitted data.
251 if (GV
->getSection() == "llvm.metadata") return true;
253 if (!GV
->hasAppendingLinkage()) return false;
255 assert(GV
->hasInitializer() && "Not a special LLVM global!");
257 if (GV
->getName() == "llvm.used")
258 return true; // No need to emit this at all.
260 if (GV
->getName() == "llvm.global_ctors" && GV
->use_empty()) {
261 SwitchToDataSection(StaticCtorsSection
, 0);
263 EmitXXStructorList(GV
->getInitializer());
267 if (GV
->getName() == "llvm.global_dtors" && GV
->use_empty()) {
268 SwitchToDataSection(StaticDtorsSection
, 0);
270 EmitXXStructorList(GV
->getInitializer());
277 /// EmitXXStructorList - Emit the ctor or dtor list. This just prints out the
278 /// function pointers, ignoring the init priority.
279 void AsmPrinter::EmitXXStructorList(Constant
*List
) {
280 // Should be an array of '{ int, void ()* }' structs. The first value is the
281 // init priority, which we ignore.
282 if (!isa
<ConstantArray
>(List
)) return;
283 ConstantArray
*InitList
= cast
<ConstantArray
>(List
);
284 for (unsigned i
= 0, e
= InitList
->getNumOperands(); i
!= e
; ++i
)
285 if (ConstantStruct
*CS
= dyn_cast
<ConstantStruct
>(InitList
->getOperand(i
))){
286 if (CS
->getNumOperands() != 2) return; // Not array of 2-element structs.
288 if (CS
->getOperand(1)->isNullValue())
289 return; // Found a null terminator, exit printing.
290 // Emit the function pointer.
291 EmitGlobalConstant(CS
->getOperand(1));
295 /// getPreferredAlignmentLog - Return the preferred alignment of the
296 /// specified global, returned in log form. This includes an explicitly
297 /// requested alignment (if the global has one).
298 unsigned AsmPrinter::getPreferredAlignmentLog(const GlobalVariable
*GV
) const {
299 const Type
*ElemType
= GV
->getType()->getElementType();
300 unsigned Alignment
= TM
.getTargetData()->getTypeAlignmentShift(ElemType
);
301 if (GV
->getAlignment() > (1U << Alignment
))
302 Alignment
= Log2_32(GV
->getAlignment());
304 if (GV
->hasInitializer()) {
305 // Always round up alignment of global doubles to 8 bytes.
306 if (GV
->getType()->getElementType() == Type::DoubleTy
&& Alignment
< 3)
309 // If the global is not external, see if it is large. If so, give it a
311 if (TM
.getTargetData()->getTypeSize(ElemType
) > 128)
312 Alignment
= 4; // 16-byte alignment.
318 // EmitAlignment - Emit an alignment directive to the specified power of two.
319 void AsmPrinter::EmitAlignment(unsigned NumBits
, const GlobalValue
*GV
) const {
320 if (GV
&& GV
->getAlignment())
321 NumBits
= Log2_32(GV
->getAlignment());
322 if (NumBits
== 0) return; // No need to emit alignment.
323 if (AlignmentIsInBytes
) NumBits
= 1 << NumBits
;
324 O
<< AlignDirective
<< NumBits
<< "\n";
327 /// EmitZeros - Emit a block of zeros.
329 void AsmPrinter::EmitZeros(uint64_t NumZeros
) const {
332 O
<< ZeroDirective
<< NumZeros
;
333 if (ZeroDirectiveSuffix
)
334 O
<< ZeroDirectiveSuffix
;
337 for (; NumZeros
; --NumZeros
)
338 O
<< Data8bitsDirective
<< "0\n";
343 // Print out the specified constant, without a storage class. Only the
344 // constants valid in constant expressions can occur here.
345 void AsmPrinter::EmitConstantValueOnly(const Constant
*CV
) {
346 if (CV
->isNullValue() || isa
<UndefValue
>(CV
))
348 else if (const ConstantBool
*CB
= dyn_cast
<ConstantBool
>(CV
)) {
349 assert(CB
== ConstantBool::True
);
351 } else if (const ConstantSInt
*CI
= dyn_cast
<ConstantSInt
>(CV
))
352 if (((CI
->getValue() << 32) >> 32) == CI
->getValue())
355 O
<< (uint64_t)CI
->getValue();
356 else if (const ConstantUInt
*CI
= dyn_cast
<ConstantUInt
>(CV
))
358 else if (const GlobalValue
*GV
= dyn_cast
<GlobalValue
>(CV
)) {
359 // This is a constant address for a global variable or function. Use the
360 // name of the variable or function as the address value, possibly
361 // decorating it with GlobalVarAddrPrefix/Suffix or
362 // FunctionAddrPrefix/Suffix (these all default to "" )
363 if (isa
<Function
>(GV
))
364 O
<< FunctionAddrPrefix
<< Mang
->getValueName(GV
) << FunctionAddrSuffix
;
366 O
<< GlobalVarAddrPrefix
<< Mang
->getValueName(GV
) << GlobalVarAddrSuffix
;
367 } else if (const ConstantExpr
*CE
= dyn_cast
<ConstantExpr
>(CV
)) {
368 const TargetData
*TD
= TM
.getTargetData();
369 switch(CE
->getOpcode()) {
370 case Instruction::GetElementPtr
: {
371 // generate a symbolic expression for the byte address
372 const Constant
*ptrVal
= CE
->getOperand(0);
373 std::vector
<Value
*> idxVec(CE
->op_begin()+1, CE
->op_end());
374 if (int64_t Offset
= TD
->getIndexedOffset(ptrVal
->getType(), idxVec
)) {
377 EmitConstantValueOnly(ptrVal
);
379 O
<< ") + " << Offset
;
381 O
<< ") - " << -Offset
;
383 EmitConstantValueOnly(ptrVal
);
387 case Instruction::Cast
: {
388 // Support only foldable casts to/from pointers that can be eliminated by
389 // changing the pointer to the appropriately sized integer type.
390 Constant
*Op
= CE
->getOperand(0);
391 const Type
*OpTy
= Op
->getType(), *Ty
= CE
->getType();
393 // Handle casts to pointers by changing them into casts to the appropriate
394 // integer type. This promotes constant folding and simplifies this code.
395 if (isa
<PointerType
>(Ty
)) {
396 const Type
*IntPtrTy
= TD
->getIntPtrType();
397 Op
= ConstantExpr::getCast(Op
, IntPtrTy
);
398 return EmitConstantValueOnly(Op
);
401 // We know the dest type is not a pointer. Is the src value a pointer or
403 if (isa
<PointerType
>(OpTy
) || OpTy
->isIntegral()) {
404 // We can emit the pointer value into this slot if the slot is an
405 // integer slot greater or equal to the size of the pointer.
406 if (Ty
->isIntegral() && TD
->getTypeSize(Ty
) >= TD
->getTypeSize(OpTy
))
407 return EmitConstantValueOnly(Op
);
410 assert(0 && "FIXME: Don't yet support this kind of constant cast expr");
411 EmitConstantValueOnly(Op
);
414 case Instruction::Add
:
416 EmitConstantValueOnly(CE
->getOperand(0));
418 EmitConstantValueOnly(CE
->getOperand(1));
422 assert(0 && "Unsupported operator!");
425 assert(0 && "Unknown constant value!");
429 /// toOctal - Convert the low order bits of X into an octal digit.
431 static inline char toOctal(int X
) {
435 /// printAsCString - Print the specified array as a C compatible string, only if
436 /// the predicate isString is true.
438 static void printAsCString(std::ostream
&O
, const ConstantArray
*CVA
,
440 assert(CVA
->isString() && "Array is not string compatible!");
443 for (unsigned i
= 0; i
!= LastElt
; ++i
) {
445 (unsigned char)cast
<ConstantInt
>(CVA
->getOperand(i
))->getRawValue();
449 } else if (C
== '\\') {
451 } else if (isprint(C
)) {
455 case '\b': O
<< "\\b"; break;
456 case '\f': O
<< "\\f"; break;
457 case '\n': O
<< "\\n"; break;
458 case '\r': O
<< "\\r"; break;
459 case '\t': O
<< "\\t"; break;
462 O
<< toOctal(C
>> 6);
463 O
<< toOctal(C
>> 3);
464 O
<< toOctal(C
>> 0);
472 /// EmitString - Emit a zero-byte-terminated string constant.
474 void AsmPrinter::EmitString(const ConstantArray
*CVA
) const {
475 unsigned NumElts
= CVA
->getNumOperands();
476 if (AscizDirective
&& NumElts
&&
477 cast
<ConstantInt
>(CVA
->getOperand(NumElts
-1))->getRawValue() == 0) {
479 printAsCString(O
, CVA
, NumElts
-1);
482 printAsCString(O
, CVA
, NumElts
);
487 /// EmitGlobalConstant - Print a general LLVM constant to the .s file.
489 void AsmPrinter::EmitGlobalConstant(const Constant
*CV
) {
490 const TargetData
*TD
= TM
.getTargetData();
492 if (CV
->isNullValue() || isa
<UndefValue
>(CV
)) {
493 EmitZeros(TD
->getTypeSize(CV
->getType()));
495 } else if (const ConstantArray
*CVA
= dyn_cast
<ConstantArray
>(CV
)) {
496 if (CVA
->isString()) {
498 } else { // Not a string. Print the values in successive locations
499 for (unsigned i
= 0, e
= CVA
->getNumOperands(); i
!= e
; ++i
)
500 EmitGlobalConstant(CVA
->getOperand(i
));
503 } else if (const ConstantStruct
*CVS
= dyn_cast
<ConstantStruct
>(CV
)) {
504 // Print the fields in successive locations. Pad to align if needed!
505 const StructLayout
*cvsLayout
= TD
->getStructLayout(CVS
->getType());
506 uint64_t sizeSoFar
= 0;
507 for (unsigned i
= 0, e
= CVS
->getNumOperands(); i
!= e
; ++i
) {
508 const Constant
* field
= CVS
->getOperand(i
);
510 // Check if padding is needed and insert one or more 0s.
511 uint64_t fieldSize
= TD
->getTypeSize(field
->getType());
512 uint64_t padSize
= ((i
== e
-1? cvsLayout
->StructSize
513 : cvsLayout
->MemberOffsets
[i
+1])
514 - cvsLayout
->MemberOffsets
[i
]) - fieldSize
;
515 sizeSoFar
+= fieldSize
+ padSize
;
517 // Now print the actual field value
518 EmitGlobalConstant(field
);
520 // Insert the field padding unless it's zero bytes...
523 assert(sizeSoFar
== cvsLayout
->StructSize
&&
524 "Layout of constant struct may be incorrect!");
526 } else if (const ConstantFP
*CFP
= dyn_cast
<ConstantFP
>(CV
)) {
527 // FP Constants are printed as integer constants to avoid losing
529 double Val
= CFP
->getValue();
530 if (CFP
->getType() == Type::DoubleTy
) {
531 if (Data64bitsDirective
)
532 O
<< Data64bitsDirective
<< DoubleToBits(Val
) << "\t" << CommentString
533 << " double value: " << Val
<< "\n";
534 else if (TD
->isBigEndian()) {
535 O
<< Data32bitsDirective
<< unsigned(DoubleToBits(Val
) >> 32)
536 << "\t" << CommentString
<< " double most significant word "
538 O
<< Data32bitsDirective
<< unsigned(DoubleToBits(Val
))
539 << "\t" << CommentString
<< " double least significant word "
542 O
<< Data32bitsDirective
<< unsigned(DoubleToBits(Val
))
543 << "\t" << CommentString
<< " double least significant word " << Val
545 O
<< Data32bitsDirective
<< unsigned(DoubleToBits(Val
) >> 32)
546 << "\t" << CommentString
<< " double most significant word " << Val
551 O
<< Data32bitsDirective
<< FloatToBits(Val
) << "\t" << CommentString
552 << " float " << Val
<< "\n";
555 } else if (CV
->getType() == Type::ULongTy
|| CV
->getType() == Type::LongTy
) {
556 if (const ConstantInt
*CI
= dyn_cast
<ConstantInt
>(CV
)) {
557 uint64_t Val
= CI
->getRawValue();
559 if (Data64bitsDirective
)
560 O
<< Data64bitsDirective
<< Val
<< "\n";
561 else if (TD
->isBigEndian()) {
562 O
<< Data32bitsDirective
<< unsigned(Val
>> 32)
563 << "\t" << CommentString
<< " Double-word most significant word "
565 O
<< Data32bitsDirective
<< unsigned(Val
)
566 << "\t" << CommentString
<< " Double-word least significant word "
569 O
<< Data32bitsDirective
<< unsigned(Val
)
570 << "\t" << CommentString
<< " Double-word least significant word "
572 O
<< Data32bitsDirective
<< unsigned(Val
>> 32)
573 << "\t" << CommentString
<< " Double-word most significant word "
578 } else if (const ConstantPacked
*CP
= dyn_cast
<ConstantPacked
>(CV
)) {
579 const PackedType
*PTy
= CP
->getType();
581 for (unsigned I
= 0, E
= PTy
->getNumElements(); I
< E
; ++I
)
582 EmitGlobalConstant(CP
->getOperand(I
));
587 const Type
*type
= CV
->getType();
588 switch (type
->getTypeID()) {
590 case Type::UByteTyID
: case Type::SByteTyID
:
591 O
<< Data8bitsDirective
;
593 case Type::UShortTyID
: case Type::ShortTyID
:
594 O
<< Data16bitsDirective
;
596 case Type::PointerTyID
:
597 if (TD
->getPointerSize() == 8) {
598 assert(Data64bitsDirective
&&
599 "Target cannot handle 64-bit pointer exprs!");
600 O
<< Data64bitsDirective
;
603 //Fall through for pointer size == int size
604 case Type::UIntTyID
: case Type::IntTyID
:
605 O
<< Data32bitsDirective
;
607 case Type::ULongTyID
: case Type::LongTyID
:
608 assert(Data64bitsDirective
&&"Target cannot handle 64-bit constant exprs!");
609 O
<< Data64bitsDirective
;
611 case Type::FloatTyID
: case Type::DoubleTyID
:
612 assert (0 && "Should have already output floating point constant.");
614 assert (0 && "Can't handle printing this type of thing");
617 EmitConstantValueOnly(CV
);
621 /// printInlineAsm - This method formats and prints the specified machine
622 /// instruction that is an inline asm.
623 void AsmPrinter::printInlineAsm(const MachineInstr
*MI
) const {
624 unsigned NumOperands
= MI
->getNumOperands();
626 // Count the number of register definitions.
627 unsigned NumDefs
= 0;
628 for (; MI
->getOperand(NumDefs
).isDef(); ++NumDefs
)
629 assert(NumDefs
!= NumOperands
-1 && "No asm string?");
631 assert(MI
->getOperand(NumDefs
).isExternalSymbol() && "No asm string?");
633 // Disassemble the AsmStr, printing out the literal pieces, the operands, etc.
634 const char *AsmStr
= MI
->getOperand(NumDefs
).getSymbolName();
636 // If this asmstr is empty, don't bother printing the #APP/#NOAPP markers.
637 if (AsmStr
[0] == 0) {
638 O
<< "\n"; // Tab already printed, avoid double indenting next instr.
642 O
<< InlineAsmStart
<< "\n\t";
644 // The variant of the current asmprinter: FIXME: change.
645 int AsmPrinterVariant
= 0;
647 int CurVariant
= -1; // The number of the {.|.|.} region we are in.
648 const char *LastEmitted
= AsmStr
; // One past the last character emitted.
650 while (*LastEmitted
) {
651 switch (*LastEmitted
) {
653 // Not a special case, emit the string section literally.
654 const char *LiteralEnd
= LastEmitted
+1;
655 while (*LiteralEnd
&& *LiteralEnd
!= '{' && *LiteralEnd
!= '|' &&
656 *LiteralEnd
!= '}' && *LiteralEnd
!= '$' && *LiteralEnd
!= '\n')
658 if (CurVariant
== -1 || CurVariant
== AsmPrinterVariant
)
659 O
.write(LastEmitted
, LiteralEnd
-LastEmitted
);
660 LastEmitted
= LiteralEnd
;
664 ++LastEmitted
; // Consume newline character.
665 O
<< "\n\t"; // Indent code with newline.
668 ++LastEmitted
; // Consume '$' character.
669 if (*LastEmitted
== '$') { // $$ -> $
670 if (CurVariant
== -1 || CurVariant
== AsmPrinterVariant
)
672 ++LastEmitted
; // Consume second '$' character.
676 bool HasCurlyBraces
= false;
677 if (*LastEmitted
== '{') { // ${variable}
678 ++LastEmitted
; // Consume '{' character.
679 HasCurlyBraces
= true;
682 const char *IDStart
= LastEmitted
;
684 long Val
= strtol(IDStart
, &IDEnd
, 10); // We only accept numbers for IDs.
685 if (!isdigit(*IDStart
) || (Val
== 0 && errno
== EINVAL
)) {
686 std::cerr
<< "Bad $ operand number in inline asm string: '"
692 char Modifier
[2] = { 0, 0 };
694 if (HasCurlyBraces
) {
695 // If we have curly braces, check for a modifier character. This
696 // supports syntax like ${0:u}, which correspond to "%u0" in GCC asm.
697 if (*LastEmitted
== ':') {
698 ++LastEmitted
; // Consume ':' character.
699 if (*LastEmitted
== 0) {
700 std::cerr
<< "Bad ${:} expression in inline asm string: '"
705 Modifier
[0] = *LastEmitted
;
706 ++LastEmitted
; // Consume modifier character.
709 if (*LastEmitted
!= '}') {
710 std::cerr
<< "Bad ${} expression in inline asm string: '"
714 ++LastEmitted
; // Consume '}' character.
717 if ((unsigned)Val
>= NumOperands
-1) {
718 std::cerr
<< "Invalid $ operand number in inline asm string: '"
723 // Okay, we finally have a value number. Ask the target to print this
725 if (CurVariant
== -1 || CurVariant
== AsmPrinterVariant
) {
730 // Scan to find the machine operand number for the operand.
732 if (OpNo
>= MI
->getNumOperands()) break;
733 unsigned OpFlags
= MI
->getOperand(OpNo
).getImmedValue();
734 OpNo
+= (OpFlags
>> 3) + 1;
737 if (OpNo
>= MI
->getNumOperands()) {
740 unsigned OpFlags
= MI
->getOperand(OpNo
).getImmedValue();
741 ++OpNo
; // Skip over the ID number.
743 AsmPrinter
*AP
= const_cast<AsmPrinter
*>(this);
744 if ((OpFlags
& 7) == 4 /*ADDR MODE*/) {
745 Error
= AP
->PrintAsmMemoryOperand(MI
, OpNo
, AsmPrinterVariant
,
746 Modifier
[0] ? Modifier
: 0);
748 Error
= AP
->PrintAsmOperand(MI
, OpNo
, AsmPrinterVariant
,
749 Modifier
[0] ? Modifier
: 0);
753 std::cerr
<< "Invalid operand found in inline asm: '"
762 ++LastEmitted
; // Consume '{' character.
763 if (CurVariant
!= -1) {
764 std::cerr
<< "Nested variants found in inline asm string: '"
768 CurVariant
= 0; // We're in the first variant now.
771 ++LastEmitted
; // consume '|' character.
772 if (CurVariant
== -1) {
773 std::cerr
<< "Found '|' character outside of variant in inline asm "
774 << "string: '" << AsmStr
<< "'\n";
777 ++CurVariant
; // We're in the next variant.
780 ++LastEmitted
; // consume '}' character.
781 if (CurVariant
== -1) {
782 std::cerr
<< "Found '}' character outside of variant in inline asm "
783 << "string: '" << AsmStr
<< "'\n";
790 O
<< "\n\t" << InlineAsmEnd
<< "\n";
793 /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
794 /// instruction, using the specified assembler variant. Targets should
795 /// overried this to format as appropriate.
796 bool AsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
797 unsigned AsmVariant
, const char *ExtraCode
) {
798 // Target doesn't support this yet!
802 bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
, unsigned OpNo
,
804 const char *ExtraCode
) {
805 // Target doesn't support this yet!
809 /// printBasicBlockLabel - This method prints the label for the specified
810 /// MachineBasicBlock
811 void AsmPrinter::printBasicBlockLabel(const MachineBasicBlock
*MBB
,
813 bool printComment
) const {
814 O
<< PrivateGlobalPrefix
<< "BB" << FunctionNumber
<< "_"
819 O
<< '\t' << CommentString
<< MBB
->getBasicBlock()->getName();