X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FPowerPC%2FPPCAsmPrinter.cpp;h=7969d02b23e7199573fb11d5d1ad3b39eac2866f;hb=3459bfbc395914ec895aef13123f3b180242577f;hp=a3d89a3996668a12ac7bc5d9acf0c6a2edb55c05;hpb=2497e6391f8df05926fe17b5cf08dad61c4797d2;p=oota-llvm.git diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp index a3d89a39966..7969d02b23e 100644 --- a/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -1,4 +1,4 @@ -//===-- PowerPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --===// +//===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --------=// // // The LLVM Compiler Infrastructure // @@ -17,8 +17,9 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "asmprinter" -#include "PowerPC.h" -#include "PowerPCTargetMachine.h" +#include "PPC.h" +#include "PPCTargetMachine.h" +#include "PPCSubtarget.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" @@ -42,10 +43,10 @@ using namespace llvm; namespace { Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); - struct PowerPCAsmPrinter : public AsmPrinter { + struct PPCAsmPrinter : public AsmPrinter { std::set FnStubs, GVStubs, LinkOnceStubs; - PowerPCAsmPrinter(std::ostream &O, TargetMachine &TM) + PPCAsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM), LabelNumber(0) {} /// Unique incrementer for label values for referencing Global values. @@ -56,8 +57,8 @@ namespace { return "PowerPC Assembly Printer"; } - PowerPCTargetMachine &getTM() { - return static_cast(TM); + PPCTargetMachine &getTM() { + return static_cast(TM); } unsigned enumRegToMachineReg(unsigned enumReg) { @@ -88,7 +89,7 @@ namespace { const MachineOperand &MO = MI->getOperand(OpNo); if (MO.getType() == MachineOperand::MO_MachineRegister) { assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physreg??"); - O << LowercaseString(TM.getRegisterInfo()->get(MO.getReg()).Name); + O << TM.getRegisterInfo()->get(MO.getReg()).Name; } else if (MO.isImmediate()) { O << MO.getImmedValue(); } else { @@ -116,6 +117,10 @@ namespace { MVT::ValueType VT) { O << (unsigned short)MI->getOperand(OpNo).getImmedValue(); } + void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo, + MVT::ValueType VT) { + O << (short)MI->getOperand(OpNo).getImmedValue()*4; + } void printBranchOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT) { // Branches can take an immediate operand. This is used by the branch @@ -159,14 +164,6 @@ namespace { O << ')'; } } - void printcrbit(const MachineInstr *MI, unsigned OpNo, - MVT::ValueType VT) { - unsigned char value = MI->getOperand(OpNo).getImmedValue(); - assert(value <= 3 && "Invalid crbit argument!"); - unsigned CCReg = MI->getOperand(OpNo-1).getReg(); - unsigned RegNo = enumRegToMachineReg(CCReg); - O << 4 * RegNo + value; - } void printcrbitm(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT) { unsigned CCReg = MI->getOperand(OpNo).getReg(); @@ -182,10 +179,10 @@ namespace { /// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS /// X /// - struct DarwinAsmPrinter : public PowerPCAsmPrinter { + struct DarwinAsmPrinter : public PPCAsmPrinter { DarwinAsmPrinter(std::ostream &O, TargetMachine &TM) - : PowerPCAsmPrinter(O, TM) { + : PPCAsmPrinter(O, TM) { CommentString = ";"; GlobalPrefix = "_"; ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. @@ -205,15 +202,15 @@ namespace { /// AIXAsmPrinter - PowerPC assembly printer, customized for AIX /// - struct AIXAsmPrinter : public PowerPCAsmPrinter { + struct AIXAsmPrinter : public PPCAsmPrinter { /// Map for labels corresponding to global variables /// std::map GVToLabelMap; AIXAsmPrinter(std::ostream &O, TargetMachine &TM) - : PowerPCAsmPrinter(O, TM) { + : PPCAsmPrinter(O, TM) { CommentString = "#"; - GlobalPrefix = "_"; + GlobalPrefix = "."; ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. Data64bitsDirective = 0; // we can't emit a 64-bit unit AlignmentIsInBytes = false; // Alignment is by power of 2. @@ -259,9 +256,9 @@ FunctionPass *llvm::createAIXAsmPrinter(std::ostream &o, TargetMachine &tm) { } // Include the auto-generated portion of the assembly writer -#include "PowerPCGenAsmWriter.inc" +#include "PPCGenAsmWriter.inc" -void PowerPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) { +void PPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) { const MRegisterInfo &RI = *TM.getRegisterInfo(); int new_symbol; @@ -274,7 +271,7 @@ void PowerPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) { // FALLTHROUGH case MachineOperand::MO_MachineRegister: case MachineOperand::MO_CCRegister: - O << LowercaseString(RI.get(MO.getReg()).Name); + O << RI.get(MO.getReg()).Name; return; case MachineOperand::MO_SignExtendedImmed: @@ -290,14 +287,14 @@ void PowerPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) { case MachineOperand::MO_MachineBasicBlock: { MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); - O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) + O << "LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) << "_" << MBBOp->getNumber() << "\t; " << MBBOp->getBasicBlock()->getName(); return; } case MachineOperand::MO_ConstantPoolIndex: - O << ".CPI" << CurrentFnName << "_" << MO.getConstantPoolIndex(); + O << "LCPI" << CurrentFnName << "_" << MO.getConstantPoolIndex(); return; case MachineOperand::MO_ExternalSymbol: @@ -347,8 +344,9 @@ void PowerPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) { /// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to /// the current output stream. /// -void PowerPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) { +void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) { ++EmittedInsts; + // Check for slwi/srwi mnemonics. if (MI->getOpcode() == PPC::RLWINM) { bool FoundMnemonic = false; @@ -391,16 +389,21 @@ bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) { // Print out labels for the function. O << "\t.text\n"; - emitAlignment(2); - O << "\t.globl\t" << CurrentFnName << "\n"; + emitAlignment(4); + if (!MF.getFunction()->hasInternalLinkage()) + O << "\t.globl\t" << CurrentFnName << "\n"; O << CurrentFnName << ":\n"; // Print out code for the function. for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); I != E; ++I) { // Print a label for the basic block. - O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t" - << CommentString << " " << I->getBasicBlock()->getName() << "\n"; + if (I != MF.begin()) { + O << "LBB" << CurrentFnName << "_" << I->getNumber() << ":\t"; + if (!I->getBasicBlock()->getName().empty()) + O << CommentString << " " << I->getBasicBlock()->getName(); + O << "\n"; + } for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); II != E; ++II) { // Print the assembly for the instruction. @@ -427,15 +430,21 @@ void DarwinAsmPrinter::printConstantPool(MachineConstantPool *MCP) { for (unsigned i = 0, e = CP.size(); i != e; ++i) { O << "\t.const\n"; - emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType())); - O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString + // FIXME: force doubles to be naturally aligned. We should handle this + // more correctly in the future. + if (Type::DoubleTy == CP[i]->getType()) + emitAlignment(3); + else + emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType())); + O << "LCPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString << *CP[i] << "\n"; emitGlobalConstant(CP[i]); } } bool DarwinAsmPrinter::doInitialization(Module &M) { - if (GPOPT) O << "\t.machine ppc970\n"; + if (TM.getSubtarget().isGigaProcessor()) + O << "\t.machine ppc970\n"; AsmPrinter::doInitialization(M); return false; } @@ -462,9 +471,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) { O << ".lcomm " << name << "," << Size << "," << Align; else O << ".comm " << name << "," << Size; - O << "\t\t; "; - WriteAsOperand(O, I, true, true, &M); - O << '\n'; + O << "\t\t; '" << I->getName() << "'\n"; } else { switch (I->getLinkage()) { case GlobalValue::LinkOnceLinkage: @@ -474,11 +481,9 @@ bool DarwinAsmPrinter::doFinalization(Module &M) { << ".section __DATA,__datacoal_nt,coalesced,no_toc\n"; LinkOnceStubs.insert(name); break; - case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. - // Nonnull linkonce -> weak - O << "\t.weak " << name << "\n"; - SwitchSection(O, CurSection, ""); - O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n"; + case GlobalValue::WeakLinkage: + O << ".weak_definition " << name << '\n' + << ".private_extern " << name << '\n'; break; case GlobalValue::AppendingLinkage: // FIXME: appending linkage variables should go into a section of @@ -496,11 +501,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) { } emitAlignment(Align); - O << name << ":\t\t\t\t; "; - WriteAsOperand(O, I, true, true, &M); - O << " = "; - WriteAsOperand(O, C, false, false, &M); - O << "\n"; + O << name << ":\t\t\t\t; '" << I->getName() << "'\n"; emitGlobalConstant(C); } } @@ -566,6 +567,13 @@ bool DarwinAsmPrinter::doFinalization(Module &M) { << "\t.long\t" << *i << '\n'; } + // Funny Darwin hack: This flag tells the linker that no global symbols + // contain code that falls through to other global symbols (e.g. the obvious + // implementation of multiple entry points). If this doesn't occur, the + // linker can safely perform dead code stripping. Since LLVM never generates + // code that does this, it is always safe to set. + O << "\t.subsections_via_symbols\n"; + AsmPrinter::doFinalization(M); return false; // success } @@ -632,7 +640,7 @@ void AIXAsmPrinter::printConstantPool(MachineConstantPool *MCP) { O << "\t.const\n"; O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType()) << "\n"; - O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t;" + O << "LCPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t;" << *CP[i] << "\n"; emitGlobalConstant(CP[i]); } @@ -647,7 +655,8 @@ bool AIXAsmPrinter::doInitialization(Module &M) { << "\t.csect .text[PR]\n"; // Print out module-level global variables - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { if (!I->hasInitializer()) continue; @@ -666,7 +675,8 @@ bool AIXAsmPrinter::doInitialization(Module &M) { // Output labels for globals if (M.global_begin() != M.global_end()) O << "\t.toc\n"; - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { const GlobalVariable *GV = I; // Do not output labels for unused variables if (GV->isExternal() && GV->use_begin() == GV->use_end()) @@ -681,14 +691,15 @@ bool AIXAsmPrinter::doInitialization(Module &M) { O << '\n'; } - Mang = new Mangler(M, "."); + AsmPrinter::doInitialization(M); return false; // success } bool AIXAsmPrinter::doFinalization(Module &M) { const TargetData &TD = TM.getTargetData(); // Print out module-level global variables - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { if (I->hasInitializer() || I->hasExternalLinkage()) continue; @@ -697,17 +708,16 @@ bool AIXAsmPrinter::doFinalization(Module &M) { O << "\t.lcomm " << Name << ",16,_global.bss_c"; } else { O << "\t.comm " << Name << "," << TD.getTypeSize(I->getType()) - << "," << log2((unsigned)TD.getTypeAlignment(I->getType())); + << "," << Log2_32((unsigned)TD.getTypeAlignment(I->getType())); } O << "\t\t# "; - WriteAsOperand(O, I, true, true, &M); + WriteAsOperand(O, I, false, true, &M); O << "\n"; } O << "_section_.text:\n" << "\t.csect .data[RW],3\n" << "\t.llong _section_.text\n"; - - delete Mang; + AsmPrinter::doFinalization(M); return false; // success }