X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FAsmPrinter.h;h=e1be58ee5688ece34b4415cf7096e7e59e26c0b0;hb=62ed6b9ade63bf01717ce5274fa11e93e873d245;hp=2a56543612e5db5cecc4d3824c70684875323b04;hpb=37efe6764568a3829fee26aba532283131d1a104;p=oota-llvm.git diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 2a56543612e..e1be58ee568 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -2,14 +2,14 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // -// This class is intended to be used as a base class for target-specific -// asmwriters. This class primarily takes care of printing global constants, -// which are printed in a very similar way across all targets. +// This file contains a class to be used as the base class for target specific +// asm writers. This class primarily handles common functionality used by +// all asm writers. // //===----------------------------------------------------------------------===// @@ -18,17 +18,24 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/Support/DataTypes.h" +#include namespace llvm { class Constant; - class Mangler; + class ConstantArray; class GlobalVariable; + class GlobalAlias; + class MachineConstantPoolEntry; + class MachineConstantPoolValue; + class Mangler; + class TargetAsmInfo; + class Type; + /// AsmPrinter - This class is intended to be used as a driving class for all + /// asm writers. class AsmPrinter : public MachineFunctionPass { - /// CurrentSection - The current section we are emitting to. This is - /// controlled and used by the SwitchSection method. - std::string CurrentSection; - + static char ID; + /// FunctionNumber - This provides a unique ID for each function emitted in /// this translation unit. It is autoincremented by SetupMachineFunction, /// and can be accessed with getFunctionNumber() and @@ -36,6 +43,10 @@ namespace llvm { /// unsigned FunctionNumber; + protected: + // Necessary for external weak linkage support + std::set ExtWeakSymbols; + public: /// Output stream on which we're printing assembly code. /// @@ -44,6 +55,10 @@ namespace llvm { /// Target machine description. /// TargetMachine &TM; + + /// Target Asm Printer information. + /// + const TargetAsmInfo *TAI; /// Name-mangler for global names. /// @@ -53,143 +68,55 @@ namespace llvm { /// beginning of each call to runOnMachineFunction(). /// std::string CurrentFnName; - - //===------------------------------------------------------------------===// - // Properties to be set by the derived class ctor, used to configure the - // asmwriter. - - /// CommentString - This indicates the comment character used by the - /// assembler. - const char *CommentString; // Defaults to "#" - - /// GlobalPrefix - If this is set to a non-empty string, it is prepended - /// onto all global symbols. This is often used for "_" or ".". - const char *GlobalPrefix; // Defaults to "" - - /// PrivateGlobalPrefix - This prefix is used for globals like constant - /// pool entries that are completely private to the .o file and should not - /// have names in the .o file. This is often "." or "L". - const char *PrivateGlobalPrefix; // Defaults to "." - - /// GlobalVarAddrPrefix/Suffix - If these are nonempty, these strings - /// will enclose any GlobalVariable (that isn't a function) - /// - const char *GlobalVarAddrPrefix; // Defaults to "" - const char *GlobalVarAddrSuffix; // Defaults to "" - - /// FunctionAddrPrefix/Suffix - If these are nonempty, these strings - /// will enclose any GlobalVariable that points to a function. - /// For example, this is used by the IA64 backend to materialize - /// function descriptors, by decorating the ".data8" object with the - /// @fptr( ) link-relocation operator. - /// - const char *FunctionAddrPrefix; // Defaults to "" - const char *FunctionAddrSuffix; // Defaults to "" - - /// InlineAsmStart/End - If these are nonempty, they contain a directive to - /// emit before and after an inline assmebly statement. - const char *InlineAsmStart; // Defaults to "#APP\n" - const char *InlineAsmEnd; // Defaults to "#NO_APP\n" - - //===--- Data Emission Directives -------------------------------------===// - - /// ZeroDirective - this should be set to the directive used to get some - /// number of zero bytes emitted to the current section. Common cases are - /// "\t.zero\t" and "\t.space\t". If this is set to null, the - /// Data*bitsDirective's will be used to emit zero bytes. - const char *ZeroDirective; // Defaults to "\t.zero\t" - - /// AsciiDirective - This directive allows emission of an ascii string with - /// the standard C escape characters embedded into it. - const char *AsciiDirective; // Defaults to "\t.ascii\t" - - /// AscizDirective - If not null, this allows for special handling of - /// zero terminated strings on this target. This is commonly supported as - /// ".asciz". If a target doesn't support this, it can be set to null. - const char *AscizDirective; // Defaults to "\t.asciz\t" - - /// DataDirectives - These directives are used to output some unit of - /// integer data to the current section. If a data directive is set to - /// null, smaller data directives will be used to emit the large sizes. - const char *Data8bitsDirective; // Defaults to "\t.byte\t" - const char *Data16bitsDirective; // Defaults to "\t.short\t" - const char *Data32bitsDirective; // Defaults to "\t.long\t" - const char *Data64bitsDirective; // Defaults to "\t.quad\t" - - //===--- Alignment Information ----------------------------------------===// - - /// AlignDirective - The directive used to emit round up to an alignment - /// boundary. - /// - const char *AlignDirective; // Defaults to "\t.align\t" - - /// AlignmentIsInBytes - If this is true (the default) then the asmprinter - /// emits ".align N" directives, where N is the number of bytes to align to. - /// Otherwise, it emits ".align log2(N)", e.g. 3 to align to an 8 byte - /// boundary. - bool AlignmentIsInBytes; // Defaults to true - - //===--- Section Switching Directives ---------------------------------===// - - /// SwitchToSectionDirective - This is the directive used when we want to - /// emit a global to an arbitrary section. The section name is emited after - /// this. - const char *SwitchToSectionDirective; // Defaults to "\t.section\t" - - /// ConstantPoolSection - This is the section that we SwitchToSection right - /// before emitting the constant pool for a function. - const char *ConstantPoolSection; // Defaults to "\t.section .rodata\n" - - /// JumpTableSection - This is the section that we SwitchToSection right - /// before emitting the jump tables for a function. - const char *JumpTableSection; // Defaults to "\t.section .rodata\n" - - /// StaticCtorsSection - This is the directive that is emitted to switch to - /// a section to emit the static constructor list. - /// Defaults to "\t.section .ctors,\"aw\",@progbits". - const char *StaticCtorsSection; - - /// StaticDtorsSection - This is the directive that is emitted to switch to - /// a section to emit the static destructor list. - /// Defaults to "\t.section .dtors,\"aw\",@progbits". - const char *StaticDtorsSection; - - //===--- Global Variable Emission Directives --------------------------===// - - /// LCOMMDirective - This is the name of a directive (if supported) that can - /// be used to efficiently declare a local (internal) block of zero - /// initialized data in the .bss/.data section. The syntax expected is: - /// SYMBOLNAME LENGTHINBYTES, ALIGNMENT - const char *LCOMMDirective; // Defaults to null. - const char *COMMDirective; // Defaults to "\t.comm\t". - - /// COMMDirectiveTakesAlignment - True if COMMDirective take a third - /// argument that specifies the alignment of the declaration. - bool COMMDirectiveTakesAlignment; // Defaults to true. - - /// HasDotTypeDotSizeDirective - True if the target has .type and .size - /// directives, this is true for most ELF targets. - bool HasDotTypeDotSizeDirective; // Defaults to true. + /// CurrentSection - The current section we are emitting to. This is + /// controlled and used by the SwitchSection method. + std::string CurrentSection; protected: - AsmPrinter(std::ostream &o, TargetMachine &TM); + AsmPrinter(std::ostream &o, TargetMachine &TM, const TargetAsmInfo *T); public: - /// SwitchSection - Switch to the specified section of the executable if we - /// are not already in it! If GV is non-null and if the global has an + /// SwitchToTextSection - Switch to the specified section of the executable + /// if we are not already in it! If GV is non-null and if the global has an /// explicitly requested section, we switch to the section indicated for the /// global instead of NewSection. /// /// If the new section is an empty string, this method forgets what the /// current section is, but does not emit a .section directive. /// - void SwitchSection(const char *NewSection, const GlobalValue *GV); + /// This method is used when about to emit executable code. + /// + void SwitchToTextSection(const char *NewSection, const GlobalValue *GV = NULL); + + /// SwitchToDataSection - Switch to the specified section of the executable + /// if we are not already in it! If GV is non-null and if the global has an + /// explicitly requested section, we switch to the section indicated for the + /// global instead of NewSection. + /// + /// If the new section is an empty string, this method forgets what the + /// current section is, but does not emit a .section directive. + /// + /// This method is used when about to emit data. For most assemblers, this + /// is the same as the SwitchToTextSection method, but not all assemblers + /// are the same. + /// + void SwitchToDataSection(const char *NewSection, const GlobalValue *GV = NULL); + + /// getGlobalLinkName - Returns the asm/link name of of the specified + /// global variable. Should be overridden by each target asm printer to + /// generate the appropriate value. + virtual const std::string getGlobalLinkName(const GlobalVariable *GV) const; + + /// EmitExternalGlobal - Emit the external reference to a global variable. + /// Should be overridden if an indirect reference should be used. + virtual void EmitExternalGlobal(const GlobalVariable *GV); + + /// getCurrentFunctionEHName - Called to return (and cache) the + /// CurrentFnEHName. + /// + std::string getCurrentFunctionEHName(const MachineFunction *MF); - /// getPreferredAlignmentLog - Return the preferred alignment of the - /// specified global, returned in log form. This includes an explicitly - /// requested alignment (if the global has one). - unsigned getPreferredAlignmentLog(const GlobalVariable *GV) const; protected: /// doInitialization - Set up the AsmPrinter when we are working on a new /// module. If your pass overrides this, it must make sure to explicitly @@ -199,6 +126,14 @@ namespace llvm { /// doFinalization - Shut down the asmprinter. If you override this in your /// pass, you must make sure to call it explicitly. bool doFinalization(Module &M); + + /// PrintSpecial - Print information related to the specified machine instr + /// that is independent of the operand, and may be independent of the instr + /// itself. This can be useful for portably encoding the comment character + /// or other bits of target-specific knowledge into the asmstrings. The + /// syntax used is ${:comment}. Targets can override this to add support + /// for their own strange codes. + virtual void PrintSpecial(const MachineInstr *MI, const char *Code); /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM /// instruction, using the specified assembler variant. Targets should @@ -215,6 +150,12 @@ namespace llvm { unsigned AsmVariant, const char *ExtraCode); + /// getSectionForFunction - Return the section that we should emit the + /// specified function body into. This defaults to 'TextSection'. This + /// should most likely be overridden by the target to put linkonce/weak + /// functions into special sections. + virtual std::string getSectionForFunction(const Function &F) const; + /// SetupMachineFunction - This should be called when a new MachineFunction /// is being processed from runOnMachineFunction. void SetupMachineFunction(MachineFunction &MF); @@ -238,41 +179,151 @@ namespace llvm { /// EmitJumpTableInfo - Print assembly representations of the jump tables /// used by the current function to the current output stream. /// - void EmitJumpTableInfo(MachineJumpTableInfo *MJTI); + void EmitJumpTableInfo(MachineJumpTableInfo *MJTI, MachineFunction &MF); /// EmitSpecialLLVMGlobal - Check to see if the specified global is a /// special global used by LLVM. If so, emit it and return true, otherwise /// do nothing and return false. bool EmitSpecialLLVMGlobal(const GlobalVariable *GV); + + public: + //===------------------------------------------------------------------===// + /// LEB 128 number encoding. + + /// PrintULEB128 - Print a series of hexidecimal values(separated by commas) + /// representing an unsigned leb128 value. + void PrintULEB128(unsigned Value) const; + + /// SizeULEB128 - Compute the number of bytes required for an unsigned + /// leb128 value. + static unsigned SizeULEB128(unsigned Value); + + /// PrintSLEB128 - Print a series of hexidecimal values(separated by commas) + /// representing a signed leb128 value. + void PrintSLEB128(int Value) const; + + /// SizeSLEB128 - Compute the number of bytes required for a signed leb128 + /// value. + static unsigned SizeSLEB128(int Value); + + //===------------------------------------------------------------------===// + // Emission and print routines + // + + /// PrintHex - Print a value as a hexidecimal value. + /// + void PrintHex(int Value) const; + + /// 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 EOL() const; + void EOL(const std::string &Comment) const; + + /// EmitULEB128Bytes - Emit an assembler byte data directive to compose an + /// unsigned leb128 value. + void EmitULEB128Bytes(unsigned Value) const; + + /// EmitSLEB128Bytes - print an assembler byte data directive to compose a + /// signed leb128 value. + void EmitSLEB128Bytes(int Value) const; + + /// EmitInt8 - Emit a byte directive and value. + /// + void EmitInt8(int Value) const; + + /// EmitInt16 - Emit a short directive and value. + /// + void EmitInt16(int Value) const; + + /// EmitInt32 - Emit a long directive and value. + /// + void EmitInt32(int Value) const; + + /// EmitInt64 - Emit a long long directive and value. + /// + void EmitInt64(uint64_t Value) const; + + /// EmitString - Emit a string with quotes and a null terminator. + /// Special characters are emitted properly. + /// @verbatim (Eg. '\t') @endverbatim + void EmitString(const std::string &String) const; + + /// EmitFile - Emit a .file directive. + void EmitFile(unsigned Number, const std::string &Name) const; + + //===------------------------------------------------------------------===// /// EmitAlignment - Emit an alignment directive to the specified power of /// two boundary. For example, if you pass in 3 here, you will get an 8 /// byte alignment. If a global value is specified, and if that global has - /// an explicit alignment requested, it will override the alignment request. - void EmitAlignment(unsigned NumBits, const GlobalValue *GV = 0) const; + /// an explicit alignment requested, it will unconditionally override the + /// alignment request. However, if ForcedAlignBits is specified, this value + /// has final say: the ultimate alignment will be the max of ForcedAlignBits + /// and the alignment computed with NumBits and the global. If UseFillExpr + /// is true, it also emits an optional second value FillValue which the + /// assembler uses to fill gaps to match alignment. + /// + /// The algorithm is: + /// Align = NumBits; + /// if (GV && GV->hasalignment) Align = GV->getalignment(); + /// Align = std::max(Align, ForcedAlignBits); + /// + void EmitAlignment(unsigned NumBits, const GlobalValue *GV = 0, + unsigned ForcedAlignBits = 0, bool UseFillExpr = false, + unsigned FillValue = 0) const; + protected: /// EmitZeros - Emit a block of zeros. /// void EmitZeros(uint64_t NumZeros) const; + /// EmitString - Emit a zero-byte-terminated string constant. + /// + virtual void EmitString(const ConstantArray *CVA) const; + /// EmitConstantValueOnly - Print out the specified constant, without a /// storage class. Only constants of first-class type are allowed here. void EmitConstantValueOnly(const Constant *CV); /// EmitGlobalConstant - Print a general LLVM constant to the .s file. - /// - void EmitGlobalConstant(const Constant* CV); + /// If Packed is false, pad to the ABI size. + void EmitGlobalConstant(const Constant* CV, bool Packed = false); + + virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV); /// printInlineAsm - This method formats and prints the specified machine /// instruction that is an inline asm. void printInlineAsm(const MachineInstr *MI) const; + /// printLabel - This method prints a local label used by debug and + /// exception handling tables. + void printLabel(const MachineInstr *MI) const; + /// printBasicBlockLabel - This method prints the label for the specified /// MachineBasicBlock - virtual void printBasicBlockLabel(const MachineBasicBlock *MBB) const; + virtual void printBasicBlockLabel(const MachineBasicBlock *MBB, + bool printColon = false, + bool printComment = true) const; + + /// printPICJumpTableSetLabel - This method prints a set label for the + /// specified MachineBasicBlock for a jumptable entry. + virtual void printPICJumpTableSetLabel(unsigned uid, + const MachineBasicBlock *MBB) const; + virtual void printPICJumpTableSetLabel(unsigned uid, unsigned uid2, + const MachineBasicBlock *MBB) const; + virtual void printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, + const MachineBasicBlock *MBB, + unsigned uid) const; + /// printDataDirective - This method prints the asm directive for the + /// specified type. + void printDataDirective(const Type *type); + private: + void EmitLLVMUsedList(Constant *List); void EmitXXStructorList(Constant *List); + void EmitConstantPool(unsigned Alignment, const char *Section, + std::vector > &CP); }; }