Index: lib/Target/Mips/MipsCallingConv.td
===================================================================
--- lib/Target/Mips/MipsCallingConv.td
+++ lib/Target/Mips/MipsCallingConv.td
@@ -203,8 +203,13 @@
       CCAssignToReg<[A0, A1, A2, A3, T0, T1, T2, T3, T4, T5, V1]>>>,
 
   // f32 arguments are passed in single-precision floating pointer registers.
-  CCIfType<[f32], CCAssignToReg<[F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10,
-                                 F11, F12, F13, F14, F15, F16, F17, F18, F19]>>,
+  CCIfType<[f32], CCIfSubtarget<"useOddSPReg()",
+      CCAssignToReg<[F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13,
+                     F14, F15, F16, F17, F18, F19]>>>,
+
+  // Don't use odd numbered single-precision registers for -mno-odd-spreg.
+  CCIfType<[f32], CCIfSubtarget<"noOddSPReg()",
+      CCAssignToReg<[F0, F2, F4, F6, F8, F10, F12, F14, F16, F18]>>>,
 
   // Stack parameter slots for i32 and f32 are 32-bit words and 4-byte aligned.
   CCIfType<[i32, f32], CCAssignToStack<4, 4>>,
Index: lib/Target/Mips/MipsSubtarget.h
===================================================================
--- lib/Target/Mips/MipsSubtarget.h
+++ lib/Target/Mips/MipsSubtarget.h
@@ -203,6 +203,7 @@
   bool isFPXX() const { return IsFPXX; }
   bool isFP64bit() const { return IsFP64bit; }
   bool useOddSPReg() const { return UseOddSPReg; }
+  bool noOddSPReg() const { return !UseOddSPReg; }
   bool isNaN2008() const { return IsNaN2008bit; }
   bool isNotFP64bit() const { return !IsFP64bit; }
   bool isGP64bit() const { return IsGP64bit; }
Index: test/CodeGen/Mips/fastcc.ll
===================================================================
--- test/CodeGen/Mips/fastcc.ll
+++ test/CodeGen/Mips/fastcc.ll
@@ -1,6 +1,7 @@
 ; RUN: llc  < %s -march=mipsel | FileCheck %s 
 ; RUN: llc  < %s -mtriple=mipsel-none-nacl-gnu \
 ; RUN:  | FileCheck %s -check-prefix=CHECK-NACL
+; RUN: llc  < %s -march=mipsel -mcpu=mips32 -mattr=+nooddspreg | FileCheck %s -check-prefix=NOODDSPREG
 
 
 @gi0 = external global i32
@@ -264,3 +265,110 @@
   ret void
 }
 
+define void @caller2(float %a0, float %a1, float %a2, float %a3, float %a4,
+                     float %a5, float %a6, float %a7, float %a8, float %a9,
+                     float %a10) {
+entry:
+
+; NOODDSPREG-LABEL:  caller2
+
+; Check that first 10 arguments are passed in even float registers
+; f0, f2, ... , f18. Check that 11th argument is passed on stack.
+
+; NOODDSPREG-DAG:    lw $[[R0:[0-9]+]], %got(gfa0)($[[GP:[0-9]+|gp]])
+; NOODDSPREG-DAG:    lwc1 $f0, 0($[[R0]])
+; NOODDSPREG-DAG:    lw $[[R0:[0-9]+]], %got(gfa1)($[[GP]])
+; NOODDSPREG-DAG:    lwc1 $f2, 0($[[R0]])
+; NOODDSPREG-DAG:    lw $[[R0:[0-9]+]], %got(gfa2)($[[GP]])
+; NOODDSPREG-DAG:    lwc1 $f4, 0($[[R0]])
+; NOODDSPREG-DAG:    lw $[[R0:[0-9]+]], %got(gfa3)($[[GP]])
+; NOODDSPREG-DAG:    lwc1 $f6, 0($[[R0]])
+; NOODDSPREG-DAG:    lw $[[R0:[0-9]+]], %got(gfa4)($[[GP]])
+; NOODDSPREG-DAG:    lwc1 $f8, 0($[[R0]])
+; NOODDSPREG-DAG:    lw $[[R0:[0-9]+]], %got(gfa5)($[[GP]])
+; NOODDSPREG-DAG:    lwc1 $f10, 0($[[R0]])
+; NOODDSPREG-DAG:    lw $[[R0:[0-9]+]], %got(gfa6)($[[GP]])
+; NOODDSPREG-DAG:    lwc1 $f12, 0($[[R0]])
+; NOODDSPREG-DAG:    lw $[[R0:[0-9]+]], %got(gfa7)($[[GP]])
+; NOODDSPREG-DAG:    lwc1 $f14, 0($[[R0]])
+; NOODDSPREG-DAG:    lw $[[R0:[0-9]+]], %got(gfa8)($[[GP]])
+; NOODDSPREG-DAG:    lwc1 $f16, 0($[[R0]])
+; NOODDSPREG-DAG:    lw $[[R0:[0-9]+]], %got(gfa9)($[[GP]])
+; NOODDSPREG-DAG:    lwc1 $f18, 0($[[R0]])
+
+; I omitted DAG from the following 3 lines because otherwise the pattern
+; $[[F0:f[0-9]*[02468]]] for even float registers doesn't work for some
+; reason (it works below in callee2). Alternatively, if DAG has to be used,
+; the pattern can be replaced with $[[F0:f20|f22|f24|f26|f28|f30]].
+; NOODDSPREG:        lw $[[R0:[0-9]+]], %got(gfa10)($[[GP]])
+; NOODDSPREG:        lwc1 $[[F0:f[0-9]*[02468]]], 0($[[R0]])
+; NOODDSPREG:        swc1 $[[F0]], 0($sp)
+
+  %0 = load float* @gfa0, align 4
+  %1 = load float* @gfa1, align 4
+  %2 = load float* @gfa2, align 4
+  %3 = load float* @gfa3, align 4
+  %4 = load float* @gfa4, align 4
+  %5 = load float* @gfa5, align 4
+  %6 = load float* @gfa6, align 4
+  %7 = load float* @gfa7, align 4
+  %8 = load float* @gfa8, align 4
+  %9 = load float* @gfa9, align 4
+  %10 = load float* @gfa10, align 4
+  tail call fastcc void @callee2(float %0, float %1, float %2, float %3,
+                                 float %4, float %5, float %6, float %7,
+                                 float %8, float %9, float %10)
+  ret void
+}
+
+define fastcc void @callee2(float %a0, float %a1, float %a2, float %a3,
+                            float %a4, float %a5, float %a6, float %a7,
+                            float %a8, float %a9, float %a10) {
+entry:
+
+; NOODDSPREG-LABEL:  callee2
+
+; NOODDSPREG:        addiu   $sp, $sp, -[[OFFSET:[0-9]+]]
+
+; Check that first 10 arguments are received in even float registers
+; f0, f2, ... , f18. Check that 11th argument is received on stack.
+
+; NOODDSPREG-DAG:    lw      $[[R0:[0-9]+]], %got(gf0)($[[GP:[0-9]+|gp]])
+; NOODDSPREG-DAG:    swc1    $f0, 0($[[R0]])
+; NOODDSPREG-DAG:    lw      $[[R0:[0-9]+]], %got(gf1)($[[GP]])
+; NOODDSPREG-DAG:    swc1    $f2, 0($[[R0]])
+; NOODDSPREG-DAG:    lw      $[[R0:[0-9]+]], %got(gf2)($[[GP]])
+; NOODDSPREG-DAG:    swc1    $f4, 0($[[R0]])
+; NOODDSPREG-DAG:    lw      $[[R0:[0-9]+]], %got(gf3)($[[GP]])
+; NOODDSPREG-DAG:    swc1    $f6, 0($[[R0]])
+; NOODDSPREG-DAG:    lw      $[[R0:[0-9]+]], %got(gf4)($[[GP]])
+; NOODDSPREG-DAG:    swc1    $f8, 0($[[R0]])
+; NOODDSPREG-DAG:    lw      $[[R0:[0-9]+]], %got(gf5)($[[GP]])
+; NOODDSPREG-DAG:    swc1    $f10, 0($[[R0]])
+; NOODDSPREG-DAG:    lw      $[[R0:[0-9]+]], %got(gf6)($[[GP]])
+; NOODDSPREG-DAG:    swc1    $f12, 0($[[R0]])
+; NOODDSPREG-DAG:    lw      $[[R0:[0-9]+]], %got(gf7)($[[GP]])
+; NOODDSPREG-DAG:    swc1    $f14, 0($[[R0]])
+; NOODDSPREG-DAG:    lw      $[[R0:[0-9]+]], %got(gf8)($[[GP]])
+; NOODDSPREG-DAG:    swc1    $f16, 0($[[R0]])
+; NOODDSPREG-DAG:    lw      $[[R0:[0-9]+]], %got(gf9)($[[GP]])
+; NOODDSPREG-DAG:    swc1    $f18, 0($[[R0]])
+
+; NOODDSPREG-DAG:    lw      $[[R0:[0-9]+]], %got(gf10)($[[GP]])
+; NOODDSPREG-DAG:    lwc1    $[[F0:f[0-9]*[02468]]], [[OFFSET]]($sp)
+; NOODDSPREG-DAG:    swc1    $[[F0]], 0($[[R0]])
+
+  store float %a0, float* @gf0, align 4
+  store float %a1, float* @gf1, align 4
+  store float %a2, float* @gf2, align 4
+  store float %a3, float* @gf3, align 4
+  store float %a4, float* @gf4, align 4
+  store float %a5, float* @gf5, align 4
+  store float %a6, float* @gf6, align 4
+  store float %a7, float* @gf7, align 4
+  store float %a8, float* @gf8, align 4
+  store float %a9, float* @gf9, align 4
+  store float %a10, float* @gf10, align 4
+  ret void
+}
+