aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMisha Brukman <brukman+llvm@gmail.com>2003-12-17 22:04:00 +0000
committerMisha Brukman <brukman+llvm@gmail.com>2003-12-17 22:04:00 +0000
commitd71295a684fb351e196f4f78ea94e5d1af904eb8 (patch)
treeebc260c7a6036eb8c698cd062804a8beacbc9e31 /lib
parent3e7ada642a00c6904231f2446b33c7f15bb45151 (diff)
downloadexternal_llvm-d71295a684fb351e196f4f78ea94e5d1af904eb8.zip
external_llvm-d71295a684fb351e196f4f78ea94e5d1af904eb8.tar.gz
external_llvm-d71295a684fb351e196f4f78ea94e5d1af904eb8.tar.bz2
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10500 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/SparcV9/SparcV9CodeEmitter.cpp63
-rw-r--r--lib/Target/SparcV9/SparcV9FrameInfo.cpp65
-rw-r--r--lib/Target/SparcV9/SparcV9FrameInfo.h174
-rw-r--r--lib/Target/SparcV9/SparcV9InstrInfo.cpp43
-rw-r--r--lib/Target/SparcV9/SparcV9InstrInfo.h201
-rw-r--r--lib/Target/SparcV9/SparcV9InstrSelection.cpp15
-rw-r--r--lib/Target/SparcV9/SparcV9Internals.h583
-rw-r--r--lib/Target/SparcV9/SparcV9RegClassInfo.cpp9
-rw-r--r--lib/Target/SparcV9/SparcV9RegInfo.cpp88
-rw-r--r--lib/Target/SparcV9/SparcV9RegInfo.h190
-rw-r--r--lib/Target/SparcV9/SparcV9SchedInfo.cpp6
-rw-r--r--lib/Target/SparcV9/SparcV9TargetMachine.cpp122
-rw-r--r--lib/Target/SparcV9/SparcV9TargetMachine.h59
13 files changed, 845 insertions, 773 deletions
diff --git a/lib/Target/SparcV9/SparcV9CodeEmitter.cpp b/lib/Target/SparcV9/SparcV9CodeEmitter.cpp
index 9a51faa..bb4bdaf 100644
--- a/lib/Target/SparcV9/SparcV9CodeEmitter.cpp
+++ b/lib/Target/SparcV9/SparcV9CodeEmitter.cpp
@@ -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
index 0000000..d283e94
--- /dev/null
+++ b/lib/Target/SparcV9/SparcV9FrameInfo.cpp
@@ -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
index 0000000..9038596
--- /dev/null
+++ b/lib/Target/SparcV9/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 &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
diff --git a/lib/Target/SparcV9/SparcV9InstrInfo.cpp b/lib/Target/SparcV9/SparcV9InstrInfo.cpp
index 11b0c7b..af458ea 100644
--- a/lib/Target/SparcV9/SparcV9InstrInfo.cpp
+++ b/lib/Target/SparcV9/SparcV9InstrInfo.cpp
@@ -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
index 0000000..0926c07
--- /dev/null
+++ b/lib/Target/SparcV9/SparcV9InstrInfo.h
@@ -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
diff --git a/lib/Target/SparcV9/SparcV9InstrSelection.cpp b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
index 21e884b..c5fa145 100644
--- a/lib/Target/SparcV9/SparcV9InstrSelection.cpp
+++ b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
@@ -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"
@@ -28,6 +25,10 @@
#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*
diff --git a/lib/Target/SparcV9/SparcV9Internals.h b/lib/Target/SparcV9/SparcV9Internals.h
index e6926bb..27dc7d0 100644
--- a/lib/Target/SparcV9/SparcV9Internals.h
+++ b/lib/Target/SparcV9/SparcV9Internals.h
@@ -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
diff --git a/lib/Target/SparcV9/SparcV9RegClassInfo.cpp b/lib/Target/SparcV9/SparcV9RegClassInfo.cpp
index 564e59c..c6d559a 100644
--- a/lib/Target/SparcV9/SparcV9RegClassInfo.cpp
+++ b/lib/Target/SparcV9/SparcV9RegClassInfo.cpp
@@ -11,9 +11,10 @@
//
//===----------------------------------------------------------------------===//
+#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)
diff --git a/lib/Target/SparcV9/SparcV9RegInfo.cpp b/lib/Target/SparcV9/SparcV9RegInfo.cpp
index 5edbbe0..1d742ef 100644
--- a/lib/Target/SparcV9/SparcV9RegInfo.cpp
+++ b/lib/Target/SparcV9/SparcV9RegInfo.cpp
@@ -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"
@@ -22,10 +20,14 @@
#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
index 0000000..68d0ad8
--- /dev/null
+++ b/lib/Target/SparcV9/SparcV9RegInfo.h
@@ -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
diff --git a/lib/Target/SparcV9/SparcV9SchedInfo.cpp b/lib/Target/SparcV9/SparcV9SchedInfo.cpp
index 7d8ea05..0165874 100644
--- a/lib/Target/SparcV9/SparcV9SchedInfo.cpp
+++ b/lib/Target/SparcV9/SparcV9SchedInfo.cpp
@@ -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();
diff --git a/lib/Target/SparcV9/SparcV9TargetMachine.cpp b/lib/Target/SparcV9/SparcV9TargetMachine.cpp
index 1502dfc..5bbed40 100644
--- a/lib/Target/SparcV9/SparcV9TargetMachine.cpp
+++ b/lib/Target/SparcV9/SparcV9TargetMachine.cpp
@@ -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
index 0000000..c8a6116
--- /dev/null
+++ b/lib/Target/SparcV9/SparcV9TargetMachine.h
@@ -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