static cl::opt<bool>
AsmVerbose("asm-verbose", cl::Hidden, cl::desc("Add comments to directives."));
+char AsmPrinter::ID = 0;
AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm,
const TargetAsmInfo *T)
-: FunctionNumber(0), O(o), TM(tm), TAI(T)
+ : MachineFunctionPass((intptr_t)&ID), FunctionNumber(0), O(o), TM(tm), TAI(T)
{}
std::string AsmPrinter::getSectionForFunction(const Function &F) const {
SwitchToDataSection(""); // Reset back to no section.
- if (MachineDebugInfo *DebugInfo = getAnalysisToUpdate<MachineDebugInfo>()) {
- DebugInfo->AnalyzeModule(M);
+ if (MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>()) {
+ MMI->AnalyzeModule(M);
}
return false;
bool AsmPrinter::doFinalization(Module &M) {
if (TAI->getWeakRefDirective()) {
- if (ExtWeakSymbols.begin() != ExtWeakSymbols.end())
+ if (!ExtWeakSymbols.empty())
SwitchToDataSection("");
for (std::set<const GlobalValue*>::iterator i = ExtWeakSymbols.begin(),
}
}
+ if (TAI->getSetDirective()) {
+ if (!M.alias_empty())
+ SwitchToTextSection(TAI->getTextSection());
+
+ O << "\n";
+ for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
+ I!=E; ++I) {
+ std::string Name = Mang->getValueName(I);
+ std::string Target;
+
+ if (const GlobalValue *GV = I->getAliasedGlobal())
+ Target = Mang->getValueName(GV);
+ else
+ assert(0 && "Unsupported aliasee");
+
+ if (I->hasExternalLinkage())
+ O << "\t.globl\t" << Name << "\n";
+ else if (I->hasWeakLinkage())
+ O << TAI->getWeakRefDirective() << Name << "\n";
+ else if (!I->hasInternalLinkage())
+ assert(0 && "Invalid alias linkage");
+
+ O << TAI->getSetDirective() << Name << ", " << Target << "\n";
+ }
+ }
+
delete Mang; Mang = 0;
return false;
}
return LinkName;
}
+/// EmitExternalGlobal - Emit the external reference to a global variable.
+/// Should be overridden if an indirect reference should be used.
+void AsmPrinter::EmitExternalGlobal(const GlobalVariable *GV) {
+ O << getGlobalLinkName(GV);
+}
+
+
+
//===----------------------------------------------------------------------===//
/// LEB 128 number encoding.
/// EOL - Print a newline character to asm stream. If a comment is present
/// then it will be printed first. Comments should not contain '\n'.
+void AsmPrinter::EOL() const {
+ O << "\n";
+}
void AsmPrinter::EOL(const std::string &Comment) const {
if (AsmVerbose && !Comment.empty()) {
O << "\t"
/// Special characters are emitted properly.
/// \literal (Eg. '\t') \endliteral
void AsmPrinter::EmitString(const std::string &String) const {
- O << TAI->getAsciiDirective()
- << "\"";
+ const char* AscizDirective = TAI->getAscizDirective();
+ if (AscizDirective)
+ O << AscizDirective;
+ else
+ O << TAI->getAsciiDirective();
+ O << "\"";
for (unsigned i = 0, N = String.size(); i < N; ++i) {
unsigned char C = String[i];
printStringChar(O, C);
}
- O << "\\0\"";
+ if (AscizDirective)
+ O << "\"";
+ else
+ O << "\\0\"";
}
//===----------------------------------------------------------------------===//
// EmitAlignment - Emit an alignment directive to the specified power of two.
+// Use the maximum of the specified alignment and the alignment from the
+// specified GlobalValue (if any).
void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV) const {
if (GV && GV->getAlignment())
- NumBits = Log2_32(GV->getAlignment());
+ NumBits = std::max(NumBits, Log2_32(GV->getAlignment()));
if (NumBits == 0) return; // No need to emit alignment.
if (TAI->getAlignmentIsInBytes()) NumBits = 1 << NumBits;
O << TAI->getAlignDirective() << NumBits << "\n";
}
+
/// EmitZeros - Emit a block of zeros.
///
void AsmPrinter::EmitZeros(uint64_t NumZeros) const {
}
} else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
const TargetData *TD = TM.getTargetData();
- switch(CE->getOpcode()) {
+ unsigned Opcode = CE->getOpcode();
+ switch (Opcode) {
case Instruction::GetElementPtr: {
// generate a symbolic expression for the byte address
const Constant *ptrVal = CE->getOperand(0);
- std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end());
- if (int64_t Offset = TD->getIndexedOffset(ptrVal->getType(), idxVec)) {
+ SmallVector<Value*, 8> idxVec(CE->op_begin()+1, CE->op_end());
+ if (int64_t Offset = TD->getIndexedOffset(ptrVal->getType(), &idxVec[0],
+ idxVec.size())) {
if (Offset)
O << "(";
EmitConstantValueOnly(ptrVal);
break;
}
case Instruction::Add:
+ case Instruction::Sub:
O << "(";
EmitConstantValueOnly(CE->getOperand(0));
- O << ") + (";
+ O << (Opcode==Instruction::Add ? ") + (" : ") - (");
EmitConstantValueOnly(CE->getOperand(1));
O << ")";
break;
// Check if padding is needed and insert one or more 0s.
uint64_t fieldSize = TD->getTypeSize(field->getType());
- uint64_t padSize = ((i == e-1? cvsLayout->StructSize
- : cvsLayout->MemberOffsets[i+1])
- - cvsLayout->MemberOffsets[i]) - fieldSize;
+ uint64_t padSize = ((i == e-1? cvsLayout->getSizeInBytes()
+ : cvsLayout->getElementOffset(i+1))
+ - cvsLayout->getElementOffset(i)) - fieldSize;
sizeSoFar += fieldSize + padSize;
// Now print the actual field value
// Insert the field padding unless it's zero bytes...
EmitZeros(padSize);
}
- assert(sizeSoFar == cvsLayout->StructSize &&
+ assert(sizeSoFar == cvsLayout->getSizeInBytes() &&
"Layout of constant struct may be incorrect!");
return;
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
}
return;
}
- } else if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(CV)) {
- const PackedType *PTy = CP->getType();
+ } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
+ const VectorType *PTy = CP->getType();
for (unsigned I = 0, E = PTy->getNumElements(); I < E; ++I)
EmitGlobalConstant(CP->getOperand(I));
} else if (!strcmp(Code, "uid")) {
// Assign a unique ID to this machine instruction.
static const MachineInstr *LastMI = 0;
+ static const Function *F = 0;
static unsigned Counter = 0U-1;
+
+ // Comparing the address of MI isn't sufficient, because machineinstrs may
+ // be allocated to the same address across functions.
+ const Function *ThisF = MI->getParent()->getParent()->getFunction();
+
// If this is a new machine instruction, bump the counter.
- if (LastMI != MI) { ++Counter; LastMI = MI; }
+ if (LastMI != MI || F != ThisF) {
+ ++Counter;
+ LastMI = MI;
+ F = ThisF;
+ }
O << Counter;
} else {
cerr << "Unknown special formatter '" << Code
}
case '\n':
++LastEmitted; // Consume newline character.
- O << "\n\t"; // Indent code with newline.
+ O << "\n"; // Indent code with newline.
break;
case '$': {
++LastEmitted; // Consume '$' character.
/// printLabel - This method prints a local label used by debug and
/// exception handling tables.
void AsmPrinter::printLabel(const MachineInstr *MI) const {
- if (AsmVerbose) O << "\n";
- O << TAI->getPrivateGlobalPrefix()
- << "debug_loc"
+ O << "\n"
+ << TAI->getPrivateGlobalPrefix()
+ << "label"
<< MI->getOperand(0).getImmedValue()
<< ":\n";
}
break;
}
}
+