//
//===----------------------------------------------------------------------===//
-#include "Mips.h"
-#include "MipsTargetAsmInfo.h"
#include "MipsTargetMachine.h"
-#include "llvm/Module.h"
+#include "Mips.h"
+#include "MipsFrameLowering.h"
+#include "MipsInstrInfo.h"
+#include "MipsModuleISelDAGToDAG.h"
+#include "MipsOs16.h"
+#include "MipsSEFrameLowering.h"
+#include "MipsSEInstrInfo.h"
+#include "MipsSEISelLowering.h"
+#include "MipsSEISelDAGToDAG.h"
+#include "Mips16FrameLowering.h"
+#include "Mips16HardFloat.h"
+#include "Mips16InstrInfo.h"
+#include "Mips16ISelDAGToDAG.h"
+#include "Mips16ISelLowering.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/CodeGen/Passes.h"
#include "llvm/PassManager.h"
-#include "llvm/Target/TargetMachineRegistry.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Transforms/Scalar.h"
using namespace llvm;
-/// MipsTargetMachineModule - Note that this is used on hosts that
-/// cannot link in a library unless there are references into the
-/// library. In particular, it seems that it is not possible to get
-/// things to work on Win32 without this. Though it is unused, do not
-/// remove it.
-extern "C" int MipsTargetMachineModule;
-int MipsTargetMachineModule = 0;
-
-// Register the target.
-static RegisterTarget<MipsTargetMachine> X("mips", "Mips");
-static RegisterTarget<MipselTargetMachine> Y("mipsel", "Mipsel");
-MipsTargetMachine::AsmPrinterCtorFn MipsTargetMachine::AsmPrinterCtor = 0;
-
-// Force static initialization when called from llvm/InitializeAllTargets.h
-namespace llvm {
- void InitializeMipsTarget() { }
-}
-
-const TargetAsmInfo *MipsTargetMachine::
-createTargetAsmInfo() const
-{
- return new MipsTargetAsmInfo(*this);
+extern "C" void LLVMInitializeMipsTarget() {
+ // Register the target.
+ RegisterTargetMachine<MipsebTargetMachine> X(TheMipsTarget);
+ RegisterTargetMachine<MipselTargetMachine> Y(TheMipselTarget);
+ RegisterTargetMachine<MipsebTargetMachine> A(TheMips64Target);
+ RegisterTargetMachine<MipselTargetMachine> B(TheMips64elTarget);
}
// DataLayout --> Big-endian, 32-bit pointer/ABI/alignment
// The stack is always 8 byte aligned
// On function prologue, the stack is created by decrementing
// its pointer. Once decremented, all references are done with positive
-// offset from the stack/frame pointer, using StackGrowsUp enables
+// offset from the stack/frame pointer, using StackGrowsUp enables
// an easier handling.
// Using CodeModel::Large enables different CALL behavior.
MipsTargetMachine::
-MipsTargetMachine(const Module &M, const std::string &FS, bool isLittle=false):
- Subtarget(*this, M, FS, isLittle),
- DataLayout(isLittle ? std::string("e-p:32:32:32-i8:8:32-i16:16:32") :
- std::string("E-p:32:32:32-i8:8:32-i16:16:32")),
- InstrInfo(*this),
- FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0),
- TLInfo(*this)
-{
- // Abicall enables PIC by default
- if (Subtarget.hasABICall())
- setRelocationModel(Reloc::PIC_);
-
- // TODO: create an option to enable long calls, like -mlong-calls,
- // that would be our CodeModel::Large. It must not work with Abicall.
- if (getCodeModel() == CodeModel::Default)
- setCodeModel(CodeModel::Small);
+MipsTargetMachine(const Target &T, StringRef TT,
+ StringRef CPU, StringRef FS, const TargetOptions &Options,
+ Reloc::Model RM, CodeModel::Model CM,
+ CodeGenOpt::Level OL,
+ bool isLittle)
+ : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
+ Subtarget(TT, CPU, FS, isLittle, RM, this),
+ DL(isLittle ?
+ (Subtarget.isABI_N64() ?
+ "e-p:64:64:64-i8:8:32-i16:16:32-i64:64:64-f128:128:128-"
+ "n32:64-S128" :
+ "e-p:32:32:32-i8:8:32-i16:16:32-i64:64:64-n32-S64") :
+ (Subtarget.isABI_N64() ?
+ "E-p:64:64:64-i8:8:32-i16:16:32-i64:64:64-f128:128:128-"
+ "n32:64-S128" :
+ "E-p:32:32:32-i8:8:32-i16:16:32-i64:64:64-n32-S64")),
+ InstrInfo(MipsInstrInfo::create(*this)),
+ FrameLowering(MipsFrameLowering::create(*this, Subtarget)),
+ TLInfo(MipsTargetLowering::create(*this)), TSInfo(*this),
+ InstrItins(Subtarget.getInstrItineraryData()), JITInfo() {
+ initAsmInfo();
}
-MipselTargetMachine::
-MipselTargetMachine(const Module &M, const std::string &FS) :
- MipsTargetMachine(M, FS, true) {}
-
-// return 0 and must specify -march to gen MIPS code.
-unsigned MipsTargetMachine::
-getModuleMatchQuality(const Module &M)
-{
- // We strongly match "mips*-*".
- std::string TT = M.getTargetTriple();
- if (TT.size() >= 5 && std::string(TT.begin(), TT.begin()+5) == "mips-")
- return 20;
-
- if (TT.size() >= 13 && std::string(TT.begin(),
- TT.begin()+13) == "mipsallegrex-")
- return 20;
-
- return 0;
+
+void MipsTargetMachine::setHelperClassesMips16() {
+ InstrInfoSE.swap(InstrInfo);
+ FrameLoweringSE.swap(FrameLowering);
+ TLInfoSE.swap(TLInfo);
+ if (!InstrInfo16) {
+ InstrInfo.reset(MipsInstrInfo::create(*this));
+ FrameLowering.reset(MipsFrameLowering::create(*this, Subtarget));
+ TLInfo.reset(MipsTargetLowering::create(*this));
+ } else {
+ InstrInfo16.swap(InstrInfo);
+ FrameLowering16.swap(FrameLowering);
+ TLInfo16.swap(TLInfo);
+ }
+ assert(TLInfo && "null target lowering 16");
+ assert(InstrInfo && "null instr info 16");
+ assert(FrameLowering && "null frame lowering 16");
}
-// return 0 and must specify -march to gen MIPSEL code.
-unsigned MipselTargetMachine::
-getModuleMatchQuality(const Module &M)
-{
- // We strongly match "mips*el-*".
- std::string TT = M.getTargetTriple();
- if (TT.size() >= 7 && std::string(TT.begin(), TT.begin()+7) == "mipsel-")
- return 20;
-
- if (TT.size() >= 15 && std::string(TT.begin(),
- TT.begin()+15) == "mipsallegrexel-")
- return 20;
-
- if (TT.size() == 3 && std::string(TT.begin(), TT.begin()+3) == "psp")
- return 20;
-
- return 0;
+void MipsTargetMachine::setHelperClassesMipsSE() {
+ InstrInfo16.swap(InstrInfo);
+ FrameLowering16.swap(FrameLowering);
+ TLInfo16.swap(TLInfo);
+ if (!InstrInfoSE) {
+ InstrInfo.reset(MipsInstrInfo::create(*this));
+ FrameLowering.reset(MipsFrameLowering::create(*this, Subtarget));
+ TLInfo.reset(MipsTargetLowering::create(*this));
+ } else {
+ InstrInfoSE.swap(InstrInfo);
+ FrameLoweringSE.swap(FrameLowering);
+ TLInfoSE.swap(TLInfo);
+ }
+ assert(TLInfo && "null target lowering in SE");
+ assert(InstrInfo && "null instr info SE");
+ assert(FrameLowering && "null frame lowering SE");
}
+void MipsebTargetMachine::anchor() { }
+
+MipsebTargetMachine::
+MipsebTargetMachine(const Target &T, StringRef TT,
+ StringRef CPU, StringRef FS, const TargetOptions &Options,
+ Reloc::Model RM, CodeModel::Model CM,
+ CodeGenOpt::Level OL)
+ : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
-// Install an instruction selector pass using
+void MipselTargetMachine::anchor() { }
+
+MipselTargetMachine::
+MipselTargetMachine(const Target &T, StringRef TT,
+ StringRef CPU, StringRef FS, const TargetOptions &Options,
+ Reloc::Model RM, CodeModel::Model CM,
+ CodeGenOpt::Level OL)
+ : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
+
+namespace {
+/// Mips Code Generator Pass Configuration Options.
+class MipsPassConfig : public TargetPassConfig {
+public:
+ MipsPassConfig(MipsTargetMachine *TM, PassManagerBase &PM)
+ : TargetPassConfig(TM, PM) {}
+
+ MipsTargetMachine &getMipsTargetMachine() const {
+ return getTM<MipsTargetMachine>();
+ }
+
+ const MipsSubtarget &getMipsSubtarget() const {
+ return *getMipsTargetMachine().getSubtargetImpl();
+ }
+
+ virtual void addIRPasses();
+ virtual bool addInstSelector();
+ virtual bool addPreEmitPass();
+};
+} // namespace
+
+TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) {
+ return new MipsPassConfig(this, PM);
+}
+
+void MipsPassConfig::addIRPasses() {
+ TargetPassConfig::addIRPasses();
+ if (getMipsSubtarget().os16())
+ addPass(createMipsOs16(getMipsTargetMachine()));
+ if (getMipsSubtarget().inMips16HardFloat())
+ addPass(createMips16HardFloat(getMipsTargetMachine()));
+ addPass(createPartiallyInlineLibCallsPass());
+}
+// Install an instruction selector pass using
// the ISelDag to gen Mips code.
-bool MipsTargetMachine::
-addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel)
-{
- PM.add(createMipsISelDag(*this));
+bool MipsPassConfig::addInstSelector() {
+ if (getMipsSubtarget().allowMixed16_32()) {
+ addPass(createMipsModuleISelDag(getMipsTargetMachine()));
+ addPass(createMips16ISelDag(getMipsTargetMachine()));
+ addPass(createMipsSEISelDag(getMipsTargetMachine()));
+ } else {
+ addPass(createMipsISelDag(getMipsTargetMachine()));
+ }
return false;
}
-// Implemented by targets that want to run passes immediately before
-// machine code is emitted. return true if -print-machineinstrs should
+void MipsTargetMachine::addAnalysisPasses(PassManagerBase &PM) {
+ if (Subtarget.allowMixed16_32()) {
+ DEBUG(errs() << "No ");
+ //FIXME: The Basic Target Transform Info
+ // pass needs to become a function pass instead of
+ // being an immutable pass and then this method as it exists now
+ // would be unnecessary.
+ PM.add(createNoTargetTransformInfoPass());
+ } else
+ LLVMTargetMachine::addAnalysisPasses(PM);
+ DEBUG(errs() << "Target Transform Info Pass Added\n");
+}
+
+// Implemented by targets that want to run passes immediately before
+// machine code is emitted. return true if -print-machineinstrs should
// print out the code after the passes.
-bool MipsTargetMachine::
-addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel)
-{
- PM.add(createMipsDelaySlotFillerPass(*this));
+bool MipsPassConfig::addPreEmitPass() {
+ MipsTargetMachine &TM = getMipsTargetMachine();
+ const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>();
+ addPass(createMipsDelaySlotFillerPass(TM));
+
+ if (Subtarget.hasStandardEncoding() ||
+ Subtarget.allowMixed16_32())
+ addPass(createMipsLongBranchPass(TM));
+ if (Subtarget.inMips16Mode() ||
+ Subtarget.allowMixed16_32())
+ addPass(createMipsConstantIslandPass(TM));
+
return true;
}
-// Implements the AssemblyEmitter for the target. Must return
-// true if AssemblyEmitter is supported
-bool MipsTargetMachine::
-addAssemblyEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel,
- bool Verbose, raw_ostream &Out) {
- // Output assembly language.
- assert(AsmPrinterCtor && "AsmPrinter was not linked in");
- PM.add(AsmPrinterCtor(Out, *this, OptLevel, Verbose));
+bool MipsTargetMachine::addCodeEmitter(PassManagerBase &PM,
+ JITCodeEmitter &JCE) {
+ // Machine code emitter pass for Mips.
+ PM.add(createMipsJITCodeEmitterPass(*this, JCE));
return false;
}