[llvm] r181641 - Checkin in of first of several patches to finish implementation of

Pete Cooper peter_cooper at apple.com
Fri May 10 16:43:16 PDT 2013


Hi Reed

This is breaking the buildbot.  Can you please take a look?

http://lab.llvm.org:8013/builders/clang-x86_64-darwin11-nobootstrap-RAincremental/builds/1578

Thanks,
Pete
On May 10, 2013, at 3:25 PM, Reed Kotler <rkotler at mips.com> wrote:

> Author: rkotler
> Date: Fri May 10 17:25:39 2013
> New Revision: 181641
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=181641&view=rev
> Log:
> Checkin in of first of several patches to finish implementation of
> mips16/mips32 floating point interoperability. 
> 
> This patch fixes returns from mips16 functions so that if the function
> was in fact called by a mips32 hard float routine, then values
> that would have been returned in floating point registers are so returned.
> 
> Mips16 mode has no floating point instructions so there is no way to
> load values into floating point registers.
> 
> This is needed when returning float, double, single complex, double complex
> in the Mips ABI.
> 
> Helper functions in libc for mips16 are available to do this.
> 
> For efficiency purposes, these helper functions have a different calling
> convention from normal Mips calls.
> 
> Registers v0,v1,a0,a1 are used to pass parameters instead of
> a0,a1,a2,a3.
> 
> This is because v0,v1,a0,a1 are the natural registers used to return
> floating point values in soft float. These values can then be moved
> to the appropriate floating point registers with no extra cost.
> 
> The only register that is modified is ra in this call.
> 
> The helper functions make sure that the return values are in the floating
> point registers that they would be in if soft float was not in effect
> (which it is for mips16, though the soft float is implemented using a mips32
> library that uses hard float).
> 
> 
> Added:
>    llvm/trunk/lib/Target/Mips/Mips16HardFloat.cpp
>    llvm/trunk/lib/Target/Mips/Mips16HardFloat.h
>    llvm/trunk/test/CodeGen/Mips/mips16_fpret.ll
> Modified:
>    llvm/trunk/lib/Target/Mips/CMakeLists.txt
>    llvm/trunk/lib/Target/Mips/Mips16ISelLowering.cpp
>    llvm/trunk/lib/Target/Mips/MipsCallingConv.td
>    llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
>    llvm/trunk/lib/Target/Mips/MipsISelLowering.h
>    llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp
>    llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h
>    llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp
>    llvm/trunk/lib/Target/Mips/MipsSubtarget.h
>    llvm/trunk/lib/Target/Mips/MipsTargetMachine.cpp
> 
> Modified: llvm/trunk/lib/Target/Mips/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/CMakeLists.txt?rev=181641&r1=181640&r2=181641&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/CMakeLists.txt (original)
> +++ llvm/trunk/lib/Target/Mips/CMakeLists.txt Fri May 10 17:25:39 2013
> @@ -15,6 +15,7 @@ add_public_tablegen_target(MipsCommonTab
> 
> add_llvm_target(MipsCodeGen
>   Mips16FrameLowering.cpp
> +  Mips16HardFloat.cpp
>   Mips16InstrInfo.cpp
>   Mips16ISelDAGToDAG.cpp
>   Mips16ISelLowering.cpp
> 
> Added: llvm/trunk/lib/Target/Mips/Mips16HardFloat.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips16HardFloat.cpp?rev=181641&view=auto
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/Mips16HardFloat.cpp (added)
> +++ llvm/trunk/lib/Target/Mips/Mips16HardFloat.cpp Fri May 10 17:25:39 2013
> @@ -0,0 +1,141 @@
> +//===---- Mips16HardFloat.cpp for Mips16 Hard Float               --------===//
> +//
> +//                     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 needed for Mips16 Hard Float
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#define DEBUG_TYPE "mips16-hard-float"
> +#include "Mips16HardFloat.h"
> +#include "llvm/IR/Module.h"
> +#include "llvm/Support/Debug.h"
> +#include "llvm/Support/raw_ostream.h"
> +#include <string>
> +
> +//
> +// Return types that matter for hard float are:
> +// float, double, complex float, and complex double
> +//
> +enum FPReturnVariant {
> +  FRet, DRet, CFRet, CDRet, NoFPRet
> +};
> +
> +//
> +// Determine which FP return type this function has
> +//
> +static FPReturnVariant whichFPReturnVariant(Type *T) {
> +  switch (T->getTypeID()) {
> +  case Type::FloatTyID:
> +    return FRet;
> +  case Type::DoubleTyID:
> +    return DRet;
> +  case Type::StructTyID:
> +    if (T->getStructNumElements() != 2)
> +      break;
> +    if ((T->getContainedType(0)->isFloatTy()) &&
> +        (T->getContainedType(1)->isFloatTy()))
> +      return CFRet;
> +    if ((T->getContainedType(0)->isDoubleTy()) &&
> +        (T->getContainedType(1)->isDoubleTy()))
> +      return CDRet;
> +    break;
> +  default:
> +    break;
> +  }
> +  return NoFPRet;
> +}
> +
> +//
> +// Returns of float, double and complex need to be handled with a helper
> +// function. The "AndCal" part is coming in a later patch.
> +//
> +static bool fixupFPReturnAndCall
> +  (Function &F, Module *M,  const MipsSubtarget &Subtarget) {
> +  bool Modified = false;
> +  LLVMContext &C = M->getContext();
> +  Type *MyVoid = Type::getVoidTy(C);
> +  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
> +    for (BasicBlock::iterator I = BB->begin(), E = BB->end();
> +         I != E; ++I) {
> +      Instruction &Inst = *I;
> +      if (const ReturnInst *RI = dyn_cast<ReturnInst>(I)) {
> +        Value *RVal = RI->getReturnValue();
> +        if (!RVal) continue;
> +        //
> +        // If there is a return value and it needs a helper function,
> +        // figure out which one and add a call before the actual
> +        // return to this helper. The purpose of the helper is to move
> +        // floating point values from their soft float return mapping to
> +        // where they would have been mapped to in floating point registers.
> +        //
> +        Type *T = RVal->getType();
> +        FPReturnVariant RV = whichFPReturnVariant(T);
> +        if (RV == NoFPRet) continue;
> +        static const char* Helper[NoFPRet] =
> +          {"__mips16_ret_sf", "__mips16_ret_df", "__mips16_ret_sc",
> +           "__mips16_ret_dc"};
> +        const char *Name = Helper[RV];
> +        AttributeSet A;
> +        Value *Params[] = {RVal};
> +        Modified = true;
> +        //
> +        // These helper functions have a different calling ABI so
> +        // this __Mips16RetHelper indicates that so that later
> +        // during call setup, the proper call lowering to the helper
> +        // functions will take place.
> +        //
> +        A = A.addAttribute(C, AttributeSet::FunctionIndex,
> +                           "__Mips16RetHelper");
> +        A = A.addAttribute(C, AttributeSet::FunctionIndex,
> +                           Attribute::ReadNone);
> +        Value *F = (M->getOrInsertFunction(Name, A, MyVoid, T, NULL));
> +        CallInst::Create(F, Params, "", &Inst );
> +      }
> +    }
> +  return Modified;
> +}
> +
> +namespace llvm {
> +
> +//
> +// This pass only makes sense when the underlying chip has floating point but
> +// we are compiling as mips16.
> +// For all mips16 functions (that are not stubs we have already generated), or
> +// declared via attributes as nomips16, we must:
> +//    1) fixup all returns of float, double, single and double complex
> +//       by calling a helper function before the actual return.
> +//    2) generate helper functions (stubs) that can be called by mips32 functions
> +//       that will move parameters passed normally passed in floating point
> +//       registers the soft float equivalents. (Coming in a later patch).
> +//    3) in the case of static relocation, generate helper functions so that
> +//       mips16 functions can call extern functions of unknown type (mips16 or
> +//       mips32). (Coming in a later patch).
> +//    4) TBD. For pic, calls to extern functions of unknown type are handled by
> +//       predefined helper functions in libc but this work is currently done
> +//       during call lowering but it should be moved here in the future.
> +//
> +bool Mips16HardFloat::runOnModule(Module &M) {
> +  DEBUG(errs() << "Run on Module Mips16HardFloat\n");
> +  bool Modified = false;
> +  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
> +    if (F->isDeclaration() || F->hasFnAttribute("mips16_fp_stub") ||
> +        F->hasFnAttribute("nomips16")) continue;
> +    Modified |= fixupFPReturnAndCall(*F, &M, Subtarget);
> +  }
> +  return Modified;
> +}
> +
> +char Mips16HardFloat::ID = 0;
> +
> +}
> +
> +ModulePass *llvm::createMips16HardFloat(MipsTargetMachine &TM) {
> +  return new Mips16HardFloat(TM);
> +}
> +
> 
> Added: llvm/trunk/lib/Target/Mips/Mips16HardFloat.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips16HardFloat.h?rev=181641&view=auto
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/Mips16HardFloat.h (added)
> +++ llvm/trunk/lib/Target/Mips/Mips16HardFloat.h Fri May 10 17:25:39 2013
> @@ -0,0 +1,54 @@
> +//===---- Mips16HardFloat.h for Mips16 Hard Float                  --------===//
> +//
> +//                     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 phase which implements part of the floating point
> +// interoperability between Mips16 and Mips32 code.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "MCTargetDesc/MipsMCTargetDesc.h"
> +#include "MipsTargetMachine.h"
> +#include "llvm/Pass.h"
> +#include "llvm/Target/TargetMachine.h"
> +
> +
> +#ifndef MIPS16HARDFLOAT_H
> +#define MIPS16HARDFLOAT_H
> +
> +using namespace llvm;
> +
> +namespace llvm {
> +
> +class Mips16HardFloat : public ModulePass {
> +
> +public:
> +  static char ID;
> +
> +  Mips16HardFloat(MipsTargetMachine &TM_) : ModulePass(ID),
> +    TM(TM_), Subtarget(TM.getSubtarget<MipsSubtarget>()) {
> +  }
> +
> +  virtual const char *getPassName() const {
> +    return "MIPS16 Hard Float Pass";
> +  }
> +
> +  virtual bool runOnModule(Module &M);
> +
> +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;
> +
> +};
> +
> +ModulePass *createMips16HardFloat(MipsTargetMachine &TM);
> +
> +}
> +#endif
> 
> Modified: llvm/trunk/lib/Target/Mips/Mips16ISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips16ISelLowering.cpp?rev=181641&r1=181640&r2=181641&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/Mips16ISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/Mips/Mips16ISelLowering.cpp Fri May 10 17:25:39 2013
> @@ -13,6 +13,7 @@
> #define DEBUG_TYPE "mips-lower"
> #include "Mips16ISelLowering.h"
> #include "MipsRegisterInfo.h"
> +#include "MipsTargetMachine.h"
> #include "MCTargetDesc/MipsBaseInfo.h"
> #include "llvm/CodeGen/MachineInstrBuilder.h"
> #include "llvm/Support/CommandLine.h"
> @@ -21,11 +22,6 @@
> 
> using namespace llvm;
> 
> -static cl::opt<bool>
> -Mips16HardFloat("mips16-hard-float", cl::NotHidden,
> -                cl::desc("MIPS: mips16 hard float enable."),
> -                cl::init(false));
> -
> static cl::opt<bool> DontExpandCondPseudos16(
>   "mips16-dont-expand-cond-pseudo",
>   cl::init(false),
> @@ -50,7 +46,7 @@ Mips16TargetLowering::Mips16TargetLoweri
>   // Set up the register classes
>   addRegisterClass(MVT::i32, &Mips::CPU16RegsRegClass);
> 
> -  if (Mips16HardFloat)
> +  if (Subtarget->inMips16HardFloat())
>     setMips16HardFloatLibCalls();
> 
>   setOperationAction(ISD::ATOMIC_FENCE,       MVT::Other, Expand);
> @@ -374,7 +370,8 @@ getOpndList(SmallVectorImpl<SDValue> &Op
>   const char* Mips16HelperFunction = 0;
>   bool NeedMips16Helper = false;
> 
> -  if (getTargetMachine().Options.UseSoftFloat && Mips16HardFloat) {
> +  if (getTargetMachine().Options.UseSoftFloat &&
> +      Subtarget->inMips16HardFloat()) {
>     //
>     // currently we don't have symbols tagged with the mips16 or mips32
>     // qualifier so we will assume that we don't know what kind it is.
> 
> Modified: llvm/trunk/lib/Target/Mips/MipsCallingConv.td
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsCallingConv.td?rev=181641&r1=181640&r2=181641&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/MipsCallingConv.td (original)
> +++ llvm/trunk/lib/Target/Mips/MipsCallingConv.td Fri May 10 17:25:39 2013
> @@ -196,6 +196,13 @@ def CC_Mips_FastCC : CallingConv<[
>   CCDelegateTo<CC_MipsN_FastCC>
> ]>;
> 
> +//==
> +
> +def CC_Mips16RetHelper : CallingConv<[
> +  // Integer arguments are passed in integer registers.
> +  CCIfType<[i32], CCAssignToReg<[V0, V1, A0, A1]>>
> +]>;
> +
> //===----------------------------------------------------------------------===//
> // Mips Calling Convention Dispatch
> //===----------------------------------------------------------------------===//
> @@ -223,3 +230,6 @@ def CSR_N32 : CalleeSavedRegs<(add D31_6
> 
> def CSR_N64 : CalleeSavedRegs<(add (sequence "D%u_64", 31, 24), RA_64, FP_64,
>                                    GP_64, (sequence "S%u_64", 7, 0))>;
> +
> +def CSR_Mips16RetHelper : 
> +  CalleeSavedRegs<(add V0, V1, (sequence "A%u", 3, 0), S0, S1)>;
> 
> Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=181641&r1=181640&r2=181641&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Fri May 10 17:25:39 2013
> @@ -2229,6 +2229,15 @@ getOpndList(SmallVectorImpl<SDValue> &Op
>   const TargetRegisterInfo *TRI = getTargetMachine().getRegisterInfo();
>   const uint32_t *Mask = TRI->getCallPreservedMask(CLI.CallConv);
>   assert(Mask && "Missing call preserved mask for calling convention");
> +  if (Subtarget->inMips16HardFloat()) {
> +    if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
> +      llvm::StringRef Sym = G->getGlobal()->getName();
> +      Function *F = G->getGlobal()->getParent()->getFunction(Sym);
> +      if (F->hasFnAttribute("__Mips16RetHelper")) {
> +        Mask = MipsRegisterInfo::getMips16RetHelperMask();
> +      }
> +    }
> +  }
>   Ops.push_back(CLI.DAG.getRegisterMask(Mask));
> 
>   if (InFlag.getNode())
> @@ -2260,7 +2269,9 @@ MipsTargetLowering::LowerCall(TargetLowe
>   SmallVector<CCValAssign, 16> ArgLocs;
>   CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),
>                  getTargetMachine(), ArgLocs, *DAG.getContext());
> -  MipsCC MipsCCInfo(CallConv, IsO32, CCInfo);
> +  MipsCC::SpecialCallingConvType SpecialCallingConv =
> +    getSpecialCallingConv(Callee);
> +  MipsCC MipsCCInfo(CallConv, IsO32, CCInfo, SpecialCallingConv);
> 
>   MipsCCInfo.analyzeCallOperands(Outs, IsVarArg,
>                                  getTargetMachine().Options.UseSoftFloat,
> @@ -3029,13 +3040,32 @@ static bool originalTypeIsF128(const Typ
>   return (ES && Ty->isIntegerTy(128) && isF128SoftLibCall(ES->getSymbol()));
> }
> 
> -MipsTargetLowering::MipsCC::MipsCC(CallingConv::ID CC, bool IsO32_,
> -                                   CCState &Info)
> -  : CCInfo(Info), CallConv(CC), IsO32(IsO32_) {
> +MipsTargetLowering::MipsCC::SpecialCallingConvType
> +  MipsTargetLowering::getSpecialCallingConv(SDValue Callee) const {
> +  MipsCC::SpecialCallingConvType SpecialCallingConv =
> +    MipsCC::NoSpecialCallingConv;;
> +  if (Subtarget->inMips16HardFloat()) {
> +    if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
> +      llvm::StringRef Sym = G->getGlobal()->getName();
> +      Function *F = G->getGlobal()->getParent()->getFunction(Sym);
> +      if (F->hasFnAttribute("__Mips16RetHelper")) {
> +        SpecialCallingConv = MipsCC::Mips16RetHelperConv;
> +      }
> +    }
> +  }
> +  return SpecialCallingConv;
> +}
> +
> +MipsTargetLowering::MipsCC::MipsCC(
> +  CallingConv::ID CC, bool IsO32_, CCState &Info,
> +    MipsCC::SpecialCallingConvType SpecialCallingConv_)
> +  : CCInfo(Info), CallConv(CC), IsO32(IsO32_),
> +    SpecialCallingConv(SpecialCallingConv_){
>   // Pre-allocate reserved argument area.
>   CCInfo.AllocateStack(reservedArgArea(), 1);
> }
> 
> +
> void MipsTargetLowering::MipsCC::
> analyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Args,
>                     bool IsVarArg, bool IsSoftFloat, const SDNode *CallNode,
> @@ -3183,6 +3213,8 @@ llvm::CCAssignFn *MipsTargetLowering::Mi
>   if (CallConv == CallingConv::Fast)
>     return CC_Mips_FastCC;
> 
> +  if (SpecialCallingConv == Mips16RetHelperConv)
> +    return CC_Mips16RetHelper;
>   return IsO32 ? CC_MipsO32 : CC_MipsN;
> }
> 
> 
> Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.h?rev=181641&r1=181640&r2=181641&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/MipsISelLowering.h (original)
> +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.h Fri May 10 17:25:39 2013
> @@ -240,7 +240,14 @@ namespace llvm {
>     /// arguments and inquire about calling convention information.
>     class MipsCC {
>     public:
> -      MipsCC(CallingConv::ID CallConv, bool IsO32, CCState &Info);
> +      enum SpecialCallingConvType {
> +        Mips16RetHelperConv, NoSpecialCallingConv
> +      };
> +
> +      MipsCC(
> +        CallingConv::ID CallConv, bool IsO32, CCState &Info,
> +        SpecialCallingConvType SpecialCallingConv = NoSpecialCallingConv);
> +
> 
>       void analyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs,
>                                bool IsVarArg, bool IsSoftFloat,
> @@ -313,15 +320,18 @@ namespace llvm {
>       CCState &CCInfo;
>       CallingConv::ID CallConv;
>       bool IsO32;
> +      SpecialCallingConvType SpecialCallingConv;
>       SmallVector<ByValArgInfo, 2> ByValArgs;
>     };
> -
> +  protected:
>     // Subtarget Info
>     const MipsSubtarget *Subtarget;
> 
>     bool HasMips64, IsN64, IsO32;
> 
>   private:
> +
> +    MipsCC::SpecialCallingConvType getSpecialCallingConv(SDValue Callee) const;
>     // Lower Operand helpers
>     SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
>                             CallingConv::ID CallConv, bool isVarArg,
> 
> Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp?rev=181641&r1=181640&r2=181641&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp (original)
> +++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp Fri May 10 17:25:39 2013
> @@ -100,6 +100,10 @@ MipsRegisterInfo::getCallPreservedMask(C
>   return CSR_N64_RegMask;
> }
> 
> +const uint32_t *MipsRegisterInfo::getMips16RetHelperMask() {
> +  return CSR_Mips16RetHelper_RegMask;
> +}
> +
> BitVector MipsRegisterInfo::
> getReservedRegs(const MachineFunction &MF) const {
>   static const uint16_t ReservedCPURegs[] = {
> 
> Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h?rev=181641&r1=181640&r2=181641&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h (original)
> +++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.h Fri May 10 17:25:39 2013
> @@ -46,6 +46,7 @@ public:
>                                MachineFunction &MF) const;
>   const uint16_t *getCalleeSavedRegs(const MachineFunction *MF = 0) const;
>   const uint32_t *getCallPreservedMask(CallingConv::ID) const;
> +  static const uint32_t *getMips16RetHelperMask();
> 
>   BitVector getReservedRegs(const MachineFunction &MF) const;
> 
> 
> Modified: llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp?rev=181641&r1=181640&r2=181641&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp (original)
> +++ llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp Fri May 10 17:25:39 2013
> @@ -48,6 +48,11 @@ static cl::opt<bool> Mips_Os16(
>            "floating point as Mips 16"),
>   cl::Hidden);
> 
> +static cl::opt<bool>
> +Mips16HardFloat("mips16-hard-float", cl::NotHidden,
> +                cl::desc("MIPS: mips16 hard float enable."),
> +                cl::init(false));
> +
> void MipsSubtarget::anchor() { }
> 
> MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU,
> @@ -58,7 +63,8 @@ MipsSubtarget::MipsSubtarget(const std::
>   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),
> +  InMips16Mode(false), InMips16HardFloat(Mips16HardFloat),
> +  InMicroMipsMode(false), HasDSP(false), HasDSPR2(false),
>   AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16),
>   RM(_RM), OverrideMode(NoOverride), TM(_TM)
> {
> 
> Modified: llvm/trunk/lib/Target/Mips/MipsSubtarget.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSubtarget.h?rev=181641&r1=181640&r2=181641&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/MipsSubtarget.h (original)
> +++ llvm/trunk/lib/Target/Mips/MipsSubtarget.h Fri May 10 17:25:39 2013
> @@ -93,6 +93,9 @@ protected:
>   // InMips16 -- can process Mips16 instructions
>   bool InMips16Mode;
> 
> +  // Mips16 hard float
> +  bool InMips16HardFloat;
> +
>   // PreviousInMips16 -- the function we just processed was in Mips 16 Mode
>   bool PreviousInMips16Mode;
> 
> @@ -170,9 +173,12 @@ public:
>     }
>     llvm_unreachable("Unexpected mode");
>   }
> -  bool inMips16ModeDefault() {
> +  bool inMips16ModeDefault() const {
>     return InMips16Mode;
>   }
> +  bool inMips16HardFloat() const {
> +    return inMips16Mode() && InMips16HardFloat;
> +  }
>   bool inMicroMipsMode() const { return InMicroMipsMode; }
>   bool hasDSP() const { return HasDSP; }
>   bool hasDSPR2() const { return HasDSPR2; }
> @@ -188,7 +194,8 @@ public:
>   bool hasBitCount()  const { return HasBitCount; }
>   bool hasFPIdx()     const { return HasFPIdx; }
> 
> -  bool allowMixed16_32() const { return AllowMixed16_32;};
> +  bool allowMixed16_32() const { return inMips16ModeDefault() |
> +                                        AllowMixed16_32;}
> 
>   bool os16() const { return Os16;};
> 
> 
> Modified: llvm/trunk/lib/Target/Mips/MipsTargetMachine.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsTargetMachine.cpp?rev=181641&r1=181640&r2=181641&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/MipsTargetMachine.cpp (original)
> +++ llvm/trunk/lib/Target/Mips/MipsTargetMachine.cpp Fri May 10 17:25:39 2013
> @@ -22,6 +22,7 @@
> #include "MipsSEISelLowering.h"
> #include "MipsSEISelDAGToDAG.h"
> #include "Mips16FrameLowering.h"
> +#include "Mips16HardFloat.h"
> #include "Mips16InstrInfo.h"
> #include "Mips16ISelDAGToDAG.h"
> #include "Mips16ISelLowering.h"
> @@ -156,6 +157,8 @@ void MipsPassConfig::addIRPasses() {
>   TargetPassConfig::addIRPasses();
>   if (getMipsSubtarget().os16())
>     addPass(createMipsOs16(getMipsTargetMachine()));
> +  if (getMipsSubtarget().inMips16HardFloat())
> +    addPass(createMips16HardFloat(getMipsTargetMachine()));
> }
> // Install an instruction selector pass using
> // the ISelDag to gen Mips code.
> 
> Added: llvm/trunk/test/CodeGen/Mips/mips16_fpret.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/mips16_fpret.ll?rev=181641&view=auto
> ==============================================================================
> --- llvm/trunk/test/CodeGen/Mips/mips16_fpret.ll (added)
> +++ llvm/trunk/test/CodeGen/Mips/mips16_fpret.ll Fri May 10 17:25:39 2013
> @@ -0,0 +1,77 @@
> +; RUN: llc -march=mipsel -mcpu=mips16 -soft-float -mips16-hard-float -relocation-model=static < %s | FileCheck %s -check-prefix=1
> +; RUN: llc -march=mipsel -mcpu=mips16 -soft-float -mips16-hard-float -relocation-model=static < %s | FileCheck %s -check-prefix=2
> +; RUN: llc -march=mipsel -mcpu=mips16 -soft-float -mips16-hard-float -relocation-model=static < %s | FileCheck %s -check-prefix=3
> +; RUN: llc -march=mipsel -mcpu=mips16 -soft-float -mips16-hard-float -relocation-model=static < %s | FileCheck %s -check-prefix=4
> +
> +
> + at x = global float 0x41F487E980000000, align 4
> + at dx = global double 0x41CDCC8BC4800000, align 8
> + at cx = global { float, float } { float 1.000000e+00, float 9.900000e+01 }, align 4
> + at dcx = global { double, double } { double 0x42CE5E14A412B480, double 0x423AA4C580DB0000 }, align 8
> +
> +define float @foox()  {
> +entry:
> +  %0 = load float* @x, align 4
> +  ret float %0
> +; 1: 	.ent	foox
> +; 1:	lw	$2, %lo(x)(${{[0-9]+}})
> +; 1:	jal	__mips16_ret_sf
> +}
> +
> +define double @foodx()  {
> +entry:
> +  %0 = load double* @dx, align 8
> +  ret double %0
> +; 1: 	.ent	foodx
> +; 1: 	lw	$2, %lo(dx)(${{[0-9]+}})
> +; 1:	jal	__mips16_ret_df
> +; 2: 	.ent	foodx
> +; 2:	lw	$3, 4(${{[0-9]+}})
> +; 2:	jal	__mips16_ret_df
> +
> +}
> +
> +define { float, float } @foocx()  {
> +entry:
> +  %retval = alloca { float, float }, align 4
> +  %cx.real = load float* getelementptr inbounds ({ float, float }* @cx, i32 0, i32 0)
> +  %cx.imag = load float* getelementptr inbounds ({ float, float }* @cx, i32 0, i32 1)
> +  %real = getelementptr inbounds { float, float }* %retval, i32 0, i32 0
> +  %imag = getelementptr inbounds { float, float }* %retval, i32 0, i32 1
> +  store float %cx.real, float* %real
> +  store float %cx.imag, float* %imag
> +  %0 = load { float, float }* %retval
> +  ret { float, float } %0
> +; 1: 	.ent	foocx
> +; 1: 	lw	$2, %lo(cx)(${{[0-9]+}})
> +; 1:	jal	__mips16_ret_sc
> +; 2: 	.ent	foocx
> +; 2:	lw	$3, 4(${{[0-9]+}})
> +; 2:	jal	__mips16_ret_sc
> +}
> +
> +define { double, double } @foodcx()  {
> +entry:
> +  %retval = alloca { double, double }, align 8
> +  %dcx.real = load double* getelementptr inbounds ({ double, double }* @dcx, i32 0, i32 0)
> +  %dcx.imag = load double* getelementptr inbounds ({ double, double }* @dcx, i32 0, i32 1)
> +  %real = getelementptr inbounds { double, double }* %retval, i32 0, i32 0
> +  %imag = getelementptr inbounds { double, double }* %retval, i32 0, i32 1
> +  store double %dcx.real, double* %real
> +  store double %dcx.imag, double* %imag
> +  %0 = load { double, double }* %retval
> +  ret { double, double } %0
> +; 1: 	.ent	foodcx
> +; 1: 	lw	$2, %lo(dcx)(${{[0-9]+}})
> +; 1:	jal	__mips16_ret_dc
> +; 2: 	.ent	foodcx
> +; 2:	lw	$3, 4(${{[0-9]+}})
> +; 2:	jal	__mips16_ret_dc
> +; 3: 	.ent	foodcx
> +; 3:	lw	$4, 8(${{[0-9]+}})
> +; 3:	jal	__mips16_ret_dc
> +; 4: 	.ent	foodcx
> +; 4:	lw	$5, 12(${{[0-9]+}})
> +; 4:	jal	__mips16_ret_dc
> +}
> +
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130510/2ab1bd7c/attachment.html>


More information about the llvm-commits mailing list