Reorganized the Sparc backend to be more modular -- each different
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.

llvm-svn: 10500
diff --git a/llvm/lib/Target/Sparc/SparcV9FrameInfo.h b/llvm/lib/Target/Sparc/SparcV9FrameInfo.h
new file mode 100644
index 0000000..9038596
--- /dev/null
+++ b/llvm/lib/Target/Sparc/SparcV9FrameInfo.h
@@ -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 ⌖
+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