X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FSparcV9%2FSparcV9Internals.h;h=72691a2613fb0b094a4a7cf312c2303c0719bc54;hb=5638bf973f92a6653566cf4195ffe30f490fb7a8;hp=c5047f96a570c441b5f4b2c12666aa39d18d96f7;hpb=6a49a1e321b53aa3cc93d4c98abe621d957a9a4a;p=oota-llvm.git diff --git a/lib/Target/SparcV9/SparcV9Internals.h b/lib/Target/SparcV9/SparcV9Internals.h index c5047f96a57..72691a2613f 100644 --- a/lib/Target/SparcV9/SparcV9Internals.h +++ b/lib/Target/SparcV9/SparcV9Internals.h @@ -1,12 +1,9 @@ -//*************************************************************************** -// File: -// SparcInternals.h +//===-- SparcInternals.h ----------------------------------------*- C++ -*-===// // -// Purpose: -// This file defines stuff that is to be private to the Sparc -// backend, but is shared among different portions of the backend. -//**************************************************************************/ - +// This file defines stuff that is to be private to the Sparc backend, but is +// shared among different portions of the backend. +// +//===----------------------------------------------------------------------===// #ifndef SPARC_INTERNALS_H #define SPARC_INTERNALS_H @@ -16,6 +13,7 @@ #include "llvm/Target/MachineFrameInfo.h" #include "llvm/Target/MachineCacheInfo.h" #include "llvm/Target/MachineRegInfo.h" +#include "llvm/Target/MachineOptInfo.h" #include "llvm/Type.h" #include @@ -24,8 +22,6 @@ class UltraSparc; class PhyRegAlloc; class Pass; -Pass *createPrologEpilogCodeInserter(TargetMachine &TM); - // OpCodeMask definitions for the Sparc V9 // const OpCodeMask Immed = 0x00002000; // immed or reg operand? @@ -86,13 +82,12 @@ extern const MachineInstrDescriptor SparcMachineInstrDesc[]; // default to member functions in base class MachineInstrInfo. //--------------------------------------------------------------------------- -class UltraSparcInstrInfo : public MachineInstrInfo { -public: - /*ctor*/ UltraSparcInstrInfo(const TargetMachine& tgt); +struct UltraSparcInstrInfo : public MachineInstrInfo { + UltraSparcInstrInfo(const TargetMachine& tgt); // // All immediate constants are in position 1 except the - // store instructions. + // store instructions and SETxx. // virtual int getImmedConstantPos(MachineOpCode opCode) const { bool ignore; @@ -100,7 +95,11 @@ public: { assert(! this->isStore((MachineOpCode) STB - 1)); // 1st store opcode assert(! this->isStore((MachineOpCode) STXFSR+1));// last store opcode - return (opCode >= STB && opCode <= STXFSR)? 2 : 1; + if (opCode==SETSW || opCode==SETUW || opCode==SETX || opCode==SETHI) + return 0; + if (opCode >= STB && opCode <= STXFSR) + return 2; + return 1; } else return -1; @@ -117,10 +116,22 @@ public: return (opCode == FCMPS || opCode == FCMPD || opCode == FCMPQ); } + //------------------------------------------------------------------------- + // Queries about representation of LLVM quantities (e.g., constants) + //------------------------------------------------------------------------- + + virtual bool ConstantMayNotFitInImmedField(const Constant* CV, + const Instruction* I) const; + //------------------------------------------------------------------------- // Code generation support for creating individual machine instructions //------------------------------------------------------------------------- - + + // Get certain common op codes for the current target. This and all the + // Create* methods below should be moved to a machine code generation class + // + virtual MachineOpCode getNOPOpCode() const { return NOP; } + // Create an instruction sequence to put the constant `val' into // the virtual register `dest'. `val' may be a Constant or a // GlobalValue, viz., the constant address of a global variable or function. @@ -176,13 +187,29 @@ public: // Create instruction sequence to produce a sign-extended register value // from an arbitrary sized value (sized in bits, not bytes). + // The generated instructions are appended to `mvec'. + // Any temp. registers (TmpInstruction) created are recorded in mcfi. // Any stack space required is allocated via mcff. // virtual void CreateSignExtensionInstructions(const TargetMachine& target, Function* F, - Value* unsignedSrcVal, - unsigned int srcSizeInBits, - Value* dest, + Value* srcVal, + Value* destVal, + unsigned int numLowBits, + std::vector& mvec, + MachineCodeForInstruction& mcfi) const; + + // Create instruction sequence to produce a zero-extended register value + // from an arbitrary sized value (sized in bits, not bytes). + // The generated instructions are appended to `mvec'. + // Any temp. registers (TmpInstruction) created are recorded in mcfi. + // Any stack space required is allocated via mcff. + // + virtual void CreateZeroExtensionInstructions(const TargetMachine& target, + Function* F, + Value* srcVal, + Value* destVal, + unsigned int numLowBits, std::vector& mvec, MachineCodeForInstruction& mcfi) const; }; @@ -223,10 +250,6 @@ class UltraSparcRegInfo : public MachineRegInfo { // order for efficiency. - // reverse pointer to get info about the ultra sparc machine - // - const UltraSparc *const UltraSparcInfo; - // Number of registers used for passing int args (usually 6: %o0 - %o5) // unsigned const NumOfIntArgRegs; @@ -250,8 +273,7 @@ class UltraSparcRegInfo : public MachineRegInfo { void suggestReg4RetAddr(MachineInstr *RetMI, LiveRangeInfo &LRI) const; - void suggestReg4CallAddr(MachineInstr *CallMI, LiveRangeInfo &LRI, - std::vector RCList) const; + void suggestReg4CallAddr(MachineInstr *CallMI, LiveRangeInfo &LRI) const; void InitializeOutgoingArg(MachineInstr* CallMI, AddedInstrns *CallAI, PhyRegAlloc &PRA, LiveRange* LR, @@ -303,13 +325,6 @@ class UltraSparcRegInfo : public MachineRegInfo { public: UltraSparcRegInfo(const UltraSparc &tgt); - // To get complete machine information structure using the machine register - // information - // - inline const UltraSparc &getUltraSparcInfo() const { - return *UltraSparcInfo; - } - // To find the register class used for a specified Type // unsigned getRegClassIDOfType(const Type *type, @@ -357,8 +372,7 @@ public: LiveRangeInfo& LRI) const; void suggestRegs4CallArgs(MachineInstr *CallMI, - LiveRangeInfo& LRI, - std::vector RCL) const; + LiveRangeInfo& LRI) const; void suggestReg4RetValue(MachineInstr *RetMI, LiveRangeInfo& LRI) const; @@ -418,11 +432,12 @@ public: else if (ureg < 1 +100) { regClassID = IntCCRegClassID; return ureg-100;} else if (ureg == InvalidRegNum) { return InvalidRegNum; } else { assert(0 && "Invalid unified register number"); } + return 0; } // Returns the assembly-language name of the specified machine register. // - virtual const std::string getUnifiedRegName(int reg) const; + virtual const char * const getUnifiedRegName(int reg) const; // returns the # of bytes of stack space allocated for each register @@ -485,8 +500,8 @@ public: // This method inserts the caller saving code for call instructions // - void insertCallerSavingCode(vector& instrnsBefore, - vector& instrnsAfter, + void insertCallerSavingCode(std::vector& instrnsBefore, + std::vector& instrnsAfter, MachineInstr *MInst, const BasicBlock *BB, PhyRegAlloc &PRA ) const; }; @@ -525,43 +540,52 @@ public: UltraSparcFrameInfo(const TargetMachine &tgt) : MachineFrameInfo(tgt) {} public: + // These methods provide constant parameters of the frame layout. + // int getStackFrameSizeAlignment() const { return StackFrameSizeAlignment;} int getMinStackFrameSize() const { return MinStackFrameSize; } int getNumFixedOutgoingArgs() const { return NumFixedOutgoingArgs; } int getSizeOfEachArgOnStack() const { return SizeOfEachArgOnStack; } bool argsOnStackHaveFixedSize() const { return true; } - // + // This method adjusts a stack offset to meet alignment rules of target. + // The fixed OFFSET (0x7ff) must be subtracted and the result aligned. + virtual int adjustAlignment (int unalignedOffset, + bool growUp, + unsigned int align) const { + return unalignedOffset + (growUp? +1:-1)*((unalignedOffset-OFFSET) % align); + } + // These methods compute offsets using the frame contents for a // particular function. The frame contents are obtained from the // MachineCodeInfoForMethod object for the given function. // - int getFirstIncomingArgOffset (MachineCodeForMethod& mcInfo, + int getFirstIncomingArgOffset (MachineFunction& mcInfo, bool& growUp) const { growUp = true; // arguments area grows upwards return FirstIncomingArgOffsetFromFP; } - int getFirstOutgoingArgOffset (MachineCodeForMethod& mcInfo, + int getFirstOutgoingArgOffset (MachineFunction& mcInfo, bool& growUp) const { growUp = true; // arguments area grows upwards return FirstOutgoingArgOffsetFromSP; } - int getFirstOptionalOutgoingArgOffset(MachineCodeForMethod& mcInfo, + int getFirstOptionalOutgoingArgOffset(MachineFunction& mcInfo, bool& growUp)const { growUp = true; // arguments area grows upwards return FirstOptionalOutgoingArgOffsetFromSP; } - int getFirstAutomaticVarOffset (MachineCodeForMethod& mcInfo, + int getFirstAutomaticVarOffset (MachineFunction& mcInfo, bool& growUp) const; - int getRegSpillAreaOffset (MachineCodeForMethod& mcInfo, + int getRegSpillAreaOffset (MachineFunction& mcInfo, bool& growUp) const; - int getTmpAreaOffset (MachineCodeForMethod& mcInfo, + int getTmpAreaOffset (MachineFunction& mcInfo, bool& growUp) const; - int getDynamicAreaOffset (MachineCodeForMethod& mcInfo, + int getDynamicAreaOffset (MachineFunction& mcInfo, bool& growUp) const; // @@ -588,15 +612,58 @@ public: } private: + /*---------------------------------------------------------------------- + This diagram shows the stack frame layout used by llc on Sparc V9. + Note that only the location of automatic variables, spill area, + temporary storage, and dynamically allocated stack area are chosen + by us. The rest conform to the Sparc V9 ABI. + All stack addresses are offset by OFFSET = 0x7ff (2047). + + Alignment assumpteions and other invariants: + (1) %sp+OFFSET and %fp+OFFSET are always aligned on 16-byte boundary + (2) Variables in automatic, spill, temporary, or dynamic regions + are aligned according to their size as in all memory accesses. + (3) Everything below the dynamically allocated stack area is only used + during a call to another function, so it is never needed when + the current function is active. This is why space can be allocated + dynamically by incrementing %sp any time within the function. + + STACK FRAME LAYOUT: + + ... + %fp+OFFSET+176 Optional extra incoming arguments# 1..N + %fp+OFFSET+168 Incoming argument #6 + ... ... + %fp+OFFSET+128 Incoming argument #1 + ... ... + ---%fp+OFFSET-0--------Bottom of caller's stack frame-------------------- + %fp+OFFSET-8 Automatic variables <-- ****TOP OF STACK FRAME**** + Spill area + Temporary storage + ... + + %sp+OFFSET+176+8N Bottom of dynamically allocated stack area + %sp+OFFSET+168+8N Optional extra outgoing argument# N + ... ... + %sp+OFFSET+176 Optional extra outgoing argument# 1 + %sp+OFFSET+168 Outgoing argument #6 + ... ... + %sp+OFFSET+128 Outgoing argument #1 + %sp+OFFSET+120 Save area for %i7 + ... ... + %sp+OFFSET+0 Save area for %l0 <-- ****BOTTOM OF STACK FRAME**** + + *----------------------------------------------------------------------*/ + // All stack addresses must be offset by 0x7ff (2047) on Sparc V9. static const int OFFSET = (int) 0x7ff; static const int StackFrameSizeAlignment = 16; static const int MinStackFrameSize = 176; static const int NumFixedOutgoingArgs = 6; static const int SizeOfEachArgOnStack = 8; - static const int StaticAreaOffsetFromFP = 0 + OFFSET; static const int FirstIncomingArgOffsetFromFP = 128 + OFFSET; static const int FirstOptionalIncomingArgOffsetFromFP = 176 + OFFSET; + static const int StaticAreaOffsetFromFP = 0 + OFFSET; static const int FirstOutgoingArgOffsetFromSP = 128 + OFFSET; static const int FirstOptionalOutgoingArgOffsetFromSP = 176 + OFFSET; }; @@ -616,6 +683,21 @@ public: }; +//--------------------------------------------------------------------------- +// class UltraSparcOptInfo +// +// Purpose: +// Interface to machine-level optimization routines for the UltraSPARC. +//--------------------------------------------------------------------------- + +class UltraSparcOptInfo: public MachineOptInfo { +public: + UltraSparcOptInfo(const TargetMachine &T) : MachineOptInfo(T) {} + + virtual bool IsUselessCopy (const MachineInstr* MI) const; +}; + + //--------------------------------------------------------------------------- // class UltraSparcMachine // @@ -627,31 +709,35 @@ public: //--------------------------------------------------------------------------- class UltraSparc : public TargetMachine { -private: UltraSparcInstrInfo instrInfo; UltraSparcSchedInfo schedInfo; UltraSparcRegInfo regInfo; UltraSparcFrameInfo frameInfo; UltraSparcCacheInfo cacheInfo; + UltraSparcOptInfo optInfo; public: UltraSparc(); - + virtual const MachineInstrInfo &getInstrInfo() const { return instrInfo; } virtual const MachineSchedInfo &getSchedInfo() const { return schedInfo; } virtual const MachineRegInfo &getRegInfo() const { return regInfo; } virtual const MachineFrameInfo &getFrameInfo() const { return frameInfo; } virtual const MachineCacheInfo &getCacheInfo() const { return cacheInfo; } + virtual const MachineOptInfo &getOptInfo() const { return optInfo; } - // - // addPassesToEmitAssembly - Add passes to the specified pass manager to get - // assembly langage code emited. For sparc, we have to do ... - // virtual void addPassesToEmitAssembly(PassManager &PM, std::ostream &Out); -private: - Pass *getFunctionAsmPrinterPass(PassManager &PM, std::ostream &Out); - Pass *getModuleAsmPrinterPass(PassManager &PM, std::ostream &Out); - Pass *getEmitBytecodeToAsmPass(std::ostream &Out); + // getPrologEpilogCodeInserter - Inserts prolog/epilog code. + virtual Pass* getPrologEpilogInsertionPass(); + + // getFunctionAsmPrinterPass - Writes out machine code for a single function + virtual Pass* getFunctionAsmPrinterPass(std::ostream &Out); + + // getModuleAsmPrinterPass - Writes generated machine code to assembly file. + virtual Pass* getModuleAsmPrinterPass(std::ostream &Out); + + // getEmitBytecodeToAsmPass - Emits final LLVM bytecode to assembly file. + virtual Pass* getEmitBytecodeToAsmPass(std::ostream &Out); }; #endif