Don't bother passing in default value
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9Internals.h
index 92c938ece0b45b7d21f173d6071025796ca71c5a..72691a2613fb0b094a4a7cf312c2303c0719bc54 100644 (file)
@@ -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 <sys/types.h>
 
@@ -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<MachineInstr*>& 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<MachineInstr*>& 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<RegClass *> 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<RegClass *> 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
@@ -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