diff --git a/lib/Target/IA64/IA64AsmPrinter.cpp b/lib/Target/IA64/IA64AsmPrinter.cpp index d3cb56dd45c..dbb470ba3c7 100644 --- a/lib/Target/IA64/IA64AsmPrinter.cpp +++ b/lib/Target/IA64/IA64AsmPrinter.cpp @@ -33,107 +33,10 @@ using namespace llvm; namespace { Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); - struct IA64SharedAsmPrinter : public AsmPrinter { - + struct IA64AsmPrinter : public AsmPrinter { std::set<std::string> ExternalFunctionNames, ExternalObjectNames; - IA64SharedAsmPrinter(std::ostream &O, TargetMachine &TM) - : AsmPrinter(O, TM) { } - - bool doFinalization(Module &M); - }; -} - -bool IA64SharedAsmPrinter::doFinalization(Module &M) { - const TargetData &TD = TM.getTargetData(); - - // Print out module-level global variables here. - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) - if (I->hasInitializer()) { // External global require no code - O << "\n\n"; - std::string name = Mang->getValueName(I); - Constant *C = I->getInitializer(); - unsigned Size = TD.getTypeSize(C->getType()); - unsigned Align = TD.getTypeAlignmentShift(C->getType()); - - if (C->isNullValue() && - (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || - I->hasWeakLinkage() /* FIXME: Verify correct */)) { - SwitchSection(".data", I); - if (I->hasInternalLinkage()) { - O << "\t.lcomm " << name << "," << TD.getTypeSize(C->getType()) - << "," << (1 << Align); - O << "\t\t// "; - } else { - O << "\t.common " << name << "," << TD.getTypeSize(C->getType()) - << "," << (1 << Align); - O << "\t\t// "; - } - WriteAsOperand(O, I, true, true, &M); - O << "\n"; - } else { - switch (I->getLinkage()) { - case GlobalValue::LinkOnceLinkage: - case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. - // Nonnull linkonce -> weak - O << "\t.weak " << name << "\n"; - O << "\t.section\t.llvm.linkonce.d." << name - << ", \"aw\", \"progbits\"\n"; - SwitchSection("", I); - break; - case GlobalValue::AppendingLinkage: - // FIXME: appending linkage variables should go into a section of - // their name or something. For now, just emit them as external. - case GlobalValue::ExternalLinkage: - // If external or appending, declare as a global symbol - O << "\t.global " << name << "\n"; - // FALL THROUGH - case GlobalValue::InternalLinkage: - SwitchSection(C->isNullValue() ? ".bss" : ".data", I); - break; - case GlobalValue::GhostLinkage: - std::cerr << "GhostLinkage cannot appear in IA64AsmPrinter!\n"; - abort(); - } - - EmitAlignment(Align); - O << "\t.type " << name << ",@object\n"; - O << "\t.size " << name << "," << Size << "\n"; - O << name << ":\t\t\t\t// "; - WriteAsOperand(O, I, true, true, &M); - O << " = "; - WriteAsOperand(O, C, false, false, &M); - O << "\n"; - EmitGlobalConstant(C); - } - } - - // we print out ".global X \n .type X, @function" for each external function - O << "\n\n// br.call targets referenced (and not defined) above: \n"; - for (std::set<std::string>::iterator i = ExternalFunctionNames.begin(), - e = ExternalFunctionNames.end(); i!=e; ++i) { - O << "\t.global " << *i << "\n\t.type " << *i << ", @function\n"; - } - O << "\n\n"; - - // we print out ".global X \n .type X, @object" for each external object - O << "\n\n// (external) symbols referenced (and not defined) above: \n"; - for (std::set<std::string>::iterator i = ExternalObjectNames.begin(), - e = ExternalObjectNames.end(); i!=e; ++i) { - O << "\t.global " << *i << "\n\t.type " << *i << ", @object\n"; - } - O << "\n\n"; - - AsmPrinter::doFinalization(M); - return false; // success -} - -namespace { - struct IA64AsmPrinter : public IA64SharedAsmPrinter { - IA64AsmPrinter(std::ostream &O, TargetMachine &TM) - : IA64SharedAsmPrinter(O, TM) { - + IA64AsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM) { CommentString = "//"; Data8bitsDirective = "\tdata1\t"; // FIXME: check that we are Data16bitsDirective = "\tdata2.ua\t"; // disabling auto-alignment @@ -227,6 +130,7 @@ namespace { void printOp(const MachineOperand &MO, bool isBRCALLinsn= false); bool runOnMachineFunction(MachineFunction &F); bool doInitialization(Module &M); + bool doFinalization(Module &M); }; } // end of anonymous namespace @@ -379,6 +283,91 @@ bool IA64AsmPrinter::doInitialization(Module &M) { return false; } +bool IA64AsmPrinter::doFinalization(Module &M) { + const TargetData &TD = TM.getTargetData(); + + // Print out module-level global variables here. + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) + if (I->hasInitializer()) { // External global require no code + O << "\n\n"; + std::string name = Mang->getValueName(I); + Constant *C = I->getInitializer(); + unsigned Size = TD.getTypeSize(C->getType()); + unsigned Align = TD.getTypeAlignmentShift(C->getType()); + + if (C->isNullValue() && + (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || + I->hasWeakLinkage() /* FIXME: Verify correct */)) { + SwitchSection(".data", I); + if (I->hasInternalLinkage()) { + O << "\t.lcomm " << name << "," << TD.getTypeSize(C->getType()) + << "," << (1 << Align); + O << "\t\t// "; + } else { + O << "\t.common " << name << "," << TD.getTypeSize(C->getType()) + << "," << (1 << Align); + O << "\t\t// "; + } + WriteAsOperand(O, I, true, true, &M); + O << "\n"; + } else { + switch (I->getLinkage()) { + case GlobalValue::LinkOnceLinkage: + case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. + // Nonnull linkonce -> weak + O << "\t.weak " << name << "\n"; + O << "\t.section\t.llvm.linkonce.d." << name + << ", \"aw\", \"progbits\"\n"; + SwitchSection("", I); + break; + case GlobalValue::AppendingLinkage: + // FIXME: appending linkage variables should go into a section of + // their name or something. For now, just emit them as external. + case GlobalValue::ExternalLinkage: + // If external or appending, declare as a global symbol + O << "\t.global " << name << "\n"; + // FALL THROUGH + case GlobalValue::InternalLinkage: + SwitchSection(C->isNullValue() ? ".bss" : ".data", I); + break; + case GlobalValue::GhostLinkage: + std::cerr << "GhostLinkage cannot appear in IA64AsmPrinter!\n"; + abort(); + } + + EmitAlignment(Align); + O << "\t.type " << name << ",@object\n"; + O << "\t.size " << name << "," << Size << "\n"; + O << name << ":\t\t\t\t// "; + WriteAsOperand(O, I, true, true, &M); + O << " = "; + WriteAsOperand(O, C, false, false, &M); + O << "\n"; + EmitGlobalConstant(C); + } + } + + // we print out ".global X \n .type X, @function" for each external function + O << "\n\n// br.call targets referenced (and not defined) above: \n"; + for (std::set<std::string>::iterator i = ExternalFunctionNames.begin(), + e = ExternalFunctionNames.end(); i!=e; ++i) { + O << "\t.global " << *i << "\n\t.type " << *i << ", @function\n"; + } + O << "\n\n"; + + // we print out ".global X \n .type X, @object" for each external object + O << "\n\n// (external) symbols referenced (and not defined) above: \n"; + for (std::set<std::string>::iterator i = ExternalObjectNames.begin(), + e = ExternalObjectNames.end(); i!=e; ++i) { + O << "\t.global " << *i << "\n\t.type " << *i << ", @object\n"; + } + O << "\n\n"; + + AsmPrinter::doFinalization(M); + return false; // success +} + /// createIA64CodePrinterPass - Returns a pass that prints the IA64 /// assembly code for a MachineFunction to the given output stream, using /// the given target machine description.