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