Reorganized the Sparc backend to be more modular -- each different
authorMisha Brukman <brukman+llvm@gmail.com>
Wed, 17 Dec 2003 22:04:00 +0000 (22:04 +0000)
committerMisha Brukman <brukman+llvm@gmail.com>
Wed, 17 Dec 2003 22:04:00 +0000 (22:04 +0000)
implementation of a Target{RegInfo, InstrInfo, Machine, etc} now has a separate
header and a separate implementation file.

This means that instead of a massive SparcInternals.h that forces a
recompilation of the whole target whenever a minor detail is changed, you should
only recompile a few files.

Note that SparcInternals.h is still around; its contents should be minimized.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10500 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
lib/Target/SparcV9/SparcV9CodeEmitter.cpp
lib/Target/SparcV9/SparcV9FrameInfo.cpp [new file with mode: 0644]
lib/Target/SparcV9/SparcV9FrameInfo.h [new file with mode: 0644]
lib/Target/SparcV9/SparcV9InstrInfo.cpp
lib/Target/SparcV9/SparcV9InstrInfo.h [new file with mode: 0644]
lib/Target/SparcV9/SparcV9InstrSelection.cpp
lib/Target/SparcV9/SparcV9Internals.h
lib/Target/SparcV9/SparcV9RegClassInfo.cpp
lib/Target/SparcV9/SparcV9RegInfo.cpp
lib/Target/SparcV9/SparcV9RegInfo.h [new file with mode: 0644]
lib/Target/SparcV9/SparcV9SchedInfo.cpp
lib/Target/SparcV9/SparcV9TargetMachine.cpp
lib/Target/SparcV9/SparcV9TargetMachine.h [new file with mode: 0644]

index 9a51faa4cc3fa65f044f9d07c839dafa2167990b..bb4bdaf8a417ea23c658a3a3251c11c7b5d19e64 100644 (file)
@@ -35,6 +35,8 @@
 #include "Support/hash_set"
 #include "Support/Statistic.h"
 #include "SparcInternals.h"
+#include "SparcTargetMachine.h"
+#include "SparcRegInfo.h"
 #include "SparcV9CodeEmitter.h"
 #include "Config/alloca.h"
 
@@ -46,8 +48,8 @@ namespace {
   Statistic<> CallbackCalls("callback", "Number CompilationCallback() calls");
 }
 
-bool UltraSparc::addPassesToEmitMachineCode(FunctionPassManager &PM,
-                                            MachineCodeEmitter &MCE) {
+bool SparcTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
+                                                    MachineCodeEmitter &MCE) {
   MachineCodeEmitter *M = &MCE;
   DEBUG(M = MachineCodeEmitter::createFilePrinterEmitter(MCE));
   PM.add(new SparcV9CodeEmitter(*this, *M));
@@ -102,10 +104,10 @@ namespace {
 
   private:
     uint64_t emitStubForFunction(Function *F);
-    static void SaveRegisters(uint64_t DoubleFP[], uint64_t &FSR,
-                              uint64_t &FPRS, uint64_t &CCR);
-    static void RestoreRegisters(uint64_t DoubleFP[], uint64_t &FSR,
-                                 uint64_t &FPRS, uint64_t &CCR);
+    static void SaveRegisters(uint64_t DoubleFP[], uint64_t CC[],
+                              uint64_t Globals[]);
+    static void RestoreRegisters(uint64_t DoubleFP[], uint64_t CC[],
+                                 uint64_t Globals[]);
     static void CompilationCallback();
     uint64_t resolveFunctionReference(uint64_t RetAddr);
 
@@ -209,17 +211,20 @@ void JITResolver::insertFarJumpAtAddr(int64_t Target, uint64_t Addr) {
   }
 }
 
-void JITResolver::SaveRegisters(uint64_t DoubleFP[], uint64_t &FSR
-                                uint64_t &FPRS, uint64_t &CCR) {
+void JITResolver::SaveRegisters(uint64_t DoubleFP[], uint64_t CC[]
+                                uint64_t Globals[]) {
 #if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
 
-#if 0
   __asm__ __volatile__ (// Save condition-code registers
                         "stx %%fsr, %0;\n\t" 
                         "rd %%fprs, %1;\n\t" 
                         "rd %%ccr,  %2;\n\t"
-                        : "=m"(FSR), "=r"(FPRS), "=r"(CCR));
-#endif
+                        : "=m"(CC[0]), "=r"(CC[1]), "=r"(CC[2]));
+
+  __asm__ __volatile__ (// Save globals g1 and g5
+                        "stx %%g1, %0;\n\t"
+                        "stx %%g5, %0;\n\t"
+                        : "=m"(Globals[0]), "=m"(Globals[1]));
 
   // GCC says: `asm' only allows up to thirty parameters!
   __asm__ __volatile__ (// Save Single/Double FP registers, part 1
@@ -261,18 +266,21 @@ void JITResolver::SaveRegisters(uint64_t DoubleFP[], uint64_t &FSR,
 }
 
 
-void JITResolver::RestoreRegisters(uint64_t DoubleFP[], uint64_t &FSR
-                                   uint64_t &FPRS, uint64_t &CCR)
+void JITResolver::RestoreRegisters(uint64_t DoubleFP[], uint64_t CC[]
+                                   uint64_t Globals[])
 {
 #if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
 
-#if 0
   __asm__ __volatile__ (// Restore condition-code registers
                         "ldx %0,    %%fsr;\n\t" 
                         "wr  %1, 0, %%fprs;\n\t"
                         "wr  %2, 0, %%ccr;\n\t" 
-                        :: "m"(FSR), "r"(FPRS), "r"(CCR));
-#endif
+                        :: "m"(CC[0]), "r"(CC[1]), "r"(CC[2]));
+
+  __asm__ __volatile__ (// Restore globals g1 and g5
+                        "ldx %0, %%g1;\n\t"
+                        "ldx %0, %%g5;\n\t"
+                        :: "m"(Globals[0]), "m"(Globals[1]));
 
   // GCC says: `asm' only allows up to thirty parameters!
   __asm__ __volatile__ (// Restore Single/Double FP registers, part 1
@@ -314,11 +322,12 @@ void JITResolver::RestoreRegisters(uint64_t DoubleFP[], uint64_t &FSR,
 }
 
 void JITResolver::CompilationCallback() {
-  // Local space to save double registers
+  // Local space to save the registers
   uint64_t DoubleFP[32];
-  uint64_t FSR, FPRS, CCR;
+  uint64_t CC[3];
+  uint64_t Globals[2];
 
-  SaveRegisters(DoubleFP, FSR, FPRS, CCR);
+  SaveRegisters(DoubleFP, CC, Globals);
   ++CallbackCalls;
 
   uint64_t CameFrom = (uint64_t)(intptr_t)__builtin_return_address(0);
@@ -394,7 +403,7 @@ void JITResolver::CompilationCallback() {
   __asm__ __volatile__ ("sub %%i7, %0, %%i7" : : "r" (Offset+12));
 #endif
 
-  RestoreRegisters(DoubleFP, FSR, FPRS, CCR);
+  RestoreRegisters(DoubleFP, CC, Globals);
 }
 
 /// emitStubForFunction - This method is used by the JIT when it needs to emit
@@ -476,7 +485,7 @@ SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg,
   fakeReg = RI.getClassRegNum(fakeReg, regClass);
 
   switch (regClass) {
-  case UltraSparcRegInfo::IntRegClassID: {
+  case SparcRegInfo::IntRegClassID: {
     // Sparc manual, p31
     static const unsigned IntRegMap[] = {
       // "o0", "o1", "o2", "o3", "o4", "o5",       "o7",
@@ -494,12 +503,12 @@ SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg,
     return IntRegMap[fakeReg];
     break;
   }
-  case UltraSparcRegInfo::FloatRegClassID: {
+  case SparcRegInfo::FloatRegClassID: {
     DEBUG(std::cerr << "FP reg: " << fakeReg << "\n");
-    if (regType == UltraSparcRegInfo::FPSingleRegType) {
+    if (regType == SparcRegInfo::FPSingleRegType) {
       // only numbered 0-31, hence can already fit into 5 bits (and 6)
       DEBUG(std::cerr << "FP single reg, returning: " << fakeReg << "\n");
-    } else if (regType == UltraSparcRegInfo::FPDoubleRegType) {
+    } else if (regType == SparcRegInfo::FPDoubleRegType) {
       // FIXME: This assumes that we only have 5-bit register fields!
       // From Sparc Manual, page 40.
       // The bit layout becomes: b[4], b[3], b[2], b[1], b[5]
@@ -509,7 +518,7 @@ SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg,
     }
     return fakeReg;
   }
-  case UltraSparcRegInfo::IntCCRegClassID: {
+  case SparcRegInfo::IntCCRegClassID: {
     /*                                   xcc, icc, ccr */
     static const unsigned IntCCReg[] = {  6,   4,   2 };
     
@@ -518,7 +527,7 @@ SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg,
     DEBUG(std::cerr << "IntCC reg: " << IntCCReg[fakeReg] << "\n");
     return IntCCReg[fakeReg];
   }
-  case UltraSparcRegInfo::FloatCCRegClassID: {
+  case SparcRegInfo::FloatCCRegClassID: {
     /* These are laid out %fcc0 - %fcc3 => 0 - 3, so are correct */
     DEBUG(std::cerr << "FP CC reg: " << fakeReg << "\n");
     return fakeReg;
@@ -573,7 +582,7 @@ inline void SparcV9CodeEmitter::emitFarCall(uint64_t Target, Function *F) {
   }
 }
 
-void UltraSparc::replaceMachineCodeForFunction (void *Old, void *New) {
+void SparcTargetMachine::replaceMachineCodeForFunction (void *Old, void *New) {
   assert (TheJITResolver &&
        "Can only call replaceMachineCodeForFunction from within JIT");
   uint64_t Target = (uint64_t)(intptr_t)New;
diff --git a/lib/Target/SparcV9/SparcV9FrameInfo.cpp b/lib/Target/SparcV9/SparcV9FrameInfo.cpp
new file mode 100644 (file)
index 0000000..d283e94
--- /dev/null
@@ -0,0 +1,65 @@
+//===-- Sparc.cpp - General implementation file for the Sparc Target ------===//
+// 
+//                     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.
+// 
+//===----------------------------------------------------------------------===//
+// 
+// Interface to stack frame layout info for the UltraSPARC.  Starting offsets
+// for each area of the stack frame are aligned at a multiple of
+// getStackFrameSizeAlignment().
+// 
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionInfo.h"
+#include "llvm/Target/TargetFrameInfo.h"
+#include "SparcFrameInfo.h"
+
+using namespace llvm;
+
+int
+SparcFrameInfo::getFirstAutomaticVarOffset(MachineFunction&, bool& pos) const {
+  pos = false;                          // static stack area grows downwards
+  return StaticAreaOffsetFromFP;
+}
+
+int
+SparcFrameInfo::getRegSpillAreaOffset(MachineFunction& mcInfo, bool& pos) const 
+{
+  // ensure no more auto vars are added
+  mcInfo.getInfo()->freezeAutomaticVarsArea();
+  
+  pos = false;                          // static stack area grows downwards
+  unsigned autoVarsSize = mcInfo.getInfo()->getAutomaticVarsSize();
+  return StaticAreaOffsetFromFP - autoVarsSize; 
+}
+
+int SparcFrameInfo::getTmpAreaOffset(MachineFunction& mcInfo, bool& pos) const {
+  MachineFunctionInfo *MFI = mcInfo.getInfo();
+  MFI->freezeAutomaticVarsArea();     // ensure no more auto vars are added
+  MFI->freezeSpillsArea();            // ensure no more spill slots are added
+  
+  pos = false;                          // static stack area grows downwards
+  unsigned autoVarsSize = MFI->getAutomaticVarsSize();
+  unsigned spillAreaSize = MFI->getRegSpillsSize();
+  int offset = autoVarsSize + spillAreaSize;
+  return StaticAreaOffsetFromFP - offset;
+}
+
+int
+SparcFrameInfo::getDynamicAreaOffset(MachineFunction& mcInfo, bool& pos) const {
+  // Dynamic stack area grows downwards starting at top of opt-args area.
+  // The opt-args, required-args, and register-save areas are empty except
+  // during calls and traps, so they are shifted downwards on each
+  // dynamic-size alloca.
+  pos = false;
+  unsigned optArgsSize = mcInfo.getInfo()->getMaxOptionalArgsSize();
+  if (int extra = optArgsSize % getStackFrameSizeAlignment())
+    optArgsSize += (getStackFrameSizeAlignment() - extra);
+  int offset = optArgsSize + FirstOptionalOutgoingArgOffsetFromSP;
+  assert((offset - OFFSET) % getStackFrameSizeAlignment() == 0);
+  return offset;
+}
diff --git a/lib/Target/SparcV9/SparcV9FrameInfo.h b/lib/Target/SparcV9/SparcV9FrameInfo.h
new file mode 100644 (file)
index 0000000..9038596
--- /dev/null
@@ -0,0 +1,174 @@
+//===-- SparcFrameInfo.h - Define TargetFrameInfo for Sparc -----*- 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.
+// 
+//===----------------------------------------------------------------------===//
+//
+// Interface to stack frame layout info for the UltraSPARC.
+// Starting offsets for each area of the stack frame are aligned at
+// a multiple of getStackFrameSizeAlignment().
+//
+//----------------------------------------------------------------------------
+
+#ifndef SPARC_FRAMEINFO_H
+#define SPARC_FRAMEINFO_H
+
+#include "llvm/Target/TargetFrameInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegInfo.h"
+
+namespace llvm {
+
+class SparcFrameInfo: public TargetFrameInfo {
+  const TargetMachine &target;
+public:
+  SparcFrameInfo(const TargetMachine &TM)
+    : TargetFrameInfo(StackGrowsDown, StackFrameSizeAlignment, 0), target(TM) {}
+  
+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(MachineFunction& mcInfo, bool& growUp) const {
+    growUp = true;                         // arguments area grows upwards
+    return FirstIncomingArgOffsetFromFP;
+  }
+  int getFirstOutgoingArgOffset(MachineFunction& mcInfo, bool& growUp) const {
+    growUp = true;                         // arguments area grows upwards
+    return FirstOutgoingArgOffsetFromSP;
+  }
+  int getFirstOptionalOutgoingArgOffset(MachineFunction& mcInfo,
+                                        bool& growUp) const {
+    growUp = true;                         // arguments area grows upwards
+    return FirstOptionalOutgoingArgOffsetFromSP;
+  }
+  
+  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
+  // (generally FP or SP)
+  // 
+  virtual int getIncomingArgBaseRegNum() const {
+    return (int) target.getRegInfo().getFramePointer();
+  }
+  virtual int getOutgoingArgBaseRegNum() const {
+    return (int) target.getRegInfo().getStackPointer();
+  }
+  virtual int getOptionalOutgoingArgBaseRegNum() const {
+    return (int) target.getRegInfo().getStackPointer();
+  }
+  virtual int getAutomaticVarBaseRegNum() const {
+    return (int) target.getRegInfo().getFramePointer();
+  }
+  virtual int getRegSpillAreaBaseRegNum() const {
+    return (int) target.getRegInfo().getFramePointer();
+  }
+  virtual int getDynamicAreaBaseRegNum() const {
+    return (int) target.getRegInfo().getStackPointer();
+  }
+
+  virtual int getIncomingArgOffset(MachineFunction& mcInfo, 
+                                   unsigned argNum) const {
+    assert(argsOnStackHaveFixedSize()); 
+  
+    unsigned relativeOffset = argNum * getSizeOfEachArgOnStack();
+    bool growUp;                          // do args grow up or down
+    int firstArg = getFirstIncomingArgOffset(mcInfo, growUp);
+    return growUp ? firstArg + relativeOffset : firstArg - relativeOffset; 
+  }
+
+  virtual int getOutgoingArgOffset(MachineFunction& mcInfo,
+                                  unsigned argNum) const {
+    assert(argsOnStackHaveFixedSize()); 
+    //assert(((int) argNum - this->getNumFixedOutgoingArgs())
+    //     <= (int) mcInfo.getInfo()->getMaxOptionalNumArgs());
+    
+    unsigned relativeOffset = argNum * getSizeOfEachArgOnStack();
+    bool growUp;                          // do args grow up or down
+    int firstArg = getFirstOutgoingArgOffset(mcInfo, growUp);
+    return growUp ? firstArg + relativeOffset : firstArg - relativeOffset; 
+  }
+  
+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 assumptions 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 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;
+};
+
+} // End llvm namespace
+
+#endif
index 11b0c7beab58433b4ac82faf0128ec323199f42c..af458ea03990e23c454013160b063dc0ed7cfdb8 100644 (file)
@@ -9,8 +9,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "SparcInternals.h"
-#include "SparcInstrSelectionSupport.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
@@ -22,6 +20,9 @@
 #include "llvm/CodeGen/MachineFunctionInfo.h"
 #include "llvm/CodeGen/MachineCodeForInstruction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "SparcInternals.h"
+#include "SparcInstrSelectionSupport.h"
+#include "SparcInstrInfo.h"
 
 namespace llvm {
 
@@ -41,7 +42,7 @@ static const uint32_t MAXSIMM = (1 << 12) - 1; // set bits in simm13 field of OR
 //---------------------------------------------------------------------------
 
 uint64_t
-UltraSparcInstrInfo::ConvertConstantToIntType(const TargetMachine &target,
+SparcInstrInfo::ConvertConstantToIntType(const TargetMachine &target,
                                               const Value *V,
                                               const Type *destType,
                                               bool  &isValidConstant) const
@@ -406,7 +407,7 @@ InitializeMaxConstantsTable()
 
 
 //---------------------------------------------------------------------------
-// class UltraSparcInstrInfo 
+// class SparcInstrInfo 
 // 
 // Purpose:
 //   Information about individual instructions.
@@ -416,7 +417,7 @@ InitializeMaxConstantsTable()
 //---------------------------------------------------------------------------
 
 /*ctor*/
-UltraSparcInstrInfo::UltraSparcInstrInfo()
+SparcInstrInfo::SparcInstrInfo()
   : TargetInstrInfo(SparcMachineInstrDesc,
                     /*descSize = */ V9::NUM_TOTAL_OPCODES,
                     /*numRealOpCodes = */ V9::NUM_REAL_OPCODES)
@@ -425,7 +426,7 @@ UltraSparcInstrInfo::UltraSparcInstrInfo()
 }
 
 bool
-UltraSparcInstrInfo::ConstantMayNotFitInImmedField(const Constant* CV,
+SparcInstrInfo::ConstantMayNotFitInImmedField(const Constant* CV,
                                                    const Instruction* I) const
 {
   if (I->getOpcode() >= MaxConstantsTable.size()) // user-defined op (or bug!)
@@ -455,12 +456,12 @@ UltraSparcInstrInfo::ConstantMayNotFitInImmedField(const Constant* CV,
 // Any stack space required is allocated via MachineFunction.
 // 
 void
-UltraSparcInstrInfo::CreateCodeToLoadConst(const TargetMachine& target,
-                                           Function* F,
-                                           Value* val,
-                                           Instruction* dest,
-                                           std::vector<MachineInstr*>& mvec,
-                                       MachineCodeForInstruction& mcfi) const
+SparcInstrInfo::CreateCodeToLoadConst(const TargetMachine& target,
+                                      Function* F,
+                                      Value* val,
+                                      Instruction* dest,
+                                      std::vector<MachineInstr*>& mvec,
+                                      MachineCodeForInstruction& mcfi) const
 {
   assert(isa<Constant>(val) || isa<GlobalValue>(val) &&
          "I only know about constant values and global addresses");
@@ -552,7 +553,7 @@ UltraSparcInstrInfo::CreateCodeToLoadConst(const TargetMachine& target,
 // Any stack space required is allocated via MachineFunction.
 // 
 void
-UltraSparcInstrInfo::CreateCodeToCopyIntToFloat(const TargetMachine& target,
+SparcInstrInfo::CreateCodeToCopyIntToFloat(const TargetMachine& target,
                                         Function* F,
                                         Value* val,
                                         Instruction* dest,
@@ -613,7 +614,7 @@ UltraSparcInstrInfo::CreateCodeToCopyIntToFloat(const TargetMachine& target,
 // Temporary stack space required is allocated via MachineFunction.
 // 
 void
-UltraSparcInstrInfo::CreateCodeToCopyFloatToInt(const TargetMachine& target,
+SparcInstrInfo::CreateCodeToCopyFloatToInt(const TargetMachine& target,
                                         Function* F,
                                         Value* val,
                                         Instruction* dest,
@@ -664,11 +665,11 @@ UltraSparcInstrInfo::CreateCodeToCopyFloatToInt(const TargetMachine& target,
 // Any stack space required is allocated via MachineFunction.
 // 
 void
-UltraSparcInstrInfo::CreateCopyInstructionsByType(const TargetMachine& target,
-                                                  Function *F,
-                                                  Value* src,
-                                                  Instruction* dest,
-                                               std::vector<MachineInstr*>& mvec,
+SparcInstrInfo::CreateCopyInstructionsByType(const TargetMachine& target,
+                                             Function *F,
+                                             Value* src,
+                                             Instruction* dest,
+                                             std::vector<MachineInstr*>& mvec,
                                           MachineCodeForInstruction& mcfi) const
 {
   bool loadConstantToReg = false;
@@ -760,7 +761,7 @@ CreateBitExtensionInstructions(bool signExtend,
 // Any stack space required is allocated via MachineFunction.
 // 
 void
-UltraSparcInstrInfo::CreateSignExtensionInstructions(
+SparcInstrInfo::CreateSignExtensionInstructions(
                                         const TargetMachine& target,
                                         Function* F,
                                         Value* srcVal,
@@ -782,7 +783,7 @@ UltraSparcInstrInfo::CreateSignExtensionInstructions(
 // Any stack space required is allocated via MachineFunction.
 // 
 void
-UltraSparcInstrInfo::CreateZeroExtensionInstructions(
+SparcInstrInfo::CreateZeroExtensionInstructions(
                                         const TargetMachine& target,
                                         Function* F,
                                         Value* srcVal,
diff --git a/lib/Target/SparcV9/SparcV9InstrInfo.h b/lib/Target/SparcV9/SparcV9InstrInfo.h
new file mode 100644 (file)
index 0000000..0926c07
--- /dev/null
@@ -0,0 +1,201 @@
+//===-- SparcInstrInfo.h - Define TargetInstrInfo for Sparc -----*- 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 class contains information about individual instructions.
+// Most information is stored in the SparcMachineInstrDesc array above.
+// Other information is computed on demand, and most such functions
+// default to member functions in base class TargetInstrInfo. 
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SPARC_INSTRINFO_H
+#define SPARC_INSTRINFO_H
+
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "SparcInternals.h"
+
+namespace llvm {
+
+struct SparcInstrInfo : public TargetInstrInfo {
+  SparcInstrInfo();
+
+  // All immediate constants are in position 1 except the
+  // store instructions and SETxx.
+  // 
+  virtual int getImmedConstantPos(MachineOpCode opCode) const {
+    bool ignore;
+    if (this->maxImmedConstant(opCode, ignore) != 0) {
+      // 1st store opcode
+      assert(! this->isStore((MachineOpCode) V9::STBr - 1));
+      // last store opcode
+      assert(! this->isStore((MachineOpCode) V9::STXFSRi + 1));
+
+      if (opCode == V9::SETSW || opCode == V9::SETUW ||
+          opCode == V9::SETX  || opCode == V9::SETHI)
+        return 0;
+      if (opCode >= V9::STBr && opCode <= V9::STXFSRi)
+        return 2;
+      return 1;
+    }
+    else
+      return -1;
+  }
+
+  /// createNOPinstr - returns the target's implementation of NOP, which is
+  /// usually a pseudo-instruction, implemented by a degenerate version of
+  /// another instruction, e.g. X86: xchg ax, ax; SparcV9: sethi 0, g0
+  ///
+  MachineInstr* createNOPinstr() const {
+    return BuildMI(V9::SETHI, 2).addZImm(0).addReg(SparcIntRegClass::g0);
+  }
+
+  /// isNOPinstr - not having a special NOP opcode, we need to know if a given
+  /// instruction is interpreted as an `official' NOP instr, i.e., there may be
+  /// more than one way to `do nothing' but only one canonical way to slack off.
+  ///
+  bool isNOPinstr(const MachineInstr &MI) const {
+    // Make sure the instruction is EXACTLY `sethi g0, 0'
+    if (MI.getOpcode() == V9::SETHI && MI.getNumOperands() == 2) {
+      const MachineOperand &op0 = MI.getOperand(0), &op1 = MI.getOperand(1);
+      if (op0.isImmediate() && op0.getImmedValue() == 0 &&
+          op1.isMachineRegister() &&
+          op1.getMachineRegNum() == SparcIntRegClass::g0)
+      {
+        return true;
+      }
+    }
+    return false;
+  }
+  
+  virtual bool hasResultInterlock(MachineOpCode opCode) const
+  {
+    // All UltraSPARC instructions have interlocks (note that delay slots
+    // are not considered here).
+    // However, instructions that use the result of an FCMP produce a
+    // 9-cycle stall if they are issued less than 3 cycles after the FCMP.
+    // Force the compiler to insert a software interlock (i.e., gap of
+    // 2 other groups, including NOPs if necessary).
+    return (opCode == V9::FCMPS || opCode == V9::FCMPD || opCode == V9::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 V9::NOP; }
+
+  // Get the value of an integral constant in the form that must
+  // be put into the machine register.  The specified constant is interpreted
+  // as (i.e., converted if necessary to) the specified destination type.  The
+  // result is always returned as an uint64_t, since the representation of
+  // int64_t and uint64_t are identical.  The argument can be any known const.
+  // 
+  // isValidConstant is set to true if a valid constant was found.
+  // 
+  virtual uint64_t ConvertConstantToIntType(const TargetMachine &target,
+                                            const Value *V,
+                                            const Type *destType,
+                                            bool  &isValidConstant) const;
+
+  // 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.
+  // 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(const TargetMachine& target,
+                                      Function* F,
+                                      Value* val,
+                                      Instruction* dest,
+                                      std::vector<MachineInstr*>& 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 `mvec'.
+  // Any temp. registers (TmpInstruction) created are recorded in mcfi.
+  // Any stack space required is allocated via mcff.
+  // 
+  virtual void  CreateCodeToCopyIntToFloat(const TargetMachine& target,
+                                       Function* F,
+                                       Value* val,
+                                       Instruction* dest,
+                                       std::vector<MachineInstr*>& 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.
+  // 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<MachineInstr*>& 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<MachineInstr*>& 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<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;
+};
+
+} // End llvm namespace
+
+#endif
index 21e884be8e1b418bbe5d502ea0dd8a42efac5893..c5fa145a8eff8bd500b38eb4d1f8fa14108ba20d 100644 (file)
@@ -11,9 +11,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "SparcInstrSelectionSupport.h"
-#include "SparcInternals.h"
-#include "SparcRegClassInfo.h"
 #include "llvm/Constants.h"
 #include "llvm/ConstantHandling.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/CodeGen/MachineFunctionInfo.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineInstrAnnot.h"
+#include "SparcInstrSelectionSupport.h"
+#include "SparcInternals.h"
+#include "SparcRegClassInfo.h"
+#include "SparcRegInfo.h"
 #include "Support/MathExtras.h"
 #include <algorithm>
 #include <cmath>
@@ -1583,8 +1584,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
         //     -- For non-FP values, create an add-with-0 instruction
         // 
         if (retVal != NULL) {
-          const UltraSparcRegInfo& regInfo =
-            (UltraSparcRegInfo&) target.getRegInfo();
+          const SparcRegInfo& regInfo =
+            (SparcRegInfo&) target.getRegInfo();
           const Type* retType = retVal->getType();
           unsigned regClassID = regInfo.getRegClassIDOfType(retType);
           unsigned retRegNum = (retType->isFloatingPoint()
@@ -2488,8 +2489,8 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
           MachineFunction& MF = MachineFunction::get(currentFunc);
           MachineCodeForInstruction& mcfi =
             MachineCodeForInstruction::get(callInstr); 
-          const UltraSparcRegInfo& regInfo =
-            (UltraSparcRegInfo&) target.getRegInfo();
+          const SparcRegInfo& regInfo =
+            (SparcRegInfo&) target.getRegInfo();
           const TargetFrameInfo& frameInfo = target.getFrameInfo();
 
           // Create hidden virtual register for return address with type void*
index e6926bbcd61ce5f107c6efce64c9a6d6b588e0bc..27dc7d012c526fd93a278ec77327b536ab5d12ed 100644 (file)
@@ -28,7 +28,7 @@
 namespace llvm {
 
 class LiveRange;
-class UltraSparc;
+class SparcTargetMachine;
 class Pass;
 
 enum SparcInstrSchedClass {
@@ -71,571 +71,34 @@ namespace V9 {
   };
 }
 
-
 // Array of machine instruction descriptions...
 extern const TargetInstrDescriptor SparcMachineInstrDesc[];
 
-
-//---------------------------------------------------------------------------
-// class UltraSparcInstrInfo 
-// 
-// Purpose:
-//   Information about individual instructions.
-//   Most information is stored in the SparcMachineInstrDesc array above.
-//   Other information is computed on demand, and most such functions
-//   default to member functions in base class TargetInstrInfo. 
-//---------------------------------------------------------------------------
-
-struct UltraSparcInstrInfo : public TargetInstrInfo {
-  UltraSparcInstrInfo();
-
-  //
-  // All immediate constants are in position 1 except the
-  // store instructions and SETxx.
-  // 
-  virtual int getImmedConstantPos(MachineOpCode opCode) const {
-    bool ignore;
-    if (this->maxImmedConstant(opCode, ignore) != 0) {
-      // 1st store opcode
-      assert(! this->isStore((MachineOpCode) V9::STBr - 1));
-      // last store opcode
-      assert(! this->isStore((MachineOpCode) V9::STXFSRi + 1));
-
-      if (opCode == V9::SETSW || opCode == V9::SETUW ||
-          opCode == V9::SETX  || opCode == V9::SETHI)
-        return 0;
-      if (opCode >= V9::STBr && opCode <= V9::STXFSRi)
-        return 2;
-      return 1;
-    }
-    else
-      return -1;
-  }
-
-  /// createNOPinstr - returns the target's implementation of NOP, which is
-  /// usually a pseudo-instruction, implemented by a degenerate version of
-  /// another instruction, e.g. X86: xchg ax, ax; SparcV9: sethi 0, g0
-  ///
-  MachineInstr* createNOPinstr() const {
-    return BuildMI(V9::SETHI, 2).addZImm(0).addReg(SparcIntRegClass::g0);
-  }
-
-  /// isNOPinstr - not having a special NOP opcode, we need to know if a given
-  /// instruction is interpreted as an `official' NOP instr, i.e., there may be
-  /// more than one way to `do nothing' but only one canonical way to slack off.
-  ///
-  bool isNOPinstr(const MachineInstr &MI) const {
-    // Make sure the instruction is EXACTLY `sethi g0, 0'
-    if (MI.getOpcode() == V9::SETHI && MI.getNumOperands() == 2) {
-      const MachineOperand &op0 = MI.getOperand(0), &op1 = MI.getOperand(1);
-      if (op0.isImmediate() && op0.getImmedValue() == 0 &&
-          op1.isMachineRegister() &&
-          op1.getMachineRegNum() == SparcIntRegClass::g0)
-      {
-        return true;
-      }
-    }
-    return false;
-  }
-  
-  virtual bool hasResultInterlock(MachineOpCode opCode) const
-  {
-    // All UltraSPARC instructions have interlocks (note that delay slots
-    // are not considered here).
-    // However, instructions that use the result of an FCMP produce a
-    // 9-cycle stall if they are issued less than 3 cycles after the FCMP.
-    // Force the compiler to insert a software interlock (i.e., gap of
-    // 2 other groups, including NOPs if necessary).
-    return (opCode == V9::FCMPS || opCode == V9::FCMPD || opCode == V9::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 V9::NOP; }
-
-  // Get the value of an integral constant in the form that must
-  // be put into the machine register.  The specified constant is interpreted
-  // as (i.e., converted if necessary to) the specified destination type.  The
-  // result is always returned as an uint64_t, since the representation of
-  // int64_t and uint64_t are identical.  The argument can be any known const.
-  // 
-  // isValidConstant is set to true if a valid constant was found.
-  // 
-  virtual uint64_t ConvertConstantToIntType(const TargetMachine &target,
-                                            const Value *V,
-                                            const Type *destType,
-                                            bool  &isValidConstant) const;
-
-  // 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.
-  // 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(const TargetMachine& target,
-                                      Function* F,
-                                      Value* val,
-                                      Instruction* dest,
-                                      std::vector<MachineInstr*>& 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 `mvec'.
-  // Any temp. registers (TmpInstruction) created are recorded in mcfi.
-  // Any stack space required is allocated via mcff.
-  // 
-  virtual void  CreateCodeToCopyIntToFloat(const TargetMachine& target,
-                                       Function* F,
-                                       Value* val,
-                                       Instruction* dest,
-                                       std::vector<MachineInstr*>& 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.
-  // 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<MachineInstr*>& 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<MachineInstr*>& 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<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;
-};
-
-
-//----------------------------------------------------------------------------
-// class UltraSparcRegInfo
-//
-// This class implements the virtual class TargetRegInfo for Sparc.
-//
-//----------------------------------------------------------------------------
-
-class UltraSparcRegInfo : public TargetRegInfo {
-
-private:
-
-  // Number of registers used for passing int args (usually 6: %o0 - %o5)
-  //
-  unsigned const NumOfIntArgRegs;
-
-  // Number of registers used for passing float args (usually 32: %f0 - %f31)
-  //
-  unsigned const NumOfFloatArgRegs;
-
-  // ========================  Private Methods =============================
-
-  // The following methods are used to color special live ranges (e.g.
-  // function args and return values etc.) with specific hardware registers
-  // as required. See SparcRegInfo.cpp for the implementation.
-  //
-  void suggestReg4RetAddr(MachineInstr *RetMI, 
-                         LiveRangeInfo &LRI) const;
-
-  void suggestReg4CallAddr(MachineInstr *CallMI, LiveRangeInfo &LRI) const;
-  
-  // Helper used by the all the getRegType() functions.
-  int getRegTypeForClassAndType(unsigned regClassID, const Type* type) const;
-
-public:
-  // Type of registers available in Sparc. There can be several reg types
-  // in the same class. For instace, the float reg class has Single/Double
-  // types
-  //
-  enum RegTypes {
-    IntRegType,
-    FPSingleRegType,
-    FPDoubleRegType,
-    IntCCRegType,
-    FloatCCRegType,
-    SpecialRegType
-  };
-
-  // The actual register classes in the Sparc
-  //
-  // **** WARNING: If this enum order is changed, also modify 
-  // getRegisterClassOfValue method below since it assumes this particular 
-  // order for efficiency.
-  // 
-  enum RegClassIDs { 
-    IntRegClassID,                      // Integer
-    FloatRegClassID,                    // Float (both single/double)
-    IntCCRegClassID,                    // Int Condition Code
-    FloatCCRegClassID,                  // Float Condition code
-    SpecialRegClassID                   // Special (unallocated) registers
-  };
-
-  UltraSparcRegInfo(const UltraSparc &tgt);
-
-  // To find the register class used for a specified Type
-  //
-  unsigned getRegClassIDOfType(const Type *type,
-                               bool isCCReg = false) const;
-
-  // To find the register class to which a specified register belongs
-  //
-  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
-  // function is called. This can be used for other purposes between calls
-  //
-  unsigned getCallAddressReg() const;
-
-  // Returns the register containing the return address.
-  // It should be made sure that this  register contains the return 
-  // value when a return instruction is reached.
-  //
-  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; }
-  
-  // Compute which register can be used for an argument, if any
-  // 
-  int regNumForIntArg(bool inCallee, bool isVarArgsCall,
-                      unsigned argNo, unsigned& regClassId) const;
-
-  int regNumForFPArg(unsigned RegType, bool inCallee, bool isVarArgsCall,
-                     unsigned argNo, unsigned& regClassId) const;
-  
-  // The following methods are used to color special live ranges (e.g.
-  // function args and return values etc.) with specific hardware registers
-  // as required. See SparcRegInfo.cpp for the implementation for Sparc.
-  //
-  void suggestRegs4MethodArgs(const Function *Meth, 
-                             LiveRangeInfo& LRI) const;
-
-  void suggestRegs4CallArgs(MachineInstr *CallMI, 
-                           LiveRangeInfo& LRI) const; 
-
-  void suggestReg4RetValue(MachineInstr *RetMI, 
-                           LiveRangeInfo& LRI) const;
-  
-  void colorMethodArgs(const Function *Meth,  LiveRangeInfo& LRI,
-                       std::vector<MachineInstr*>& InstrnsBefore,
-                       std::vector<MachineInstr*>& InstrnsAfter) const;
-
-  // method used for printing a register for debugging purposes
-  //
-  void printReg(const LiveRange *LR) const;
-  
-  // returns the # of bytes of stack space allocated for each register
-  // type. For Sparc, currently we allocate 8 bytes on stack for all 
-  // register types. We can optimize this later if necessary to save stack
-  // space (However, should make sure that stack alignment is correct)
-  //
-  inline int getSpilledRegSize(int RegType) const {
-    return 8;
-  }
-
-
-  // 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.
-  //
-  // 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;
-
-  void cpReg2RegMI(std::vector<MachineInstr*>& mvec,
-                   unsigned SrcReg, unsigned DestReg,
-                   int RegType) const;
-
-  void cpReg2MemMI(std::vector<MachineInstr*>& mvec,
-                   unsigned SrcReg, unsigned DestPtrReg,
-                   int Offset, int RegType, int scratchReg = -1) const;
-
-  void cpMem2RegMI(std::vector<MachineInstr*>& mvec,
-                   unsigned SrcPtrReg, int Offset, unsigned DestReg,
-                   int RegType, int scratchReg = -1) const;
-
-  void cpValue2Value(Value *Src, Value *Dest,
-                     std::vector<MachineInstr*>& mvec) const;
-
-  // Get the register type for a register identified different ways.
-  // Note that getRegTypeForLR(LR) != getRegTypeForDataType(LR->getType())!
-  // The reg class of a LR depends both on the Value types in it and whether
-  // they are CC registers or not (for example).
-  int getRegTypeForDataType(const Type* type) const;
-  int getRegTypeForLR(const LiveRange *LR) const;
-  int getRegType(int unifiedRegNum) const;
-
-  virtual unsigned getFramePointer() const;
-  virtual unsigned getStackPointer() const;
-};
-
-
-
-
 //---------------------------------------------------------------------------
-// class UltraSparcSchedInfo
+// class SparcSchedInfo
 // 
 // Purpose:
 //   Interface to instruction scheduling information for UltraSPARC.
 //   The parameter values above are based on UltraSPARC IIi.
 //---------------------------------------------------------------------------
 
-
-class UltraSparcSchedInfo: public TargetSchedInfo {
+class SparcSchedInfo: public TargetSchedInfo {
 public:
-  UltraSparcSchedInfo(const TargetMachine &tgt);
+  SparcSchedInfo(const TargetMachine &tgt);
 protected:
   virtual void initializeResources();
 };
 
-
 //---------------------------------------------------------------------------
-// class UltraSparcFrameInfo 
-// 
-// Purpose:
-//   Interface to stack frame layout info for the UltraSPARC.
-//   Starting offsets for each area of the stack frame are aligned at
-//   a multiple of getStackFrameSizeAlignment().
-//---------------------------------------------------------------------------
-
-class UltraSparcFrameInfo: public TargetFrameInfo {
-  const TargetMachine &target;
-public:
-  UltraSparcFrameInfo(const TargetMachine &TM)
-    : TargetFrameInfo(StackGrowsDown, StackFrameSizeAlignment, 0), target(TM) {}
-  
-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  (MachineFunction& mcInfo,
-                                  bool& growUp) const
-  {
-    growUp = true;                         // arguments area grows upwards
-    return FirstIncomingArgOffsetFromFP;
-  }
-  int getFirstOutgoingArgOffset  (MachineFunction& mcInfo,
-                                  bool& growUp) const
-  {
-    growUp = true;                         // arguments area grows upwards
-    return FirstOutgoingArgOffsetFromSP;
-  }
-  int getFirstOptionalOutgoingArgOffset(MachineFunction& mcInfo,
-                                        bool& growUp)const
-  {
-    growUp = true;                         // arguments area grows upwards
-    return FirstOptionalOutgoingArgOffsetFromSP;
-  }
-  
-  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
-  // (generally FP or SP)
-  // 
-  virtual int getIncomingArgBaseRegNum()               const {
-    return (int) target.getRegInfo().getFramePointer();
-  }
-  virtual int getOutgoingArgBaseRegNum()               const {
-    return (int) target.getRegInfo().getStackPointer();
-  }
-  virtual int getOptionalOutgoingArgBaseRegNum()       const {
-    return (int) target.getRegInfo().getStackPointer();
-  }
-  virtual int getAutomaticVarBaseRegNum()              const {
-    return (int) target.getRegInfo().getFramePointer();
-  }
-  virtual int getRegSpillAreaBaseRegNum()              const {
-    return (int) target.getRegInfo().getFramePointer();
-  }
-  virtual int getDynamicAreaBaseRegNum()               const {
-    return (int) target.getRegInfo().getStackPointer();
-  }
-
-  virtual int getIncomingArgOffset(MachineFunction& mcInfo,
-                                  unsigned argNum) const {
-    assert(argsOnStackHaveFixedSize()); 
-  
-    unsigned relativeOffset = argNum * getSizeOfEachArgOnStack();
-    bool growUp;                          // do args grow up or down
-    int firstArg = getFirstIncomingArgOffset(mcInfo, growUp);
-    return growUp ? firstArg + relativeOffset : firstArg - relativeOffset; 
-  }
-
-  virtual int getOutgoingArgOffset(MachineFunction& mcInfo,
-                                  unsigned argNum) const {
-    assert(argsOnStackHaveFixedSize()); 
-    //assert(((int) argNum - this->getNumFixedOutgoingArgs())
-    //     <= (int) mcInfo.getInfo()->getMaxOptionalNumArgs());
-    
-    unsigned relativeOffset = argNum * getSizeOfEachArgOnStack();
-    bool growUp;                          // do args grow up or down
-    int firstArg = getFirstOutgoingArgOffset(mcInfo, growUp);
-    return growUp ? firstArg + relativeOffset : firstArg - relativeOffset; 
-  }
-  
-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 assumptions 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 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;
-};
-
-
-//---------------------------------------------------------------------------
-// class UltraSparcCacheInfo 
+// class SparcCacheInfo 
 // 
 // Purpose:
 //   Interface to cache parameters for the UltraSPARC.
 //   Just use defaults for now.
 //---------------------------------------------------------------------------
 
-struct UltraSparcCacheInfo: public TargetCacheInfo {
-  UltraSparcCacheInfo(const TargetMachine &T) : TargetCacheInfo(T) {} 
+struct SparcCacheInfo: public TargetCacheInfo {
+  SparcCacheInfo(const TargetMachine &T) : TargetCacheInfo(T) {} 
 };
 
 
@@ -664,38 +127,6 @@ FunctionPass* createPrologEpilogInsertionPass();
 ///
 Pass* createBytecodeAsmPrinterPass(std::ostream &Out);
 
-//---------------------------------------------------------------------------
-// class UltraSparc 
-// 
-// Purpose:
-//   Primary interface to machine description for the UltraSPARC.
-//   Primarily just initializes machine-dependent parameters in
-//   class TargetMachine, and creates machine-dependent subclasses
-//   for classes such as InstrInfo, SchedInfo and RegInfo. 
-//---------------------------------------------------------------------------
-
-class UltraSparc : public TargetMachine {
-  UltraSparcInstrInfo instrInfo;
-  UltraSparcSchedInfo schedInfo;
-  UltraSparcRegInfo   regInfo;
-  UltraSparcFrameInfo frameInfo;
-  UltraSparcCacheInfo cacheInfo;
-public:
-  UltraSparc();
-
-  virtual const TargetInstrInfo  &getInstrInfo() const { return instrInfo; }
-  virtual const TargetSchedInfo  &getSchedInfo() const { return schedInfo; }
-  virtual const TargetRegInfo    &getRegInfo()   const { return regInfo; }
-  virtual const TargetFrameInfo  &getFrameInfo() const { return frameInfo; }
-  virtual const TargetCacheInfo  &getCacheInfo() const { return cacheInfo; }
-
-  virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out);
-  virtual bool addPassesToJITCompile(FunctionPassManager &PM);
-  virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
-                                          MachineCodeEmitter &MCE);
-  virtual void replaceMachineCodeForFunction(void *Old, void *New);
-};
-
 } // End llvm namespace
 
 #endif
index 564e59cd70ec1d52238f0bd3eab1070c234b16ab..c6d559abdb930f7d4fc3201105e50d850967da16 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/Type.h"
 #include "SparcRegClassInfo.h"
 #include "SparcInternals.h"
-#include "llvm/Type.h"
+#include "SparcRegInfo.h"
 #include "../../CodeGen/RegAlloc/RegAllocCommon.h"   // FIXME!
 #include "../../CodeGen/RegAlloc/IGNode.h"           // FIXME!
 
@@ -320,8 +321,8 @@ void SparcFloatRegClass::markColorsUsed(unsigned RegInClass,
                                         int RegTypeWanted,
                                     std::vector<bool> &IsColorUsedArr) const
 {
-  if (UserRegType == UltraSparcRegInfo::FPDoubleRegType ||
-      RegTypeWanted == UltraSparcRegInfo::FPDoubleRegType) {
+  if (UserRegType == SparcRegInfo::FPDoubleRegType ||
+      RegTypeWanted == SparcRegInfo::FPDoubleRegType) {
     // This register is used as or is needed as a double-precision reg.
     // We need to mark the [even,odd] pair corresponding to this reg.
     // Get the even numbered register corresponding to this reg.
@@ -348,7 +349,7 @@ void SparcFloatRegClass::markColorsUsed(unsigned RegInClass,
 int SparcFloatRegClass::findUnusedColor(int RegTypeWanted,
                                 const std::vector<bool> &IsColorUsedArr) const
 {
-  if (RegTypeWanted == UltraSparcRegInfo::FPDoubleRegType) {
+  if (RegTypeWanted == SparcRegInfo::FPDoubleRegType) {
     unsigned NC = 2 * this->getNumOfAvailRegs();
     assert(IsColorUsedArr.size() == NC && "Invalid colors-used array");
     for (unsigned c = 0; c < NC; c+=2)
index 5edbbe06470f3386dd2f9dd93c2d2a50776f6fd3..1d742ef8da9ebbe709d7ec674b9cbaada440aa51 100644 (file)
@@ -12,8 +12,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "SparcInternals.h"
-#include "SparcRegClassInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunctionInfo.h"
 #include "llvm/CodeGen/InstrSelection.h"
 #include "llvm/CodeGen/MachineInstrAnnot.h"
 #include "../../CodeGen/RegAlloc/LiveRangeInfo.h"   // FIXME!!
 #include "../../CodeGen/RegAlloc/LiveRange.h"       // FIXME!!
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
 #include "llvm/iTerminators.h"
 #include "llvm/iOther.h"
-#include "llvm/Function.h"
-#include "llvm/DerivedTypes.h"
+#include "SparcInternals.h"
+#include "SparcRegClassInfo.h"
+#include "SparcRegInfo.h"
+#include "SparcTargetMachine.h"
 
 namespace llvm {
 
@@ -33,7 +35,7 @@ enum {
   BadRegClass = ~0
 };
 
-UltraSparcRegInfo::UltraSparcRegInfo(const UltraSparc &tgt)
+SparcRegInfo::SparcRegInfo(const SparcTargetMachine &tgt)
   : TargetRegInfo(tgt), NumOfIntArgRegs(6), NumOfFloatArgRegs(32)
 {
   MachineRegClassArr.push_back(new SparcIntRegClass(IntRegClassID));
@@ -50,16 +52,16 @@ UltraSparcRegInfo::UltraSparcRegInfo(const UltraSparc &tgt)
 // getZeroRegNum - returns the register that contains always zero.
 // this is the unified register number
 //
-int UltraSparcRegInfo::getZeroRegNum() const {
-  return getUnifiedRegNum(UltraSparcRegInfo::IntRegClassID,
+int SparcRegInfo::getZeroRegNum() const {
+  return getUnifiedRegNum(SparcRegInfo::IntRegClassID,
                           SparcIntRegClass::g0);
 }
 
 // getCallAddressReg - returns the reg used for pushing the address when a
 // method is called. This can be used for other purposes between calls
 //
-unsigned UltraSparcRegInfo::getCallAddressReg() const {
-  return getUnifiedRegNum(UltraSparcRegInfo::IntRegClassID,
+unsigned SparcRegInfo::getCallAddressReg() const {
+  return getUnifiedRegNum(SparcRegInfo::IntRegClassID,
                           SparcIntRegClass::o7);
 }
 
@@ -67,8 +69,8 @@ unsigned UltraSparcRegInfo::getCallAddressReg() const {
 // It should be made sure that this  register contains the return 
 // value when a return instruction is reached.
 //
-unsigned UltraSparcRegInfo::getReturnAddressReg() const {
-  return getUnifiedRegNum(UltraSparcRegInfo::IntRegClassID,
+unsigned SparcRegInfo::getReturnAddressReg() const {
+  return getUnifiedRegNum(SparcRegInfo::IntRegClassID,
                           SparcIntRegClass::i7);
 }
 
@@ -133,14 +135,14 @@ const char * const SparcSpecialRegClass::getRegName(unsigned reg) const {
 }
 
 // Get unified reg number for frame pointer
-unsigned UltraSparcRegInfo::getFramePointer() const {
-  return getUnifiedRegNum(UltraSparcRegInfo::IntRegClassID,
+unsigned SparcRegInfo::getFramePointer() const {
+  return getUnifiedRegNum(SparcRegInfo::IntRegClassID,
                           SparcIntRegClass::i6);
 }
 
 // Get unified reg number for stack pointer
-unsigned UltraSparcRegInfo::getStackPointer() const {
-  return getUnifiedRegNum(UltraSparcRegInfo::IntRegClassID,
+unsigned SparcRegInfo::getStackPointer() const {
+  return getUnifiedRegNum(SparcRegInfo::IntRegClassID,
                           SparcIntRegClass::o6);
 }
 
@@ -173,7 +175,7 @@ isVarArgsCall(const MachineInstr *CallMI) {
 //                           regClassId is set to the register class ID.
 // 
 int
-UltraSparcRegInfo::regNumForIntArg(bool inCallee, bool isVarArgsCall,
+SparcRegInfo::regNumForIntArg(bool inCallee, bool isVarArgsCall,
                                    unsigned argNo, unsigned& regClassId) const
 {
   regClassId = IntRegClassID;
@@ -192,7 +194,7 @@ UltraSparcRegInfo::regNumForIntArg(bool inCallee, bool isVarArgsCall,
 //                           regClassId is set to the register class ID.
 // 
 int
-UltraSparcRegInfo::regNumForFPArg(unsigned regType,
+SparcRegInfo::regNumForFPArg(unsigned regType,
                                   bool inCallee, bool isVarArgsCall,
                                   unsigned argNo, unsigned& regClassId) const
 {
@@ -221,7 +223,7 @@ UltraSparcRegInfo::regNumForFPArg(unsigned regType,
 // The following 4  methods are used to find the RegType (SparcInternals.h)
 // of a LiveRange, a Value, and for a given register unified reg number.
 //
-int UltraSparcRegInfo::getRegTypeForClassAndType(unsigned regClassID,
+int SparcRegInfo::getRegTypeForClassAndType(unsigned regClassID,
                                                  const Type* type) const
 {
   switch (regClassID) {
@@ -237,17 +239,17 @@ int UltraSparcRegInfo::getRegTypeForClassAndType(unsigned regClassID,
   }
 }
 
-int UltraSparcRegInfo::getRegTypeForDataType(const Type* type) const
+int SparcRegInfo::getRegTypeForDataType(const Type* type) const
 {
   return getRegTypeForClassAndType(getRegClassIDOfType(type), type);
 }
 
-int UltraSparcRegInfo::getRegTypeForLR(const LiveRange *LR) const
+int SparcRegInfo::getRegTypeForLR(const LiveRange *LR) const
 {
   return getRegTypeForClassAndType(LR->getRegClassID(), LR->getType());
 }
 
-int UltraSparcRegInfo::getRegType(int unifiedRegNum) const
+int SparcRegInfo::getRegType(int unifiedRegNum) const
 {
   if (unifiedRegNum < 32) 
     return IntRegType;
@@ -267,7 +269,7 @@ int UltraSparcRegInfo::getRegType(int unifiedRegNum) const
 
 // To find the register class used for a specified Type
 //
-unsigned UltraSparcRegInfo::getRegClassIDOfType(const Type *type,
+unsigned SparcRegInfo::getRegClassIDOfType(const Type *type,
                                                 bool isCCReg) const {
   Type::PrimitiveID ty = type->getPrimitiveID();
   unsigned res;
@@ -290,7 +292,7 @@ unsigned UltraSparcRegInfo::getRegClassIDOfType(const Type *type,
     return res;
 }
 
-unsigned UltraSparcRegInfo::getRegClassIDOfRegType(int regType) const {
+unsigned SparcRegInfo::getRegClassIDOfRegType(int regType) const {
   switch(regType) {
   case IntRegType:      return IntRegClassID;
   case FPSingleRegType:
@@ -307,7 +309,7 @@ unsigned UltraSparcRegInfo::getRegClassIDOfRegType(int regType) const {
 // Suggests a register for the ret address in the RET machine instruction.
 // We always suggest %i7 by convention.
 //---------------------------------------------------------------------------
-void UltraSparcRegInfo::suggestReg4RetAddr(MachineInstr *RetMI, 
+void SparcRegInfo::suggestReg4RetAddr(MachineInstr *RetMI, 
                                           LiveRangeInfo& LRI) const {
 
   assert(target.getInstrInfo().isReturn(RetMI->getOpCode()));
@@ -336,7 +338,7 @@ void UltraSparcRegInfo::suggestReg4RetAddr(MachineInstr *RetMI,
 // Sparc ABI dictates that %o7 be used for this purpose.
 //---------------------------------------------------------------------------
 void
-UltraSparcRegInfo::suggestReg4CallAddr(MachineInstr * CallMI,
+SparcRegInfo::suggestReg4CallAddr(MachineInstr * CallMI,
                                        LiveRangeInfo& LRI) const
 {
   CallArgsDescriptor* argDesc = CallArgsDescriptor::get(CallMI); 
@@ -360,7 +362,7 @@ UltraSparcRegInfo::suggestReg4CallAddr(MachineInstr * CallMI,
 //  If the arg is passed on stack due to the lack of regs, NOTHING will be
 //  done - it will be colored (or spilled) as a normal live range.
 //---------------------------------------------------------------------------
-void UltraSparcRegInfo::suggestRegs4MethodArgs(const Function *Meth, 
+void SparcRegInfo::suggestRegs4MethodArgs(const Function *Meth, 
                                               LiveRangeInfo& LRI) const 
 {
   // Check if this is a varArgs function. needed for choosing regs.
@@ -393,7 +395,7 @@ void UltraSparcRegInfo::suggestRegs4MethodArgs(const Function *Meth,
 // the correct hardware registers if they did not receive the correct
 // (suggested) color through graph coloring.
 //---------------------------------------------------------------------------
-void UltraSparcRegInfo::colorMethodArgs(const Function *Meth, 
+void SparcRegInfo::colorMethodArgs(const Function *Meth, 
                             LiveRangeInfo &LRI,
                             std::vector<MachineInstr*>& InstrnsBefore,
                             std::vector<MachineInstr*>& InstrnsAfter) const {
@@ -566,7 +568,7 @@ void UltraSparcRegInfo::colorMethodArgs(const Function *Meth,
 // This method is called before graph coloring to suggest colors to the
 // outgoing call args and the return value of the call.
 //---------------------------------------------------------------------------
-void UltraSparcRegInfo::suggestRegs4CallArgs(MachineInstr *CallMI, 
+void SparcRegInfo::suggestRegs4CallArgs(MachineInstr *CallMI, 
                                             LiveRangeInfo& LRI) const {
   assert ( (target.getInstrInfo()).isCall(CallMI->getOpCode()) );
 
@@ -634,7 +636,7 @@ void UltraSparcRegInfo::suggestRegs4CallArgs(MachineInstr *CallMI,
 // this method is called for an LLVM return instruction to identify which
 // values will be returned from this method and to suggest colors.
 //---------------------------------------------------------------------------
-void UltraSparcRegInfo::suggestReg4RetValue(MachineInstr *RetMI, 
+void SparcRegInfo::suggestReg4RetValue(MachineInstr *RetMI, 
                                             LiveRangeInfo& LRI) const {
 
   assert( (target.getInstrInfo()).isReturn( RetMI->getOpCode() ) );
@@ -662,7 +664,7 @@ void UltraSparcRegInfo::suggestReg4RetValue(MachineInstr *RetMI,
 //---------------------------------------------------------------------------
 
 bool
-UltraSparcRegInfo::regTypeNeedsScratchReg(int RegType,
+SparcRegInfo::regTypeNeedsScratchReg(int RegType,
                                           int& scratchRegType) const
 {
   if (RegType == IntCCRegType)
@@ -679,7 +681,7 @@ UltraSparcRegInfo::regTypeNeedsScratchReg(int RegType,
 //---------------------------------------------------------------------------
 
 void
-UltraSparcRegInfo::cpReg2RegMI(std::vector<MachineInstr*>& mvec,
+SparcRegInfo::cpReg2RegMI(std::vector<MachineInstr*>& mvec,
                                unsigned SrcReg,
                                unsigned DestReg,
                                int RegType) const {
@@ -695,7 +697,7 @@ UltraSparcRegInfo::cpReg2RegMI(std::vector<MachineInstr*>& mvec,
     if (getRegType(DestReg) == IntRegType) {
       // copy intCC reg to int reg
       MI = (BuildMI(V9::RDCCR, 2)
-            .addMReg(getUnifiedRegNum(UltraSparcRegInfo::IntCCRegClassID,
+            .addMReg(getUnifiedRegNum(SparcRegInfo::IntCCRegClassID,
                                       SparcIntCCRegClass::ccr))
             .addMReg(DestReg,MOTy::Def));
     } else {
@@ -705,7 +707,7 @@ UltraSparcRegInfo::cpReg2RegMI(std::vector<MachineInstr*>& mvec,
       MI = (BuildMI(V9::WRCCRr, 3)
             .addMReg(SrcReg)
             .addMReg(SparcIntRegClass::g0)
-            .addMReg(getUnifiedRegNum(UltraSparcRegInfo::IntCCRegClassID,
+            .addMReg(getUnifiedRegNum(SparcRegInfo::IntCCRegClassID,
                                       SparcIntCCRegClass::ccr), MOTy::Def));
     }
     break;
@@ -743,7 +745,7 @@ UltraSparcRegInfo::cpReg2RegMI(std::vector<MachineInstr*>& mvec,
 
 
 void
-UltraSparcRegInfo::cpReg2MemMI(std::vector<MachineInstr*>& mvec,
+SparcRegInfo::cpReg2MemMI(std::vector<MachineInstr*>& mvec,
                                unsigned SrcReg, 
                                unsigned PtrReg,
                                int Offset, int RegType,
@@ -763,7 +765,7 @@ UltraSparcRegInfo::cpReg2MemMI(std::vector<MachineInstr*>& mvec,
       OffReg = PRA.getUnusedUniRegAtMI(RC, RegType, MInst, LVSetBef);
 #else
       // Default to using register g4 for holding large offsets
-      OffReg = getUnifiedRegNum(UltraSparcRegInfo::IntRegClassID,
+      OffReg = getUnifiedRegNum(SparcRegInfo::IntRegClassID,
                                 SparcIntRegClass::g4);
 #endif
       assert(OffReg >= 0 && "FIXME: cpReg2MemMI cannot find an unused reg.");
@@ -796,7 +798,7 @@ UltraSparcRegInfo::cpReg2MemMI(std::vector<MachineInstr*>& mvec,
     assert(scratchReg >= 0 && "Need scratch reg to store %ccr to memory");
     assert(getRegType(scratchReg) ==IntRegType && "Invalid scratch reg");
     MI = (BuildMI(V9::RDCCR, 2)
-          .addMReg(getUnifiedRegNum(UltraSparcRegInfo::IntCCRegClassID,
+          .addMReg(getUnifiedRegNum(SparcRegInfo::IntCCRegClassID,
                                     SparcIntCCRegClass::ccr))
           .addMReg(scratchReg, MOTy::Def));
     mvec.push_back(MI);
@@ -805,7 +807,7 @@ UltraSparcRegInfo::cpReg2MemMI(std::vector<MachineInstr*>& mvec,
     return;
 
   case FloatCCRegType: {
-    unsigned fsrReg =  getUnifiedRegNum(UltraSparcRegInfo::SpecialRegClassID,
+    unsigned fsrReg =  getUnifiedRegNum(SparcRegInfo::SpecialRegClassID,
                                            SparcSpecialRegClass::fsr);
     if (target.getInstrInfo().constantFitsInImmedField(V9::STXFSRi, Offset))
       MI=BuildMI(V9::STXFSRi,3).addMReg(fsrReg).addMReg(PtrReg).addSImm(Offset);
@@ -827,7 +829,7 @@ UltraSparcRegInfo::cpReg2MemMI(std::vector<MachineInstr*>& mvec,
 
 
 void
-UltraSparcRegInfo::cpMem2RegMI(std::vector<MachineInstr*>& mvec,
+SparcRegInfo::cpMem2RegMI(std::vector<MachineInstr*>& mvec,
                                unsigned PtrReg,        
                                int Offset,
                                unsigned DestReg,
@@ -848,7 +850,7 @@ UltraSparcRegInfo::cpMem2RegMI(std::vector<MachineInstr*>& mvec,
       OffReg = PRA.getUnusedUniRegAtMI(RC, RegType, MInst, LVSetBef);
 #else
       // Default to using register g4 for holding large offsets
-      OffReg = getUnifiedRegNum(UltraSparcRegInfo::IntRegClassID,
+      OffReg = getUnifiedRegNum(SparcRegInfo::IntRegClassID,
                                 SparcIntRegClass::g4);
 #endif
       assert(OffReg >= 0 && "FIXME: cpReg2MemMI cannot find an unused reg.");
@@ -890,12 +892,12 @@ UltraSparcRegInfo::cpMem2RegMI(std::vector<MachineInstr*>& mvec,
     MI = (BuildMI(V9::WRCCRr, 3)
           .addMReg(scratchReg)
           .addMReg(SparcIntRegClass::g0)
-          .addMReg(getUnifiedRegNum(UltraSparcRegInfo::IntCCRegClassID,
+          .addMReg(getUnifiedRegNum(SparcRegInfo::IntCCRegClassID,
                                     SparcIntCCRegClass::ccr), MOTy::Def));
     break;
     
   case FloatCCRegType: {
-    unsigned fsrRegNum =  getUnifiedRegNum(UltraSparcRegInfo::SpecialRegClassID,
+    unsigned fsrRegNum =  getUnifiedRegNum(SparcRegInfo::SpecialRegClassID,
                                            SparcSpecialRegClass::fsr);
     if (target.getInstrInfo().constantFitsInImmedField(V9::LDXFSRi, Offset))
       MI = BuildMI(V9::LDXFSRi, 3).addMReg(PtrReg).addSImm(Offset)
@@ -919,7 +921,7 @@ UltraSparcRegInfo::cpMem2RegMI(std::vector<MachineInstr*>& mvec,
 
 
 void
-UltraSparcRegInfo::cpValue2Value(Value *Src, Value *Dest,
+SparcRegInfo::cpValue2Value(Value *Src, Value *Dest,
                                  std::vector<MachineInstr*>& mvec) const {
   int RegType = getRegTypeForDataType(Src->getType());
   MachineInstr * MI = NULL;
@@ -948,7 +950,7 @@ UltraSparcRegInfo::cpValue2Value(Value *Src, Value *Dest,
 // Print the register assigned to a LR
 //---------------------------------------------------------------------------
 
-void UltraSparcRegInfo::printReg(const LiveRange *LR) const {
+void SparcRegInfo::printReg(const LiveRange *LR) const {
   unsigned RegClassID = LR->getRegClassID();
   std::cerr << " Node ";
 
diff --git a/lib/Target/SparcV9/SparcV9RegInfo.h b/lib/Target/SparcV9/SparcV9RegInfo.h
new file mode 100644 (file)
index 0000000..68d0ad8
--- /dev/null
@@ -0,0 +1,190 @@
+//===-- SparcRegInfo.h - Define TargetRegInfo for Sparc ---------*- 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 class implements the virtual class TargetRegInfo for Sparc.
+//
+//----------------------------------------------------------------------------
+
+#ifndef SPARC_REGINFO_H
+#define SPARC_REGINFO_H
+
+namespace llvm {
+
+class SparcRegInfo : public TargetRegInfo {
+
+private:
+
+  // Number of registers used for passing int args (usually 6: %o0 - %o5)
+  //
+  unsigned const NumOfIntArgRegs;
+
+  // Number of registers used for passing float args (usually 32: %f0 - %f31)
+  //
+  unsigned const NumOfFloatArgRegs;
+
+  // The following methods are used to color special live ranges (e.g.
+  // function args and return values etc.) with specific hardware registers
+  // as required. See SparcRegInfo.cpp for the implementation.
+  //
+  void suggestReg4RetAddr(MachineInstr *RetMI, 
+                         LiveRangeInfo &LRI) const;
+
+  void suggestReg4CallAddr(MachineInstr *CallMI, LiveRangeInfo &LRI) const;
+  
+  // Helper used by the all the getRegType() functions.
+  int getRegTypeForClassAndType(unsigned regClassID, const Type* type) const;
+
+public:
+  // Type of registers available in Sparc. There can be several reg types
+  // in the same class. For instace, the float reg class has Single/Double
+  // types
+  //
+  enum RegTypes {
+    IntRegType,
+    FPSingleRegType,
+    FPDoubleRegType,
+    IntCCRegType,
+    FloatCCRegType,
+    SpecialRegType
+  };
+
+  // The actual register classes in the Sparc
+  //
+  // **** WARNING: If this enum order is changed, also modify 
+  // getRegisterClassOfValue method below since it assumes this particular 
+  // order for efficiency.
+  // 
+  enum RegClassIDs { 
+    IntRegClassID,                      // Integer
+    FloatRegClassID,                    // Float (both single/double)
+    IntCCRegClassID,                    // Int Condition Code
+    FloatCCRegClassID,                  // Float Condition code
+    SpecialRegClassID                   // Special (unallocated) registers
+  };
+
+  SparcRegInfo(const SparcTargetMachine &tgt);
+
+  // To find the register class used for a specified Type
+  //
+  unsigned getRegClassIDOfType(const Type *type,
+                               bool isCCReg = false) const;
+
+  // To find the register class to which a specified register belongs
+  //
+  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
+  // function is called. This can be used for other purposes between calls
+  //
+  unsigned getCallAddressReg() const;
+
+  // Returns the register containing the return address.
+  // It should be made sure that this  register contains the return 
+  // value when a return instruction is reached.
+  //
+  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; }
+  
+  // Compute which register can be used for an argument, if any
+  // 
+  int regNumForIntArg(bool inCallee, bool isVarArgsCall,
+                      unsigned argNo, unsigned& regClassId) const;
+
+  int regNumForFPArg(unsigned RegType, bool inCallee, bool isVarArgsCall,
+                     unsigned argNo, unsigned& regClassId) const;
+  
+  // The following methods are used to color special live ranges (e.g.
+  // function args and return values etc.) with specific hardware registers
+  // as required. See SparcRegInfo.cpp for the implementation for Sparc.
+  //
+  void suggestRegs4MethodArgs(const Function *Meth, 
+                             LiveRangeInfo& LRI) const;
+
+  void suggestRegs4CallArgs(MachineInstr *CallMI, 
+                           LiveRangeInfo& LRI) const; 
+
+  void suggestReg4RetValue(MachineInstr *RetMI, 
+                           LiveRangeInfo& LRI) const;
+  
+  void colorMethodArgs(const Function *Meth,  LiveRangeInfo& LRI,
+                       std::vector<MachineInstr*>& InstrnsBefore,
+                       std::vector<MachineInstr*>& InstrnsAfter) const;
+
+  // method used for printing a register for debugging purposes
+  //
+  void printReg(const LiveRange *LR) const;
+  
+  // returns the # of bytes of stack space allocated for each register
+  // type. For Sparc, currently we allocate 8 bytes on stack for all 
+  // register types. We can optimize this later if necessary to save stack
+  // space (However, should make sure that stack alignment is correct)
+  //
+  inline int getSpilledRegSize(int RegType) const {
+    return 8;
+  }
+
+
+  // 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.
+  //
+  // 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;
+
+  void cpReg2RegMI(std::vector<MachineInstr*>& mvec,
+                   unsigned SrcReg, unsigned DestReg,
+                   int RegType) const;
+
+  void cpReg2MemMI(std::vector<MachineInstr*>& mvec,
+                   unsigned SrcReg, unsigned DestPtrReg,
+                   int Offset, int RegType, int scratchReg = -1) const;
+
+  void cpMem2RegMI(std::vector<MachineInstr*>& mvec,
+                   unsigned SrcPtrReg, int Offset, unsigned DestReg,
+                   int RegType, int scratchReg = -1) const;
+
+  void cpValue2Value(Value *Src, Value *Dest,
+                     std::vector<MachineInstr*>& mvec) const;
+
+  // Get the register type for a register identified different ways.
+  // Note that getRegTypeForLR(LR) != getRegTypeForDataType(LR->getType())!
+  // The reg class of a LR depends both on the Value types in it and whether
+  // they are CC registers or not (for example).
+  int getRegTypeForDataType(const Type* type) const;
+  int getRegTypeForLR(const LiveRange *LR) const;
+  int getRegType(int unifiedRegNum) const;
+
+  virtual unsigned getFramePointer() const;
+  virtual unsigned getStackPointer() const;
+};
+
+} // End llvm namespace
+
+#endif
index 7d8ea05066c231a8f058471029832b1a0eda40ae..016587458bacdb6e8b97d60d26ffd965534d98f0 100644 (file)
@@ -728,7 +728,7 @@ static const InstrRUsageDelta SparcInstrUsageDeltas[] = {
 
 
 //---------------------------------------------------------------------------
-// class UltraSparcSchedInfo 
+// class SparcSchedInfo 
 // 
 // Purpose:
 //   Scheduling information for the UltraSPARC.
@@ -737,7 +737,7 @@ static const InstrRUsageDelta SparcInstrUsageDeltas[] = {
 //---------------------------------------------------------------------------
 
 /*ctor*/
-UltraSparcSchedInfo::UltraSparcSchedInfo(const TargetMachine& tgt)
+SparcSchedInfo::SparcSchedInfo(const TargetMachine& tgt)
   : TargetSchedInfo(tgt,
                      (unsigned int) SPARC_NUM_SCHED_CLASSES,
                     SparcRUsageDesc,
@@ -764,7 +764,7 @@ UltraSparcSchedInfo::UltraSparcSchedInfo(const TargetMachine& tgt)
 }
 
 void
-UltraSparcSchedInfo::initializeResources()
+SparcSchedInfo::initializeResources()
 {
   // Compute TargetSchedInfo::instrRUsages and TargetSchedInfo::issueGaps
   TargetSchedInfo::initializeResources();
index 1502dfc0f303d504cc8131f6330702d854aa6ac8..5bbed409dc5f14eee10768d13f3367778e8efb17 100644 (file)
@@ -6,27 +6,31 @@
 // the University of Illinois Open Source License. See LICENSE.TXT for details.
 // 
 //===----------------------------------------------------------------------===//
-//
-// This file contains the code for the Sparc Target that does not fit in any of
-// the other files in this directory.
-//
+// 
+// Primary interface to machine description for the UltraSPARC.  Primarily just
+// initializes machine-dependent parameters in class TargetMachine, and creates
+// machine-dependent subclasses for classes such as TargetInstrInfo.
+// 
 //===----------------------------------------------------------------------===//
 
-#include "SparcInternals.h"
-#include "MappingInfo.h" 
 #include "llvm/Function.h"
 #include "llvm/PassManager.h"
 #include "llvm/Assembly/PrintModulePass.h"
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFunctionInfo.h"
 #include "llvm/CodeGen/InstrSelection.h"
 #include "llvm/CodeGen/InstrScheduling.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionInfo.h"
 #include "llvm/CodeGen/MachineCodeForInstruction.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/Target/TargetMachineImpls.h"
+#include "llvm/Transforms/Scalar.h"
+#include "MappingInfo.h" 
+#include "SparcInternals.h"
+#include "SparcTargetMachine.h"
 #include "Support/CommandLine.h"
 
+using namespace llvm;
+
 namespace llvm {
 
 static const unsigned ImplicitRegUseList[] = { 0 }; /* not used yet */
@@ -62,87 +66,9 @@ namespace {
                           cl::Hidden);
 }
 
-//----------------------------------------------------------------------------
-// allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
-// that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
-//----------------------------------------------------------------------------
-
-TargetMachine *allocateSparcTargetMachine(const Module &M) {
-  return new UltraSparc();
-}
-
-//---------------------------------------------------------------------------
-// class UltraSparcFrameInfo 
-// 
-//   Interface to stack frame layout info for the UltraSPARC.
-//   Starting offsets for each area of the stack frame are aligned at
-//   a multiple of getStackFrameSizeAlignment().
-//---------------------------------------------------------------------------
-
-int
-UltraSparcFrameInfo::getFirstAutomaticVarOffset(MachineFunction& ,
-                                                bool& pos) const
-{
-  pos = false;                          // static stack area grows downwards
-  return StaticAreaOffsetFromFP;
-}
-
-int
-UltraSparcFrameInfo::getRegSpillAreaOffset(MachineFunction& mcInfo,
-                                           bool& pos) const
-{
-  // ensure no more auto vars are added
-  mcInfo.getInfo()->freezeAutomaticVarsArea();
-  
-  pos = false;                          // static stack area grows downwards
-  unsigned autoVarsSize = mcInfo.getInfo()->getAutomaticVarsSize();
-  return StaticAreaOffsetFromFP - autoVarsSize; 
-}
-
-int
-UltraSparcFrameInfo::getTmpAreaOffset(MachineFunction& mcInfo,
-                                      bool& pos) const
-{
-  MachineFunctionInfo *MFI = mcInfo.getInfo();
-  MFI->freezeAutomaticVarsArea();     // ensure no more auto vars are added
-  MFI->freezeSpillsArea();            // ensure no more spill slots are added
-  
-  pos = false;                          // static stack area grows downwards
-  unsigned autoVarsSize = MFI->getAutomaticVarsSize();
-  unsigned spillAreaSize = MFI->getRegSpillsSize();
-  int offset = autoVarsSize + spillAreaSize;
-  return StaticAreaOffsetFromFP - offset;
-}
-
-int
-UltraSparcFrameInfo::getDynamicAreaOffset(MachineFunction& mcInfo,
-                                          bool& pos) const
-{
-  // Dynamic stack area grows downwards starting at top of opt-args area.
-  // The opt-args, required-args, and register-save areas are empty except
-  // during calls and traps, so they are shifted downwards on each
-  // dynamic-size alloca.
-  pos = false;
-  unsigned optArgsSize = mcInfo.getInfo()->getMaxOptionalArgsSize();
-  if (int extra = optArgsSize % getStackFrameSizeAlignment())
-    optArgsSize += (getStackFrameSizeAlignment() - extra);
-  int offset = optArgsSize + FirstOptionalOutgoingArgOffsetFromSP;
-  assert((offset - OFFSET) % getStackFrameSizeAlignment() == 0);
-  return offset;
-}
-
-//---------------------------------------------------------------------------
-// class UltraSparcMachine 
-// 
-// Purpose:
-//   Primary interface to machine description for the UltraSPARC.
-//   Primarily just initializes machine-dependent parameters in
-//   class TargetMachine, and creates machine-dependent subclasses
-//   for classes such as TargetInstrInfo. 
-// 
-//---------------------------------------------------------------------------
+} // End llvm namespace
 
-UltraSparc::UltraSparc()
+SparcTargetMachine::SparcTargetMachine()
   : TargetMachine("UltraSparc-Native", false),
     schedInfo(*this),
     regInfo(*this),
@@ -153,7 +79,8 @@ UltraSparc::UltraSparc()
 // addPassesToEmitAssembly - This method controls the entire code generation
 // process for the ultra sparc.
 //
-bool UltraSparc::addPassesToEmitAssembly(PassManager &PM, std::ostream &Out)
+bool
+SparcTargetMachine::addPassesToEmitAssembly(PassManager &PM, std::ostream &Out)
 {
   // The following 3 passes used to be inserted specially by llc.
   // Replace malloc and free instructions with library calls.
@@ -225,7 +152,7 @@ bool UltraSparc::addPassesToEmitAssembly(PassManager &PM, std::ostream &Out)
 // addPassesToJITCompile - This method controls the JIT method of code
 // generation for the UltraSparc.
 //
-bool UltraSparc::addPassesToJITCompile(FunctionPassManager &PM) {
+bool SparcTargetMachine::addPassesToJITCompile(FunctionPassManager &PM) {
   const TargetData &TD = getTargetData();
 
   PM.add(new TargetData("lli", TD.isLittleEndian(), TD.getPointerSize(),
@@ -269,4 +196,15 @@ bool UltraSparc::addPassesToJITCompile(FunctionPassManager &PM) {
   return false; // success!
 }
 
-} // End llvm namespace
+//----------------------------------------------------------------------------
+// allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
+// that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
+//----------------------------------------------------------------------------
+
+namespace llvm {
+
+TargetMachine *allocateSparcTargetMachine(const Module &M) {
+  return new SparcTargetMachine();
+}
+
+}
diff --git a/lib/Target/SparcV9/SparcV9TargetMachine.h b/lib/Target/SparcV9/SparcV9TargetMachine.h
new file mode 100644 (file)
index 0000000..c8a6116
--- /dev/null
@@ -0,0 +1,59 @@
+//===-- SparcTargetMachine.h - Define TargetMachine for Sparc ---*- 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 declares the primary interface to machine description for the
+// UltraSPARC.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SPARC_TARGETMACHINE_H
+#define SPARC_TARGETMACHINE_H
+
+#include "llvm/PassManager.h"
+#include "llvm/Target/TargetFrameInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "SparcInstrInfo.h"
+#include "SparcInternals.h"
+#include "SparcRegInfo.h"
+#include "SparcFrameInfo.h"
+
+namespace llvm {
+
+class SparcTargetMachine : public TargetMachine {
+  SparcInstrInfo instrInfo;
+  SparcSchedInfo schedInfo;
+  SparcRegInfo   regInfo;
+  SparcFrameInfo frameInfo;
+  SparcCacheInfo cacheInfo;
+public:
+  SparcTargetMachine();
+
+  virtual const TargetInstrInfo  &getInstrInfo() const { return instrInfo; }
+  virtual const TargetSchedInfo  &getSchedInfo() const { return schedInfo; }
+  virtual const TargetRegInfo    &getRegInfo()   const { return regInfo; }
+  virtual const TargetFrameInfo  &getFrameInfo() const { return frameInfo; }
+  virtual const TargetCacheInfo  &getCacheInfo() const { return cacheInfo; }
+
+  virtual bool addPassesToEmitAssembly(PassManager &PM, std::ostream &Out);
+  virtual bool addPassesToJITCompile(FunctionPassManager &PM);
+  virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
+                                          MachineCodeEmitter &MCE);
+  virtual void replaceMachineCodeForFunction(void *Old, void *New);
+
+  /// getJITStubForFunction - Create or return a stub for the specified
+  /// function.  This stub acts just like the specified function, except that it
+  /// allows the "address" of the function to be taken without having to
+  /// generate code for it.
+  ///
+  ///virtual void *getJITStubForFunction(Function *F, MachineCodeEmitter &MCE);
+};
+
+} // End llvm namespace
+
+#endif