X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FTarget%2FX86%2FX86AsmPrinter.h;h=9c6c683608bcc40cfcdb9244897e55de96839157;hp=4f53de8fb581696eef6be4369746b94de1adb2e1;hb=a1c0ce85180dd1c96ebc1ed48eb693c87a07aa7d;hpb=72b286b0a0f8987bc247ae052ac86008c553e9ae diff --git a/lib/Target/X86/X86AsmPrinter.h b/lib/Target/X86/X86AsmPrinter.h old mode 100755 new mode 100644 index 4f53de8fb58..9c6c683608b --- a/lib/Target/X86/X86AsmPrinter.h +++ b/lib/Target/X86/X86AsmPrinter.h @@ -1,74 +1,130 @@ -//===-- X86AsmPrinter.h - Convert X86 LLVM code to Intel assembly ---------===// +//===-- X86AsmPrinter.h - X86 implementation of AsmPrinter ------*- C++ -*-===// // // 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 the shared super class printer that converts from our internal -// representation of machine-dependent LLVM code to Intel and AT&T format -// assembly language. This printer is the output mechanism used by `llc'. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#ifndef X86ASMPRINTER_H -#define X86ASMPRINTER_H +#ifndef LLVM_LIB_TARGET_X86_X86ASMPRINTER_H +#define LLVM_LIB_TARGET_X86_X86ASMPRINTER_H -#include "X86.h" +#include "X86Subtarget.h" #include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/ADT/Statistic.h" -#include +#include "llvm/CodeGen/StackMaps.h" +#include "llvm/Target/TargetMachine.h" +// Implemented in X86MCInstLower.cpp +namespace { + class X86MCInstLower; +} namespace llvm { -namespace x86 { +class MCStreamer; +class MCSymbol; + +class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter { + const X86Subtarget *Subtarget; + StackMaps SM; + + void GenerateExportDirective(const MCSymbol *Sym, bool IsData); + + // This utility class tracks the length of a stackmap instruction's 'shadow'. + // It is used by the X86AsmPrinter to ensure that the stackmap shadow + // invariants (i.e. no other stackmaps, patchpoints, or control flow within + // the shadow) are met, while outputting a minimal number of NOPs for padding. + // + // To minimise the number of NOPs used, the shadow tracker counts the number + // of instruction bytes output since the last stackmap. Only if there are too + // few instruction bytes to cover the shadow are NOPs used for padding. + class StackMapShadowTracker { + public: + StackMapShadowTracker(TargetMachine &TM); + ~StackMapShadowTracker(); + void startFunction(MachineFunction &MF); + void count(MCInst &Inst, const MCSubtargetInfo &STI); + + // Called to signal the start of a shadow of RequiredSize bytes. + void reset(unsigned RequiredSize) { + RequiredShadowSize = RequiredSize; + CurrentShadowSize = 0; + InShadow = true; + } + + // Called before every stackmap/patchpoint, and at the end of basic blocks, + // to emit any necessary padding-NOPs. + void emitShadowPadding(MCStreamer &OutStreamer, const MCSubtargetInfo &STI); + private: + TargetMachine &TM; + const MachineFunction *MF; + std::unique_ptr CodeEmitter; + bool InShadow; -extern Statistic<> EmittedInsts; + // RequiredShadowSize holds the length of the shadow specified in the most + // recently encountered STACKMAP instruction. + // CurrentShadowSize counts the number of bytes encoded since the most + // recently encountered STACKMAP, stopping when that number is greater than + // or equal to RequiredShadowSize. + unsigned RequiredShadowSize, CurrentShadowSize; + }; -struct X86SharedAsmPrinter : public AsmPrinter { - X86SharedAsmPrinter(std::ostream &O, TargetMachine &TM) - : AsmPrinter(O, TM), forCygwin(false), forDarwin(false) { } + StackMapShadowTracker SMShadowTracker; - bool doInitialization(Module &M); - void printConstantPool(MachineConstantPool *MCP); - bool doFinalization(Module &M); + // All instructions emitted by the X86AsmPrinter should use this helper + // method. + // + // This helper function invokes the SMShadowTracker on each instruction before + // outputting it to the OutStream. This allows the shadow tracker to minimise + // the number of NOPs used for stackmap padding. + void EmitAndCountInstruction(MCInst &Inst); - bool forCygwin; - bool forDarwin; + void InsertStackMapShadows(MachineFunction &MF); + void LowerSTACKMAP(const MachineInstr &MI); + void LowerPATCHPOINT(const MachineInstr &MI, X86MCInstLower &MCIL); - // Necessary for Darwin to print out the apprioriate types of linker stubs - std::set FnStubs, GVStubs, LinkOnceStubs; + void LowerTlsAddr(X86MCInstLower &MCInstLowering, const MachineInstr &MI); - inline static bool isScale(const MachineOperand &MO) { - return MO.isImmediate() && - (MO.getImmedValue() == 1 || MO.getImmedValue() == 2 || - MO.getImmedValue() == 4 || MO.getImmedValue() == 8); + public: + explicit X86AsmPrinter(TargetMachine &TM, + std::unique_ptr Streamer) + : AsmPrinter(TM, std::move(Streamer)), SM(*this), SMShadowTracker(TM) {} + + const char *getPassName() const override { + return "X86 Assembly / Object Emitter"; } - inline static bool isMem(const MachineInstr *MI, unsigned Op) { - if (MI->getOperand(Op).isFrameIndex()) return true; - if (MI->getOperand(Op).isConstantPoolIndex()) return true; - return Op+4 <= MI->getNumOperands() && - MI->getOperand(Op ).isRegister() && isScale(MI->getOperand(Op+1)) && - MI->getOperand(Op+2).isRegister() && (MI->getOperand(Op+3).isImmediate()|| - MI->getOperand(Op+3).isGlobalAddress()); + const X86Subtarget &getSubtarget() const { return *Subtarget; } + + void EmitStartOfAsmFile(Module &M) override; + + void EmitEndOfAsmFile(Module &M) override; + + void EmitInstruction(const MachineInstr *MI) override; + + void EmitBasicBlockEnd(const MachineBasicBlock &MBB) override { + SMShadowTracker.emitShadowPadding(OutStreamer, getSubtargetInfo()); } - // SwitchSection - Switch to the specified section of the executable if we are - // not already in it! - inline static void SwitchSection(std::ostream &OS, std::string &CurSection, - const char *NewSection) { - if (CurSection != NewSection) { - CurSection = NewSection; - if (!CurSection.empty()) - OS << "\t" << NewSection << "\n"; - } + bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, const char *ExtraCode, + raw_ostream &OS) override; + bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, const char *ExtraCode, + raw_ostream &OS) override; + + /// \brief Return the symbol for the specified constant pool entry. + MCSymbol *GetCPISymbol(unsigned CPID) const override; + + bool doInitialization(Module &M) override { + SMShadowTracker.reset(0); + SM.reset(); + return AsmPrinter::doInitialization(M); } + + bool runOnMachineFunction(MachineFunction &F) override; }; -} // end namespace x86 } // end namespace llvm #endif