diff --git a/llvm/lib/Target/Mips/CMakeLists.txt b/llvm/lib/Target/Mips/CMakeLists.txt index cf8bb189e475f417b46d712e0649bb6ea8143863..a75e8bd4dee17e90f889ee73a37d72e5ee963698 100644 --- a/llvm/lib/Target/Mips/CMakeLists.txt +++ b/llvm/lib/Target/Mips/CMakeLists.txt @@ -32,6 +32,7 @@ add_llvm_target(MipsCodeGen MipsLongBranch.cpp MipsMCInstLower.cpp MipsMachineFunction.cpp + MipsModuleISelDAGToDAG.cpp MipsRegisterInfo.cpp MipsSEFrameLowering.cpp MipsSEInstrInfo.cpp diff --git a/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.cpp b/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.cpp index 00b3449300c5286ad809bcd764559d184be8776d..2ffd3a992962f7f08974fae8bec93d2e98e49178 100644 --- a/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.cpp @@ -35,6 +35,11 @@ #include "llvm/Target/TargetMachine.h" using namespace llvm; +bool Mips16DAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { + if (!Subtarget.inMips16Mode()) + return false; + return MipsDAGToDAGISel::runOnMachineFunction(MF); +} /// Select multiply instructions. std::pair Mips16DAGToDAGISel::selectMULT(SDNode *N, unsigned Opc, DebugLoc DL, EVT Ty, diff --git a/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.h b/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.h index baa85877d957e757c79cb7d461c15c994931b21e..f05f9b766df862625aee24003843295b0471e2a9 100644 --- a/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/Mips16ISelDAGToDAG.h @@ -28,6 +28,8 @@ private: SDValue getMips16SPAliasReg(); + virtual bool runOnMachineFunction(MachineFunction &MF); + void getMips16SPRefReg(SDNode *Parent, SDValue &AliasReg); virtual bool selectAddr16(SDNode *Parent, SDValue N, SDValue &Base, diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp index 1876cb6ffae4d3b4844f31bab73a5af38323559e..e0ddade15f84b1cf3a00b0a3440e38dd28116b0b 100644 --- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp @@ -46,6 +46,10 @@ using namespace llvm; bool MipsAsmPrinter::runOnMachineFunction(MachineFunction &MF) { + // Initialize TargetLoweringObjectFile. + if (Subtarget->allowMixed16_32()) + const_cast(getObjFileLowering()) + .Initialize(OutContext, TM); MipsFI = MF.getInfo(); AsmPrinter::runOnMachineFunction(MF); return true; diff --git a/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp b/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp index b5de1ebad22bb26123d3944c30b9b42b688cf0bb..1951324cf1a1f968660c1aeaea95f1fe4ef54156 100644 --- a/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp +++ b/llvm/lib/Target/Mips/MipsConstantIslandPass.cpp @@ -80,6 +80,10 @@ FunctionPass *llvm::createMipsConstantIslandPass(MipsTargetMachine &tm) { } bool MipsConstantIslands::runOnMachineFunction(MachineFunction &F) { - return true; + // The intention is for this to be a mips16 only pass for now + // FIXME: + // if (!TM.getSubtarget().inMips16Mode()) + // return false; + return false; } diff --git a/llvm/lib/Target/Mips/MipsLongBranch.cpp b/llvm/lib/Target/Mips/MipsLongBranch.cpp index 2efe534053a2411664599a34781207afe48bd77f..bf5ad37031191efbfb0c77aaf82db357ebd156b3 100644 --- a/llvm/lib/Target/Mips/MipsLongBranch.cpp +++ b/llvm/lib/Target/Mips/MipsLongBranch.cpp @@ -399,6 +399,8 @@ static void emitGPDisp(MachineFunction &F, const MipsInstrInfo *TII) { } bool MipsLongBranch::runOnMachineFunction(MachineFunction &F) { + if (TM.getSubtarget().inMips16Mode()) + return false; if ((TM.getRelocationModel() == Reloc::PIC_) && TM.getSubtarget().isABI_O32() && F.getInfo()->globalBaseRegSet()) diff --git a/llvm/lib/Target/Mips/MipsModuleISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsModuleISelDAGToDAG.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c6abf17df35395eaee361bfe49d164813882ad24 --- /dev/null +++ b/llvm/lib/Target/Mips/MipsModuleISelDAGToDAG.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// Instruction Selector Subtarget Control +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// This file defines a pass used to change the subtarget for the +// Mips Instruction selector. +// +//===----------------------------------------------------------------------===// + +#include "MipsISelDAGToDAG.h" +#include "MipsModuleISelDAGToDAG.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { + +bool MipsModuleDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { + DEBUG(errs() << "In MipsModuleDAGToDAGISel::runMachineFunction\n"); + const_cast(Subtarget).resetSubtarget(&MF); + return false; +} + +char MipsModuleDAGToDAGISel::ID = 0; + +} + + +llvm::FunctionPass *llvm::createMipsModuleISelDag(MipsTargetMachine &TM) { + return new MipsModuleDAGToDAGISel(TM); +} + + diff --git a/llvm/lib/Target/Mips/MipsModuleISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsModuleISelDAGToDAG.h new file mode 100644 index 0000000000000000000000000000000000000000..fda35ae288bbe581cd393245d3f2e8f3f0782fac --- /dev/null +++ b/llvm/lib/Target/Mips/MipsModuleISelDAGToDAG.h @@ -0,0 +1,66 @@ +//===---- MipsModuleISelDAGToDAG.h - Change Subtarget --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines a pass used to change the subtarget for the +// Mips Instruction selector. +// +//===----------------------------------------------------------------------===// + +#ifndef MIPSMODULEISELDAGTODAG_H +#define MIPSMODULEISELDAGTODAG_H + +#include "Mips.h" +#include "MipsSubtarget.h" +#include "MipsTargetMachine.h" +#include "llvm/CodeGen/SelectionDAGISel.h" + + +//===----------------------------------------------------------------------===// +// Instruction Selector Implementation +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// MipsModuleDAGToDAGISel - MIPS specific code to select MIPS machine +// instructions for SelectionDAG operations. +//===----------------------------------------------------------------------===// +namespace llvm { + +class MipsModuleDAGToDAGISel : public MachineFunctionPass { +public: + + static char ID; + + explicit MipsModuleDAGToDAGISel(MipsTargetMachine &TM_) + : MachineFunctionPass(ID), + TM(TM_), Subtarget(TM.getSubtarget()) {} + + // Pass Name + virtual const char *getPassName() const { + return "MIPS DAG->DAG Pattern Instruction Selection"; + } + + virtual bool runOnMachineFunction(MachineFunction &MF); + + virtual SDNode *Select(SDNode *N) { + llvm_unreachable("unexpected"); + } + +protected: + /// Keep a pointer to the MipsSubtarget around so that we can make the right + /// decision when generating code for different targets. + const TargetMachine &TM; + const MipsSubtarget &Subtarget; +}; + +/// createMipsISelDag - This pass converts a legalized DAG into a +/// MIPS-specific DAG, ready for instruction scheduling. +FunctionPass *createMipsModuleISelDag(MipsTargetMachine &TM); +} + +#endif diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index d6d220750c616a9eef50e68178cf05200b2d73e1..0fc3c5e6ad98120ab29484e35ae9f18dc15affb0 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -35,6 +35,11 @@ #include "llvm/Target/TargetMachine.h" using namespace llvm; +bool MipsSEDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { + if (Subtarget.inMips16Mode()) + return false; + return MipsDAGToDAGISel::runOnMachineFunction(MF); +} bool MipsSEDAGToDAGISel::replaceUsesWithZeroReg(MachineRegisterInfo *MRI, const MachineInstr& MI) { diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h index 6137ab040bbc5b2736860c5e42c18cc3c434ed42..0dae73dd5ed78ac7b7ba1757253502e336241de9 100644 --- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h +++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h @@ -24,6 +24,9 @@ public: explicit MipsSEDAGToDAGISel(MipsTargetMachine &TM) : MipsDAGToDAGISel(TM) {} private: + + virtual bool runOnMachineFunction(MachineFunction &MF); + bool replaceUsesWithZeroReg(MachineRegisterInfo *MRI, const MachineInstr&); std::pair selectMULT(SDNode *N, unsigned Opc, DebugLoc dl, diff --git a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp index 4f219218d31f65ed359eaf9a5f1c27d09b9072b5..df6af096f6efed51e8a4bda732e69f721e85a2d8 100644 --- a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp @@ -27,6 +27,9 @@ EnableMipsTailCalls("enable-mips-tail-calls", cl::Hidden, MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM) : MipsTargetLowering(TM) { // Set up the register classes + + clearRegisterClasses(); + addRegisterClass(MVT::i32, &Mips::CPURegsRegClass); if (HasMips64) diff --git a/llvm/lib/Target/Mips/MipsSubtarget.cpp b/llvm/lib/Target/Mips/MipsSubtarget.cpp index e11e5d142b74171e1391a741939353bad312a1fc..b91f5472c8ba9ee324c2d52d5ab0c804b0b3bc6e 100644 --- a/llvm/lib/Target/Mips/MipsSubtarget.cpp +++ b/llvm/lib/Target/Mips/MipsSubtarget.cpp @@ -11,29 +11,49 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "mips-subtarget" + +#include "MipsMachineFunction.h" #include "MipsSubtarget.h" +#include "MipsTargetMachine.h" #include "Mips.h" #include "MipsRegisterInfo.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/Function.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/raw_ostream.h" #define GET_SUBTARGETINFO_TARGET_DESC #define GET_SUBTARGETINFO_CTOR #include "MipsGenSubtargetInfo.inc" + using namespace llvm; +// FIXME: Maybe this should be on by default when Mips16 is specified +// +static cl::opt Mixed16_32( + "mips-mixed-16-32", + cl::init(false), + cl::desc("Allow for a mixture of Mips16 " + "and Mips32 code in a single source file"), + cl::Hidden); + void MipsSubtarget::anchor() { } MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU, const std::string &FS, bool little, - Reloc::Model _RM) : + Reloc::Model _RM, MipsTargetMachine *_TM) : MipsGenSubtargetInfo(TT, CPU, FS), MipsArchVersion(Mips32), MipsABI(UnknownABI), IsLittle(little), IsSingleFloat(false), IsFP64bit(false), IsGP64bit(false), HasVFPU(false), IsLinux(true), HasSEInReg(false), HasCondMov(false), HasSwap(false), HasBitCount(false), HasFPIdx(false), InMips16Mode(false), InMicroMipsMode(false), HasDSP(false), HasDSPR2(false), - RM(_RM) + AllowMixed16_32(Mixed16_32), + RM(_RM), OverrideMode(NoOverride), TM(_TM) { std::string CPUName = CPU; if (CPUName.empty()) @@ -42,6 +62,8 @@ MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU, // Parse features string. ParseSubtargetFeatures(CPUName, FS); + PreviousInMips16Mode = InMips16Mode; + // Initialize scheduling itinerary for the specified CPU. InstrItins = getInstrItineraryForCPU(CPUName); @@ -72,3 +94,48 @@ MipsSubtarget::enablePostRAScheduler(CodeGenOpt::Level OptLevel, &Mips::CPU64RegsRegClass : &Mips::CPURegsRegClass); return OptLevel >= CodeGenOpt::Aggressive; } + +//FIXME: This logic for reseting the subtarget along with +// the helper classes can probably be simplified but there are a lot of +// cases so we will defer rewriting this to later. +// +void MipsSubtarget::resetSubtarget(MachineFunction *MF) { + bool ChangeToMips16 = false, ChangeToNoMips16 = false; + DEBUG(dbgs() << "resetSubtargetFeatures" << "\n"); + AttributeSet FnAttrs = MF->getFunction()->getAttributes(); + ChangeToMips16 = FnAttrs.hasAttribute(AttributeSet::FunctionIndex, + "mips16"); + ChangeToNoMips16 = FnAttrs.hasAttribute(AttributeSet::FunctionIndex, + "nomips16"); + assert (!(ChangeToMips16 & ChangeToNoMips16) && + "mips16 and nomips16 specified on the same function"); + if (ChangeToMips16) { + if (PreviousInMips16Mode) + return; + OverrideMode = Mips16Override; + PreviousInMips16Mode = true; + TM->setHelperClassesMips16(); + return; + } else if (ChangeToNoMips16) { + if (!PreviousInMips16Mode) + return; + OverrideMode = NoMips16Override; + PreviousInMips16Mode = false; + TM->setHelperClassesMipsSE(); + return; + } else { + if (OverrideMode == NoOverride) + return; + OverrideMode = NoOverride; + DEBUG(dbgs() << "back to default" << "\n"); + if (inMips16Mode() && !PreviousInMips16Mode) { + TM->setHelperClassesMips16(); + PreviousInMips16Mode = true; + } else if (!inMips16Mode() && PreviousInMips16Mode) { + TM->setHelperClassesMipsSE(); + PreviousInMips16Mode = false; + } + return; + } +} + diff --git a/llvm/lib/Target/Mips/MipsSubtarget.h b/llvm/lib/Target/Mips/MipsSubtarget.h index 7a2e47ce5a9d901184ee022dbeac8cd51b6b5be8..5ad627c4c1fbe071d2b7d555bd9372e9f01ec257 100644 --- a/llvm/lib/Target/Mips/MipsSubtarget.h +++ b/llvm/lib/Target/Mips/MipsSubtarget.h @@ -16,7 +16,9 @@ #include "MCTargetDesc/MipsReginfo.h" #include "llvm/MC/MCInstrItineraries.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetSubtargetInfo.h" + #include #define GET_SUBTARGETINFO_HEADER @@ -25,6 +27,8 @@ namespace llvm { class StringRef; +class MipsTargetMachine; + class MipsSubtarget : public MipsGenSubtargetInfo { virtual void anchor(); @@ -89,12 +93,18 @@ protected: // InMips16 -- can process Mips16 instructions bool InMips16Mode; + // PreviousInMips16 -- the function we just processed was in Mips 16 Mode + bool PreviousInMips16Mode; + // InMicroMips -- can process MicroMips instructions bool InMicroMipsMode; // HasDSP, HasDSPR2 -- supports DSP ASE. bool HasDSP, HasDSPR2; + // Allow mixed Mips16 and Mips32 in one source file + bool AllowMixed16_32; + InstrItineraryData InstrItins; // The instance to the register info section object @@ -103,6 +113,12 @@ protected: // Relocation Model Reloc::Model RM; + // We can override the determination of whether we are in mips16 mode + // as from the command line + enum {NoOverride, Mips16Override, NoMips16Override} OverrideMode; + + MipsTargetMachine *TM; + public: virtual bool enablePostRAScheduler(CodeGenOpt::Level OptLevel, AntiDepBreakMode& Mode, @@ -118,7 +134,8 @@ public: /// This constructor initializes the data members to match that /// of the specified triple. MipsSubtarget(const std::string &TT, const std::string &CPU, - const std::string &FS, bool little, Reloc::Model RM); + const std::string &FS, bool little, Reloc::Model RM, + MipsTargetMachine *TM); /// ParseSubtargetFeatures - Parses features string setting specified /// subtarget options. Definition of function is auto generated by tblgen. @@ -137,7 +154,20 @@ public: bool isSingleFloat() const { return IsSingleFloat; } bool isNotSingleFloat() const { return !IsSingleFloat; } bool hasVFPU() const { return HasVFPU; } - bool inMips16Mode() const { return InMips16Mode; } + bool inMips16Mode() const { + switch (OverrideMode) { + case NoOverride: + return InMips16Mode; + case Mips16Override: + return true; + case NoMips16Override: + return false; + } + llvm_unreachable("Unexpected mode"); + } + bool inMips16ModeDefault() { + return InMips16Mode; + } bool inMicroMipsMode() const { return InMicroMipsMode; } bool hasDSP() const { return HasDSP; } bool hasDSPR2() const { return HasDSPR2; } @@ -153,11 +183,18 @@ public: bool hasBitCount() const { return HasBitCount; } bool hasFPIdx() const { return HasFPIdx; } + bool allowMixed16_32() const { return AllowMixed16_32;}; + // Grab MipsRegInfo object const MipsReginfo &getMReginfo() const { return MRI; } // Grab relocation model Reloc::Model getRelocationModel() const {return RM;} + + /// \brief Reset the subtarget for the Mips target. + void resetSubtarget(MachineFunction *MF); + + }; } // End llvm namespace diff --git a/llvm/lib/Target/Mips/MipsTargetMachine.cpp b/llvm/lib/Target/Mips/MipsTargetMachine.cpp index 33363580aba7d404776591c2472d70c3790e4bab..18c1ccedfd58d2404cf48766c65761f09659ad33 100644 --- a/llvm/lib/Target/Mips/MipsTargetMachine.cpp +++ b/llvm/lib/Target/Mips/MipsTargetMachine.cpp @@ -15,11 +15,25 @@ #include "Mips.h" #include "MipsFrameLowering.h" #include "MipsInstrInfo.h" +#include "MipsModuleISelDAGToDAG.h" +#include "MipsSEFrameLowering.h" +#include "MipsSEInstrInfo.h" +#include "MipsSEISelLowering.h" +#include "MipsSEISelDAGToDAG.h" +#include "Mips16FrameLowering.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/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Support/TargetRegistry.h" using namespace llvm; + + extern "C" void LLVMInitializeMipsTarget() { // Register the target. RegisterTargetMachine X(TheMipsTarget); @@ -42,7 +56,7 @@ MipsTargetMachine(const Target &T, StringRef TT, CodeGenOpt::Level OL, bool isLittle) : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), - Subtarget(TT, CPU, FS, isLittle, RM), + 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-" @@ -54,9 +68,46 @@ MipsTargetMachine(const Target &T, StringRef TT, "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), JITInfo() { + TLInfo(MipsTargetLowering::create(*this)), + TSInfo(*this), JITInfo() { +} + + +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"); } +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:: @@ -102,21 +153,42 @@ TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) { // Install an instruction selector pass using // the ISelDag to gen Mips code. bool MipsPassConfig::addInstSelector() { - addPass(createMipsISelDag(getMipsTargetMachine())); + if (getMipsSubtarget().allowMixed16_32()) { + addPass(createMipsModuleISelDag(getMipsTargetMachine())); + addPass(createMips16ISelDag(getMipsTargetMachine())); + addPass(createMipsSEISelDag(getMipsTargetMachine())); + } else { + addPass(createMipsISelDag(getMipsTargetMachine())); + } return false; } +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 MipsPassConfig::addPreEmitPass() { MipsTargetMachine &TM = getMipsTargetMachine(); + const MipsSubtarget &Subtarget = TM.getSubtarget(); addPass(createMipsDelaySlotFillerPass(TM)); - // NOTE: long branch has not been implemented for mips16. - if (TM.getSubtarget().hasStandardEncoding()) + if (Subtarget.hasStandardEncoding() || + Subtarget.allowMixed16_32()) addPass(createMipsLongBranchPass(TM)); - if (TM.getSubtarget().inMips16Mode()) + if (Subtarget.inMips16Mode() || + Subtarget.allowMixed16_32()) addPass(createMipsConstantIslandPass(TM)); return true; diff --git a/llvm/lib/Target/Mips/MipsTargetMachine.h b/llvm/lib/Target/Mips/MipsTargetMachine.h index 7e5f1922643356a44b8b6a7e8436c287581148ab..ee557084fbbff89ddd025dbe0c700d72b5de90e5 100644 --- a/llvm/lib/Target/Mips/MipsTargetMachine.h +++ b/llvm/lib/Target/Mips/MipsTargetMachine.h @@ -21,6 +21,8 @@ #include "MipsSelectionDAGInfo.h" #include "MipsSubtarget.h" #include "llvm/ADT/OwningPtr.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/IR/DataLayout.h" #include "llvm/Target/TargetFrameLowering.h" #include "llvm/Target/TargetMachine.h" @@ -35,6 +37,12 @@ class MipsTargetMachine : public LLVMTargetMachine { OwningPtr InstrInfo; OwningPtr FrameLowering; OwningPtr TLInfo; + OwningPtr InstrInfo16; + OwningPtr FrameLowering16; + OwningPtr TLInfo16; + OwningPtr InstrInfoSE; + OwningPtr FrameLoweringSE; + OwningPtr TLInfoSE; MipsSelectionDAGInfo TSInfo; MipsJITInfo JITInfo; @@ -47,6 +55,8 @@ public: virtual ~MipsTargetMachine() {} + virtual void addAnalysisPasses(PassManagerBase &PM); + virtual const MipsInstrInfo *getInstrInfo() const { return InstrInfo.get(); } virtual const TargetFrameLowering *getFrameLowering() const @@ -73,6 +83,13 @@ public: // Pass Pipeline Configuration virtual TargetPassConfig *createPassConfig(PassManagerBase &PM); virtual bool addCodeEmitter(PassManagerBase &PM, JITCodeEmitter &JCE); + + // Set helper classes + void setHelperClassesMips16(); + + void setHelperClassesMipsSE(); + + }; /// MipsebTargetMachine - Mips32/64 big endian target machine. diff --git a/llvm/test/CodeGen/Mips/mips16_32_1.ll b/llvm/test/CodeGen/Mips/mips16_32_1.ll new file mode 100644 index 0000000000000000000000000000000000000000..6f4826ea9600386cd322682ef861a850c8ef773d --- /dev/null +++ b/llvm/test/CodeGen/Mips/mips16_32_1.ll @@ -0,0 +1,14 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s -mips-mixed-16-32 | FileCheck %s +; RUN: llc -march=mipsel -mcpu=mips32 -relocation-model=pic -O3 < %s -mips-mixed-16-32 | FileCheck %s + +define void @foo() #0 { +entry: + ret void +} + +; CHECK: .set mips16 # @foo +; CHECK: .ent foo +; CHECK: save {{.+}} +; CHECK: restore {{.+}} +; CHECK: .end foo +attributes #0 = { nounwind "less-precise-fpmad"="false" "mips16" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/llvm/test/CodeGen/Mips/mips16_32_10.ll b/llvm/test/CodeGen/Mips/mips16_32_10.ll new file mode 100644 index 0000000000000000000000000000000000000000..330dbfec63b92fd189bbd21c16e09c902e5ea443 --- /dev/null +++ b/llvm/test/CodeGen/Mips/mips16_32_10.ll @@ -0,0 +1,59 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=static -O3 < %s -mips-mixed-16-32 | FileCheck %s -check-prefix=16 + +define void @foo() #0 { +entry: + ret void +} +; 16: .set nomips16 # @foo +; 16: .ent foo +; 16: .set noreorder +; 16: .set nomacro +; 16: .set noat +; 16: jr $ra +; 16: nop +; 16: .set at +; 16: .set macro +; 16: .set reorder +; 16: .end foo + +define void @nofoo() #1 { +entry: + ret void +} + +; 16: .set mips16 # @nofoo +; 16: .ent nofoo + +; 16: save {{.+}} +; 16: restore {{.+}} +; 16: .end nofoo + +define i32 @main() #2 { +entry: + ret i32 0 +} + +; 16: .set nomips16 # @main +; 16: .ent main +; 16: .set noreorder +; 16: .set nomacro +; 16: .set noat +; 16: jr $ra +; 16: .set at +; 16: .set macro +; 16: .set reorder +; 16: .end main + + + + + + + + + + + +attributes #0 = { nounwind "less-precise-fpmad"="false" "nomips16" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind "less-precise-fpmad"="false" "nomips16" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/llvm/test/CodeGen/Mips/mips16_32_3.ll b/llvm/test/CodeGen/Mips/mips16_32_3.ll new file mode 100644 index 0000000000000000000000000000000000000000..8874a887253448c69938a168f4e3ce8205059f76 --- /dev/null +++ b/llvm/test/CodeGen/Mips/mips16_32_3.ll @@ -0,0 +1,70 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=static -O3 < %s -mips-mixed-16-32 | FileCheck %s -check-prefix=16 +; RUN: llc -march=mipsel -mcpu=mips32 -relocation-model=static -O3 < %s -mips-mixed-16-32 | FileCheck %s -check-prefix=32 + +define void @foo() #0 { +entry: + ret void +} + +; 16: .set mips16 # @foo +; 16: .ent foo +; 16: save {{.+}} +; 16: restore {{.+}} +; 16: .end foo +; 32: .set mips16 # @foo +; 32: .ent foo +; 32: save {{.+}} +; 32: restore {{.+}} +; 32: .end foo +define void @nofoo() #1 { +entry: + ret void +} + +; 16: .set nomips16 # @nofoo +; 16: .ent nofoo +; 16: .set noreorder +; 16: .set nomacro +; 16: .set noat +; 16: jr $ra +; 16: nop +; 16: .set at +; 16: .set macro +; 16: .set reorder +; 16: .end nofoo +; 32: .set nomips16 # @nofoo +; 32: .ent nofoo +; 32: .set noreorder +; 32: .set nomacro +; 32: .set noat +; 32: jr $ra +; 32: nop +; 32: .set at +; 32: .set macro +; 32: .set reorder +; 32: .end nofoo +define i32 @main() #2 { +entry: + ret i32 0 +} + +; 16: .set mips16 # @main +; 16: .ent main +; 16: save {{.+}} +; 16: restore {{.+}} +; 16: .end main +; 32: .set nomips16 # @main +; 32: .ent main +; 32: .set noreorder +; 32: .set nomacro +; 32: .set noat +; 32: jr $ra +; 32: addiu $2, $zero, 0 +; 32: .set at +; 32: .set macro +; 32: .set reorder +; 32: .end main + +attributes #0 = { nounwind "less-precise-fpmad"="false" "mips16" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "nomips16" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/llvm/test/CodeGen/Mips/mips16_32_4.ll b/llvm/test/CodeGen/Mips/mips16_32_4.ll new file mode 100644 index 0000000000000000000000000000000000000000..cdaed6c71be0962af06b4af69ef5d8d639c2066b --- /dev/null +++ b/llvm/test/CodeGen/Mips/mips16_32_4.ll @@ -0,0 +1,65 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=static -O3 < %s -mips-mixed-16-32 | FileCheck %s -check-prefix=16 +; RUN: llc -march=mipsel -mcpu=mips32 -relocation-model=static -O3 < %s -mips-mixed-16-32 | FileCheck %s -check-prefix=32 + +define void @foo() #0 { +entry: + ret void +} + +; 16: .set mips16 # @foo +; 16: .ent foo +; 16: save {{.+}} +; 16: restore {{.+}} +; 16: .end foo +; 32: .set mips16 # @foo +; 32: .ent foo +; 32: save {{.+}} +; 32: restore {{.+}} +; 32: .end foo +define void @nofoo() #1 { +entry: + ret void +} + +; 16: .set nomips16 # @nofoo +; 16: .ent nofoo +; 16: .set noreorder +; 16: .set nomacro +; 16: .set noat +; 16: jr $ra +; 16: nop +; 16: .set at +; 16: .set macro +; 16: .set reorder +; 16: .end nofoo +; 32: .set nomips16 # @nofoo +; 32: .ent nofoo +; 32: .set noreorder +; 32: .set nomacro +; 32: .set noat +; 32: jr $ra +; 32: nop +; 32: .set at +; 32: .set macro +; 32: .set reorder +; 32: .end nofoo +define i32 @main() #2 { +entry: + ret i32 0 +} + +; 16: .set mips16 # @main +; 16: .ent main +; 16: save {{.+}} +; 16: restore {{.+}} +; 16: .end main +; 32: .set mips16 # @main +; 32: .ent main +; 32: save {{.+}} +; 32: restore {{.+}} +; 32: .end main + + +attributes #0 = { nounwind "less-precise-fpmad"="false" "mips16" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "nomips16" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind "less-precise-fpmad"="false" "mips16" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/llvm/test/CodeGen/Mips/mips16_32_5.ll b/llvm/test/CodeGen/Mips/mips16_32_5.ll new file mode 100644 index 0000000000000000000000000000000000000000..45e0bf49ddd2eb6f4b7f33f391ab639e5e7e271a --- /dev/null +++ b/llvm/test/CodeGen/Mips/mips16_32_5.ll @@ -0,0 +1,80 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=static -O3 < %s -mips-mixed-16-32 | FileCheck %s -check-prefix=16 +; RUN: llc -march=mipsel -mcpu=mips32 -relocation-model=static -O3 < %s -mips-mixed-16-32 | FileCheck %s -check-prefix=32 + +define void @foo() #0 { +entry: + ret void +} + +; 16: .set mips16 # @foo +; 16: .ent foo +; 16: save {{.+}} +; 16: restore {{.+}} +; 16: .end foo +; 32: .set mips16 # @foo +; 32: .ent foo +; 32: save {{.+}} +; 32: restore {{.+}} +; 32: .end foo +define void @nofoo() #1 { +entry: + ret void +} + +; 16: .set nomips16 # @nofoo +; 16: .ent nofoo +; 16: .set noreorder +; 16: .set nomacro +; 16: .set noat +; 16: jr $ra +; 16: nop +; 16: .set at +; 16: .set macro +; 16: .set reorder +; 16: .end nofoo +; 32: .set nomips16 # @nofoo +; 32: .ent nofoo +; 32: .set noreorder +; 32: .set nomacro +; 32: .set noat +; 32: jr $ra +; 32: nop +; 32: .set at +; 32: .set macro +; 32: .set reorder +; 32: .end nofoo +define i32 @main() #2 { +entry: + ret i32 0 +} + +; 16: .set nomips16 # @main +; 16: .ent main +; 16: .set noreorder +; 16: .set nomacro +; 16: .set noat +; 16: jr $ra +; 16: addiu $2, $zero, 0 +; 16: .set at +; 16: .set macro +; 16: .set reorder +; 16: .end main + +; 32: .set nomips16 # @main +; 32: .ent main +; 32: .set noreorder +; 32: .set nomacro +; 32: .set noat +; 32: jr $ra +; 32: addiu $2, $zero, 0 +; 32: .set at +; 32: .set macro +; 32: .set reorder +; 32: .end main + + + + +attributes #0 = { nounwind "less-precise-fpmad"="false" "mips16" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "nomips16" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind "less-precise-fpmad"="false" "nomips16" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/llvm/test/CodeGen/Mips/mips16_32_6.ll b/llvm/test/CodeGen/Mips/mips16_32_6.ll new file mode 100644 index 0000000000000000000000000000000000000000..f4b8e7a91adcadda5e9780ab60c2231e869aec74 --- /dev/null +++ b/llvm/test/CodeGen/Mips/mips16_32_6.ll @@ -0,0 +1,86 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=static -O3 < %s -mips-mixed-16-32 | FileCheck %s -check-prefix=16 +; RUN: llc -march=mipsel -mcpu=mips32 -relocation-model=static -O3 < %s -mips-mixed-16-32 | FileCheck %s -check-prefix=32 + +define void @foo() #0 { +entry: + ret void +} + +; 16: .set mips16 # @foo +; 16: .ent foo +; 16: save {{.+}} +; 16: restore {{.+}} +; 16: .end foo +; 32: .set nomips16 # @foo +; 32: .ent foo +; 32: .set noreorder +; 32: .set nomacro +; 32: .set noat +; 32: jr $ra +; 32: nop +; 32: .set at +; 32: .set macro +; 32: .set reorder +; 32: .end foo +define void @nofoo() #1 { +entry: + ret void +} + +; 16: .set nomips16 # @nofoo +; 16: .ent nofoo +; 16: .set noreorder +; 16: .set nomacro +; 16: .set noat +; 16: jr $ra +; 16: nop +; 16: .set at +; 16: .set macro +; 16: .set reorder +; 16: .end nofoo +; 32: .set nomips16 # @nofoo +; 32: .ent nofoo +; 32: .set noreorder +; 32: .set nomacro +; 32: .set noat +; 32: jr $ra +; 32: nop +; 32: .set at +; 32: .set macro +; 32: .set reorder +; 32: .end nofoo +define i32 @main() #2 { +entry: + ret i32 0 +} + +; 16: .set nomips16 # @main +; 16: .ent main +; 16: .set noreorder +; 16: .set nomacro +; 16: .set noat +; 16: jr $ra +; 16: addiu $2, $zero, 0 +; 16: .set at +; 16: .set macro +; 16: .set reorder +; 16: .end main + +; 32: .set nomips16 # @main +; 32: .ent main +; 32: .set noreorder +; 32: .set nomacro +; 32: .set noat +; 32: jr $ra +; 32: addiu $2, $zero, 0 +; 32: .set at +; 32: .set macro +; 32: .set reorder +; 32: .end main + + + + +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "nomips16" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind "less-precise-fpmad"="false" "nomips16" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/llvm/test/CodeGen/Mips/mips16_32_7.ll b/llvm/test/CodeGen/Mips/mips16_32_7.ll new file mode 100644 index 0000000000000000000000000000000000000000..f8726eadc70ccfcabc48a8cc9f5f72db848dca07 --- /dev/null +++ b/llvm/test/CodeGen/Mips/mips16_32_7.ll @@ -0,0 +1,76 @@ +; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=static -O3 < %s -mips-mixed-16-32 | FileCheck %s -check-prefix=16 +; RUN: llc -march=mipsel -mcpu=mips32 -relocation-model=static -O3 < %s -mips-mixed-16-32 | FileCheck %s -check-prefix=32 + +define void @foo() #0 { +entry: + ret void +} + +; 16: .set mips16 # @foo +; 16: .ent foo +; 16: save {{.+}} +; 16: restore {{.+}} +; 16: .end foo +; 32: .set nomips16 # @foo +; 32: .ent foo +; 32: .set noreorder +; 32: .set nomacro +; 32: .set noat +; 32: jr $ra +; 32: nop +; 32: .set at +; 32: .set macro +; 32: .set reorder +; 32: .end foo +define void @nofoo() #1 { +entry: + ret void +} + +; 16: .set nomips16 # @nofoo +; 16: .ent nofoo +; 16: .set noreorder +; 16: .set nomacro +; 16: .set noat +; 16: jr $ra +; 16: nop +; 16: .set at +; 16: .set macro +; 16: .set reorder +; 16: .end nofoo +; 32: .set nomips16 # @nofoo +; 32: .ent nofoo +; 32: .set noreorder +; 32: .set nomacro +; 32: .set noat +; 32: jr $ra +; 32: nop +; 32: .set at +; 32: .set macro +; 32: .set reorder +; 32: .end nofoo +define i32 @main() #2 { +entry: + ret i32 0 +} + +; 16: .set mips16 # @main +; 16: .ent main +; 16: save {{.+}} +; 16: restore {{.+}} +; 16: .end main + +; 32: .set mips16 # @main +; 32: .ent main +; 32: save {{.+}} +; 32: restore {{.+}} +; 32: .end main + + + + + + +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "nomips16" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind "less-precise-fpmad"="false" "mips16" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/llvm/test/CodeGen/Mips/mips16_32_8.ll b/llvm/test/CodeGen/Mips/mips16_32_8.ll new file mode 100644 index 0000000000000000000000000000000000000000..e51f296f9df3fff134ac8b0c185fea5286c7aab8 --- /dev/null +++ b/llvm/test/CodeGen/Mips/mips16_32_8.ll @@ -0,0 +1,74 @@ +; RUN: llc -march=mipsel -mcpu=mips32 -relocation-model=static -O3 < %s -mips-mixed-16-32 | FileCheck %s -check-prefix=32 + +@x = global float 1.000000e+00, align 4 +@y = global float 0x4007333340000000, align 4 +@i = common global i32 0, align 4 +@f = common global float 0.000000e+00, align 4 +@.str = private unnamed_addr constant [8 x i8] c"f = %f\0A\00", align 1 +@.str1 = private unnamed_addr constant [11 x i8] c"hello %i \0A\00", align 1 +@.str2 = private unnamed_addr constant [13 x i8] c"goodbye %i \0A\00", align 1 + +define void @foo() #0 { +entry: + store i32 10, i32* @i, align 4 + ret void +} + +; 32: .set mips16 # @foo +; 32: .ent foo +; 32: save {{.+}} +; 32: restore {{.+}} +; 32: .end foo + +define void @nofoo() #1 { +entry: + store i32 20, i32* @i, align 4 + %0 = load float* @x, align 4 + %1 = load float* @y, align 4 + %add = fadd float %0, %1 + store float %add, float* @f, align 4 + %2 = load float* @f, align 4 + %conv = fpext float %2 to double + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([8 x i8]* @.str, i32 0, i32 0), double %conv) + ret void +} + +; 32: .set nomips16 # @nofoo +; 32: .ent nofoo +; 32: .set noreorder +; 32: .set nomacro +; 32: .set noat +; 32: add.s {{.+}} +; 32: mfc1 {{.+}} +; 32: .set at +; 32: .set macro +; 32: .set reorder +; 32: .end nofoo +declare i32 @printf(i8*, ...) #2 + +define i32 @main() #3 { +entry: + call void @foo() + %0 = load i32* @i, align 4 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([11 x i8]* @.str1, i32 0, i32 0), i32 %0) + call void @nofoo() + %1 = load i32* @i, align 4 + %call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @.str2, i32 0, i32 0), i32 %1) + ret i32 0 +} + +; 32: .set nomips16 # @main +; 32: .ent main +; 32: .set noreorder +; 32: .set nomacro +; 32: .set noat +; 32: jr $ra +; 32: .set at +; 32: .set macro +; 32: .set reorder +; 32: .end main + +attributes #0 = { nounwind "less-precise-fpmad"="false" "mips16" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "nomips16" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #3 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/llvm/test/CodeGen/Mips/mips16_32_9.ll b/llvm/test/CodeGen/Mips/mips16_32_9.ll new file mode 100644 index 0000000000000000000000000000000000000000..f5ff3684901551c5c4e190ecaedd7cdc64f966be --- /dev/null +++ b/llvm/test/CodeGen/Mips/mips16_32_9.ll @@ -0,0 +1,51 @@ +; RUN: llc -march=mipsel -mcpu=mips32 -relocation-model=static -O3 < %s -mips-mixed-16-32 | FileCheck %s -check-prefix=32 + +define void @foo() #0 { +entry: + ret void +} + +; 32: .set mips16 # @foo +; 32: .ent foo +; 32: save {{.+}} +; 32: restore {{.+}} +; 32: .end foo +define void @nofoo() #1 { +entry: + ret void +} + +; 32: .set nomips16 # @nofoo +; 32: .ent nofoo +; 32: .set noreorder +; 32: .set nomacro +; 32: .set noat +; 32: jr $ra +; 32: nop +; 32: .set at +; 32: .set macro +; 32: .set reorder +; 32: .end nofoo +define i32 @main() #2 { +entry: + ret i32 0 +} + +; 32: .set mips16 # @main +; 32: .ent main +; 32: save {{.+}} +; 32: restore {{.+}} +; 32: .end main + + + + + + + + + + +attributes #0 = { nounwind "less-precise-fpmad"="false" "mips16" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind "less-precise-fpmad"="false" "mips16" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }