X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FSparcV9%2FSparcV9Internals.h;h=72691a2613fb0b094a4a7cf312c2303c0719bc54;hb=5638bf973f92a6653566cf4195ffe30f490fb7a8;hp=ad3f478b334969283a75e582f602cc3711d73443;hpb=699683c58599ee1a8da95c231d338fd673943ec0;p=oota-llvm.git diff --git a/lib/Target/SparcV9/SparcV9Internals.h b/lib/Target/SparcV9/SparcV9Internals.h index ad3f478b334..72691a2613f 100644 --- a/lib/Target/SparcV9/SparcV9Internals.h +++ b/lib/Target/SparcV9/SparcV9Internals.h @@ -1,30 +1,26 @@ -// $Id$ -*- C++ -*-- -//*************************************************************************** -// 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 #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/MachineInstrInfo.h" #include "llvm/Target/MachineSchedInfo.h" #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 class LiveRange; class UltraSparc; class PhyRegAlloc; - +class Pass; // OpCodeMask definitions for the Sparc V9 // @@ -86,21 +82,24 @@ 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 0 except the - // store instructions. + // All immediate constants are in position 1 except the + // store instructions and SETxx. // - virtual int getImmmedConstantPos(MachineOpCode opCode) const { + virtual int getImmedConstantPos(MachineOpCode opCode) const { bool ignore; if (this->maxImmedConstant(opCode, ignore) != 0) { - assert(! this->isStore((MachineOpCode) STB - 1)); // first store is STB - assert(! this->isStore((MachineOpCode) STD + 1)); // last store is STD - return (opCode >= STB || opCode <= STD)? 2 : 1; + assert(! this->isStore((MachineOpCode) STB - 1)); // 1st store opcode + assert(! this->isStore((MachineOpCode) STXFSR+1));// last store opcode + if (opCode==SETSW || opCode==SETUW || opCode==SETX || opCode==SETHI) + return 0; + if (opCode >= STB && opCode <= STXFSR) + return 2; + return 1; } else return -1; @@ -117,51 +116,102 @@ 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'. The generated instructions are - // returned in `minstrVec'. Any temporary registers (TmpInstruction) - // created are returned in `tempVec'. + // the virtual register `dest'. `val' may be a Constant or a + // GlobalValue, viz., the constant address of a global variable or function. + // The generated instructions are returned in `mvec'. + // Any temp. registers (TmpInstruction) created are recorded in mcfi. + // Any stack space required is allocated via mcff. // - virtual void CreateCodeToLoadConst(Value* val, + virtual void CreateCodeToLoadConst(const TargetMachine& target, + Function* F, + Value* val, Instruction* dest, - std::vector& minstrVec, - std::vector& tmp) const; + std::vector& mvec, + MachineCodeForInstruction& mcfi) const; - // Create an instruction sequence to copy an integer value `val' // to a floating point value `dest' by copying to memory and back. // val must be an integral type. dest must be a Float or Double. - // The generated instructions are returned in `minstrVec'. - // Any temp. registers (TmpInstruction) created are returned in `tempVec'. + // The generated instructions are returned in `mvec'. + // Any temp. registers (TmpInstruction) created are recorded in mcfi. + // Any stack space required is allocated via mcff. // - virtual void CreateCodeToCopyIntToFloat(Method* method, - Value* val, - Instruction* dest, - std::vector& minstr, - std::vector& temp, - TargetMachine& target) const; + virtual void CreateCodeToCopyIntToFloat(const TargetMachine& target, + Function* F, + Value* val, + Instruction* dest, + std::vector& mvec, + MachineCodeForInstruction& mcfi) const; // Similarly, create an instruction sequence to copy an FP value // `val' to an integer value `dest' by copying to memory and back. - // See the previous function for information about return values. + // The generated instructions are returned in `mvec'. + // Any temp. registers (TmpInstruction) created are recorded in mcfi. + // Any stack space required is allocated via mcff. + // + virtual void CreateCodeToCopyFloatToInt(const TargetMachine& target, + Function* F, + Value* val, + Instruction* dest, + std::vector& mvec, + MachineCodeForInstruction& mcfi) const; + + // Create instruction(s) to copy src to dest, for arbitrary types + // The generated instructions are returned in `mvec'. + // Any temp. registers (TmpInstruction) created are recorded in mcfi. + // Any stack space required is allocated via mcff. + // + virtual void CreateCopyInstructionsByType(const TargetMachine& target, + Function* F, + Value* src, + Instruction* dest, + std::vector& mvec, + MachineCodeForInstruction& mcfi) const; + + // 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* 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 CreateCodeToCopyFloatToInt(Method* method, - Value* val, - Instruction* dest, - std::vector& minstr, - std::vector& temp, - TargetMachine& target) const; - - // create copy instruction(s) - virtual void - CreateCopyInstructionsByType(const TargetMachine& target, - Value* src, - Instruction* dest, - std::vector& minstr) const; + virtual void CreateZeroExtensionInstructions(const TargetMachine& target, + Function* F, + Value* srcVal, + Value* destVal, + unsigned int numLowBits, + std::vector& mvec, + MachineCodeForInstruction& mcfi) const; }; @@ -200,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; @@ -221,45 +267,30 @@ class UltraSparcRegInfo : public MachineRegInfo { // ======================== Private Methods ============================= // The following methods are used to color special live ranges (e.g. - // method args and return values etc.) with specific hardware registers + // function args and return values etc.) with specific hardware registers // as required. See SparcRegInfo.cpp for the implementation. // - void setCallOrRetArgCol(LiveRange *LR, unsigned RegNo, - const MachineInstr *MI, - std::hash_map &AIMap) const; - - MachineInstr *getCopy2RegMI(const Value *SrcVal, unsigned Reg, - unsigned RegClassID) const; - - void suggestReg4RetAddr(const MachineInstr *RetMI, + void suggestReg4RetAddr(MachineInstr *RetMI, LiveRangeInfo &LRI) const; - void suggestReg4CallAddr(const MachineInstr *CallMI, LiveRangeInfo &LRI, - std::vector RCList) const; - - - - // The following methods are used to find the addresses etc. contained - // in specail machine instructions like CALL/RET - // - Value *getValue4ReturnAddr(const MachineInstr *MInst) const; - const Value *getCallInstRetAddr(const MachineInstr *CallMI) const; - unsigned getCallInstNumArgs(const MachineInstr *CallMI) const; - - - // The following 3 methods are used to find the RegType (see enum above) - // of a LiveRange, Value and using the unified RegClassID + void suggestReg4CallAddr(MachineInstr *CallMI, LiveRangeInfo &LRI) const; + + void InitializeOutgoingArg(MachineInstr* CallMI, AddedInstrns *CallAI, + PhyRegAlloc &PRA, LiveRange* LR, + unsigned regType, unsigned RegClassID, + int UniArgReg, unsigned int argNo, + std::vector& AddedInstrnsBefore) + const; + + // The following 4 methods are used to find the RegType (see enum above) + // for a reg class and a given primitive type, a LiveRange, a Value, + // or a particular machine register. + // The fifth function gives the reg class of the given RegType. + // + int getRegType(unsigned regClassID, const Type* type) const; int getRegType(const LiveRange *LR) const; int getRegType(const Value *Val) const; - int getRegType(int reg) const; - - - // The following methods are used to generate copy instructions to move - // data between condition code registers - // - MachineInstr *cpCCR2IntMI(unsigned IntReg) const; - MachineInstr *cpInt2CCRMI(unsigned IntReg) const; + int getRegType(int unifiedRegNum) const; // Used to generate a copy instruction based on the register class of // value. @@ -269,7 +300,7 @@ class UltraSparcRegInfo : public MachineRegInfo { // The following 2 methods are used to order the instructions addeed by - // the register allocator in association with method calling. See + // the register allocator in association with function calling. See // SparcRegInfo.cpp for more details // void moveInst2OrdVec(std::vector &OrdVec, @@ -281,54 +312,43 @@ class UltraSparcRegInfo : public MachineRegInfo { PhyRegAlloc &PRA) const; - // To find whether a particular call is to a var arg method - // - bool isVarArgCall(const MachineInstr *CallMI) const; - + // Compute which register can be used for an argument, if any + // + int regNumForIntArg(bool inCallee, bool isVarArgsCall, + unsigned argNo, unsigned intArgNo, unsigned fpArgNo, + unsigned& regClassId) const; + int regNumForFPArg(unsigned RegType, bool inCallee, bool isVarArgsCall, + unsigned argNo, unsigned intArgNo, unsigned fpArgNo, + unsigned& regClassId) const; + public: UltraSparcRegInfo(const UltraSparc &tgt); - // To get complete machine information structure using the machine register - // information + // To find the register class used for a specified Type // - inline const UltraSparc &getUltraSparcInfo() const { - return *UltraSparcInfo; - } + unsigned getRegClassIDOfType(const Type *type, + bool isCCReg = false) const; // To find the register class of a Value // inline unsigned getRegClassIDOfValue(const Value *Val, bool isCCReg = false) const { - - Type::PrimitiveID ty = Val->getType()->getPrimitiveID(); - unsigned res; - - if ((ty && ty <= Type::LongTyID) || (ty == Type::LabelTyID) || - (ty == Type::MethodTyID) || (ty == Type::PointerTyID) ) - res = IntRegClassID; // sparc int reg (ty=0: void) - else if (ty <= Type::DoubleTyID) - res = FloatRegClassID; // sparc float reg class - else { - std::cerr << "TypeID: " << ty << "\n"; - assert(0 && "Cannot resolve register class for type"); - return 0; - } - - if(isCCReg) - return res + 2; // corresponidng condition code regiser - else - return res; + return getRegClassIDOfType(Val->getType(), isCCReg); } - + // To find the register class to which a specified register belongs + // + unsigned getRegClassIDOfReg(int unifiedRegNum) const; + unsigned getRegClassIDOfRegType(int regType) const; + // getZeroRegNum - returns the register that contains always zero this is the // unified register number // virtual int getZeroRegNum() const; // getCallAddressReg - returns the reg used for pushing the address when a - // method is called. This can be used for other purposes between calls + // function is called. This can be used for other purposes between calls // unsigned getCallAddressReg() const; @@ -338,62 +358,86 @@ public: // unsigned getReturnAddressReg() const; - - + // Number of registers used for passing int args (usually 6: %o0 - %o5) + // and float args (usually 32: %f0 - %f31) + // + unsigned const GetNumOfIntArgRegs() const { return NumOfIntArgRegs; } + unsigned const GetNumOfFloatArgRegs() const { return NumOfFloatArgRegs; } + // The following methods are used to color special live ranges (e.g. - // method args and return values etc.) with specific hardware registers + // function args and return values etc.) with specific hardware registers // as required. See SparcRegInfo.cpp for the implementation for Sparc. // - void suggestRegs4MethodArgs(const Method *Meth, + void suggestRegs4MethodArgs(const Function *Meth, LiveRangeInfo& LRI) const; - void suggestRegs4CallArgs(const MachineInstr *CallMI, - LiveRangeInfo& LRI, - std::vector RCL) const; + void suggestRegs4CallArgs(MachineInstr *CallMI, + LiveRangeInfo& LRI) const; - void suggestReg4RetValue(const MachineInstr *RetMI, + void suggestReg4RetValue(MachineInstr *RetMI, LiveRangeInfo& LRI) const; - - - void colorMethodArgs(const Method *Meth, LiveRangeInfo &LRI, + + void colorMethodArgs(const Function *Meth, LiveRangeInfo &LRI, AddedInstrns *FirstAI) const; - void colorCallArgs(const MachineInstr *CallMI, LiveRangeInfo &LRI, + void colorCallArgs(MachineInstr *CallMI, LiveRangeInfo &LRI, AddedInstrns *CallAI, PhyRegAlloc &PRA, const BasicBlock *BB) const; - void colorRetValue(const MachineInstr *RetI, LiveRangeInfo& LRI, + void colorRetValue(MachineInstr *RetI, LiveRangeInfo& LRI, AddedInstrns *RetAI) const; - // method used for printing a register for debugging purposes // static void printReg(const LiveRange *LR); - // this method provides a unique number for each register + // Each register class has a seperate space for register IDs. To convert + // a regId in a register class to a common Id, or vice versa, + // we use the folloing methods. // - inline int getUnifiedRegNum(int RegClassID, int reg) const { - - if( RegClassID == IntRegClassID && reg < 32 ) + // This method provides a unique number for each register + inline int getUnifiedRegNum(unsigned regClassID, int reg) const { + + if (regClassID == IntRegClassID) { + assert(reg < 32 && "Invalid reg. number"); return reg; - else if ( RegClassID == FloatRegClassID && reg < 64) + } + else if (regClassID == FloatRegClassID) { + assert(reg < 64 && "Invalid reg. number"); return reg + 32; // we have 32 int regs - else if( RegClassID == FloatCCRegClassID && reg < 4) + } + else if (regClassID == FloatCCRegClassID) { + assert(reg < 4 && "Invalid reg. number"); return reg + 32 + 64; // 32 int, 64 float - else if( RegClassID == IntCCRegClassID ) - return 4+ 32 + 64; // only int cc reg - else if (reg==InvalidRegNum) + } + else if (regClassID == IntCCRegClassID ) { + assert(reg == 0 && "Invalid reg. number"); + return reg + 4+ 32 + 64; // only one int CC reg + } + else if (reg==InvalidRegNum) { return InvalidRegNum; + } else - assert(0 && "Invalid register class or reg number"); + assert(0 && "Invalid register class"); return 0; } - - // given the unified register number, this gives the name - // for generating assembly code or debugging. + + // This method converts the unified number to the number in its class, + // and returns the class ID in regClassID. + inline int getClassRegNum(int ureg, unsigned& regClassID) const { + if (ureg < 32) { regClassID = IntRegClassID; return ureg; } + else if (ureg < 32+64) { regClassID = FloatRegClassID; return ureg-32; } + else if (ureg < 4 +96) { regClassID = FloatCCRegClassID; return ureg-96; } + 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 @@ -406,25 +450,38 @@ public: } - // To obtain the return value contained in a CALL machine instruction + // To obtain the return value and the indirect call address (if any) + // contained in a CALL machine instruction // const Value * getCallInstRetVal(const MachineInstr *CallMI) const; - + const Value * getCallInstIndirectAddrVal(const MachineInstr *CallMI) const; // The following methods are used to generate "copy" machine instructions // for an architecture. // - MachineInstr * cpReg2RegMI(unsigned SrcReg, unsigned DestReg, - int RegType) const; + // The function regTypeNeedsScratchReg() can be used to check whether a + // scratch register is needed to copy a register of type `regType' to + // or from memory. If so, such a scratch register can be provided by + // the caller (e.g., if it knows which regsiters are free); otherwise + // an arbitrary one will be chosen and spilled by the copy instructions. + // + bool regTypeNeedsScratchReg(int RegType, + int& scratchRegClassId) const; - MachineInstr * cpReg2MemMI(unsigned SrcReg, unsigned DestPtrReg, - int Offset, int RegType) const; + void cpReg2RegMI(std::vector& mvec, + unsigned SrcReg, unsigned DestReg, + int RegType) const; - MachineInstr * cpMem2RegMI(unsigned SrcPtrReg, int Offset, - unsigned DestReg, int RegType) const; + void cpReg2MemMI(std::vector& mvec, + unsigned SrcReg, unsigned DestPtrReg, + int Offset, int RegType, int scratchReg = -1) const; - MachineInstr* cpValue2Value(Value *Src, Value *Dest) const; + void cpMem2RegMI(std::vector& mvec, + unsigned SrcPtrReg, int Offset, unsigned DestReg, + int RegType, int scratchReg = -1) const; + void cpValue2Value(Value *Src, Value *Dest, + std::vector& mvec) const; // To see whether a register is a volatile (i.e., whehter it must be // preserved acorss calls) @@ -443,7 +500,9 @@ public: // This method inserts the caller saving code for call instructions // - void insertCallerSavingCode(const MachineInstr *MInst, + void insertCallerSavingCode(std::vector& instrnsBefore, + std::vector& instrnsAfter, + MachineInstr *MInst, const BasicBlock *BB, PhyRegAlloc &PRA ) const; }; @@ -481,44 +540,53 @@ public: UltraSparcFrameInfo(const TargetMachine &tgt) : MachineFrameInfo(tgt) {} public: - 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; } + // 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 method. The frame contents are obtained from the - // MachineCodeInfoForMethod object for the given method. + // particular function. The frame contents are obtained from the + // MachineCodeInfoForMethod object for the given function. // - int getFirstIncomingArgOffset (MachineCodeForMethod& mcInfo, - bool& pos) const + int getFirstIncomingArgOffset (MachineFunction& mcInfo, + bool& growUp) const { - pos = true; // arguments area grows upwards + growUp = true; // arguments area grows upwards return FirstIncomingArgOffsetFromFP; } - int getFirstOutgoingArgOffset (MachineCodeForMethod& mcInfo, - bool& pos) const + int getFirstOutgoingArgOffset (MachineFunction& mcInfo, + bool& growUp) const { - pos = true; // arguments area grows upwards + growUp = true; // arguments area grows upwards return FirstOutgoingArgOffsetFromSP; } - int getFirstOptionalOutgoingArgOffset(MachineCodeForMethod& mcInfo, - bool& pos)const + int getFirstOptionalOutgoingArgOffset(MachineFunction& mcInfo, + bool& growUp)const { - pos = true; // arguments area grows upwards + growUp = true; // arguments area grows upwards return FirstOptionalOutgoingArgOffsetFromSP; } - int getFirstAutomaticVarOffset (MachineCodeForMethod& mcInfo, - bool& pos) const; - int getRegSpillAreaOffset (MachineCodeForMethod& mcInfo, - bool& pos) const; - int getTmpAreaOffset (MachineCodeForMethod& mcInfo, - bool& pos) const; - int getDynamicAreaOffset (MachineCodeForMethod& mcInfo, - bool& pos) const; + int getFirstAutomaticVarOffset (MachineFunction& mcInfo, + bool& growUp) const; + int getRegSpillAreaOffset (MachineFunction& mcInfo, + bool& growUp) const; + int getTmpAreaOffset (MachineFunction& mcInfo, + bool& growUp) const; + int getDynamicAreaOffset (MachineFunction& mcInfo, + bool& growUp) const; // // These methods specify the base register used for each stack area @@ -544,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; }; @@ -572,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 // @@ -583,30 +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 *getMethodAsmPrinterPass(PassManager &PM, std::ostream &Out); - Pass *getModuleAsmPrinterPass(PassManager &PM, 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