X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FSparcV9%2FSparcV9AsmPrinter.cpp;h=af86e05a9050b8679873760c0d61a9d8b07f7518;hb=12c1d2c25ac0f7cb9b6bb927e0283d2c376d3456;hp=fa749b8e1fd3fd90c816c6ac6163a70987560252;hpb=3d0ad411a5f16e176f9ece702d08774fbf1a4d8e;p=oota-llvm.git diff --git a/lib/Target/SparcV9/SparcV9AsmPrinter.cpp b/lib/Target/SparcV9/SparcV9AsmPrinter.cpp index fa749b8e1fd..af86e05a905 100644 --- a/lib/Target/SparcV9/SparcV9AsmPrinter.cpp +++ b/lib/Target/SparcV9/SparcV9AsmPrinter.cpp @@ -22,70 +22,32 @@ #include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/Pass.h" -#include "llvm/SlotCalculator.h" #include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionInfo.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Support/Mangler.h" #include "Support/StringExtras.h" #include "Support/Statistic.h" #include "SparcInternals.h" #include - using namespace llvm; -namespace llvm { - namespace { - Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); - class GlobalIdTable: public Annotation { - static AnnotationID AnnotId; - friend class AsmPrinter; // give access to AnnotId - - typedef hash_map ValIdMap; - typedef ValIdMap::const_iterator ValIdMapConstIterator; - typedef ValIdMap:: iterator ValIdMapIterator; - public: - SlotCalculator Table; // map anonymous values to unique integer IDs - ValIdMap valToIdMap; // used for values not handled by SlotCalculator - - GlobalIdTable(Module* M) : Annotation(AnnotId), Table(M, true) {} - }; - - AnnotationID GlobalIdTable::AnnotId = - AnnotationManager::getID("ASM PRINTER GLOBAL TABLE ANNOT"); - //===--------------------------------------------------------------------===// // Utility functions - /// Can we treat the specified array as a string? Only if it is an array of - /// ubytes or non-negative sbytes. - /// - bool isStringCompatible(const ConstantArray *CVA) { - const Type *ETy = cast(CVA->getType())->getElementType(); - if (ETy == Type::UByteTy) return true; - if (ETy != Type::SByteTy) return false; - - for (unsigned i = 0; i < CVA->getNumOperands(); ++i) - if (cast(CVA->getOperand(i))->getValue() < 0) - return false; - - return true; - } - /// getAsCString - Return the specified array as a C compatible string, only - /// if the predicate isStringCompatible is true. + /// if the predicate isString() is true. /// std::string getAsCString(const ConstantArray *CVA) { - assert(isStringCompatible(CVA) && "Array is not string compatible!"); + assert(CVA->isString() && "Array is not string compatible!"); - std::string Result; - const Type *ETy = cast(CVA->getType())->getElementType(); - Result = "\""; - for (unsigned i = 0; i < CVA->getNumOperands(); ++i) { + std::string Result = "\""; + for (unsigned i = 0; i != CVA->getNumOperands(); ++i) { unsigned char C = cast(CVA->getOperand(i))->getRawValue(); if (C == '"') { @@ -186,20 +148,17 @@ namespace { } // End anonymous namespace -} // End namespace llvm - //===---------------------------------------------------------------------===// // Code abstracted away from the AsmPrinter //===---------------------------------------------------------------------===// -namespace llvm { - namespace { - class AsmPrinter { - GlobalIdTable* idTable; + // Mangle symbol names appropriately + Mangler *Mang; + public: std::ostream &toAsm; const TargetMachine &Target; @@ -213,27 +172,23 @@ namespace { } CurSection; AsmPrinter(std::ostream &os, const TargetMachine &T) - : idTable(0), toAsm(os), Target(T), CurSection(Unknown) {} + : /* idTable(0), */ toAsm(os), Target(T), CurSection(Unknown) {} + ~AsmPrinter() { + delete Mang; + } + // (start|end)(Module|Function) - Callback methods invoked by subclasses void startModule(Module &M) { - // Create the global id table if it does not already exist - idTable = (GlobalIdTable*)M.getAnnotation(GlobalIdTable::AnnotId); - if (idTable == NULL) { - idTable = new GlobalIdTable(&M); - M.addAnnotation(idTable); - } + Mang = new Mangler(M); } void PrintZeroBytesToPad(int numBytes) { - for (/* no init */; numBytes >= 8; numBytes -= 8) - printSingleConstantValue(Constant::getNullValue(Type::ULongTy)); - - if (numBytes >= 4) { - printSingleConstantValue(Constant::getNullValue(Type::UIntTy)); - numBytes -= 4; - } - + // + // Always use single unsigned bytes for padding. We don't know upon + // what data size the beginning address is aligned, so using anything + // other than a byte may cause alignment errors in the assembler. + // while (numBytes--) printSingleConstantValue(Constant::getNullValue(Type::UByteTy)); } @@ -257,13 +212,13 @@ namespace { toAsm << "\t.align\t" << ConstantToAlignment(CV, Target) << "\n"; // Print .size and .type only if it is not a string. - const ConstantArray *CVA = dyn_cast(CV); - if (CVA && isStringCompatible(CVA)) { - // print it as a string and return - toAsm << valID << ":\n"; - toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n"; - return; - } + if (const ConstantArray *CVA = dyn_cast(CV)) + if (CVA->isString()) { + // print it as a string and return + toAsm << valID << ":\n"; + toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n"; + return; + } toAsm << "\t.type" << "\t" << valID << ",#object\n"; @@ -276,20 +231,6 @@ namespace { printConstantValueOnly(CV); } - void startFunction(Function &F) { - // Make sure the slot table has information about this function... - idTable->Table.incorporateFunction(&F); - } - void endFunction(Function &) { - idTable->Table.purgeFunction(); // Forget all about F - } - - // Check if a value is external or accessible from external code. - bool isExternal(const Value* V) { - const GlobalValue *GV = dyn_cast(V); - return GV && GV->hasExternalLinkage(); - } - // enterSection - Use this method to enter a different section of the output // executable. This is used to only output necessary section transitions. // @@ -309,72 +250,21 @@ namespace { toAsm << "\n"; } - static std::string getValidSymbolName(const std::string &S) { - std::string Result; - - // Symbol names in Sparc assembly language have these rules: - // (a) Must match { letter | _ | . | $ } { letter | _ | . | $ | digit }* - // (b) A name beginning in "." is treated as a local name. - // - if (isdigit(S[0])) - Result = "ll"; - - for (unsigned i = 0; i < S.size(); ++i) { - char C = S[i]; - if (C == '_' || C == '.' || C == '$' || isalpha(C) || isdigit(C)) - Result += C; - else { - Result += '_'; - Result += char('0' + ((unsigned char)C >> 4)); - Result += char('0' + (C & 0xF)); - } - } - return Result; - } - - // getID - Return a valid identifier for the specified value. Base it on - // the name of the identifier if possible (qualified by the type), and - // use a numbered value based on prefix otherwise. - // FPrefix is always prepended to the output identifier. - // - std::string getID(const Value *V, const char *Prefix, - const char *FPrefix = 0) - { - std::string Result = FPrefix ? FPrefix : ""; // "Forced prefix" - - Result += V->hasName() ? V->getName() : std::string(Prefix); - - // Qualify all internal names with a unique id. - if (!isExternal(V)) { - int valId = idTable->Table.getSlot(V); - if (valId == -1) { - GlobalIdTable::ValIdMapConstIterator I = idTable->valToIdMap.find(V); - if (I == idTable->valToIdMap.end()) - valId = idTable->valToIdMap[V] = idTable->valToIdMap.size(); - else - valId = I->second; - } - Result = Result + "_" + itostr(valId); - - // Replace or prefix problem characters in the name - Result = getValidSymbolName(Result); - } - - return Result; - } - - // getID Wrappers - Ensure consistent usage... + // getID Wrappers - Ensure consistent usage + // Symbol names in Sparc assembly language have these rules: + // (a) Must match { letter | _ | . | $ } { letter | _ | . | $ | digit }* + // (b) A name beginning in "." is treated as a local name. std::string getID(const Function *F) { - return getID(F, "LLVMFunction_"); + return Mang->getValueName(F); } std::string getID(const BasicBlock *BB) { - return getID(BB, "LL", (".L_"+getID(BB->getParent())+"_").c_str()); + return ".L_" + getID(BB->getParent()) + "_" + Mang->getValueName(BB); } std::string getID(const GlobalVariable *GV) { - return getID(GV, "LLVMGlobal_"); + return Mang->getValueName(GV); } std::string getID(const Constant *CV) { - return getID(CV, "LLVMConst_", ".C_"); + return ".C_" + Mang->getValueName(CV); } std::string getID(const GlobalValue *GV) { if (const GlobalVariable *V = dyn_cast(GV)) @@ -404,10 +294,8 @@ namespace { /// std::string valToExprString(const Value* V, const TargetMachine& target); }; - } // End anonymous namespace -} // End namespace llvm /// Print a single constant value. /// @@ -452,6 +340,8 @@ void AsmPrinter::printSingleConstantValue(const Constant* CV) { toAsm << "\t! " << CV->getType()->getDescription() << " value: " << Val << "\n"; + } else if (const ConstantBool *CB = dyn_cast(CV)) { + toAsm << (int)CB->getValue() << "\n"; } else { WriteAsOperand(toAsm, CV, false, false) << "\n"; } @@ -464,18 +354,17 @@ void AsmPrinter::printSingleConstantValue(const Constant* CV) { /// Uses printSingleConstantValue() to print each individual value. /// void AsmPrinter::printConstantValueOnly(const Constant* CV, - int numPadBytesAfter) -{ - const ConstantArray *CVA = dyn_cast(CV); - - if (CVA && isStringCompatible(CVA)) { - // print the string alone and return - toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n"; - } else if (CVA) { - // Not a string. Print the values in successive locations - const std::vector &constValues = CVA->getValues(); - for (unsigned i=0; i < constValues.size(); i++) - printConstantValueOnly(cast(constValues[i].get())); + int numPadBytesAfter) { + if (const ConstantArray *CVA = dyn_cast(CV)) { + if (CVA->isString()) { + // print the string alone and return + toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n"; + } else { + // Not a string. Print the values in successive locations + const std::vector &constValues = CVA->getValues(); + for (unsigned i=0; i < constValues.size(); i++) + printConstantValueOnly(cast(constValues[i].get())); + } } else if (const ConstantStruct *CVS = dyn_cast(CV)) { // Print the fields in successive locations. Pad to align if needed! const StructLayout *cvsLayout = @@ -617,8 +506,6 @@ std::string AsmPrinter::valToExprString(const Value* V, // SparcAsmPrinter Code //===----------------------------------------------------------------------===// -namespace llvm { - namespace { struct SparcAsmPrinter : public FunctionPass, public AsmPrinter { @@ -638,9 +525,7 @@ namespace { virtual bool runOnFunction(Function &F) { currFunction = &F; - startFunction(F); emitFunction(F); - endFunction(F); return false; } @@ -681,7 +566,7 @@ namespace { inline bool SparcAsmPrinter::OpIsBranchTargetLabel(const MachineInstr *MI, unsigned int opNum) { - switch (MI->getOpCode()) { + switch (MI->getOpcode()) { case V9::JMPLCALLr: case V9::JMPLCALLi: case V9::JMPLRETr: @@ -695,9 +580,9 @@ SparcAsmPrinter::OpIsBranchTargetLabel(const MachineInstr *MI, inline bool SparcAsmPrinter::OpIsMemoryAddressBase(const MachineInstr *MI, unsigned int opNum) { - if (Target.getInstrInfo().isLoad(MI->getOpCode())) + if (Target.getInstrInfo().isLoad(MI->getOpcode())) return (opNum == 0); - else if (Target.getInstrInfo().isStore(MI->getOpCode())) + else if (Target.getInstrInfo().isStore(MI->getOpcode())) return (opNum == 1); else return false; @@ -716,15 +601,15 @@ SparcAsmPrinter::printOperands(const MachineInstr *MI, const MachineOperand& mop = MI->getOperand(opNum); if (OpIsBranchTargetLabel(MI, opNum)) { - PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode()); + PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpcode()); return 2; } else if (OpIsMemoryAddressBase(MI, opNum)) { toAsm << "["; - PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode()); + PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpcode()); toAsm << "]"; return 2; } else { - printOneOperand(mop, MI->getOpCode()); + printOneOperand(mop, MI->getOpcode()); return 1; } } @@ -806,7 +691,7 @@ SparcAsmPrinter::printOneOperand(const MachineOperand &mop, } void SparcAsmPrinter::emitMachineInst(const MachineInstr *MI) { - unsigned Opcode = MI->getOpCode(); + unsigned Opcode = MI->getOpcode(); if (Target.getInstrInfo().isDummyPhiInstr(Opcode)) return; // IGNORE PHI NODES @@ -908,8 +793,7 @@ void SparcAsmPrinter::emitGlobals(const Module &M) { toAsm << "\n"; } -FunctionPass *createAsmPrinterPass(std::ostream &Out, const TargetMachine &TM) { +FunctionPass *llvm::createAsmPrinterPass(std::ostream &Out, + const TargetMachine &TM) { return new SparcAsmPrinter(Out, TM); } - -} // End llvm namespace