<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">Hi Reed<div><br></div><div>This is breaking the buildbot.  Can you please take a look?</div><div><br></div><div><a 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br><a 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></body></html>