[llvm-branch-commits] [llvm] 61e9454 - Revert "[MIPS] soft-promote `f16` also when using `+msa` (#203065)"

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Jun 16 06:24:51 PDT 2026


Author: Folkert de Vries
Date: 2026-06-16T15:24:47+02:00
New Revision: 61e94545cbd52e5d4f480da368412c21113ab341

URL: https://github.com/llvm/llvm-project/commit/61e94545cbd52e5d4f480da368412c21113ab341
DIFF: https://github.com/llvm/llvm-project/commit/61e94545cbd52e5d4f480da368412c21113ab341.diff

LOG: Revert "[MIPS] soft-promote `f16` also when using `+msa` (#203065)"

This reverts commit b85c748c895768681b61c8047f8ff08e469408ca.

Added: 
    

Modified: 
    llvm/lib/Target/Mips/MipsMSAInstrInfo.td
    llvm/lib/Target/Mips/MipsRegisterInfo.td
    llvm/lib/Target/Mips/MipsSEISelLowering.cpp
    llvm/lib/Target/Mips/MipsSEISelLowering.h
    llvm/lib/Target/Mips/MipsScheduleGeneric.td
    llvm/lib/Target/Mips/MipsScheduleI6400.td
    llvm/lib/Target/Mips/MipsScheduleP5600.td
    llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Mips/MipsMSAInstrInfo.td b/llvm/lib/Target/Mips/MipsMSAInstrInfo.td
index 11c8c5b33a925..5c28069055f16 100644
--- a/llvm/lib/Target/Mips/MipsMSAInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsMSAInstrInfo.td
@@ -3646,6 +3646,43 @@ def SZ_W_PSEUDO : MSA_CBRANCH_PSEUDO_DESC_BASE<MipsVAllZero, v4i32, MSA128W>;
 def SZ_D_PSEUDO : MSA_CBRANCH_PSEUDO_DESC_BASE<MipsVAllZero, v2i64, MSA128D>;
 def SZ_V_PSEUDO : MSA_CBRANCH_PSEUDO_DESC_BASE<MipsVAnyZero, v16i8, MSA128B>;
 
+// Pseudoes used to implement transparent fp16 support.
+
+let ASEPredicate = [HasMSA] in {
+  let usesCustomInserter = 1 in {
+    def ST_F16 :
+        MipsPseudo<(outs), (ins MSA128F16:$ws, mem_simm10:$addr),
+                   [(store (f16 MSA128F16:$ws), (addrimm10:$addr))]>;
+    def LD_F16 :
+        MipsPseudo<(outs MSA128F16:$ws), (ins mem_simm10:$addr),
+                   [(set MSA128F16:$ws, (f16 (load addrimm10:$addr)))]>;
+  }
+
+  let usesCustomInserter = 1, hasNoSchedulingInfo = 1 in {
+    def MSA_FP_EXTEND_W_PSEUDO :
+        MipsPseudo<(outs FGR32Opnd:$fd), (ins MSA128F16:$ws),
+                   [(set FGR32Opnd:$fd, (f32 (fpextend MSA128F16:$ws)))]>;
+    def MSA_FP_ROUND_W_PSEUDO :
+        MipsPseudo<(outs MSA128F16:$wd), (ins FGR32Opnd:$fs),
+                   [(set MSA128F16:$wd, (f16 (fpround FGR32Opnd:$fs)))]>;
+    def MSA_FP_EXTEND_D_PSEUDO :
+        MipsPseudo<(outs FGR64Opnd:$fd), (ins MSA128F16:$ws),
+                   [(set FGR64Opnd:$fd, (f64 (fpextend MSA128F16:$ws)))]>;
+    def MSA_FP_ROUND_D_PSEUDO :
+        MipsPseudo<(outs MSA128F16:$wd), (ins FGR64Opnd:$fs),
+                   [(set MSA128F16:$wd, (f16 (fpround FGR64Opnd:$fs)))]>;
+  }
+
+  def : MipsPat<(MipsTruncIntFP MSA128F16:$ws),
+                (TRUNC_W_D64 (MSA_FP_EXTEND_D_PSEUDO MSA128F16:$ws))>,
+        ISA_MIPS1, ASE_MSA;
+
+  def : MipsPat<(MipsFPCmp MSA128F16:$ws, MSA128F16:$wt, imm:$cond),
+                (FCMP_S32 (MSA_FP_EXTEND_W_PSEUDO MSA128F16:$ws),
+                          (MSA_FP_EXTEND_W_PSEUDO MSA128F16:$wt), imm:$cond)>,
+        ISA_MIPS1_NOT_32R6_64R6, ASE_MSA;
+}
+
 def vsplati64_imm_eq_63 : PatLeaf<(bitconvert (v4i32 (build_vector))), [{
   APInt Imm;
   SDNode *BV = N->getOperand(0).getNode();

diff  --git a/llvm/lib/Target/Mips/MipsRegisterInfo.td b/llvm/lib/Target/Mips/MipsRegisterInfo.td
index 765179a43980d..f9d4b07471a28 100644
--- a/llvm/lib/Target/Mips/MipsRegisterInfo.td
+++ b/llvm/lib/Target/Mips/MipsRegisterInfo.td
@@ -432,6 +432,8 @@ def FCC : RegisterClass<"Mips", [i32], 32, (sequence "FCC%u", 0, 7)>,
 def FGR32CC : RegisterClass<"Mips", [i32], 32, (sequence "F%u", 0, 31)>;
 def FGR64CC : RegisterClass<"Mips", [i32, f32, f64], 64, (sequence "D%u_64", 0, 31)>;
 
+def MSA128F16 : RegisterClass<"Mips", [f16], 128, (sequence "W%u", 0, 31)>;
+
 def MSA128B: RegisterClass<"Mips", [v16i8], 128,
                            (sequence "W%u", 0, 31)>;
 def MSA128H: RegisterClass<"Mips", [v8i16, v8f16], 128,
@@ -740,6 +742,10 @@ def COP3Opnd : RegisterOperand<COP3> {
   let ParserMatchClass = COP3AsmOperand;
 }
 
+def MSA128F16Opnd : RegisterOperand<MSA128F16> {
+  let ParserMatchClass = MSA128AsmOperand;
+}
+
 def MSA128BOpnd : RegisterOperand<MSA128B> {
   let ParserMatchClass = MSA128AsmOperand;
 }

diff  --git a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
index 600255d537caa..7c49838732032 100644
--- a/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelLowering.cpp
@@ -155,16 +155,59 @@ MipsSETargetLowering::MipsSETargetLowering(const MipsTargetMachine &TM,
     addMSAFloatType(MVT::v4f32, &Mips::MSA128WRegClass);
     addMSAFloatType(MVT::v2f64, &Mips::MSA128DRegClass);
 
-    // We're using soft promotion for f16, but msa has some instructions for
-    // conversion to/from f16. Mark those conversions as custom so we can take
-    // advantage of these instructions.
-    for (MVT VT : {MVT::f32, MVT::f64}) {
-      setOperationAction(ISD::FP16_TO_FP, VT, Custom);
-      setOperationAction(ISD::FP_TO_FP16, VT, Custom);
-    }
-
-    setTargetDAGCombine(
-        {ISD::AND, ISD::OR, ISD::SRA, ISD::VSELECT, ISD::XOR, ISD::FP_TO_UINT});
+    // f16 is a storage-only type, always promote it to f32.
+    addRegisterClass(MVT::f16, &Mips::MSA128HRegClass);
+    setOperationAction(ISD::SETCC, MVT::f16, Promote);
+    setOperationAction(ISD::BR_CC, MVT::f16, Promote);
+    setOperationAction(ISD::SELECT_CC, MVT::f16, Promote);
+    setOperationAction(ISD::SELECT, MVT::f16, Promote);
+    setOperationAction(ISD::FADD, MVT::f16, Promote);
+    setOperationAction(ISD::FSUB, MVT::f16, Promote);
+    setOperationAction(ISD::FMUL, MVT::f16, Promote);
+    setOperationAction(ISD::FDIV, MVT::f16, Promote);
+    setOperationAction(ISD::FREM, MVT::f16, Promote);
+    setOperationAction(ISD::FMA, MVT::f16, Promote);
+    setOperationAction(ISD::FNEG, MVT::f16, Promote);
+    setOperationAction(ISD::FABS, MVT::f16, Promote);
+    setOperationAction(ISD::FCEIL, MVT::f16, Promote);
+    setOperationAction(ISD::FCOPYSIGN, MVT::f16, Promote);
+    setOperationAction(ISD::FCOS, MVT::f16, Promote);
+    setOperationAction(ISD::FP_EXTEND, MVT::f16, Promote);
+    setOperationAction(ISD::FFLOOR, MVT::f16, Promote);
+    setOperationAction(ISD::FNEARBYINT, MVT::f16, Promote);
+    setOperationAction(ISD::FPOW, MVT::f16, Promote);
+    setOperationAction(ISD::FPOWI, MVT::f16, Promote);
+    setOperationAction(ISD::FRINT, MVT::f16, Promote);
+    setOperationAction(ISD::FSIN, MVT::f16, Promote);
+    setOperationAction(ISD::FSINCOS, MVT::f16, Promote);
+    setOperationAction(ISD::FSQRT, MVT::f16, Promote);
+    setOperationAction(ISD::FEXP, MVT::f16, Promote);
+    setOperationAction(ISD::FEXP2, MVT::f16, Promote);
+    setOperationAction(ISD::FLOG, MVT::f16, Promote);
+    setOperationAction(ISD::FLOG2, MVT::f16, Promote);
+    setOperationAction(ISD::FLOG10, MVT::f16, Promote);
+    setOperationAction(ISD::FROUND, MVT::f16, Promote);
+    setOperationAction(ISD::FTRUNC, MVT::f16, Promote);
+    setOperationAction(ISD::FMINNUM, MVT::f16, Promote);
+    setOperationAction(ISD::FMAXNUM, MVT::f16, Promote);
+    setOperationAction(ISD::FMINIMUM, MVT::f16, Promote);
+    setOperationAction(ISD::FMAXIMUM, MVT::f16, Promote);
+
+    // Integer <-> Float conversions are keyed on the integer type. Make these
+    // custom so that we can handle the f16 case. Other float types use their
+    // default expansion.
+    setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
+    if (Subtarget.isGP64bit())
+      setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
+
+    setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
+    setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
+    setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
+    setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
+    setOperationAction(ISD::FP_TO_SINT, MVT::i128, Custom);
+    setOperationAction(ISD::FP_TO_UINT, MVT::i128, Custom);
+
+    setTargetDAGCombine({ISD::AND, ISD::OR, ISD::SRA, ISD::VSELECT, ISD::XOR});
   }
 
   if (!Subtarget.useSoftFloat()) {
@@ -486,79 +529,45 @@ SDValue MipsSETargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
                      Op->getOperand(2));
 }
 
-// Lower FP16_TO_FP (the soft-promote-half representation of an f16 -> f32/f64
-// conversion).
-SDValue MipsSETargetLowering::lowerFP16_TO_FP(SDValue Op,
-                                              SelectionDAG &DAG) const {
-  SDLoc DL(Op);
-  EVT ResTy = Op.getValueType();
-  assert((ResTy == MVT::f32 || ResTy == MVT::f64) && "Unexpected FP16_TO_FP");
-
-  // The operand type is i32 because i16 isn't actually legal on MIPS.
-  SDValue In = Op.getOperand(0);
-  assert(In.getValueType() == MVT::i32 && "Unexpected FP16_TO_FP operand type");
-
-  // Splat into a v8i16 (the 32-bit In value is truncated to the lower 16 bits).
-  SDValue Splatted = DAG.getSplatBuildVector(MVT::v8i16, DL, In);
-
-  // Bitcast from v8i16 to v8f16.
-  SDValue HVec = DAG.getNode(ISD::BITCAST, DL, MVT::v8f16, Splatted);
-
-  // Convert from v8f16 to v4f32.
-  SDValue F32Vec = DAG.getNode(
-      ISD::INTRINSIC_WO_CHAIN, DL, MVT::v4f32,
-      DAG.getConstant(Intrinsic::mips_fexupr_w, DL, MVT::i32), HVec);
-  SDValue Res;
-  if (ResTy == MVT::f32) {
-    // Every lane has the converted value, just read it from lane 0.
-    Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f32, F32Vec,
-                      DAG.getVectorIdxConstant(0, DL));
-  } else {
-    // Convert from v4f32 to v2f64.
-    SDValue F64Vec = DAG.getNode(
-        ISD::INTRINSIC_WO_CHAIN, DL, MVT::v2f64,
-        DAG.getConstant(Intrinsic::mips_fexupr_d, DL, MVT::i32), F32Vec);
-    // Every lane has the converted value, just read it from lane 0.
-    Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::f64, F64Vec,
-                      DAG.getVectorIdxConstant(0, DL));
-  }
+SDValue MipsSETargetLowering::lowerINT_TO_FP(SDValue Op,
+                                             SelectionDAG &DAG) const {
+  // The f32/f64 case is already legal.
+  if (Op.getValueType() != MVT::f16)
+    return Op;
 
-  return Res;
+  // For f16, first convert the integer to f32, then convert to f16.
+  SDLoc DL(Op);
+  SDValue FP = DAG.getNode(Op.getOpcode(), DL, MVT::f32, Op.getOperand(0));
+  return DAG.getFPExtendOrRound(FP, DL, MVT::f16);
 }
 
-// Lower FP_TO_FP16 (the soft-promote-half representation of an f32/f64 -> f16
-// conversion)
-SDValue MipsSETargetLowering::lowerFP_TO_FP16(SDValue Op,
-                                              SelectionDAG &DAG) const {
-  SDLoc DL(Op);
-  EVT ResTy = Op.getValueType();
-  SDValue In = Op.getOperand(0);
-  assert((In.getValueType() == MVT::f32 || In.getValueType() == MVT::f64) &&
-         "Unexpected FP_TO_FP16");
-
-  SDValue F32Vec;
-  if (In.getValueType() == MVT::f64) {
-    // Splat f64 to v2f64, then convert to v4f32.
-    SDValue F64Vec = DAG.getSplatBuildVector(MVT::v2f64, DL, In);
-    F32Vec = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DL, MVT::v4f32,
-                         DAG.getConstant(Intrinsic::mips_fexdo_w, DL, MVT::i32),
-                         F64Vec, F64Vec);
-  } else {
-    // Splat f32 to v4f32.
-    F32Vec = DAG.getSplatBuildVector(MVT::v4f32, DL, In);
-  }
+SDValue MipsSETargetLowering::lowerFP_TO_INT(SDValue Op,
+                                             SelectionDAG &DAG) const {
+  SDValue InOp = Op.getOperand(0);
+
+  // For f16, first convert to f32 and go from there.
+  if (InOp.getValueType() == MVT::f16) {
+    EVT VT = Op.getValueType();
 
-  // Then convert from v4f32 to v8f16.
-  SDValue HVec = DAG.getNode(
-      ISD::INTRINSIC_WO_CHAIN, DL, MVT::v8f16,
-      DAG.getConstant(Intrinsic::mips_fexdo_h, DL, MVT::i32), F32Vec, F32Vec);
+    assert((VT == MVT::i32 || VT == MVT::i64 || VT == MVT::i128) &&
+           "Unexpected result type for f16 -> integer conversion");
 
-  // Finally cast to v8i16 (f16 is soft-promoted).
-  SDValue IVec = DAG.getNode(ISD::BITCAST, DL, MVT::v8i16, HVec);
-  SDValue Res = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, ResTy, IVec,
-                            DAG.getVectorIdxConstant(0, DL));
+    SDLoc DL(Op);
+    SDValue FP = DAG.getFPExtendOrRound(InOp, DL, MVT::f32);
 
-  return Res;
+    // Use a trick from TargetLowering::expandFP_TO_UINT: we know that every
+    // integer value that can be represented by f16 is representable by i32, so
+    // fptoui and fptosi are equivalent.
+    //
+    // NOTE: the result of fptoui is poison when the value does not fit in the
+    // destination type (e.g. because it is negative).
+    return DAG.getNode(ISD::FP_TO_SINT, DL, VT, FP);
+  }
+
+  // Use the default lowering for f32/f64.
+  if (!isTypeLegal(Op.getValueType()))
+    return SDValue();
+  return MipsTargetLowering::LowerOperation(Op, DAG);
 }
 
 bool MipsSETargetLowering::allowsMisalignedMemoryAccesses(
@@ -607,14 +616,12 @@ SDValue MipsSETargetLowering::LowerOperation(SDValue Op,
   case ISD::EXTRACT_VECTOR_ELT: return lowerEXTRACT_VECTOR_ELT(Op, DAG);
   case ISD::BUILD_VECTOR:       return lowerBUILD_VECTOR(Op, DAG);
   case ISD::VECTOR_SHUFFLE:     return lowerVECTOR_SHUFFLE(Op, DAG);
-  case ISD::SELECT:
-    return lowerSELECT(Op, DAG);
-  case ISD::FP16_TO_FP:
-  case ISD::STRICT_FP16_TO_FP:
-    return lowerFP16_TO_FP(Op, DAG);
-  case ISD::FP_TO_FP16:
-  case ISD::STRICT_FP_TO_FP16:
-    return lowerFP_TO_FP16(Op, DAG);
+  case ISD::SELECT:             return lowerSELECT(Op, DAG);
+  case ISD::SINT_TO_FP:
+    return lowerINT_TO_FP(Op, DAG);
+  case ISD::FP_TO_SINT:
+  case ISD::FP_TO_UINT:
+    return lowerFP_TO_INT(Op, DAG);
   case ISD::BITCAST:            return lowerBITCAST(Op, DAG);
   case ISD::FADD:
     return lowerR5900FPOp(Op, DAG, RTLIB::ADD_F32);
@@ -1201,23 +1208,6 @@ static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG,
   return SDValue();
 }
 
-// Convert (fp_to_uint (fp16_to_fp x)) into (fp_to_sint (fp16_to_fp x)).
-static SDValue performFP_TO_UINTCombine(SDNode *N, SelectionDAG &DAG) {
-  SDValue Src = N->getOperand(0);
-  EVT VT = N->getValueType(0);
-
-  // Use a trick from TargetLowering::expandFP_TO_UINT: we know that every
-  // integer value that can be represented by f16 is <= 65504, i.e. a signed
-  // integer of 17 bits or more can represent all values and fptoui and fptosi
-  // are equivalent.
-  //
-  // NOTE: the result of fptoui is poison when the value does not fit in the
-  // destination type (e.g. because it is negative).
-  if (Src.getOpcode() != ISD::FP16_TO_FP || VT.getScalarSizeInBits() < 17)
-    return SDValue();
-  return DAG.getNode(ISD::FP_TO_SINT, SDLoc(N), VT, Src);
-}
-
 SDValue
 MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
   SelectionDAG &DAG = DCI.DAG;
@@ -1247,9 +1237,6 @@ MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
   case ISD::SETCC:
     Val = performSETCCCombine(N, DAG);
     break;
-  case ISD::FP_TO_UINT:
-    Val = performFP_TO_UINTCombine(N, DAG);
-    break;
   }
 
   if (Val.getNode()) {
@@ -1324,6 +1311,18 @@ MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
     return emitFEXP2_W_1(MI, BB);
   case Mips::FEXP2_D_1_PSEUDO:
     return emitFEXP2_D_1(MI, BB);
+  case Mips::ST_F16:
+    return emitST_F16_PSEUDO(MI, BB);
+  case Mips::LD_F16:
+    return emitLD_F16_PSEUDO(MI, BB);
+  case Mips::MSA_FP_EXTEND_W_PSEUDO:
+    return emitFPEXTEND_PSEUDO(MI, BB, false);
+  case Mips::MSA_FP_ROUND_W_PSEUDO:
+    return emitFPROUND_PSEUDO(MI, BB, false);
+  case Mips::MSA_FP_EXTEND_D_PSEUDO:
+    return emitFPEXTEND_PSEUDO(MI, BB, true);
+  case Mips::MSA_FP_ROUND_D_PSEUDO:
+    return emitFPROUND_PSEUDO(MI, BB, true);
   }
 }
 
@@ -3690,6 +3689,320 @@ MipsSETargetLowering::emitFILL_FD(MachineInstr &MI,
   return BB;
 }
 
+// Emit the ST_F16_PSEDUO instruction to store a f16 value from an MSA
+// register.
+//
+// STF16 MSA128F16:$wd, mem_simm10:$addr
+// =>
+//  copy_u.h $rtemp,$wd[0]
+//  sh $rtemp, $addr
+//
+// Safety: We can't use st.h & co as they would over write the memory after
+// the destination. It would require half floats be allocated 16 bytes(!) of
+// space.
+MachineBasicBlock *
+MipsSETargetLowering::emitST_F16_PSEUDO(MachineInstr &MI,
+                                       MachineBasicBlock *BB) const {
+
+  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
+  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
+  DebugLoc DL = MI.getDebugLoc();
+  Register Ws = MI.getOperand(0).getReg();
+  Register Rt = MI.getOperand(1).getReg();
+  const MachineMemOperand &MMO = **MI.memoperands_begin();
+  unsigned Imm = MMO.getOffset();
+
+  // Caution: A load via the GOT can expand to a GPR32 operand, a load via
+  //          spill and reload can expand as a GPR64 operand. Examine the
+  //          operand in detail and default to ABI.
+  const TargetRegisterClass *RC =
+      MI.getOperand(1).isReg() ? RegInfo.getRegClass(MI.getOperand(1).getReg())
+                               : (Subtarget.isABI_O32() ? &Mips::GPR32RegClass
+                                                        : &Mips::GPR64RegClass);
+  const bool UsingMips32 = RC == &Mips::GPR32RegClass;
+  Register Rs = RegInfo.createVirtualRegister(&Mips::GPR32RegClass);
+
+  BuildMI(*BB, MI, DL, TII->get(Mips::COPY_U_H), Rs).addReg(Ws).addImm(0);
+  if(!UsingMips32) {
+    Register Tmp = RegInfo.createVirtualRegister(&Mips::GPR64RegClass);
+    BuildMI(*BB, MI, DL, TII->get(Mips::SUBREG_TO_REG), Tmp)
+        .addReg(Rs)
+        .addImm(Mips::sub_32);
+    Rs = Tmp;
+  }
+  BuildMI(*BB, MI, DL, TII->get(UsingMips32 ? Mips::SH : Mips::SH64))
+      .addReg(Rs)
+      .addReg(Rt)
+      .addImm(Imm)
+      .addMemOperand(BB->getParent()->getMachineMemOperand(
+          &MMO, MMO.getOffset(), MMO.getSize()));
+
+  MI.eraseFromParent();
+  return BB;
+}
+
+// Emit the LD_F16_PSEDUO instruction to load a f16 value into an MSA register.
+//
+// LD_F16 MSA128F16:$wd, mem_simm10:$addr
+// =>
+//  lh $rtemp, $addr
+//  fill.h $wd, $rtemp
+//
+// Safety: We can't use ld.h & co as they over-read from the source.
+// Additionally, if the address is not modulo 16, 2 cases can occur:
+//  a) Segmentation fault as the load instruction reads from a memory page
+//     memory it's not supposed to.
+//  b) The load crosses an implementation specific boundary, requiring OS
+//     intervention.
+MachineBasicBlock *
+MipsSETargetLowering::emitLD_F16_PSEUDO(MachineInstr &MI,
+                                       MachineBasicBlock *BB) const {
+
+  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
+  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
+  DebugLoc DL = MI.getDebugLoc();
+  Register Wd = MI.getOperand(0).getReg();
+
+  // Caution: A load via the GOT can expand to a GPR32 operand, a load via
+  //          spill and reload can expand as a GPR64 operand. Examine the
+  //          operand in detail and default to ABI.
+  const TargetRegisterClass *RC =
+      MI.getOperand(1).isReg() ? RegInfo.getRegClass(MI.getOperand(1).getReg())
+                               : (Subtarget.isABI_O32() ? &Mips::GPR32RegClass
+                                                        : &Mips::GPR64RegClass);
+
+  const bool UsingMips32 = RC == &Mips::GPR32RegClass;
+  Register Rt = RegInfo.createVirtualRegister(RC);
+
+  MachineInstrBuilder MIB =
+      BuildMI(*BB, MI, DL, TII->get(UsingMips32 ? Mips::LH : Mips::LH64), Rt);
+  for (const MachineOperand &MO : llvm::drop_begin(MI.operands()))
+    MIB.add(MO);
+
+  if(!UsingMips32) {
+    Register Tmp = RegInfo.createVirtualRegister(&Mips::GPR32RegClass);
+    BuildMI(*BB, MI, DL, TII->get(Mips::COPY), Tmp)
+        .addReg(Rt, {}, Mips::sub_32);
+    Rt = Tmp;
+  }
+
+  BuildMI(*BB, MI, DL, TII->get(Mips::FILL_H), Wd).addReg(Rt);
+
+  MI.eraseFromParent();
+  return BB;
+}
+
+// Emit the FPROUND_PSEUDO instruction.
+//
+// Round an FGR64Opnd, FGR32Opnd to an f16.
+//
+// Safety: Cycle the operand through the GPRs so the result always ends up
+//         the correct MSA register.
+//
+// FIXME: This copying is strictly unnecessary. If we could tie FGR32Opnd:$Fs
+//        / FGR64Opnd:$Fs and MSA128F16:$Wd to the same physical register
+//        (which they can be, as the MSA registers are defined to alias the
+//        FPU's 64 bit and 32 bit registers) the result can be accessed using
+//        the correct register class. That requires operands be tie-able across
+//        register classes which have a sub/super register class relationship.
+//
+// For FPG32Opnd:
+//
+// FPROUND MSA128F16:$wd, FGR32Opnd:$fs
+// =>
+//  mfc1 $rtemp, $fs
+//  fill.w $rtemp, $wtemp
+//  fexdo.w $wd, $wtemp, $wtemp
+//
+// For FPG64Opnd on mips32r2+:
+//
+// FPROUND MSA128F16:$wd, FGR64Opnd:$fs
+// =>
+//  mfc1 $rtemp, $fs
+//  fill.w $rtemp, $wtemp
+//  mfhc1 $rtemp2, $fs
+//  insert.w $wtemp[1], $rtemp2
+//  insert.w $wtemp[3], $rtemp2
+//  fexdo.w $wtemp2, $wtemp, $wtemp
+//  fexdo.h $wd, $temp2, $temp2
+//
+// For FGR64Opnd on mips64r2+:
+//
+// FPROUND MSA128F16:$wd, FGR64Opnd:$fs
+// =>
+//  dmfc1 $rtemp, $fs
+//  fill.d $rtemp, $wtemp
+//  fexdo.w $wtemp2, $wtemp, $wtemp
+//  fexdo.h $wd, $wtemp2, $wtemp2
+//
+// Safety note: As $wtemp is UNDEF, we may provoke a spurious exception if the
+//              undef bits are "just right" and the exception enable bits are
+//              set. By using fill.w to replicate $fs into all elements over
+//              insert.w for one element, we avoid that potiential case. If
+//              fexdo.[hw] causes an exception in, the exception is valid and it
+//              occurs for all elements.
+MachineBasicBlock *
+MipsSETargetLowering::emitFPROUND_PSEUDO(MachineInstr &MI,
+                                         MachineBasicBlock *BB,
+                                         bool IsFGR64) const {
+
+  // Strictly speaking, we need MIPS32R5 to support MSA. We'll be generous
+  // here. It's technically doable to support MIPS32 here, but the ISA forbids
+  // it.
+  assert(Subtarget.hasMSA() && Subtarget.hasMips32r2());
+
+  bool IsFGR64onMips64 = Subtarget.hasMips64() && IsFGR64;
+  bool IsFGR64onMips32 = !Subtarget.hasMips64() && IsFGR64;
+
+  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
+  DebugLoc DL = MI.getDebugLoc();
+  Register Wd = MI.getOperand(0).getReg();
+  Register Fs = MI.getOperand(1).getReg();
+
+  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
+  Register Wtemp = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
+  const TargetRegisterClass *GPRRC =
+      IsFGR64onMips64 ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
+  unsigned MFC1Opc = IsFGR64onMips64
+                         ? Mips::DMFC1
+                         : (IsFGR64onMips32 ? Mips::MFC1_D64 : Mips::MFC1);
+  unsigned FILLOpc = IsFGR64onMips64 ? Mips::FILL_D : Mips::FILL_W;
+
+  // Perform the register class copy as mentioned above.
+  Register Rtemp = RegInfo.createVirtualRegister(GPRRC);
+  BuildMI(*BB, MI, DL, TII->get(MFC1Opc), Rtemp).addReg(Fs);
+  BuildMI(*BB, MI, DL, TII->get(FILLOpc), Wtemp).addReg(Rtemp);
+  unsigned WPHI = Wtemp;
+
+  if (IsFGR64onMips32) {
+    Register Rtemp2 = RegInfo.createVirtualRegister(GPRRC);
+    BuildMI(*BB, MI, DL, TII->get(Mips::MFHC1_D64), Rtemp2).addReg(Fs);
+    Register Wtemp2 = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
+    Register Wtemp3 = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
+    BuildMI(*BB, MI, DL, TII->get(Mips::INSERT_W), Wtemp2)
+        .addReg(Wtemp)
+        .addReg(Rtemp2)
+        .addImm(1);
+    BuildMI(*BB, MI, DL, TII->get(Mips::INSERT_W), Wtemp3)
+        .addReg(Wtemp2)
+        .addReg(Rtemp2)
+        .addImm(3);
+    WPHI = Wtemp3;
+  }
+
+  if (IsFGR64) {
+    Register Wtemp2 = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
+    BuildMI(*BB, MI, DL, TII->get(Mips::FEXDO_W), Wtemp2)
+        .addReg(WPHI)
+        .addReg(WPHI);
+    WPHI = Wtemp2;
+  }
+
+  BuildMI(*BB, MI, DL, TII->get(Mips::FEXDO_H), Wd).addReg(WPHI).addReg(WPHI);
+
+  MI.eraseFromParent();
+  return BB;
+}
+
+// Emit the FPEXTEND_PSEUDO instruction.
+//
+// Expand an f16 to either a FGR32Opnd or FGR64Opnd.
+//
+// Safety: Cycle the result through the GPRs so the result always ends up
+//         the correct floating point register.
+//
+// FIXME: This copying is strictly unnecessary. If we could tie FGR32Opnd:$Fd
+//        / FGR64Opnd:$Fd and MSA128F16:$Ws to the same physical register
+//        (which they can be, as the MSA registers are defined to alias the
+//        FPU's 64 bit and 32 bit registers) the result can be accessed using
+//        the correct register class. That requires operands be tie-able across
+//        register classes which have a sub/super register class relationship. I
+//        haven't checked.
+//
+// For FGR32Opnd:
+//
+// FPEXTEND FGR32Opnd:$fd, MSA128F16:$ws
+// =>
+//  fexupr.w $wtemp, $ws
+//  copy_s.w $rtemp, $ws[0]
+//  mtc1 $rtemp, $fd
+//
+// For FGR64Opnd on Mips64:
+//
+// FPEXTEND FGR64Opnd:$fd, MSA128F16:$ws
+// =>
+//  fexupr.w $wtemp, $ws
+//  fexupr.d $wtemp2, $wtemp
+//  copy_s.d $rtemp, $wtemp2s[0]
+//  dmtc1 $rtemp, $fd
+//
+// For FGR64Opnd on Mips32:
+//
+// FPEXTEND FGR64Opnd:$fd, MSA128F16:$ws
+// =>
+//  fexupr.w $wtemp, $ws
+//  fexupr.d $wtemp2, $wtemp
+//  copy_s.w $rtemp, $wtemp2[0]
+//  mtc1 $rtemp, $ftemp
+//  copy_s.w $rtemp2, $wtemp2[1]
+//  $fd = mthc1 $rtemp2, $ftemp
+MachineBasicBlock *
+MipsSETargetLowering::emitFPEXTEND_PSEUDO(MachineInstr &MI,
+                                          MachineBasicBlock *BB,
+                                          bool IsFGR64) const {
+
+  // Strictly speaking, we need MIPS32R5 to support MSA. We'll be generous
+  // here. It's technically doable to support MIPS32 here, but the ISA forbids
+  // it.
+  assert(Subtarget.hasMSA() && Subtarget.hasMips32r2());
+
+  bool IsFGR64onMips64 = Subtarget.hasMips64() && IsFGR64;
+  bool IsFGR64onMips32 = !Subtarget.hasMips64() && IsFGR64;
+
+  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
+  DebugLoc DL = MI.getDebugLoc();
+  Register Fd = MI.getOperand(0).getReg();
+  Register Ws = MI.getOperand(1).getReg();
+
+  MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
+  const TargetRegisterClass *GPRRC =
+      IsFGR64onMips64 ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
+  unsigned MTC1Opc = IsFGR64onMips64
+                         ? Mips::DMTC1
+                         : (IsFGR64onMips32 ? Mips::MTC1_D64 : Mips::MTC1);
+  Register COPYOpc = IsFGR64onMips64 ? Mips::COPY_S_D : Mips::COPY_S_W;
+
+  Register Wtemp = RegInfo.createVirtualRegister(&Mips::MSA128WRegClass);
+  Register WPHI = Wtemp;
+
+  BuildMI(*BB, MI, DL, TII->get(Mips::FEXUPR_W), Wtemp).addReg(Ws);
+  if (IsFGR64) {
+    WPHI = RegInfo.createVirtualRegister(&Mips::MSA128DRegClass);
+    BuildMI(*BB, MI, DL, TII->get(Mips::FEXUPR_D), WPHI).addReg(Wtemp);
+  }
+
+  // Perform the safety regclass copy mentioned above.
+  Register Rtemp = RegInfo.createVirtualRegister(GPRRC);
+  Register FPRPHI = IsFGR64onMips32
+                        ? RegInfo.createVirtualRegister(&Mips::FGR64RegClass)
+                        : Fd;
+  BuildMI(*BB, MI, DL, TII->get(COPYOpc), Rtemp).addReg(WPHI).addImm(0);
+  BuildMI(*BB, MI, DL, TII->get(MTC1Opc), FPRPHI).addReg(Rtemp);
+
+  if (IsFGR64onMips32) {
+    Register Rtemp2 = RegInfo.createVirtualRegister(GPRRC);
+    BuildMI(*BB, MI, DL, TII->get(Mips::COPY_S_W), Rtemp2)
+        .addReg(WPHI)
+        .addImm(1);
+    BuildMI(*BB, MI, DL, TII->get(Mips::MTHC1_D64), Fd)
+        .addReg(FPRPHI)
+        .addReg(Rtemp2);
+  }
+
+  MI.eraseFromParent();
+  return BB;
+}
+
 // Emit the FEXP2_W_1 pseudo instructions.
 //
 // fexp2_w_1_pseudo $wd, $wt

diff  --git a/llvm/lib/Target/Mips/MipsSEISelLowering.h b/llvm/lib/Target/Mips/MipsSEISelLowering.h
index d75acbc9698f5..b0c6cb590e528 100644
--- a/llvm/lib/Target/Mips/MipsSEISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsSEISelLowering.h
@@ -94,8 +94,6 @@ class TargetRegisterClass;
     SDValue lowerSELECT(SDValue Op, SelectionDAG &DAG) const;
     SDValue lowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
     SDValue lowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) const;
-    SDValue lowerFP16_TO_FP(SDValue Op, SelectionDAG &DAG) const;
-    SDValue lowerFP_TO_FP16(SDValue Op, SelectionDAG &DAG) const;
 
     MachineBasicBlock *emitBPOSGE32(MachineInstr &MI,
                                     MachineBasicBlock *BB) const;
@@ -131,6 +129,20 @@ class TargetRegisterClass;
     /// Emit the FEXP2_D_1 pseudo instructions.
     MachineBasicBlock *emitFEXP2_D_1(MachineInstr &MI,
                                      MachineBasicBlock *BB) const;
+    /// Emit the FILL_FW pseudo instruction
+    MachineBasicBlock *emitLD_F16_PSEUDO(MachineInstr &MI,
+                                   MachineBasicBlock *BB) const;
+    /// Emit the FILL_FD pseudo instruction
+    MachineBasicBlock *emitST_F16_PSEUDO(MachineInstr &MI,
+                                   MachineBasicBlock *BB) const;
+    /// Emit the FEXP2_W_1 pseudo instructions.
+    MachineBasicBlock *emitFPEXTEND_PSEUDO(MachineInstr &MI,
+                                           MachineBasicBlock *BB,
+                                           bool IsFGR64) const;
+    /// Emit the FEXP2_D_1 pseudo instructions.
+    MachineBasicBlock *emitFPROUND_PSEUDO(MachineInstr &MI,
+                                          MachineBasicBlock *BBi,
+                                          bool IsFGR64) const;
   };
 
 } // end namespace llvm

diff  --git a/llvm/lib/Target/Mips/MipsScheduleGeneric.td b/llvm/lib/Target/Mips/MipsScheduleGeneric.td
index d7b9a002dbc5f..6771a897eea78 100644
--- a/llvm/lib/Target/Mips/MipsScheduleGeneric.td
+++ b/llvm/lib/Target/Mips/MipsScheduleGeneric.td
@@ -1600,7 +1600,9 @@ def : InstRW<[GenericWriteFPUMoveGPRFPU], (instregex "^COPY_U_[BHW]$")>;
 def : InstRW<[GenericWriteFPUMoveGPRFPU], (instregex "^COPY_S_[BHWD]$")>;
 
 def : InstRW<[GenericWriteFPUStore], (instregex "^ST_[BHWD]$")>;
+def : InstRW<[GenericWriteFPUStore], (instrs ST_F16)>;
 def : InstRW<[GenericWriteFPULoad], (instregex "^LD_[BHWD]$")>;
+def : InstRW<[GenericWriteFPULoad], (instrs LD_F16)>;
 
 // Atomic instructions
 

diff  --git a/llvm/lib/Target/Mips/MipsScheduleI6400.td b/llvm/lib/Target/Mips/MipsScheduleI6400.td
index 342e7ac31eb5a..f168ffee06cf5 100644
--- a/llvm/lib/Target/Mips/MipsScheduleI6400.td
+++ b/llvm/lib/Target/Mips/MipsScheduleI6400.td
@@ -66,7 +66,7 @@ let SchedModel = MipsI6400Model in {
                                           CACHE_R6, SC64_R6)>;
   def : InstRW<[I6400WriteLSULoad],
                (instrs LB, LBu, LBu64, LD, LH, LHu, LHu64, LW, LWu, LDC1,
-		   LDC164, LWC1, LDC2_R6, LDC3, LWC2_R6,
+		   LDC164, LWC1, LD_F16, ST_F16, LDC2_R6, LDC3, LWC2_R6,
                    LLD_R6, LL_R6, LWPC, LWUPC, LDPC, ST_B, ST_H, ST_W, ST_D,
 		   LB64, LH64, LW64, LWL64, LWR64, SB64, SH64, SW64, SWL64,
 		   SWR64, LL64_R6)>;

diff  --git a/llvm/lib/Target/Mips/MipsScheduleP5600.td b/llvm/lib/Target/Mips/MipsScheduleP5600.td
index e8b646a37932c..c79cd876596c0 100644
--- a/llvm/lib/Target/Mips/MipsScheduleP5600.td
+++ b/llvm/lib/Target/Mips/MipsScheduleP5600.td
@@ -579,6 +579,7 @@ def : InstRW<[P5600WriteMoveFPUToGPR], (instrs BC1F, BC1FL, BC1T, BC1TL, CFC1,
 def : InstRW<[P5600WriteStoreFPUS], (instrs SDC1, SDC164, SDXC1, SDXC164,
                                      SWC1, SWXC1, SUXC1, SUXC164)>;
 def : InstRW<[P5600WriteStoreFPUS], (instregex "^ST_[BHWD]$")>;
+def : InstRW<[P5600WriteStoreFPUS], (instrs ST_F16)>;
 
 // movn.[ds], movz.[ds]
 def : InstRW<[P5600WriteStoreFPUL], (instrs MOVN_I_D32, MOVN_I_D64, MOVN_I_S,
@@ -588,6 +589,7 @@ def : InstRW<[P5600WriteStoreFPUL], (instrs MOVN_I_D32, MOVN_I_D64, MOVN_I_S,
 def : InstRW<[P5600WriteLoadFPU], (instrs LDC1, LDC164, LDXC1, LDXC164,
                                    LWC1, LWXC1, LUXC1, LUXC164)>;
 def : InstRW<[P5600WriteLoadFPU], (instregex "LD_[BHWD]")>;
+def : InstRW<[P5600WriteLoadFPU], (instrs LD_F16)>;
 
 // Unsupported Instructions
 // ========================

diff  --git a/llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll b/llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll
index e7ad69754afa4..b2fc949222ef7 100644
--- a/llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll
+++ b/llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll
@@ -107,36 +107,55 @@ define void  @f(i16 %b) {
 ; MIPS32:       # %bb.0:
 ; MIPS32-NEXT:    lui $2, %hi(_gp_disp)
 ; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; MIPS32-NEXT:    addiu $sp, $sp, -8
+; MIPS32-NEXT:    .cfi_def_cfa_offset 8
 ; MIPS32-NEXT:    addu $1, $2, $25
-; MIPS32-NEXT:    fill.h $w0, $4
+; MIPS32-NEXT:    sh $4, 4($sp)
+; MIPS32-NEXT:    lh $2, 4($sp)
+; MIPS32-NEXT:    fill.h $w0, $2
 ; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS32-NEXT:    mtc1 $2, $f0
 ; MIPS32-NEXT:    lw $1, %got(k)($1)
-; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    swc1 $f0, 0($1)
+; MIPS32-NEXT:    jr $ra
+; MIPS32-NEXT:    addiu $sp, $sp, 8
 ;
 ; MIPS64-N32-LABEL: f:
 ; MIPS64-N32:       # %bb.0:
+; MIPS64-N32-NEXT:    addiu $sp, $sp, -16
+; MIPS64-N32-NEXT:    .cfi_def_cfa_offset 16
 ; MIPS64-N32-NEXT:    lui $1, %hi(%neg(%gp_rel(f)))
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(f)))
-; MIPS64-N32-NEXT:    sll $2, $4, 0
+; MIPS64-N32-NEXT:    sh $4, 12($sp)
+; MIPS64-N32-NEXT:    lh $2, 12($sp)
 ; MIPS64-N32-NEXT:    fill.h $w0, $2
 ; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $2, $f0
 ; MIPS64-N32-NEXT:    lw $1, %got_disp(k)($1)
-; MIPS64-N32-NEXT:    jr $ra
 ; MIPS64-N32-NEXT:    swc1 $f0, 0($1)
+; MIPS64-N32-NEXT:    jr $ra
+; MIPS64-N32-NEXT:    addiu $sp, $sp, 16
 ;
 ; MIPS64-N64-LABEL: f:
 ; MIPS64-N64:       # %bb.0:
+; MIPS64-N64-NEXT:    daddiu $sp, $sp, -16
+; MIPS64-N64-NEXT:    .cfi_def_cfa_offset 16
 ; MIPS64-N64-NEXT:    lui $1, %hi(%neg(%gp_rel(f)))
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(f)))
-; MIPS64-N64-NEXT:    sll $2, $4, 0
+; MIPS64-N64-NEXT:    sh $4, 12($sp)
+; MIPS64-N64-NEXT:    lh $2, 12($sp)
 ; MIPS64-N64-NEXT:    fill.h $w0, $2
 ; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $2, $f0
 ; MIPS64-N64-NEXT:    ld $1, %got_disp(k)($1)
-; MIPS64-N64-NEXT:    jr $ra
 ; MIPS64-N64-NEXT:    swc1 $f0, 0($1)
+; MIPS64-N64-NEXT:    jr $ra
+; MIPS64-N64-NEXT:    daddiu $sp, $sp, 16
   %1 = bitcast i16 %b to half
   %2 = fpext half %1 to float
   store float %2, ptr @k
@@ -160,15 +179,23 @@ define void @fadd_f64() {
 ; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
 ; MIPS32-NEXT:    addu $1, $2, $25
 ; MIPS32-NEXT:    lw $1, %got(h)($1)
-; MIPS32-NEXT:    lhu $2, 0($1)
+; MIPS32-NEXT:    lh $2, 0($1)
 ; MIPS32-NEXT:    fill.h $w0, $2
 ; MIPS32-NEXT:    fexupr.w $w0, $w0
 ; MIPS32-NEXT:    fexupr.d $w0, $w0
-; MIPS32-NEXT:    add.d $f0, $f0, $f0
-; MIPS32-NEXT:    splati.d $w0, $w0[0]
-; MIPS32-NEXT:    fexdo.w $w0, $w0, $w0
+; MIPS32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS32-NEXT:    mtc1 $2, $f1
+; MIPS32-NEXT:    copy_s.w $2, $w0[1]
+; MIPS32-NEXT:    mthc1 $2, $f1
+; MIPS32-NEXT:    add.d $f0, $f1, $f1
+; MIPS32-NEXT:    mfc1 $2, $f0
+; MIPS32-NEXT:    fill.w $w1, $2
+; MIPS32-NEXT:    mfhc1 $2, $f0
+; MIPS32-NEXT:    insert.w $w1[1], $2
+; MIPS32-NEXT:    insert.w $w1[3], $2
+; MIPS32-NEXT:    fexdo.w $w0, $w1, $w1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    sh $2, 0($1)
 ;
@@ -178,15 +205,18 @@ define void @fadd_f64() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(fadd_f64)))
 ; MIPS64-N32-NEXT:    lw $1, %got_disp(h)($1)
-; MIPS64-N32-NEXT:    lhu $2, 0($1)
+; MIPS64-N32-NEXT:    lh $2, 0($1)
 ; MIPS64-N32-NEXT:    fill.h $w0, $2
 ; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
 ; MIPS64-N32-NEXT:    fexupr.d $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.d $2, $w0[0]
+; MIPS64-N32-NEXT:    dmtc1 $2, $f0
 ; MIPS64-N32-NEXT:    add.d $f0, $f0, $f0
-; MIPS64-N32-NEXT:    splati.d $w0, $w0[0]
+; MIPS64-N32-NEXT:    dmfc1 $2, $f0
+; MIPS64-N32-NEXT:    fill.d $w0, $2
 ; MIPS64-N32-NEXT:    fexdo.w $w0, $w0, $w0
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N32-NEXT:    jr $ra
 ; MIPS64-N32-NEXT:    sh $2, 0($1)
 ;
@@ -196,15 +226,18 @@ define void @fadd_f64() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(fadd_f64)))
 ; MIPS64-N64-NEXT:    ld $1, %got_disp(h)($1)
-; MIPS64-N64-NEXT:    lhu $2, 0($1)
+; MIPS64-N64-NEXT:    lh $2, 0($1)
 ; MIPS64-N64-NEXT:    fill.h $w0, $2
 ; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
 ; MIPS64-N64-NEXT:    fexupr.d $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.d $2, $w0[0]
+; MIPS64-N64-NEXT:    dmtc1 $2, $f0
 ; MIPS64-N64-NEXT:    add.d $f0, $f0, $f0
-; MIPS64-N64-NEXT:    splati.d $w0, $w0[0]
+; MIPS64-N64-NEXT:    dmfc1 $2, $f0
+; MIPS64-N64-NEXT:    fill.d $w0, $2
 ; MIPS64-N64-NEXT:    fexdo.w $w0, $w0, $w0
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N64-NEXT:    jr $ra
 ; MIPS64-N64-NEXT:    sh $2, 0($1)
 entry:
@@ -226,9 +259,11 @@ define i32 @ffptoui() {
 ; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
 ; MIPS32-NEXT:    addu $1, $2, $25
 ; MIPS32-NEXT:    lw $1, %got(h)($1)
-; MIPS32-NEXT:    lhu $1, 0($1)
+; MIPS32-NEXT:    lh $1, 0($1)
 ; MIPS32-NEXT:    fill.h $w0, $1
 ; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f0
 ; MIPS32-NEXT:    trunc.w.s $f0, $f0
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    mfc1 $2, $f0
@@ -239,9 +274,11 @@ define i32 @ffptoui() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(ffptoui)))
 ; MIPS64-N32-NEXT:    lw $1, %got_disp(h)($1)
-; MIPS64-N32-NEXT:    lhu $1, 0($1)
+; MIPS64-N32-NEXT:    lh $1, 0($1)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
 ; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f0
 ; MIPS64-N32-NEXT:    trunc.w.s $f0, $f0
 ; MIPS64-N32-NEXT:    jr $ra
 ; MIPS64-N32-NEXT:    mfc1 $2, $f0
@@ -252,9 +289,11 @@ define i32 @ffptoui() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(ffptoui)))
 ; MIPS64-N64-NEXT:    ld $1, %got_disp(h)($1)
-; MIPS64-N64-NEXT:    lhu $1, 0($1)
+; MIPS64-N64-NEXT:    lh $1, 0($1)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
 ; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f0
 ; MIPS64-N64-NEXT:    trunc.w.s $f0, $f0
 ; MIPS64-N64-NEXT:    jr $ra
 ; MIPS64-N64-NEXT:    mfc1 $2, $f0
@@ -271,9 +310,11 @@ define i32 @ffptosi() {
 ; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
 ; MIPS32-NEXT:    addu $1, $2, $25
 ; MIPS32-NEXT:    lw $1, %got(h)($1)
-; MIPS32-NEXT:    lhu $1, 0($1)
+; MIPS32-NEXT:    lh $1, 0($1)
 ; MIPS32-NEXT:    fill.h $w0, $1
 ; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f0
 ; MIPS32-NEXT:    trunc.w.s $f0, $f0
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    mfc1 $2, $f0
@@ -284,9 +325,11 @@ define i32 @ffptosi() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(ffptosi)))
 ; MIPS64-N32-NEXT:    lw $1, %got_disp(h)($1)
-; MIPS64-N32-NEXT:    lhu $1, 0($1)
+; MIPS64-N32-NEXT:    lh $1, 0($1)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
 ; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f0
 ; MIPS64-N32-NEXT:    trunc.w.s $f0, $f0
 ; MIPS64-N32-NEXT:    jr $ra
 ; MIPS64-N32-NEXT:    mfc1 $2, $f0
@@ -297,9 +340,11 @@ define i32 @ffptosi() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(ffptosi)))
 ; MIPS64-N64-NEXT:    ld $1, %got_disp(h)($1)
-; MIPS64-N64-NEXT:    lhu $1, 0($1)
+; MIPS64-N64-NEXT:    lh $1, 0($1)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
 ; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f0
 ; MIPS64-N64-NEXT:    trunc.w.s $f0, $f0
 ; MIPS64-N64-NEXT:    jr $ra
 ; MIPS64-N64-NEXT:    mfc1 $2, $f0
@@ -328,11 +373,15 @@ define void @uitofp(i32 %a) {
 ; MIPS32-NEXT:    ldc1 $f0, %lo($CPI5_0)($2)
 ; MIPS32-NEXT:    ldc1 $f1, 0($sp)
 ; MIPS32-NEXT:    sub.d $f0, $f1, $f0
-; MIPS32-NEXT:    cvt.s.d $f0, $f0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mfc1 $2, $f0
+; MIPS32-NEXT:    fill.w $w1, $2
+; MIPS32-NEXT:    mfhc1 $2, $f0
+; MIPS32-NEXT:    insert.w $w1[1], $2
+; MIPS32-NEXT:    insert.w $w1[3], $2
+; MIPS32-NEXT:    fexdo.w $w0, $w1, $w1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $2, $w0[0]
 ; MIPS32-NEXT:    lw $1, %got(h)($1)
+; MIPS32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS32-NEXT:    sh $2, 0($1)
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    addiu $sp, $sp, 8
@@ -352,11 +401,12 @@ define void @uitofp(i32 %a) {
 ; MIPS64R5-N32-NEXT:    ldc1 $f0, %got_ofst(.LCPI5_0)($2)
 ; MIPS64R5-N32-NEXT:    ldc1 $f1, 8($sp)
 ; MIPS64R5-N32-NEXT:    sub.d $f0, $f1, $f0
-; MIPS64R5-N32-NEXT:    cvt.s.d $f0, $f0
-; MIPS64R5-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64R5-N32-NEXT:    dmfc1 $2, $f0
+; MIPS64R5-N32-NEXT:    fill.d $w0, $2
+; MIPS64R5-N32-NEXT:    fexdo.w $w0, $w0, $w0
 ; MIPS64R5-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64R5-N32-NEXT:    copy_s.h $2, $w0[0]
 ; MIPS64R5-N32-NEXT:    lw $1, %got_disp(h)($1)
+; MIPS64R5-N32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64R5-N32-NEXT:    sh $2, 0($1)
 ; MIPS64R5-N32-NEXT:    jr $ra
 ; MIPS64R5-N32-NEXT:    addiu $sp, $sp, 16
@@ -376,11 +426,12 @@ define void @uitofp(i32 %a) {
 ; MIPS64R5-N64-NEXT:    ldc1 $f0, %got_ofst(.LCPI5_0)($2)
 ; MIPS64R5-N64-NEXT:    ldc1 $f1, 8($sp)
 ; MIPS64R5-N64-NEXT:    sub.d $f0, $f1, $f0
-; MIPS64R5-N64-NEXT:    cvt.s.d $f0, $f0
-; MIPS64R5-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64R5-N64-NEXT:    dmfc1 $2, $f0
+; MIPS64R5-N64-NEXT:    fill.d $w0, $2
+; MIPS64R5-N64-NEXT:    fexdo.w $w0, $w0, $w0
 ; MIPS64R5-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64R5-N64-NEXT:    copy_s.h $2, $w0[0]
 ; MIPS64R5-N64-NEXT:    ld $1, %got_disp(h)($1)
+; MIPS64R5-N64-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64R5-N64-NEXT:    sh $2, 0($1)
 ; MIPS64R5-N64-NEXT:    jr $ra
 ; MIPS64R5-N64-NEXT:    daddiu $sp, $sp, 16
@@ -399,11 +450,12 @@ define void @uitofp(i32 %a) {
 ; MIPSR6-N32-NEXT:    ldc1 $f0, %got_ofst(.LCPI5_0)($2)
 ; MIPSR6-N32-NEXT:    ldc1 $f1, 8($sp)
 ; MIPSR6-N32-NEXT:    sub.d $f0, $f1, $f0
-; MIPSR6-N32-NEXT:    cvt.s.d $f0, $f0
-; MIPSR6-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPSR6-N32-NEXT:    dmfc1 $2, $f0
+; MIPSR6-N32-NEXT:    fill.d $w0, $2
+; MIPSR6-N32-NEXT:    fexdo.w $w0, $w0, $w0
 ; MIPSR6-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-N32-NEXT:    copy_s.h $2, $w0[0]
 ; MIPSR6-N32-NEXT:    lw $1, %got_disp(h)($1)
+; MIPSR6-N32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPSR6-N32-NEXT:    sh $2, 0($1)
 ; MIPSR6-N32-NEXT:    jr $ra
 ; MIPSR6-N32-NEXT:    addiu $sp, $sp, 16
@@ -422,11 +474,12 @@ define void @uitofp(i32 %a) {
 ; MIPSR6-N64-NEXT:    ldc1 $f0, %got_ofst(.LCPI5_0)($2)
 ; MIPSR6-N64-NEXT:    ldc1 $f1, 8($sp)
 ; MIPSR6-N64-NEXT:    sub.d $f0, $f1, $f0
-; MIPSR6-N64-NEXT:    cvt.s.d $f0, $f0
-; MIPSR6-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPSR6-N64-NEXT:    dmfc1 $2, $f0
+; MIPSR6-N64-NEXT:    fill.d $w0, $2
+; MIPSR6-N64-NEXT:    fexdo.w $w0, $w0, $w0
 ; MIPSR6-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-N64-NEXT:    copy_s.h $2, $w0[0]
 ; MIPSR6-N64-NEXT:    ld $1, %got_disp(h)($1)
+; MIPSR6-N64-NEXT:    copy_u.h $2, $w0[0]
 ; MIPSR6-N64-NEXT:    sh $2, 0($1)
 ; MIPSR6-N64-NEXT:    jr $ra
 ; MIPSR6-N64-NEXT:    daddiu $sp, $sp, 16
@@ -456,13 +509,16 @@ define void @fadd() {
 ; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
 ; MIPS32-NEXT:    addu $1, $2, $25
 ; MIPS32-NEXT:    lw $1, %got(g)($1)
-; MIPS32-NEXT:    lhu $2, 0($1)
+; MIPS32-NEXT:    lh $2, 0($1)
 ; MIPS32-NEXT:    fill.h $w0, $2
 ; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS32-NEXT:    mtc1 $2, $f0
 ; MIPS32-NEXT:    add.s $f0, $f0, $f0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mfc1 $2, $f0
+; MIPS32-NEXT:    fill.w $w0, $2
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    sh $2, 0($1)
 ;
@@ -472,13 +528,16 @@ define void @fadd() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(fadd)))
 ; MIPS64-N32-NEXT:    lw $1, %got_disp(g)($1)
-; MIPS64-N32-NEXT:    lhu $2, 0($1)
+; MIPS64-N32-NEXT:    lh $2, 0($1)
 ; MIPS64-N32-NEXT:    fill.h $w0, $2
 ; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $2, $f0
 ; MIPS64-N32-NEXT:    add.s $f0, $f0, $f0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mfc1 $2, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $2
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N32-NEXT:    jr $ra
 ; MIPS64-N32-NEXT:    sh $2, 0($1)
 ;
@@ -488,13 +547,16 @@ define void @fadd() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(fadd)))
 ; MIPS64-N64-NEXT:    ld $1, %got_disp(g)($1)
-; MIPS64-N64-NEXT:    lhu $2, 0($1)
+; MIPS64-N64-NEXT:    lh $2, 0($1)
 ; MIPS64-N64-NEXT:    fill.h $w0, $2
 ; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $2, $f0
 ; MIPS64-N64-NEXT:    add.s $f0, $f0, $f0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mfc1 $2, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $2
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N64-NEXT:    jr $ra
 ; MIPS64-N64-NEXT:    sh $2, 0($1)
 entry:
@@ -518,13 +580,16 @@ define void @fsub() {
 ; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
 ; MIPS32-NEXT:    addu $1, $2, $25
 ; MIPS32-NEXT:    lw $1, %got(g)($1)
-; MIPS32-NEXT:    lhu $2, 0($1)
+; MIPS32-NEXT:    lh $2, 0($1)
 ; MIPS32-NEXT:    fill.h $w0, $2
 ; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS32-NEXT:    mtc1 $2, $f0
 ; MIPS32-NEXT:    sub.s $f0, $f0, $f0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mfc1 $2, $f0
+; MIPS32-NEXT:    fill.w $w0, $2
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    sh $2, 0($1)
 ;
@@ -534,13 +599,16 @@ define void @fsub() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(fsub)))
 ; MIPS64-N32-NEXT:    lw $1, %got_disp(g)($1)
-; MIPS64-N32-NEXT:    lhu $2, 0($1)
+; MIPS64-N32-NEXT:    lh $2, 0($1)
 ; MIPS64-N32-NEXT:    fill.h $w0, $2
 ; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $2, $f0
 ; MIPS64-N32-NEXT:    sub.s $f0, $f0, $f0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mfc1 $2, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $2
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N32-NEXT:    jr $ra
 ; MIPS64-N32-NEXT:    sh $2, 0($1)
 ;
@@ -550,13 +618,16 @@ define void @fsub() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(fsub)))
 ; MIPS64-N64-NEXT:    ld $1, %got_disp(g)($1)
-; MIPS64-N64-NEXT:    lhu $2, 0($1)
+; MIPS64-N64-NEXT:    lh $2, 0($1)
 ; MIPS64-N64-NEXT:    fill.h $w0, $2
 ; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $2, $f0
 ; MIPS64-N64-NEXT:    sub.s $f0, $f0, $f0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mfc1 $2, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $2
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N64-NEXT:    jr $ra
 ; MIPS64-N64-NEXT:    sh $2, 0($1)
 entry:
@@ -580,13 +651,16 @@ define void @fmult() {
 ; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
 ; MIPS32-NEXT:    addu $1, $2, $25
 ; MIPS32-NEXT:    lw $1, %got(g)($1)
-; MIPS32-NEXT:    lhu $2, 0($1)
+; MIPS32-NEXT:    lh $2, 0($1)
 ; MIPS32-NEXT:    fill.h $w0, $2
 ; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS32-NEXT:    mtc1 $2, $f0
 ; MIPS32-NEXT:    mul.s $f0, $f0, $f0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mfc1 $2, $f0
+; MIPS32-NEXT:    fill.w $w0, $2
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    sh $2, 0($1)
 ;
@@ -596,13 +670,16 @@ define void @fmult() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(fmult)))
 ; MIPS64-N32-NEXT:    lw $1, %got_disp(g)($1)
-; MIPS64-N32-NEXT:    lhu $2, 0($1)
+; MIPS64-N32-NEXT:    lh $2, 0($1)
 ; MIPS64-N32-NEXT:    fill.h $w0, $2
 ; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $2, $f0
 ; MIPS64-N32-NEXT:    mul.s $f0, $f0, $f0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mfc1 $2, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $2
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N32-NEXT:    jr $ra
 ; MIPS64-N32-NEXT:    sh $2, 0($1)
 ;
@@ -612,13 +689,16 @@ define void @fmult() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(fmult)))
 ; MIPS64-N64-NEXT:    ld $1, %got_disp(g)($1)
-; MIPS64-N64-NEXT:    lhu $2, 0($1)
+; MIPS64-N64-NEXT:    lh $2, 0($1)
 ; MIPS64-N64-NEXT:    fill.h $w0, $2
 ; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $2, $f0
 ; MIPS64-N64-NEXT:    mul.s $f0, $f0, $f0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mfc1 $2, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $2
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N64-NEXT:    jr $ra
 ; MIPS64-N64-NEXT:    sh $2, 0($1)
 entry:
@@ -642,13 +722,16 @@ define void @fdiv() {
 ; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
 ; MIPS32-NEXT:    addu $1, $2, $25
 ; MIPS32-NEXT:    lw $1, %got(g)($1)
-; MIPS32-NEXT:    lhu $2, 0($1)
+; MIPS32-NEXT:    lh $2, 0($1)
 ; MIPS32-NEXT:    fill.h $w0, $2
 ; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS32-NEXT:    mtc1 $2, $f0
 ; MIPS32-NEXT:    div.s $f0, $f0, $f0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mfc1 $2, $f0
+; MIPS32-NEXT:    fill.w $w0, $2
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    sh $2, 0($1)
 ;
@@ -658,13 +741,16 @@ define void @fdiv() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(fdiv)))
 ; MIPS64-N32-NEXT:    lw $1, %got_disp(g)($1)
-; MIPS64-N32-NEXT:    lhu $2, 0($1)
+; MIPS64-N32-NEXT:    lh $2, 0($1)
 ; MIPS64-N32-NEXT:    fill.h $w0, $2
 ; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $2, $f0
 ; MIPS64-N32-NEXT:    div.s $f0, $f0, $f0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mfc1 $2, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $2
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N32-NEXT:    jr $ra
 ; MIPS64-N32-NEXT:    sh $2, 0($1)
 ;
@@ -674,13 +760,16 @@ define void @fdiv() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(fdiv)))
 ; MIPS64-N64-NEXT:    ld $1, %got_disp(g)($1)
-; MIPS64-N64-NEXT:    lhu $2, 0($1)
+; MIPS64-N64-NEXT:    lh $2, 0($1)
 ; MIPS64-N64-NEXT:    fill.h $w0, $2
 ; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $2, $f0
 ; MIPS64-N64-NEXT:    div.s $f0, $f0, $f0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mfc1 $2, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $2
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N64-NEXT:    jr $ra
 ; MIPS64-N64-NEXT:    sh $2, 0($1)
 entry:
@@ -710,16 +799,18 @@ define void @frem() {
 ; MIPS32-NEXT:    .cfi_offset 16, -8
 ; MIPS32-NEXT:    addu $gp, $2, $25
 ; MIPS32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-NEXT:    lhu $1, 0($16)
+; MIPS32-NEXT:    lh $1, 0($16)
 ; MIPS32-NEXT:    fill.h $w0, $1
-; MIPS32-NEXT:    fexupr.w $w12, $w0
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f12
 ; MIPS32-NEXT:    lw $25, %call16(fmodf)($gp)
 ; MIPS32-NEXT:    jalr $25
 ; MIPS32-NEXT:    mov.s $f14, $f12
-; MIPS32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w0, $1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-NEXT:    sh $1, 0($16)
 ; MIPS32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -740,16 +831,18 @@ define void @frem() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(frem)))
 ; MIPS64-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64-N32-NEXT:    lhu $1, 0($16)
+; MIPS64-N32-NEXT:    lh $1, 0($16)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
 ; MIPS64-N32-NEXT:    lw $25, %call16(fmodf)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
 ; MIPS64-N32-NEXT:    mov.s $f13, $f12
-; MIPS64-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mfc1 $1, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $1
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N32-NEXT:    sh $1, 0($16)
 ; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -771,16 +864,18 @@ define void @frem() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(frem)))
 ; MIPS64-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64-N64-NEXT:    lhu $1, 0($16)
+; MIPS64-N64-NEXT:    lh $1, 0($16)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
 ; MIPS64-N64-NEXT:    ld $25, %call16(fmodf)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
 ; MIPS64-N64-NEXT:    mov.s $f13, $f12
-; MIPS64-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    sh $1, 0($16)
 ; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -810,9 +905,11 @@ define void @fcmp() {
 ; MIPS32-O32-NEXT:    addiu $2, $2, %lo(_gp_disp)
 ; MIPS32-O32-NEXT:    addu $1, $2, $25
 ; MIPS32-O32-NEXT:    lw $2, %got(g)($1)
-; MIPS32-O32-NEXT:    lhu $2, 0($2)
+; MIPS32-O32-NEXT:    lh $2, 0($2)
 ; MIPS32-O32-NEXT:    fill.h $w0, $2
 ; MIPS32-O32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-O32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS32-O32-NEXT:    mtc1 $2, $f0
 ; MIPS32-O32-NEXT:    addiu $2, $zero, 1
 ; MIPS32-O32-NEXT:    c.un.s $f0, $f0
 ; MIPS32-O32-NEXT:    movt $2, $zero, $fcc0
@@ -826,9 +923,11 @@ define void @fcmp() {
 ; MIPS64R5-N32-NEXT:    addu $1, $1, $25
 ; MIPS64R5-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(fcmp)))
 ; MIPS64R5-N32-NEXT:    lw $2, %got_disp(g)($1)
-; MIPS64R5-N32-NEXT:    lhu $2, 0($2)
+; MIPS64R5-N32-NEXT:    lh $2, 0($2)
 ; MIPS64R5-N32-NEXT:    fill.h $w0, $2
 ; MIPS64R5-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64R5-N32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64R5-N32-NEXT:    mtc1 $2, $f0
 ; MIPS64R5-N32-NEXT:    addiu $2, $zero, 1
 ; MIPS64R5-N32-NEXT:    c.un.s $f0, $f0
 ; MIPS64R5-N32-NEXT:    movt $2, $zero, $fcc0
@@ -842,9 +941,11 @@ define void @fcmp() {
 ; MIPS64R5-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64R5-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(fcmp)))
 ; MIPS64R5-N64-NEXT:    ld $2, %got_disp(g)($1)
-; MIPS64R5-N64-NEXT:    lhu $2, 0($2)
+; MIPS64R5-N64-NEXT:    lh $2, 0($2)
 ; MIPS64R5-N64-NEXT:    fill.h $w0, $2
 ; MIPS64R5-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64R5-N64-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64R5-N64-NEXT:    mtc1 $2, $f0
 ; MIPS64R5-N64-NEXT:    addiu $2, $zero, 1
 ; MIPS64R5-N64-NEXT:    c.un.s $f0, $f0
 ; MIPS64R5-N64-NEXT:    movt $2, $zero, $fcc0
@@ -858,14 +959,16 @@ define void @fcmp() {
 ; MIPSR6-O32-NEXT:    addiu $2, $2, %lo(_gp_disp)
 ; MIPSR6-O32-NEXT:    addu $1, $2, $25
 ; MIPSR6-O32-NEXT:    lw $2, %got(g)($1)
-; MIPSR6-O32-NEXT:    lhu $2, 0($2)
+; MIPSR6-O32-NEXT:    lh $2, 0($2)
 ; MIPSR6-O32-NEXT:    fill.h $w0, $2
 ; MIPSR6-O32-NEXT:    fexupr.w $w0, $w0
+; MIPSR6-O32-NEXT:    copy_s.w $2, $w0[0]
+; MIPSR6-O32-NEXT:    mtc1 $2, $f0
 ; MIPSR6-O32-NEXT:    cmp.un.s $f0, $f0, $f0
-; MIPSR6-O32-NEXT:    lw $1, %got(i1)($1)
 ; MIPSR6-O32-NEXT:    mfc1 $2, $f0
 ; MIPSR6-O32-NEXT:    not $2, $2
 ; MIPSR6-O32-NEXT:    andi $2, $2, 1
+; MIPSR6-O32-NEXT:    lw $1, %got(i1)($1)
 ; MIPSR6-O32-NEXT:    jr $ra
 ; MIPSR6-O32-NEXT:    sh $2, 0($1)
 ;
@@ -875,14 +978,16 @@ define void @fcmp() {
 ; MIPSR6-N32-NEXT:    addu $1, $1, $25
 ; MIPSR6-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(fcmp)))
 ; MIPSR6-N32-NEXT:    lw $2, %got_disp(g)($1)
-; MIPSR6-N32-NEXT:    lhu $2, 0($2)
+; MIPSR6-N32-NEXT:    lh $2, 0($2)
 ; MIPSR6-N32-NEXT:    fill.h $w0, $2
 ; MIPSR6-N32-NEXT:    fexupr.w $w0, $w0
+; MIPSR6-N32-NEXT:    copy_s.w $2, $w0[0]
+; MIPSR6-N32-NEXT:    mtc1 $2, $f0
 ; MIPSR6-N32-NEXT:    cmp.un.s $f0, $f0, $f0
-; MIPSR6-N32-NEXT:    lw $1, %got_disp(i1)($1)
 ; MIPSR6-N32-NEXT:    mfc1 $2, $f0
 ; MIPSR6-N32-NEXT:    not $2, $2
 ; MIPSR6-N32-NEXT:    andi $2, $2, 1
+; MIPSR6-N32-NEXT:    lw $1, %got_disp(i1)($1)
 ; MIPSR6-N32-NEXT:    jr $ra
 ; MIPSR6-N32-NEXT:    sh $2, 0($1)
 ;
@@ -892,14 +997,16 @@ define void @fcmp() {
 ; MIPSR6-N64-NEXT:    daddu $1, $1, $25
 ; MIPSR6-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(fcmp)))
 ; MIPSR6-N64-NEXT:    ld $2, %got_disp(g)($1)
-; MIPSR6-N64-NEXT:    lhu $2, 0($2)
+; MIPSR6-N64-NEXT:    lh $2, 0($2)
 ; MIPSR6-N64-NEXT:    fill.h $w0, $2
 ; MIPSR6-N64-NEXT:    fexupr.w $w0, $w0
+; MIPSR6-N64-NEXT:    copy_s.w $2, $w0[0]
+; MIPSR6-N64-NEXT:    mtc1 $2, $f0
 ; MIPSR6-N64-NEXT:    cmp.un.s $f0, $f0, $f0
-; MIPSR6-N64-NEXT:    ld $1, %got_disp(i1)($1)
 ; MIPSR6-N64-NEXT:    mfc1 $2, $f0
 ; MIPSR6-N64-NEXT:    not $2, $2
 ; MIPSR6-N64-NEXT:    andi $2, $2, 1
+; MIPSR6-N64-NEXT:    ld $1, %got_disp(i1)($1)
 ; MIPSR6-N64-NEXT:    jr $ra
 ; MIPSR6-N64-NEXT:    sh $2, 0($1)
 entry:
@@ -924,13 +1031,16 @@ define void @fpowi() {
 ; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
 ; MIPS32-NEXT:    addu $1, $2, $25
 ; MIPS32-NEXT:    lw $1, %got(g)($1)
-; MIPS32-NEXT:    lhu $2, 0($1)
+; MIPS32-NEXT:    lh $2, 0($1)
 ; MIPS32-NEXT:    fill.h $w0, $2
 ; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS32-NEXT:    mtc1 $2, $f0
 ; MIPS32-NEXT:    mul.s $f0, $f0, $f0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mfc1 $2, $f0
+; MIPS32-NEXT:    fill.w $w0, $2
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    sh $2, 0($1)
 ;
@@ -940,13 +1050,16 @@ define void @fpowi() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(fpowi)))
 ; MIPS64-N32-NEXT:    lw $1, %got_disp(g)($1)
-; MIPS64-N32-NEXT:    lhu $2, 0($1)
+; MIPS64-N32-NEXT:    lh $2, 0($1)
 ; MIPS64-N32-NEXT:    fill.h $w0, $2
 ; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $2, $f0
 ; MIPS64-N32-NEXT:    mul.s $f0, $f0, $f0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mfc1 $2, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $2
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N32-NEXT:    jr $ra
 ; MIPS64-N32-NEXT:    sh $2, 0($1)
 ;
@@ -956,13 +1069,16 @@ define void @fpowi() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(fpowi)))
 ; MIPS64-N64-NEXT:    ld $1, %got_disp(g)($1)
-; MIPS64-N64-NEXT:    lhu $2, 0($1)
+; MIPS64-N64-NEXT:    lh $2, 0($1)
 ; MIPS64-N64-NEXT:    fill.h $w0, $2
 ; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $2, $f0
 ; MIPS64-N64-NEXT:    mul.s $f0, $f0, $f0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mfc1 $2, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $2
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N64-NEXT:    jr $ra
 ; MIPS64-N64-NEXT:    sh $2, 0($1)
 entry:
@@ -989,17 +1105,18 @@ define void @fpowi_var(i32 %var) {
 ; MIPS32-NEXT:    .cfi_offset 16, -8
 ; MIPS32-NEXT:    addu $gp, $2, $25
 ; MIPS32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-NEXT:    lhu $1, 0($16)
+; MIPS32-NEXT:    lh $1, 0($16)
 ; MIPS32-NEXT:    fill.h $w0, $1
-; MIPS32-NEXT:    fexupr.w $w12, $w0
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f12
 ; MIPS32-NEXT:    lw $25, %call16(__powisf2)($gp)
-; MIPS32-NEXT:    # kill: def $f12 killed $f12 killed $w12
 ; MIPS32-NEXT:    jalr $25
 ; MIPS32-NEXT:    move $5, $4
-; MIPS32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w0, $1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-NEXT:    sh $1, 0($16)
 ; MIPS32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -1021,15 +1138,17 @@ define void @fpowi_var(i32 %var) {
 ; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(fpowi_var)))
 ; MIPS64-N32-NEXT:    sll $5, $4, 0
 ; MIPS64-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64-N32-NEXT:    lhu $1, 0($16)
+; MIPS64-N32-NEXT:    lh $1, 0($16)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N32-NEXT:    lw $25, %call16(__powisf2)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
+; MIPS64-N32-NEXT:    mfc1 $1, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $1
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N32-NEXT:    sh $1, 0($16)
 ; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1052,15 +1171,17 @@ define void @fpowi_var(i32 %var) {
 ; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(fpowi_var)))
 ; MIPS64-N64-NEXT:    sll $5, $4, 0
 ; MIPS64-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64-N64-NEXT:    lhu $1, 0($16)
+; MIPS64-N64-NEXT:    lh $1, 0($16)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N64-NEXT:    ld $25, %call16(__powisf2)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    sh $1, 0($16)
 ; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1094,15 +1215,17 @@ define void @fpow(float %var) {
 ; MIPS32-NEXT:    addu $gp, $2, $25
 ; MIPS32-NEXT:    mov.s $f14, $f12
 ; MIPS32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-NEXT:    lhu $1, 0($16)
+; MIPS32-NEXT:    lh $1, 0($16)
 ; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS32-NEXT:    lw $25, %call16(powf)($gp)
 ; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    fexupr.w $w12, $w0
-; MIPS32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f12
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w0, $1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-NEXT:    sh $1, 0($16)
 ; MIPS32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -1124,15 +1247,17 @@ define void @fpow(float %var) {
 ; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(fpow)))
 ; MIPS64-N32-NEXT:    mov.s $f13, $f12
 ; MIPS64-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64-N32-NEXT:    lhu $1, 0($16)
+; MIPS64-N32-NEXT:    lh $1, 0($16)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N32-NEXT:    lw $25, %call16(powf)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
+; MIPS64-N32-NEXT:    mfc1 $1, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $1
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N32-NEXT:    sh $1, 0($16)
 ; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1155,15 +1280,17 @@ define void @fpow(float %var) {
 ; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(fpow)))
 ; MIPS64-N64-NEXT:    mov.s $f13, $f12
 ; MIPS64-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64-N64-NEXT:    lhu $1, 0($16)
+; MIPS64-N64-NEXT:    lh $1, 0($16)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N64-NEXT:    ld $25, %call16(powf)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    sh $1, 0($16)
 ; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1197,15 +1324,17 @@ define void @flog2() {
 ; MIPS32-NEXT:    .cfi_offset 16, -8
 ; MIPS32-NEXT:    addu $gp, $2, $25
 ; MIPS32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-NEXT:    lhu $1, 0($16)
+; MIPS32-NEXT:    lh $1, 0($16)
 ; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS32-NEXT:    lw $25, %call16(log2f)($gp)
 ; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    fexupr.w $w12, $w0
-; MIPS32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f12
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w0, $1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-NEXT:    sh $1, 0($16)
 ; MIPS32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -1226,15 +1355,17 @@ define void @flog2() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(flog2)))
 ; MIPS64-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64-N32-NEXT:    lhu $1, 0($16)
+; MIPS64-N32-NEXT:    lh $1, 0($16)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N32-NEXT:    lw $25, %call16(log2f)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
+; MIPS64-N32-NEXT:    mfc1 $1, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $1
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N32-NEXT:    sh $1, 0($16)
 ; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1256,15 +1387,17 @@ define void @flog2() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(flog2)))
 ; MIPS64-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64-N64-NEXT:    lhu $1, 0($16)
+; MIPS64-N64-NEXT:    lh $1, 0($16)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N64-NEXT:    ld $25, %call16(log2f)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    sh $1, 0($16)
 ; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1297,15 +1430,17 @@ define void @flog10() {
 ; MIPS32-NEXT:    .cfi_offset 16, -8
 ; MIPS32-NEXT:    addu $gp, $2, $25
 ; MIPS32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-NEXT:    lhu $1, 0($16)
+; MIPS32-NEXT:    lh $1, 0($16)
 ; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS32-NEXT:    lw $25, %call16(log10f)($gp)
 ; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    fexupr.w $w12, $w0
-; MIPS32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f12
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w0, $1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-NEXT:    sh $1, 0($16)
 ; MIPS32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -1326,15 +1461,17 @@ define void @flog10() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(flog10)))
 ; MIPS64-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64-N32-NEXT:    lhu $1, 0($16)
+; MIPS64-N32-NEXT:    lh $1, 0($16)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N32-NEXT:    lw $25, %call16(log10f)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
+; MIPS64-N32-NEXT:    mfc1 $1, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $1
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N32-NEXT:    sh $1, 0($16)
 ; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1356,15 +1493,17 @@ define void @flog10() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(flog10)))
 ; MIPS64-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64-N64-NEXT:    lhu $1, 0($16)
+; MIPS64-N64-NEXT:    lh $1, 0($16)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N64-NEXT:    ld $25, %call16(log10f)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    sh $1, 0($16)
 ; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1391,13 +1530,16 @@ define void @fsqrt() {
 ; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
 ; MIPS32-NEXT:    addu $1, $2, $25
 ; MIPS32-NEXT:    lw $1, %got(g)($1)
-; MIPS32-NEXT:    lhu $2, 0($1)
+; MIPS32-NEXT:    lh $2, 0($1)
 ; MIPS32-NEXT:    fill.h $w0, $2
 ; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS32-NEXT:    mtc1 $2, $f0
 ; MIPS32-NEXT:    sqrt.s $f0, $f0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mfc1 $2, $f0
+; MIPS32-NEXT:    fill.w $w0, $2
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    sh $2, 0($1)
 ;
@@ -1407,13 +1549,16 @@ define void @fsqrt() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(fsqrt)))
 ; MIPS64-N32-NEXT:    lw $1, %got_disp(g)($1)
-; MIPS64-N32-NEXT:    lhu $2, 0($1)
+; MIPS64-N32-NEXT:    lh $2, 0($1)
 ; MIPS64-N32-NEXT:    fill.h $w0, $2
 ; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $2, $f0
 ; MIPS64-N32-NEXT:    sqrt.s $f0, $f0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mfc1 $2, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $2
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N32-NEXT:    jr $ra
 ; MIPS64-N32-NEXT:    sh $2, 0($1)
 ;
@@ -1423,13 +1568,16 @@ define void @fsqrt() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(fsqrt)))
 ; MIPS64-N64-NEXT:    ld $1, %got_disp(g)($1)
-; MIPS64-N64-NEXT:    lhu $2, 0($1)
+; MIPS64-N64-NEXT:    lh $2, 0($1)
 ; MIPS64-N64-NEXT:    fill.h $w0, $2
 ; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $2, $f0
 ; MIPS64-N64-NEXT:    sqrt.s $f0, $f0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mfc1 $2, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $2
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N64-NEXT:    jr $ra
 ; MIPS64-N64-NEXT:    sh $2, 0($1)
 entry:
@@ -1458,15 +1606,17 @@ define void @fsin() {
 ; MIPS32-NEXT:    .cfi_offset 16, -8
 ; MIPS32-NEXT:    addu $gp, $2, $25
 ; MIPS32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-NEXT:    lhu $1, 0($16)
+; MIPS32-NEXT:    lh $1, 0($16)
 ; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS32-NEXT:    lw $25, %call16(sinf)($gp)
 ; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    fexupr.w $w12, $w0
-; MIPS32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f12
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w0, $1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-NEXT:    sh $1, 0($16)
 ; MIPS32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -1487,15 +1637,17 @@ define void @fsin() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(fsin)))
 ; MIPS64-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64-N32-NEXT:    lhu $1, 0($16)
+; MIPS64-N32-NEXT:    lh $1, 0($16)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N32-NEXT:    lw $25, %call16(sinf)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
+; MIPS64-N32-NEXT:    mfc1 $1, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $1
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N32-NEXT:    sh $1, 0($16)
 ; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1517,15 +1669,17 @@ define void @fsin() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(fsin)))
 ; MIPS64-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64-N64-NEXT:    lhu $1, 0($16)
+; MIPS64-N64-NEXT:    lh $1, 0($16)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N64-NEXT:    ld $25, %call16(sinf)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    sh $1, 0($16)
 ; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1558,15 +1712,17 @@ define void @fcos() {
 ; MIPS32-NEXT:    .cfi_offset 16, -8
 ; MIPS32-NEXT:    addu $gp, $2, $25
 ; MIPS32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-NEXT:    lhu $1, 0($16)
+; MIPS32-NEXT:    lh $1, 0($16)
 ; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS32-NEXT:    lw $25, %call16(cosf)($gp)
 ; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    fexupr.w $w12, $w0
-; MIPS32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f12
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w0, $1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-NEXT:    sh $1, 0($16)
 ; MIPS32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -1587,15 +1743,17 @@ define void @fcos() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(fcos)))
 ; MIPS64-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64-N32-NEXT:    lhu $1, 0($16)
+; MIPS64-N32-NEXT:    lh $1, 0($16)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N32-NEXT:    lw $25, %call16(cosf)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
+; MIPS64-N32-NEXT:    mfc1 $1, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $1
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N32-NEXT:    sh $1, 0($16)
 ; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1617,15 +1775,17 @@ define void @fcos() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(fcos)))
 ; MIPS64-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64-N64-NEXT:    lhu $1, 0($16)
+; MIPS64-N64-NEXT:    lh $1, 0($16)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N64-NEXT:    ld $25, %call16(cosf)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    sh $1, 0($16)
 ; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1658,15 +1818,17 @@ define void @fexp() {
 ; MIPS32-NEXT:    .cfi_offset 16, -8
 ; MIPS32-NEXT:    addu $gp, $2, $25
 ; MIPS32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-NEXT:    lhu $1, 0($16)
+; MIPS32-NEXT:    lh $1, 0($16)
 ; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS32-NEXT:    lw $25, %call16(expf)($gp)
 ; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    fexupr.w $w12, $w0
-; MIPS32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f12
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w0, $1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-NEXT:    sh $1, 0($16)
 ; MIPS32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -1687,15 +1849,17 @@ define void @fexp() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(fexp)))
 ; MIPS64-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64-N32-NEXT:    lhu $1, 0($16)
+; MIPS64-N32-NEXT:    lh $1, 0($16)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N32-NEXT:    lw $25, %call16(expf)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
+; MIPS64-N32-NEXT:    mfc1 $1, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $1
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N32-NEXT:    sh $1, 0($16)
 ; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1717,15 +1881,17 @@ define void @fexp() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(fexp)))
 ; MIPS64-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64-N64-NEXT:    lhu $1, 0($16)
+; MIPS64-N64-NEXT:    lh $1, 0($16)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N64-NEXT:    ld $25, %call16(expf)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    sh $1, 0($16)
 ; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1758,15 +1924,17 @@ define void @fexp2() {
 ; MIPS32-NEXT:    .cfi_offset 16, -8
 ; MIPS32-NEXT:    addu $gp, $2, $25
 ; MIPS32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-NEXT:    lhu $1, 0($16)
+; MIPS32-NEXT:    lh $1, 0($16)
 ; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS32-NEXT:    lw $25, %call16(exp2f)($gp)
 ; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    fexupr.w $w12, $w0
-; MIPS32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f12
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w0, $1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-NEXT:    sh $1, 0($16)
 ; MIPS32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -1787,15 +1955,17 @@ define void @fexp2() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(fexp2)))
 ; MIPS64-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64-N32-NEXT:    lhu $1, 0($16)
+; MIPS64-N32-NEXT:    lh $1, 0($16)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N32-NEXT:    lw $25, %call16(exp2f)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
+; MIPS64-N32-NEXT:    mfc1 $1, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $1
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N32-NEXT:    sh $1, 0($16)
 ; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1817,15 +1987,17 @@ define void @fexp2() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(fexp2)))
 ; MIPS64-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64-N64-NEXT:    lhu $1, 0($16)
+; MIPS64-N64-NEXT:    lh $1, 0($16)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N64-NEXT:    ld $25, %call16(exp2f)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    sh $1, 0($16)
 ; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1860,17 +2032,18 @@ define void @ffma(float %b, float %c) {
 ; MIPS32-NEXT:    mov.s $f0, $f12
 ; MIPS32-NEXT:    mfc1 $6, $f14
 ; MIPS32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-NEXT:    lhu $1, 0($16)
+; MIPS32-NEXT:    lh $1, 0($16)
 ; MIPS32-NEXT:    fill.h $w1, $1
-; MIPS32-NEXT:    fexupr.w $w12, $w1
+; MIPS32-NEXT:    fexupr.w $w1, $w1
+; MIPS32-NEXT:    copy_s.w $1, $w1[0]
+; MIPS32-NEXT:    mtc1 $1, $f12
 ; MIPS32-NEXT:    lw $25, %call16(fmaf)($gp)
-; MIPS32-NEXT:    # kill: def $f12 killed $f12 killed $w12
 ; MIPS32-NEXT:    jalr $25
 ; MIPS32-NEXT:    mov.s $f14, $f0
-; MIPS32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w0, $1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-NEXT:    sh $1, 0($16)
 ; MIPS32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -1893,15 +2066,17 @@ define void @ffma(float %b, float %c) {
 ; MIPS64-N32-NEXT:    mov.s $f14, $f13
 ; MIPS64-N32-NEXT:    mov.s $f13, $f12
 ; MIPS64-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64-N32-NEXT:    lhu $1, 0($16)
+; MIPS64-N32-NEXT:    lh $1, 0($16)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N32-NEXT:    lw $25, %call16(fmaf)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
+; MIPS64-N32-NEXT:    mfc1 $1, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $1
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N32-NEXT:    sh $1, 0($16)
 ; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1925,15 +2100,17 @@ define void @ffma(float %b, float %c) {
 ; MIPS64-N64-NEXT:    mov.s $f14, $f13
 ; MIPS64-N64-NEXT:    mov.s $f13, $f12
 ; MIPS64-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64-N64-NEXT:    lhu $1, 0($16)
+; MIPS64-N64-NEXT:    lh $1, 0($16)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N64-NEXT:    ld $25, %call16(fmaf)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    sh $1, 0($16)
 ; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -1960,13 +2137,16 @@ define void @ffmuladd(float %b, float %c) {
 ; MIPS32-O32-NEXT:    addiu $2, $2, %lo(_gp_disp)
 ; MIPS32-O32-NEXT:    addu $1, $2, $25
 ; MIPS32-O32-NEXT:    lw $1, %got(g)($1)
-; MIPS32-O32-NEXT:    lhu $2, 0($1)
+; MIPS32-O32-NEXT:    lh $2, 0($1)
 ; MIPS32-O32-NEXT:    fill.h $w0, $2
 ; MIPS32-O32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-O32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS32-O32-NEXT:    mtc1 $2, $f0
 ; MIPS32-O32-NEXT:    madd.s $f0, $f14, $f0, $f12
-; MIPS32-O32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-O32-NEXT:    mfc1 $2, $f0
+; MIPS32-O32-NEXT:    fill.w $w0, $2
 ; MIPS32-O32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-O32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS32-O32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS32-O32-NEXT:    jr $ra
 ; MIPS32-O32-NEXT:    sh $2, 0($1)
 ;
@@ -1976,13 +2156,16 @@ define void @ffmuladd(float %b, float %c) {
 ; MIPS64R5-N32-NEXT:    addu $1, $1, $25
 ; MIPS64R5-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(ffmuladd)))
 ; MIPS64R5-N32-NEXT:    lw $1, %got_disp(g)($1)
-; MIPS64R5-N32-NEXT:    lhu $2, 0($1)
+; MIPS64R5-N32-NEXT:    lh $2, 0($1)
 ; MIPS64R5-N32-NEXT:    fill.h $w0, $2
 ; MIPS64R5-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64R5-N32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64R5-N32-NEXT:    mtc1 $2, $f0
 ; MIPS64R5-N32-NEXT:    madd.s $f0, $f13, $f0, $f12
-; MIPS64R5-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64R5-N32-NEXT:    mfc1 $2, $f0
+; MIPS64R5-N32-NEXT:    fill.w $w0, $2
 ; MIPS64R5-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64R5-N32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64R5-N32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64R5-N32-NEXT:    jr $ra
 ; MIPS64R5-N32-NEXT:    sh $2, 0($1)
 ;
@@ -1992,13 +2175,16 @@ define void @ffmuladd(float %b, float %c) {
 ; MIPS64R5-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64R5-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(ffmuladd)))
 ; MIPS64R5-N64-NEXT:    ld $1, %got_disp(g)($1)
-; MIPS64R5-N64-NEXT:    lhu $2, 0($1)
+; MIPS64R5-N64-NEXT:    lh $2, 0($1)
 ; MIPS64R5-N64-NEXT:    fill.h $w0, $2
 ; MIPS64R5-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64R5-N64-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64R5-N64-NEXT:    mtc1 $2, $f0
 ; MIPS64R5-N64-NEXT:    madd.s $f0, $f13, $f0, $f12
-; MIPS64R5-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64R5-N64-NEXT:    mfc1 $2, $f0
+; MIPS64R5-N64-NEXT:    fill.w $w0, $2
 ; MIPS64R5-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64R5-N64-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64R5-N64-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64R5-N64-NEXT:    jr $ra
 ; MIPS64R5-N64-NEXT:    sh $2, 0($1)
 ;
@@ -2008,14 +2194,17 @@ define void @ffmuladd(float %b, float %c) {
 ; MIPSR6-O32-NEXT:    addiu $2, $2, %lo(_gp_disp)
 ; MIPSR6-O32-NEXT:    addu $1, $2, $25
 ; MIPSR6-O32-NEXT:    lw $1, %got(g)($1)
-; MIPSR6-O32-NEXT:    lhu $2, 0($1)
+; MIPSR6-O32-NEXT:    lh $2, 0($1)
 ; MIPSR6-O32-NEXT:    fill.h $w0, $2
 ; MIPSR6-O32-NEXT:    fexupr.w $w0, $w0
+; MIPSR6-O32-NEXT:    copy_s.w $2, $w0[0]
+; MIPSR6-O32-NEXT:    mtc1 $2, $f0
 ; MIPSR6-O32-NEXT:    mul.s $f0, $f0, $f12
 ; MIPSR6-O32-NEXT:    add.s $f0, $f0, $f14
-; MIPSR6-O32-NEXT:    splati.w $w0, $w0[0]
+; MIPSR6-O32-NEXT:    mfc1 $2, $f0
+; MIPSR6-O32-NEXT:    fill.w $w0, $2
 ; MIPSR6-O32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-O32-NEXT:    copy_s.h $2, $w0[0]
+; MIPSR6-O32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPSR6-O32-NEXT:    jr $ra
 ; MIPSR6-O32-NEXT:    sh $2, 0($1)
 ;
@@ -2025,14 +2214,17 @@ define void @ffmuladd(float %b, float %c) {
 ; MIPSR6-N32-NEXT:    addu $1, $1, $25
 ; MIPSR6-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(ffmuladd)))
 ; MIPSR6-N32-NEXT:    lw $1, %got_disp(g)($1)
-; MIPSR6-N32-NEXT:    lhu $2, 0($1)
+; MIPSR6-N32-NEXT:    lh $2, 0($1)
 ; MIPSR6-N32-NEXT:    fill.h $w0, $2
 ; MIPSR6-N32-NEXT:    fexupr.w $w0, $w0
+; MIPSR6-N32-NEXT:    copy_s.w $2, $w0[0]
+; MIPSR6-N32-NEXT:    mtc1 $2, $f0
 ; MIPSR6-N32-NEXT:    mul.s $f0, $f0, $f12
 ; MIPSR6-N32-NEXT:    add.s $f0, $f0, $f13
-; MIPSR6-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPSR6-N32-NEXT:    mfc1 $2, $f0
+; MIPSR6-N32-NEXT:    fill.w $w0, $2
 ; MIPSR6-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-N32-NEXT:    copy_s.h $2, $w0[0]
+; MIPSR6-N32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPSR6-N32-NEXT:    jr $ra
 ; MIPSR6-N32-NEXT:    sh $2, 0($1)
 ;
@@ -2042,14 +2234,17 @@ define void @ffmuladd(float %b, float %c) {
 ; MIPSR6-N64-NEXT:    daddu $1, $1, $25
 ; MIPSR6-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(ffmuladd)))
 ; MIPSR6-N64-NEXT:    ld $1, %got_disp(g)($1)
-; MIPSR6-N64-NEXT:    lhu $2, 0($1)
+; MIPSR6-N64-NEXT:    lh $2, 0($1)
 ; MIPSR6-N64-NEXT:    fill.h $w0, $2
 ; MIPSR6-N64-NEXT:    fexupr.w $w0, $w0
+; MIPSR6-N64-NEXT:    copy_s.w $2, $w0[0]
+; MIPSR6-N64-NEXT:    mtc1 $2, $f0
 ; MIPSR6-N64-NEXT:    mul.s $f0, $f0, $f12
 ; MIPSR6-N64-NEXT:    add.s $f0, $f0, $f13
-; MIPSR6-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPSR6-N64-NEXT:    mfc1 $2, $f0
+; MIPSR6-N64-NEXT:    fill.w $w0, $2
 ; MIPSR6-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-N64-NEXT:    copy_s.h $2, $w0[0]
+; MIPSR6-N64-NEXT:    copy_u.h $2, $w0[0]
 ; MIPSR6-N64-NEXT:    jr $ra
 ; MIPSR6-N64-NEXT:    sh $2, 0($1)
 entry:
@@ -2072,13 +2267,16 @@ define void @ffabs() {
 ; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
 ; MIPS32-NEXT:    addu $1, $2, $25
 ; MIPS32-NEXT:    lw $1, %got(g)($1)
-; MIPS32-NEXT:    lhu $2, 0($1)
+; MIPS32-NEXT:    lh $2, 0($1)
 ; MIPS32-NEXT:    fill.h $w0, $2
 ; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS32-NEXT:    mtc1 $2, $f0
 ; MIPS32-NEXT:    abs.s $f0, $f0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mfc1 $2, $f0
+; MIPS32-NEXT:    fill.w $w0, $2
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    sh $2, 0($1)
 ;
@@ -2088,13 +2286,16 @@ define void @ffabs() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(ffabs)))
 ; MIPS64-N32-NEXT:    lw $1, %got_disp(g)($1)
-; MIPS64-N32-NEXT:    lhu $2, 0($1)
+; MIPS64-N32-NEXT:    lh $2, 0($1)
 ; MIPS64-N32-NEXT:    fill.h $w0, $2
 ; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $2, $f0
 ; MIPS64-N32-NEXT:    abs.s $f0, $f0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mfc1 $2, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $2
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N32-NEXT:    jr $ra
 ; MIPS64-N32-NEXT:    sh $2, 0($1)
 ;
@@ -2104,13 +2305,16 @@ define void @ffabs() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(ffabs)))
 ; MIPS64-N64-NEXT:    ld $1, %got_disp(g)($1)
-; MIPS64-N64-NEXT:    lhu $2, 0($1)
+; MIPS64-N64-NEXT:    lh $2, 0($1)
 ; MIPS64-N64-NEXT:    fill.h $w0, $2
 ; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $2, $f0
 ; MIPS64-N64-NEXT:    abs.s $f0, $f0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mfc1 $2, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $2
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N64-NEXT:    jr $ra
 ; MIPS64-N64-NEXT:    sh $2, 0($1)
 entry:
@@ -2140,15 +2344,17 @@ define void @fminnum(float %b) {
 ; MIPS32-O32-NEXT:    addu $gp, $2, $25
 ; MIPS32-O32-NEXT:    mov.s $f14, $f12
 ; MIPS32-O32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-O32-NEXT:    lhu $1, 0($16)
+; MIPS32-O32-NEXT:    lh $1, 0($16)
 ; MIPS32-O32-NEXT:    fill.h $w0, $1
+; MIPS32-O32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-O32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS32-O32-NEXT:    lw $25, %call16(fminf)($gp)
 ; MIPS32-O32-NEXT:    jalr $25
-; MIPS32-O32-NEXT:    fexupr.w $w12, $w0
-; MIPS32-O32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-O32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-O32-NEXT:    mtc1 $1, $f12
+; MIPS32-O32-NEXT:    mfc1 $1, $f0
+; MIPS32-O32-NEXT:    fill.w $w0, $1
 ; MIPS32-O32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-O32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-O32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-O32-NEXT:    sh $1, 0($16)
 ; MIPS32-O32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-O32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -2170,15 +2376,17 @@ define void @fminnum(float %b) {
 ; MIPS64R5-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(fminnum)))
 ; MIPS64R5-N32-NEXT:    mov.s $f13, $f12
 ; MIPS64R5-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64R5-N32-NEXT:    lhu $1, 0($16)
+; MIPS64R5-N32-NEXT:    lh $1, 0($16)
 ; MIPS64R5-N32-NEXT:    fill.h $w0, $1
+; MIPS64R5-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64R5-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64R5-N32-NEXT:    lw $25, %call16(fminf)($gp)
 ; MIPS64R5-N32-NEXT:    jalr $25
-; MIPS64R5-N32-NEXT:    fexupr.w $w12, $w0
-; MIPS64R5-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64R5-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64R5-N32-NEXT:    mtc1 $1, $f12
+; MIPS64R5-N32-NEXT:    mfc1 $1, $f0
+; MIPS64R5-N32-NEXT:    fill.w $w0, $1
 ; MIPS64R5-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64R5-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64R5-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64R5-N32-NEXT:    sh $1, 0($16)
 ; MIPS64R5-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64R5-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -2201,15 +2409,17 @@ define void @fminnum(float %b) {
 ; MIPS64R5-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(fminnum)))
 ; MIPS64R5-N64-NEXT:    mov.s $f13, $f12
 ; MIPS64R5-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64R5-N64-NEXT:    lhu $1, 0($16)
+; MIPS64R5-N64-NEXT:    lh $1, 0($16)
 ; MIPS64R5-N64-NEXT:    fill.h $w0, $1
+; MIPS64R5-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64R5-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64R5-N64-NEXT:    ld $25, %call16(fminf)($gp)
 ; MIPS64R5-N64-NEXT:    jalr $25
-; MIPS64R5-N64-NEXT:    fexupr.w $w12, $w0
-; MIPS64R5-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64R5-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64R5-N64-NEXT:    mtc1 $1, $f12
+; MIPS64R5-N64-NEXT:    mfc1 $1, $f0
+; MIPS64R5-N64-NEXT:    fill.w $w0, $1
 ; MIPS64R5-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64R5-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64R5-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64R5-N64-NEXT:    sh $1, 0($16)
 ; MIPS64R5-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64R5-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -2223,13 +2433,16 @@ define void @fminnum(float %b) {
 ; MIPSR6-O32-NEXT:    addiu $2, $2, %lo(_gp_disp)
 ; MIPSR6-O32-NEXT:    addu $1, $2, $25
 ; MIPSR6-O32-NEXT:    lw $1, %got(g)($1)
-; MIPSR6-O32-NEXT:    lhu $2, 0($1)
+; MIPSR6-O32-NEXT:    lh $2, 0($1)
 ; MIPSR6-O32-NEXT:    fill.h $w0, $2
 ; MIPSR6-O32-NEXT:    fexupr.w $w0, $w0
+; MIPSR6-O32-NEXT:    copy_s.w $2, $w0[0]
+; MIPSR6-O32-NEXT:    mtc1 $2, $f0
 ; MIPSR6-O32-NEXT:    min.s $f0, $f0, $f12
-; MIPSR6-O32-NEXT:    splati.w $w0, $w0[0]
+; MIPSR6-O32-NEXT:    mfc1 $2, $f0
+; MIPSR6-O32-NEXT:    fill.w $w0, $2
 ; MIPSR6-O32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-O32-NEXT:    copy_s.h $2, $w0[0]
+; MIPSR6-O32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPSR6-O32-NEXT:    jr $ra
 ; MIPSR6-O32-NEXT:    sh $2, 0($1)
 ;
@@ -2239,13 +2452,16 @@ define void @fminnum(float %b) {
 ; MIPSR6-N32-NEXT:    addu $1, $1, $25
 ; MIPSR6-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(fminnum)))
 ; MIPSR6-N32-NEXT:    lw $1, %got_disp(g)($1)
-; MIPSR6-N32-NEXT:    lhu $2, 0($1)
+; MIPSR6-N32-NEXT:    lh $2, 0($1)
 ; MIPSR6-N32-NEXT:    fill.h $w0, $2
 ; MIPSR6-N32-NEXT:    fexupr.w $w0, $w0
+; MIPSR6-N32-NEXT:    copy_s.w $2, $w0[0]
+; MIPSR6-N32-NEXT:    mtc1 $2, $f0
 ; MIPSR6-N32-NEXT:    min.s $f0, $f0, $f12
-; MIPSR6-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPSR6-N32-NEXT:    mfc1 $2, $f0
+; MIPSR6-N32-NEXT:    fill.w $w0, $2
 ; MIPSR6-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-N32-NEXT:    copy_s.h $2, $w0[0]
+; MIPSR6-N32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPSR6-N32-NEXT:    jr $ra
 ; MIPSR6-N32-NEXT:    sh $2, 0($1)
 ;
@@ -2255,13 +2471,16 @@ define void @fminnum(float %b) {
 ; MIPSR6-N64-NEXT:    daddu $1, $1, $25
 ; MIPSR6-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(fminnum)))
 ; MIPSR6-N64-NEXT:    ld $1, %got_disp(g)($1)
-; MIPSR6-N64-NEXT:    lhu $2, 0($1)
+; MIPSR6-N64-NEXT:    lh $2, 0($1)
 ; MIPSR6-N64-NEXT:    fill.h $w0, $2
 ; MIPSR6-N64-NEXT:    fexupr.w $w0, $w0
+; MIPSR6-N64-NEXT:    copy_s.w $2, $w0[0]
+; MIPSR6-N64-NEXT:    mtc1 $2, $f0
 ; MIPSR6-N64-NEXT:    min.s $f0, $f0, $f12
-; MIPSR6-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPSR6-N64-NEXT:    mfc1 $2, $f0
+; MIPSR6-N64-NEXT:    fill.w $w0, $2
 ; MIPSR6-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-N64-NEXT:    copy_s.h $2, $w0[0]
+; MIPSR6-N64-NEXT:    copy_u.h $2, $w0[0]
 ; MIPSR6-N64-NEXT:    jr $ra
 ; MIPSR6-N64-NEXT:    sh $2, 0($1)
 entry:
@@ -2291,15 +2510,17 @@ define void @fmaxnum(float %b) {
 ; MIPS32-O32-NEXT:    addu $gp, $2, $25
 ; MIPS32-O32-NEXT:    mov.s $f14, $f12
 ; MIPS32-O32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-O32-NEXT:    lhu $1, 0($16)
+; MIPS32-O32-NEXT:    lh $1, 0($16)
 ; MIPS32-O32-NEXT:    fill.h $w0, $1
+; MIPS32-O32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-O32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS32-O32-NEXT:    lw $25, %call16(fmaxf)($gp)
 ; MIPS32-O32-NEXT:    jalr $25
-; MIPS32-O32-NEXT:    fexupr.w $w12, $w0
-; MIPS32-O32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-O32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-O32-NEXT:    mtc1 $1, $f12
+; MIPS32-O32-NEXT:    mfc1 $1, $f0
+; MIPS32-O32-NEXT:    fill.w $w0, $1
 ; MIPS32-O32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-O32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-O32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-O32-NEXT:    sh $1, 0($16)
 ; MIPS32-O32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-O32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -2321,15 +2542,17 @@ define void @fmaxnum(float %b) {
 ; MIPS64R5-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(fmaxnum)))
 ; MIPS64R5-N32-NEXT:    mov.s $f13, $f12
 ; MIPS64R5-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64R5-N32-NEXT:    lhu $1, 0($16)
+; MIPS64R5-N32-NEXT:    lh $1, 0($16)
 ; MIPS64R5-N32-NEXT:    fill.h $w0, $1
+; MIPS64R5-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64R5-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64R5-N32-NEXT:    lw $25, %call16(fmaxf)($gp)
 ; MIPS64R5-N32-NEXT:    jalr $25
-; MIPS64R5-N32-NEXT:    fexupr.w $w12, $w0
-; MIPS64R5-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64R5-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64R5-N32-NEXT:    mtc1 $1, $f12
+; MIPS64R5-N32-NEXT:    mfc1 $1, $f0
+; MIPS64R5-N32-NEXT:    fill.w $w0, $1
 ; MIPS64R5-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64R5-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64R5-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64R5-N32-NEXT:    sh $1, 0($16)
 ; MIPS64R5-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64R5-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -2352,15 +2575,17 @@ define void @fmaxnum(float %b) {
 ; MIPS64R5-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(fmaxnum)))
 ; MIPS64R5-N64-NEXT:    mov.s $f13, $f12
 ; MIPS64R5-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64R5-N64-NEXT:    lhu $1, 0($16)
+; MIPS64R5-N64-NEXT:    lh $1, 0($16)
 ; MIPS64R5-N64-NEXT:    fill.h $w0, $1
+; MIPS64R5-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64R5-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64R5-N64-NEXT:    ld $25, %call16(fmaxf)($gp)
 ; MIPS64R5-N64-NEXT:    jalr $25
-; MIPS64R5-N64-NEXT:    fexupr.w $w12, $w0
-; MIPS64R5-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64R5-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64R5-N64-NEXT:    mtc1 $1, $f12
+; MIPS64R5-N64-NEXT:    mfc1 $1, $f0
+; MIPS64R5-N64-NEXT:    fill.w $w0, $1
 ; MIPS64R5-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64R5-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64R5-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64R5-N64-NEXT:    sh $1, 0($16)
 ; MIPS64R5-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64R5-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -2374,13 +2599,16 @@ define void @fmaxnum(float %b) {
 ; MIPSR6-O32-NEXT:    addiu $2, $2, %lo(_gp_disp)
 ; MIPSR6-O32-NEXT:    addu $1, $2, $25
 ; MIPSR6-O32-NEXT:    lw $1, %got(g)($1)
-; MIPSR6-O32-NEXT:    lhu $2, 0($1)
+; MIPSR6-O32-NEXT:    lh $2, 0($1)
 ; MIPSR6-O32-NEXT:    fill.h $w0, $2
 ; MIPSR6-O32-NEXT:    fexupr.w $w0, $w0
+; MIPSR6-O32-NEXT:    copy_s.w $2, $w0[0]
+; MIPSR6-O32-NEXT:    mtc1 $2, $f0
 ; MIPSR6-O32-NEXT:    max.s $f0, $f0, $f12
-; MIPSR6-O32-NEXT:    splati.w $w0, $w0[0]
+; MIPSR6-O32-NEXT:    mfc1 $2, $f0
+; MIPSR6-O32-NEXT:    fill.w $w0, $2
 ; MIPSR6-O32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-O32-NEXT:    copy_s.h $2, $w0[0]
+; MIPSR6-O32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPSR6-O32-NEXT:    jr $ra
 ; MIPSR6-O32-NEXT:    sh $2, 0($1)
 ;
@@ -2390,13 +2618,16 @@ define void @fmaxnum(float %b) {
 ; MIPSR6-N32-NEXT:    addu $1, $1, $25
 ; MIPSR6-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(fmaxnum)))
 ; MIPSR6-N32-NEXT:    lw $1, %got_disp(g)($1)
-; MIPSR6-N32-NEXT:    lhu $2, 0($1)
+; MIPSR6-N32-NEXT:    lh $2, 0($1)
 ; MIPSR6-N32-NEXT:    fill.h $w0, $2
 ; MIPSR6-N32-NEXT:    fexupr.w $w0, $w0
+; MIPSR6-N32-NEXT:    copy_s.w $2, $w0[0]
+; MIPSR6-N32-NEXT:    mtc1 $2, $f0
 ; MIPSR6-N32-NEXT:    max.s $f0, $f0, $f12
-; MIPSR6-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPSR6-N32-NEXT:    mfc1 $2, $f0
+; MIPSR6-N32-NEXT:    fill.w $w0, $2
 ; MIPSR6-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-N32-NEXT:    copy_s.h $2, $w0[0]
+; MIPSR6-N32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPSR6-N32-NEXT:    jr $ra
 ; MIPSR6-N32-NEXT:    sh $2, 0($1)
 ;
@@ -2406,13 +2637,16 @@ define void @fmaxnum(float %b) {
 ; MIPSR6-N64-NEXT:    daddu $1, $1, $25
 ; MIPSR6-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(fmaxnum)))
 ; MIPSR6-N64-NEXT:    ld $1, %got_disp(g)($1)
-; MIPSR6-N64-NEXT:    lhu $2, 0($1)
+; MIPSR6-N64-NEXT:    lh $2, 0($1)
 ; MIPSR6-N64-NEXT:    fill.h $w0, $2
 ; MIPSR6-N64-NEXT:    fexupr.w $w0, $w0
+; MIPSR6-N64-NEXT:    copy_s.w $2, $w0[0]
+; MIPSR6-N64-NEXT:    mtc1 $2, $f0
 ; MIPSR6-N64-NEXT:    max.s $f0, $f0, $f12
-; MIPSR6-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPSR6-N64-NEXT:    mfc1 $2, $f0
+; MIPSR6-N64-NEXT:    fill.w $w0, $2
 ; MIPSR6-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-N64-NEXT:    copy_s.h $2, $w0[0]
+; MIPSR6-N64-NEXT:    copy_u.h $2, $w0[0]
 ; MIPSR6-N64-NEXT:    jr $ra
 ; MIPSR6-N64-NEXT:    sh $2, 0($1)
 entry:
@@ -2434,14 +2668,17 @@ define void @fcopysign(float %b) {
 ; MIPS32-NEXT:    lui $2, %hi(_gp_disp)
 ; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
 ; MIPS32-NEXT:    addu $1, $2, $25
-; MIPS32-NEXT:    mfc1 $2, $f12
-; MIPS32-NEXT:    lui $3, 32768
-; MIPS32-NEXT:    and $2, $2, $3
-; MIPS32-NEXT:    srl $2, $2, 16
 ; MIPS32-NEXT:    lw $1, %got(g)($1)
-; MIPS32-NEXT:    lhu $3, 0($1)
-; MIPS32-NEXT:    andi $3, $3, 32767
-; MIPS32-NEXT:    or $2, $3, $2
+; MIPS32-NEXT:    lh $2, 0($1)
+; MIPS32-NEXT:    fill.h $w0, $2
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS32-NEXT:    mfc1 $3, $f12
+; MIPS32-NEXT:    ext $3, $3, 31, 1
+; MIPS32-NEXT:    ins $2, $3, 31, 1
+; MIPS32-NEXT:    fill.w $w0, $2
+; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
+; MIPS32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    sh $2, 0($1)
 ;
@@ -2450,14 +2687,17 @@ define void @fcopysign(float %b) {
 ; MIPS64-N32-NEXT:    lui $1, %hi(%neg(%gp_rel(fcopysign)))
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(fcopysign)))
-; MIPS64-N32-NEXT:    mfc1 $2, $f12
-; MIPS64-N32-NEXT:    lui $3, 32768
-; MIPS64-N32-NEXT:    and $2, $2, $3
-; MIPS64-N32-NEXT:    srl $2, $2, 16
 ; MIPS64-N32-NEXT:    lw $1, %got_disp(g)($1)
-; MIPS64-N32-NEXT:    lhu $3, 0($1)
-; MIPS64-N32-NEXT:    andi $3, $3, 32767
-; MIPS64-N32-NEXT:    or $2, $3, $2
+; MIPS64-N32-NEXT:    lh $2, 0($1)
+; MIPS64-N32-NEXT:    fill.h $w0, $2
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N32-NEXT:    mfc1 $3, $f12
+; MIPS64-N32-NEXT:    ext $3, $3, 31, 1
+; MIPS64-N32-NEXT:    ins $2, $3, 31, 1
+; MIPS64-N32-NEXT:    fill.w $w0, $2
+; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
+; MIPS64-N32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N32-NEXT:    jr $ra
 ; MIPS64-N32-NEXT:    sh $2, 0($1)
 ;
@@ -2466,14 +2706,17 @@ define void @fcopysign(float %b) {
 ; MIPS64-N64-NEXT:    lui $1, %hi(%neg(%gp_rel(fcopysign)))
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(fcopysign)))
-; MIPS64-N64-NEXT:    mfc1 $2, $f12
-; MIPS64-N64-NEXT:    lui $3, 32768
-; MIPS64-N64-NEXT:    and $2, $2, $3
-; MIPS64-N64-NEXT:    srl $2, $2, 16
 ; MIPS64-N64-NEXT:    ld $1, %got_disp(g)($1)
-; MIPS64-N64-NEXT:    lhu $3, 0($1)
-; MIPS64-N64-NEXT:    andi $3, $3, 32767
-; MIPS64-N64-NEXT:    or $2, $3, $2
+; MIPS64-N64-NEXT:    lh $2, 0($1)
+; MIPS64-N64-NEXT:    fill.h $w0, $2
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $2, $w0[0]
+; MIPS64-N64-NEXT:    mfc1 $3, $f12
+; MIPS64-N64-NEXT:    ext $3, $3, 31, 1
+; MIPS64-N64-NEXT:    ins $2, $3, 31, 1
+; MIPS64-N64-NEXT:    fill.w $w0, $2
+; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
+; MIPS64-N64-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N64-NEXT:    jr $ra
 ; MIPS64-N64-NEXT:    sh $2, 0($1)
 entry:
@@ -2502,15 +2745,17 @@ define void @ffloor() {
 ; MIPS32-NEXT:    .cfi_offset 16, -8
 ; MIPS32-NEXT:    addu $gp, $2, $25
 ; MIPS32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-NEXT:    lhu $1, 0($16)
+; MIPS32-NEXT:    lh $1, 0($16)
 ; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS32-NEXT:    lw $25, %call16(floorf)($gp)
 ; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    fexupr.w $w12, $w0
-; MIPS32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f12
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w0, $1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-NEXT:    sh $1, 0($16)
 ; MIPS32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -2531,15 +2776,17 @@ define void @ffloor() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(ffloor)))
 ; MIPS64-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64-N32-NEXT:    lhu $1, 0($16)
+; MIPS64-N32-NEXT:    lh $1, 0($16)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N32-NEXT:    lw $25, %call16(floorf)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
+; MIPS64-N32-NEXT:    mfc1 $1, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $1
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N32-NEXT:    sh $1, 0($16)
 ; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -2561,15 +2808,17 @@ define void @ffloor() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(ffloor)))
 ; MIPS64-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64-N64-NEXT:    lhu $1, 0($16)
+; MIPS64-N64-NEXT:    lh $1, 0($16)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N64-NEXT:    ld $25, %call16(floorf)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    sh $1, 0($16)
 ; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -2602,15 +2851,17 @@ define void @fceil() {
 ; MIPS32-NEXT:    .cfi_offset 16, -8
 ; MIPS32-NEXT:    addu $gp, $2, $25
 ; MIPS32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-NEXT:    lhu $1, 0($16)
+; MIPS32-NEXT:    lh $1, 0($16)
 ; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS32-NEXT:    lw $25, %call16(ceilf)($gp)
 ; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    fexupr.w $w12, $w0
-; MIPS32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f12
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w0, $1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-NEXT:    sh $1, 0($16)
 ; MIPS32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -2631,15 +2882,17 @@ define void @fceil() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(fceil)))
 ; MIPS64-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64-N32-NEXT:    lhu $1, 0($16)
+; MIPS64-N32-NEXT:    lh $1, 0($16)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N32-NEXT:    lw $25, %call16(ceilf)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
+; MIPS64-N32-NEXT:    mfc1 $1, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $1
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N32-NEXT:    sh $1, 0($16)
 ; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -2661,15 +2914,17 @@ define void @fceil() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(fceil)))
 ; MIPS64-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64-N64-NEXT:    lhu $1, 0($16)
+; MIPS64-N64-NEXT:    lh $1, 0($16)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N64-NEXT:    ld $25, %call16(ceilf)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    sh $1, 0($16)
 ; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -2702,15 +2957,17 @@ define void @ftrunc() {
 ; MIPS32-NEXT:    .cfi_offset 16, -8
 ; MIPS32-NEXT:    addu $gp, $2, $25
 ; MIPS32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-NEXT:    lhu $1, 0($16)
+; MIPS32-NEXT:    lh $1, 0($16)
 ; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS32-NEXT:    lw $25, %call16(truncf)($gp)
 ; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    fexupr.w $w12, $w0
-; MIPS32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f12
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w0, $1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-NEXT:    sh $1, 0($16)
 ; MIPS32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -2731,15 +2988,17 @@ define void @ftrunc() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(ftrunc)))
 ; MIPS64-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64-N32-NEXT:    lhu $1, 0($16)
+; MIPS64-N32-NEXT:    lh $1, 0($16)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N32-NEXT:    lw $25, %call16(truncf)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
+; MIPS64-N32-NEXT:    mfc1 $1, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $1
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N32-NEXT:    sh $1, 0($16)
 ; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -2761,15 +3020,17 @@ define void @ftrunc() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(ftrunc)))
 ; MIPS64-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64-N64-NEXT:    lhu $1, 0($16)
+; MIPS64-N64-NEXT:    lh $1, 0($16)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N64-NEXT:    ld $25, %call16(truncf)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    sh $1, 0($16)
 ; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -2802,15 +3063,17 @@ define void @frint() {
 ; MIPS32-NEXT:    .cfi_offset 16, -8
 ; MIPS32-NEXT:    addu $gp, $2, $25
 ; MIPS32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-NEXT:    lhu $1, 0($16)
+; MIPS32-NEXT:    lh $1, 0($16)
 ; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS32-NEXT:    lw $25, %call16(rintf)($gp)
 ; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    fexupr.w $w12, $w0
-; MIPS32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f12
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w0, $1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-NEXT:    sh $1, 0($16)
 ; MIPS32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -2831,15 +3094,17 @@ define void @frint() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(frint)))
 ; MIPS64-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64-N32-NEXT:    lhu $1, 0($16)
+; MIPS64-N32-NEXT:    lh $1, 0($16)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N32-NEXT:    lw $25, %call16(rintf)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
+; MIPS64-N32-NEXT:    mfc1 $1, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $1
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N32-NEXT:    sh $1, 0($16)
 ; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -2861,15 +3126,17 @@ define void @frint() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(frint)))
 ; MIPS64-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64-N64-NEXT:    lhu $1, 0($16)
+; MIPS64-N64-NEXT:    lh $1, 0($16)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N64-NEXT:    ld $25, %call16(rintf)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    sh $1, 0($16)
 ; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -2902,15 +3169,17 @@ define void @fnearbyint() {
 ; MIPS32-NEXT:    .cfi_offset 16, -8
 ; MIPS32-NEXT:    addu $gp, $2, $25
 ; MIPS32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-NEXT:    lhu $1, 0($16)
+; MIPS32-NEXT:    lh $1, 0($16)
 ; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS32-NEXT:    lw $25, %call16(nearbyintf)($gp)
 ; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    fexupr.w $w12, $w0
-; MIPS32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f12
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w0, $1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-NEXT:    sh $1, 0($16)
 ; MIPS32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -2931,15 +3200,17 @@ define void @fnearbyint() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(fnearbyint)))
 ; MIPS64-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64-N32-NEXT:    lhu $1, 0($16)
+; MIPS64-N32-NEXT:    lh $1, 0($16)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N32-NEXT:    lw $25, %call16(nearbyintf)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
+; MIPS64-N32-NEXT:    mfc1 $1, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $1
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N32-NEXT:    sh $1, 0($16)
 ; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -2961,15 +3232,17 @@ define void @fnearbyint() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(fnearbyint)))
 ; MIPS64-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64-N64-NEXT:    lhu $1, 0($16)
+; MIPS64-N64-NEXT:    lh $1, 0($16)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N64-NEXT:    ld $25, %call16(nearbyintf)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    sh $1, 0($16)
 ; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -3002,15 +3275,17 @@ define void @fround() {
 ; MIPS32-NEXT:    .cfi_offset 16, -8
 ; MIPS32-NEXT:    addu $gp, $2, $25
 ; MIPS32-NEXT:    lw $16, %got(g)($gp)
-; MIPS32-NEXT:    lhu $1, 0($16)
+; MIPS32-NEXT:    lh $1, 0($16)
 ; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS32-NEXT:    lw $25, %call16(roundf)($gp)
 ; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    fexupr.w $w12, $w0
-; MIPS32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f12
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w0, $1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-NEXT:    sh $1, 0($16)
 ; MIPS32-NEXT:    lw $16, 16($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
@@ -3031,15 +3306,17 @@ define void @fround() {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(fround)))
 ; MIPS64-N32-NEXT:    lw $16, %got_disp(g)($gp)
-; MIPS64-N32-NEXT:    lhu $1, 0($16)
+; MIPS64-N32-NEXT:    lh $1, 0($16)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N32-NEXT:    lw $25, %call16(roundf)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
+; MIPS64-N32-NEXT:    mfc1 $1, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $1
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N32-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N32-NEXT:    sh $1, 0($16)
 ; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -3061,15 +3338,17 @@ define void @fround() {
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(fround)))
 ; MIPS64-N64-NEXT:    ld $16, %got_disp(g)($gp)
-; MIPS64-N64-NEXT:    lhu $1, 0($16)
+; MIPS64-N64-NEXT:    lh $1, 0($16)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N64-NEXT:    ld $25, %call16(roundf)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
-; MIPS64-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64-N64-NEXT:    copy_s.h $1, $w0[0]
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    sh $1, 0($16)
 ; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
@@ -3090,274 +3369,233 @@ entry:
 define half @sitofp_i32_f16(i32 %x) {
 ; MIPS32-LABEL: sitofp_i32_f16:
 ; MIPS32:       # %bb.0: # %entry
-; MIPS32-NEXT:    mtc1 $4, $f0
+; MIPS32-NEXT:    mtc1 $5, $f0
 ; MIPS32-NEXT:    cvt.s.w $f0, $f0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w0, $1
 ; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS32-NEXT:    jr $ra
-; MIPS32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS32-NEXT:    sh $1, 0($4)
 ;
 ; MIPS64-N32-LABEL: sitofp_i32_f16:
 ; MIPS64-N32:       # %bb.0: # %entry
 ; MIPS64-N32-NEXT:    sll $1, $4, 0
-; MIPS64-N32-NEXT:    mtc1 $1, $f0
+; MIPS64-N32-NEXT:    sll $2, $5, 0
+; MIPS64-N32-NEXT:    mtc1 $2, $f0
 ; MIPS64-N32-NEXT:    cvt.s.w $f0, $f0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mfc1 $2, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $2
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
+; MIPS64-N32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N32-NEXT:    jr $ra
-; MIPS64-N32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N32-NEXT:    sh $2, 0($1)
 ;
 ; MIPS64-N64-LABEL: sitofp_i32_f16:
 ; MIPS64-N64:       # %bb.0: # %entry
-; MIPS64-N64-NEXT:    sll $1, $4, 0
+; MIPS64-N64-NEXT:    sll $1, $5, 0
 ; MIPS64-N64-NEXT:    mtc1 $1, $f0
 ; MIPS64-N64-NEXT:    cvt.s.w $f0, $f0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    jr $ra
-; MIPS64-N64-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N64-NEXT:    sh $1, 0($4)
 entry:
   %r = sitofp i32 %x to half
   ret half %r
 }
 
 define half @sitofp_i64_f16(i64 %x) {
-; MIPS32-O32-LABEL: sitofp_i64_f16:
-; MIPS32-O32:       # %bb.0: # %entry
-; MIPS32-O32-NEXT:    lui $2, %hi(_gp_disp)
-; MIPS32-O32-NEXT:    addiu $2, $2, %lo(_gp_disp)
-; MIPS32-O32-NEXT:    addiu $sp, $sp, -24
-; MIPS32-O32-NEXT:    .cfi_def_cfa_offset 24
-; MIPS32-O32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
-; MIPS32-O32-NEXT:    .cfi_offset 31, -4
-; MIPS32-O32-NEXT:    addu $gp, $2, $25
-; MIPS32-O32-NEXT:    lw $25, %call16(__floatdisf)($gp)
-; MIPS32-O32-NEXT:    jalr $25
-; MIPS32-O32-NEXT:    nop
-; MIPS32-O32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-O32-NEXT:    splati.w $w0, $w0[0]
-; MIPS32-O32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-O32-NEXT:    copy_s.h $2, $w0[0]
-; MIPS32-O32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
-; MIPS32-O32-NEXT:    jr $ra
-; MIPS32-O32-NEXT:    addiu $sp, $sp, 24
+; MIPS32-LABEL: sitofp_i64_f16:
+; MIPS32:       # %bb.0: # %entry
+; MIPS32-NEXT:    lui $2, %hi(_gp_disp)
+; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; MIPS32-NEXT:    addiu $sp, $sp, -32
+; MIPS32-NEXT:    .cfi_def_cfa_offset 32
+; MIPS32-NEXT:    sw $ra, 28($sp) # 4-byte Folded Spill
+; MIPS32-NEXT:    sw $16, 24($sp) # 4-byte Folded Spill
+; MIPS32-NEXT:    .cfi_offset 31, -4
+; MIPS32-NEXT:    .cfi_offset 16, -8
+; MIPS32-NEXT:    addu $gp, $2, $25
+; MIPS32-NEXT:    move $16, $4
+; MIPS32-NEXT:    lw $25, %call16(__floatdihf)($gp)
+; MIPS32-NEXT:    jalr $25
+; MIPS32-NEXT:    addiu $4, $sp, 22
+; MIPS32-NEXT:    lh $1, 22($sp)
+; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
+; MIPS32-NEXT:    sh $1, 0($16)
+; MIPS32-NEXT:    lw $16, 24($sp) # 4-byte Folded Reload
+; MIPS32-NEXT:    lw $ra, 28($sp) # 4-byte Folded Reload
+; MIPS32-NEXT:    jr $ra
+; MIPS32-NEXT:    addiu $sp, $sp, 32
 ;
 ; MIPS64-N32-LABEL: sitofp_i64_f16:
 ; MIPS64-N32:       # %bb.0: # %entry
-; MIPS64-N32-NEXT:    dmtc1 $4, $f0
+; MIPS64-N32-NEXT:    sll $1, $4, 0
+; MIPS64-N32-NEXT:    dmtc1 $5, $f0
 ; MIPS64-N32-NEXT:    cvt.s.l $f0, $f0
-; MIPS64-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N32-NEXT:    mfc1 $2, $f0
+; MIPS64-N32-NEXT:    fill.w $w0, $2
 ; MIPS64-N32-NEXT:    fexdo.h $w0, $w0, $w0
+; MIPS64-N32-NEXT:    copy_u.h $2, $w0[0]
 ; MIPS64-N32-NEXT:    jr $ra
-; MIPS64-N32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N32-NEXT:    sh $2, 0($1)
 ;
 ; MIPS64-N64-LABEL: sitofp_i64_f16:
 ; MIPS64-N64:       # %bb.0: # %entry
-; MIPS64-N64-NEXT:    dmtc1 $4, $f0
+; MIPS64-N64-NEXT:    dmtc1 $5, $f0
 ; MIPS64-N64-NEXT:    cvt.s.l $f0, $f0
-; MIPS64-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64-N64-NEXT:    mfc1 $1, $f0
+; MIPS64-N64-NEXT:    fill.w $w0, $1
 ; MIPS64-N64-NEXT:    fexdo.h $w0, $w0, $w0
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
 ; MIPS64-N64-NEXT:    jr $ra
-; MIPS64-N64-NEXT:    copy_s.h $2, $w0[0]
-;
-; MIPSR6-O32-LABEL: sitofp_i64_f16:
-; MIPSR6-O32:       # %bb.0: # %entry
-; MIPSR6-O32-NEXT:    lui $2, %hi(_gp_disp)
-; MIPSR6-O32-NEXT:    addiu $2, $2, %lo(_gp_disp)
-; MIPSR6-O32-NEXT:    addiu $sp, $sp, -24
-; MIPSR6-O32-NEXT:    .cfi_def_cfa_offset 24
-; MIPSR6-O32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
-; MIPSR6-O32-NEXT:    .cfi_offset 31, -4
-; MIPSR6-O32-NEXT:    addu $gp, $2, $25
-; MIPSR6-O32-NEXT:    lw $25, %call16(__floatdisf)($gp)
-; MIPSR6-O32-NEXT:    jalrc $25
-; MIPSR6-O32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPSR6-O32-NEXT:    splati.w $w0, $w0[0]
-; MIPSR6-O32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-O32-NEXT:    copy_s.h $2, $w0[0]
-; MIPSR6-O32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
-; MIPSR6-O32-NEXT:    jr $ra
-; MIPSR6-O32-NEXT:    addiu $sp, $sp, 24
+; MIPS64-N64-NEXT:    sh $1, 0($4)
 entry:
   %r = sitofp i64 %x to half
   ret half %r
 }
 
 define half @sitofp_i128_f16(i128 %x) {
-; MIPS32-O32-LABEL: sitofp_i128_f16:
-; MIPS32-O32:       # %bb.0: # %entry
-; MIPS32-O32-NEXT:    lui $2, %hi(_gp_disp)
-; MIPS32-O32-NEXT:    addiu $2, $2, %lo(_gp_disp)
-; MIPS32-O32-NEXT:    addiu $sp, $sp, -24
-; MIPS32-O32-NEXT:    .cfi_def_cfa_offset 24
-; MIPS32-O32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
-; MIPS32-O32-NEXT:    .cfi_offset 31, -4
-; MIPS32-O32-NEXT:    addu $gp, $2, $25
-; MIPS32-O32-NEXT:    lw $25, %call16(__floattisf)($gp)
-; MIPS32-O32-NEXT:    jalr $25
-; MIPS32-O32-NEXT:    nop
-; MIPS32-O32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-O32-NEXT:    splati.w $w0, $w0[0]
-; MIPS32-O32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-O32-NEXT:    copy_s.h $2, $w0[0]
-; MIPS32-O32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
-; MIPS32-O32-NEXT:    jr $ra
-; MIPS32-O32-NEXT:    addiu $sp, $sp, 24
-;
-; MIPS64R5-N32-LABEL: sitofp_i128_f16:
-; MIPS64R5-N32:       # %bb.0: # %entry
-; MIPS64R5-N32-NEXT:    addiu $sp, $sp, -16
-; MIPS64R5-N32-NEXT:    .cfi_def_cfa_offset 16
-; MIPS64R5-N32-NEXT:    sd $ra, 8($sp) # 8-byte Folded Spill
-; MIPS64R5-N32-NEXT:    sd $gp, 0($sp) # 8-byte Folded Spill
-; MIPS64R5-N32-NEXT:    .cfi_offset 31, -8
-; MIPS64R5-N32-NEXT:    .cfi_offset 28, -16
-; MIPS64R5-N32-NEXT:    lui $1, %hi(%neg(%gp_rel(sitofp_i128_f16)))
-; MIPS64R5-N32-NEXT:    addu $1, $1, $25
-; MIPS64R5-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(sitofp_i128_f16)))
-; MIPS64R5-N32-NEXT:    lw $25, %call16(__floattisf)($gp)
-; MIPS64R5-N32-NEXT:    jalr $25
-; MIPS64R5-N32-NEXT:    nop
-; MIPS64R5-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64R5-N32-NEXT:    splati.w $w0, $w0[0]
-; MIPS64R5-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64R5-N32-NEXT:    copy_s.h $2, $w0[0]
-; MIPS64R5-N32-NEXT:    ld $gp, 0($sp) # 8-byte Folded Reload
-; MIPS64R5-N32-NEXT:    ld $ra, 8($sp) # 8-byte Folded Reload
-; MIPS64R5-N32-NEXT:    jr $ra
-; MIPS64R5-N32-NEXT:    addiu $sp, $sp, 16
-;
-; MIPS64R5-N64-LABEL: sitofp_i128_f16:
-; MIPS64R5-N64:       # %bb.0: # %entry
-; MIPS64R5-N64-NEXT:    daddiu $sp, $sp, -16
-; MIPS64R5-N64-NEXT:    .cfi_def_cfa_offset 16
-; MIPS64R5-N64-NEXT:    sd $ra, 8($sp) # 8-byte Folded Spill
-; MIPS64R5-N64-NEXT:    sd $gp, 0($sp) # 8-byte Folded Spill
-; MIPS64R5-N64-NEXT:    .cfi_offset 31, -8
-; MIPS64R5-N64-NEXT:    .cfi_offset 28, -16
-; MIPS64R5-N64-NEXT:    lui $1, %hi(%neg(%gp_rel(sitofp_i128_f16)))
-; MIPS64R5-N64-NEXT:    daddu $1, $1, $25
-; MIPS64R5-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(sitofp_i128_f16)))
-; MIPS64R5-N64-NEXT:    ld $25, %call16(__floattisf)($gp)
-; MIPS64R5-N64-NEXT:    jalr $25
-; MIPS64R5-N64-NEXT:    nop
-; MIPS64R5-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64R5-N64-NEXT:    splati.w $w0, $w0[0]
-; MIPS64R5-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64R5-N64-NEXT:    copy_s.h $2, $w0[0]
-; MIPS64R5-N64-NEXT:    ld $gp, 0($sp) # 8-byte Folded Reload
-; MIPS64R5-N64-NEXT:    ld $ra, 8($sp) # 8-byte Folded Reload
-; MIPS64R5-N64-NEXT:    jr $ra
-; MIPS64R5-N64-NEXT:    daddiu $sp, $sp, 16
-;
-; MIPSR6-O32-LABEL: sitofp_i128_f16:
-; MIPSR6-O32:       # %bb.0: # %entry
-; MIPSR6-O32-NEXT:    lui $2, %hi(_gp_disp)
-; MIPSR6-O32-NEXT:    addiu $2, $2, %lo(_gp_disp)
-; MIPSR6-O32-NEXT:    addiu $sp, $sp, -24
-; MIPSR6-O32-NEXT:    .cfi_def_cfa_offset 24
-; MIPSR6-O32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
-; MIPSR6-O32-NEXT:    .cfi_offset 31, -4
-; MIPSR6-O32-NEXT:    addu $gp, $2, $25
-; MIPSR6-O32-NEXT:    lw $25, %call16(__floattisf)($gp)
-; MIPSR6-O32-NEXT:    jalrc $25
-; MIPSR6-O32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPSR6-O32-NEXT:    splati.w $w0, $w0[0]
-; MIPSR6-O32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-O32-NEXT:    copy_s.h $2, $w0[0]
-; MIPSR6-O32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
-; MIPSR6-O32-NEXT:    jr $ra
-; MIPSR6-O32-NEXT:    addiu $sp, $sp, 24
-;
-; MIPSR6-N32-LABEL: sitofp_i128_f16:
-; MIPSR6-N32:       # %bb.0: # %entry
-; MIPSR6-N32-NEXT:    addiu $sp, $sp, -16
-; MIPSR6-N32-NEXT:    .cfi_def_cfa_offset 16
-; MIPSR6-N32-NEXT:    sd $ra, 8($sp) # 8-byte Folded Spill
-; MIPSR6-N32-NEXT:    sd $gp, 0($sp) # 8-byte Folded Spill
-; MIPSR6-N32-NEXT:    .cfi_offset 31, -8
-; MIPSR6-N32-NEXT:    .cfi_offset 28, -16
-; MIPSR6-N32-NEXT:    lui $1, %hi(%neg(%gp_rel(sitofp_i128_f16)))
-; MIPSR6-N32-NEXT:    addu $1, $1, $25
-; MIPSR6-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(sitofp_i128_f16)))
-; MIPSR6-N32-NEXT:    lw $25, %call16(__floattisf)($gp)
-; MIPSR6-N32-NEXT:    jialc $25, 0
-; MIPSR6-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPSR6-N32-NEXT:    splati.w $w0, $w0[0]
-; MIPSR6-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-N32-NEXT:    copy_s.h $2, $w0[0]
-; MIPSR6-N32-NEXT:    ld $gp, 0($sp) # 8-byte Folded Reload
-; MIPSR6-N32-NEXT:    ld $ra, 8($sp) # 8-byte Folded Reload
-; MIPSR6-N32-NEXT:    jr $ra
-; MIPSR6-N32-NEXT:    addiu $sp, $sp, 16
-;
-; MIPSR6-N64-LABEL: sitofp_i128_f16:
-; MIPSR6-N64:       # %bb.0: # %entry
-; MIPSR6-N64-NEXT:    daddiu $sp, $sp, -16
-; MIPSR6-N64-NEXT:    .cfi_def_cfa_offset 16
-; MIPSR6-N64-NEXT:    sd $ra, 8($sp) # 8-byte Folded Spill
-; MIPSR6-N64-NEXT:    sd $gp, 0($sp) # 8-byte Folded Spill
-; MIPSR6-N64-NEXT:    .cfi_offset 31, -8
-; MIPSR6-N64-NEXT:    .cfi_offset 28, -16
-; MIPSR6-N64-NEXT:    lui $1, %hi(%neg(%gp_rel(sitofp_i128_f16)))
-; MIPSR6-N64-NEXT:    daddu $1, $1, $25
-; MIPSR6-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(sitofp_i128_f16)))
-; MIPSR6-N64-NEXT:    ld $25, %call16(__floattisf)($gp)
-; MIPSR6-N64-NEXT:    jalrc $25
-; MIPSR6-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPSR6-N64-NEXT:    splati.w $w0, $w0[0]
-; MIPSR6-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-N64-NEXT:    copy_s.h $2, $w0[0]
-; MIPSR6-N64-NEXT:    ld $gp, 0($sp) # 8-byte Folded Reload
-; MIPSR6-N64-NEXT:    ld $ra, 8($sp) # 8-byte Folded Reload
-; MIPSR6-N64-NEXT:    jr $ra
-; MIPSR6-N64-NEXT:    daddiu $sp, $sp, 16
-entry:
-  %r = sitofp i128 %x to half
-  ret half %r
-}
-
-define half @uitofp_i32_f16(i32 %x) {
-; MIPS32-LABEL: uitofp_i32_f16:
+; MIPS32-LABEL: sitofp_i128_f16:
 ; MIPS32:       # %bb.0: # %entry
 ; MIPS32-NEXT:    lui $2, %hi(_gp_disp)
 ; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
-; MIPS32-NEXT:    addiu $sp, $sp, -8
-; MIPS32-NEXT:    .cfi_def_cfa_offset 8
-; MIPS32-NEXT:    addu $1, $2, $25
-; MIPS32-NEXT:    lui $2, 17200
-; MIPS32-NEXT:    sw $2, 4($sp)
-; MIPS32-NEXT:    sw $4, 0($sp)
-; MIPS32-NEXT:    lw $1, %got($CPI37_0)($1)
-; MIPS32-NEXT:    ldc1 $f0, %lo($CPI37_0)($1)
-; MIPS32-NEXT:    ldc1 $f1, 0($sp)
-; MIPS32-NEXT:    sub.d $f0, $f1, $f0
-; MIPS32-NEXT:    cvt.s.d $f0, $f0
-; MIPS32-NEXT:    splati.w $w0, $w0[0]
-; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS32-NEXT:    addiu $sp, $sp, -40
+; MIPS32-NEXT:    .cfi_def_cfa_offset 40
+; MIPS32-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
+; MIPS32-NEXT:    sw $16, 32($sp) # 4-byte Folded Spill
+; MIPS32-NEXT:    .cfi_offset 31, -4
+; MIPS32-NEXT:    .cfi_offset 16, -8
+; MIPS32-NEXT:    addu $gp, $2, $25
+; MIPS32-NEXT:    move $16, $4
+; MIPS32-NEXT:    lw $1, 60($sp)
+; MIPS32-NEXT:    sw $1, 20($sp)
+; MIPS32-NEXT:    lw $1, 56($sp)
+; MIPS32-NEXT:    sw $1, 16($sp)
+; MIPS32-NEXT:    lw $25, %call16(__floattihf)($gp)
+; MIPS32-NEXT:    jalr $25
+; MIPS32-NEXT:    addiu $4, $sp, 30
+; MIPS32-NEXT:    lh $1, 30($sp)
+; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
+; MIPS32-NEXT:    sh $1, 0($16)
+; MIPS32-NEXT:    lw $16, 32($sp) # 4-byte Folded Reload
+; MIPS32-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    jr $ra
-; MIPS32-NEXT:    addiu $sp, $sp, 8
+; MIPS32-NEXT:    addiu $sp, $sp, 40
 ;
-; MIPS64R5-N32-LABEL: uitofp_i32_f16:
-; MIPS64R5-N32:       # %bb.0: # %entry
-; MIPS64R5-N32-NEXT:    addiu $sp, $sp, -16
-; MIPS64R5-N32-NEXT:    .cfi_def_cfa_offset 16
-; MIPS64R5-N32-NEXT:    lui $1, %hi(%neg(%gp_rel(uitofp_i32_f16)))
-; MIPS64R5-N32-NEXT:    addu $1, $1, $25
-; MIPS64R5-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(uitofp_i32_f16)))
-; MIPS64R5-N32-NEXT:    lui $2, 17200
-; MIPS64R5-N32-NEXT:    sw $2, 12($sp)
-; MIPS64R5-N32-NEXT:    sll $2, $4, 0
+; MIPS64-N32-LABEL: sitofp_i128_f16:
+; MIPS64-N32:       # %bb.0: # %entry
+; MIPS64-N32-NEXT:    addiu $sp, $sp, -32
+; MIPS64-N32-NEXT:    .cfi_def_cfa_offset 32
+; MIPS64-N32-NEXT:    sd $ra, 24($sp) # 8-byte Folded Spill
+; MIPS64-N32-NEXT:    sd $gp, 16($sp) # 8-byte Folded Spill
+; MIPS64-N32-NEXT:    sd $16, 8($sp) # 8-byte Folded Spill
+; MIPS64-N32-NEXT:    .cfi_offset 31, -8
+; MIPS64-N32-NEXT:    .cfi_offset 28, -16
+; MIPS64-N32-NEXT:    .cfi_offset 16, -24
+; MIPS64-N32-NEXT:    lui $1, %hi(%neg(%gp_rel(sitofp_i128_f16)))
+; MIPS64-N32-NEXT:    addu $1, $1, $25
+; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(sitofp_i128_f16)))
+; MIPS64-N32-NEXT:    move $16, $4
+; MIPS64-N32-NEXT:    lw $25, %call16(__floattihf)($gp)
+; MIPS64-N32-NEXT:    jalr $25
+; MIPS64-N32-NEXT:    addiu $4, $sp, 6
+; MIPS64-N32-NEXT:    sll $1, $16, 0
+; MIPS64-N32-NEXT:    lh $2, 6($sp)
+; MIPS64-N32-NEXT:    fill.h $w0, $2
+; MIPS64-N32-NEXT:    copy_u.h $2, $w0[0]
+; MIPS64-N32-NEXT:    sh $2, 0($1)
+; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
+; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
+; MIPS64-N32-NEXT:    ld $ra, 24($sp) # 8-byte Folded Reload
+; MIPS64-N32-NEXT:    jr $ra
+; MIPS64-N32-NEXT:    addiu $sp, $sp, 32
+;
+; MIPS64-N64-LABEL: sitofp_i128_f16:
+; MIPS64-N64:       # %bb.0: # %entry
+; MIPS64-N64-NEXT:    daddiu $sp, $sp, -32
+; MIPS64-N64-NEXT:    .cfi_def_cfa_offset 32
+; MIPS64-N64-NEXT:    sd $ra, 24($sp) # 8-byte Folded Spill
+; MIPS64-N64-NEXT:    sd $gp, 16($sp) # 8-byte Folded Spill
+; MIPS64-N64-NEXT:    sd $16, 8($sp) # 8-byte Folded Spill
+; MIPS64-N64-NEXT:    .cfi_offset 31, -8
+; MIPS64-N64-NEXT:    .cfi_offset 28, -16
+; MIPS64-N64-NEXT:    .cfi_offset 16, -24
+; MIPS64-N64-NEXT:    lui $1, %hi(%neg(%gp_rel(sitofp_i128_f16)))
+; MIPS64-N64-NEXT:    daddu $1, $1, $25
+; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(sitofp_i128_f16)))
+; MIPS64-N64-NEXT:    move $16, $4
+; MIPS64-N64-NEXT:    ld $25, %call16(__floattihf)($gp)
+; MIPS64-N64-NEXT:    jalr $25
+; MIPS64-N64-NEXT:    daddiu $4, $sp, 6
+; MIPS64-N64-NEXT:    lh $1, 6($sp)
+; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
+; MIPS64-N64-NEXT:    sh $1, 0($16)
+; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
+; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
+; MIPS64-N64-NEXT:    ld $ra, 24($sp) # 8-byte Folded Reload
+; MIPS64-N64-NEXT:    jr $ra
+; MIPS64-N64-NEXT:    daddiu $sp, $sp, 32
+entry:
+  %r = sitofp i128 %x to half
+  ret half %r
+}
+
+define half @uitofp_i32_f16(i32 %x) {
+; MIPS32-LABEL: uitofp_i32_f16:
+; MIPS32:       # %bb.0: # %entry
+; MIPS32-NEXT:    lui $2, %hi(_gp_disp)
+; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; MIPS32-NEXT:    addiu $sp, $sp, -8
+; MIPS32-NEXT:    .cfi_def_cfa_offset 8
+; MIPS32-NEXT:    addu $1, $2, $25
+; MIPS32-NEXT:    lui $2, 17200
+; MIPS32-NEXT:    sw $2, 4($sp)
+; MIPS32-NEXT:    sw $5, 0($sp)
+; MIPS32-NEXT:    lw $1, %got($CPI37_0)($1)
+; MIPS32-NEXT:    ldc1 $f0, %lo($CPI37_0)($1)
+; MIPS32-NEXT:    ldc1 $f1, 0($sp)
+; MIPS32-NEXT:    sub.d $f0, $f1, $f0
+; MIPS32-NEXT:    mfc1 $1, $f0
+; MIPS32-NEXT:    fill.w $w1, $1
+; MIPS32-NEXT:    mfhc1 $1, $f0
+; MIPS32-NEXT:    insert.w $w1[1], $1
+; MIPS32-NEXT:    insert.w $w1[3], $1
+; MIPS32-NEXT:    fexdo.w $w0, $w1, $w1
+; MIPS32-NEXT:    fexdo.h $w0, $w0, $w0
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
+; MIPS32-NEXT:    sh $1, 0($4)
+; MIPS32-NEXT:    jr $ra
+; MIPS32-NEXT:    addiu $sp, $sp, 8
+;
+; MIPS64R5-N32-LABEL: uitofp_i32_f16:
+; MIPS64R5-N32:       # %bb.0: # %entry
+; MIPS64R5-N32-NEXT:    addiu $sp, $sp, -16
+; MIPS64R5-N32-NEXT:    .cfi_def_cfa_offset 16
+; MIPS64R5-N32-NEXT:    lui $1, %hi(%neg(%gp_rel(uitofp_i32_f16)))
+; MIPS64R5-N32-NEXT:    addu $1, $1, $25
+; MIPS64R5-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(uitofp_i32_f16)))
+; MIPS64R5-N32-NEXT:    lui $2, 17200
+; MIPS64R5-N32-NEXT:    sw $2, 12($sp)
+; MIPS64R5-N32-NEXT:    sll $2, $5, 0
 ; MIPS64R5-N32-NEXT:    sw $2, 8($sp)
 ; MIPS64R5-N32-NEXT:    lw $1, %got_page(.LCPI37_0)($1)
 ; MIPS64R5-N32-NEXT:    ldc1 $f0, %got_ofst(.LCPI37_0)($1)
 ; MIPS64R5-N32-NEXT:    ldc1 $f1, 8($sp)
 ; MIPS64R5-N32-NEXT:    sub.d $f0, $f1, $f0
-; MIPS64R5-N32-NEXT:    cvt.s.d $f0, $f0
-; MIPS64R5-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPS64R5-N32-NEXT:    dmfc1 $1, $f0
+; MIPS64R5-N32-NEXT:    fill.d $w0, $1
+; MIPS64R5-N32-NEXT:    fexdo.w $w0, $w0, $w0
 ; MIPS64R5-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64R5-N32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64R5-N32-NEXT:    sll $1, $4, 0
+; MIPS64R5-N32-NEXT:    copy_u.h $2, $w0[0]
+; MIPS64R5-N32-NEXT:    sh $2, 0($1)
 ; MIPS64R5-N32-NEXT:    jr $ra
 ; MIPS64R5-N32-NEXT:    addiu $sp, $sp, 16
 ;
@@ -3370,16 +3608,18 @@ define half @uitofp_i32_f16(i32 %x) {
 ; MIPS64R5-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(uitofp_i32_f16)))
 ; MIPS64R5-N64-NEXT:    lui $2, 17200
 ; MIPS64R5-N64-NEXT:    sw $2, 12($sp)
-; MIPS64R5-N64-NEXT:    sll $2, $4, 0
+; MIPS64R5-N64-NEXT:    sll $2, $5, 0
 ; MIPS64R5-N64-NEXT:    sw $2, 8($sp)
 ; MIPS64R5-N64-NEXT:    ld $1, %got_page(.LCPI37_0)($1)
 ; MIPS64R5-N64-NEXT:    ldc1 $f0, %got_ofst(.LCPI37_0)($1)
 ; MIPS64R5-N64-NEXT:    ldc1 $f1, 8($sp)
 ; MIPS64R5-N64-NEXT:    sub.d $f0, $f1, $f0
-; MIPS64R5-N64-NEXT:    cvt.s.d $f0, $f0
-; MIPS64R5-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPS64R5-N64-NEXT:    dmfc1 $1, $f0
+; MIPS64R5-N64-NEXT:    fill.d $w0, $1
+; MIPS64R5-N64-NEXT:    fexdo.w $w0, $w0, $w0
 ; MIPS64R5-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64R5-N64-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64R5-N64-NEXT:    copy_u.h $1, $w0[0]
+; MIPS64R5-N64-NEXT:    sh $1, 0($4)
 ; MIPS64R5-N64-NEXT:    jr $ra
 ; MIPS64R5-N64-NEXT:    daddiu $sp, $sp, 16
 ;
@@ -3392,15 +3632,18 @@ define half @uitofp_i32_f16(i32 %x) {
 ; MIPSR6-N32-NEXT:    addiu $1, $1, %lo(%neg(%gp_rel(uitofp_i32_f16)))
 ; MIPSR6-N32-NEXT:    lui $2, 17200
 ; MIPSR6-N32-NEXT:    sw $2, 12($sp)
-; MIPSR6-N32-NEXT:    sw $4, 8($sp)
+; MIPSR6-N32-NEXT:    sw $5, 8($sp)
 ; MIPSR6-N32-NEXT:    lw $1, %got_page(.LCPI37_0)($1)
 ; MIPSR6-N32-NEXT:    ldc1 $f0, %got_ofst(.LCPI37_0)($1)
 ; MIPSR6-N32-NEXT:    ldc1 $f1, 8($sp)
 ; MIPSR6-N32-NEXT:    sub.d $f0, $f1, $f0
-; MIPSR6-N32-NEXT:    cvt.s.d $f0, $f0
-; MIPSR6-N32-NEXT:    splati.w $w0, $w0[0]
+; MIPSR6-N32-NEXT:    dmfc1 $1, $f0
+; MIPSR6-N32-NEXT:    fill.d $w0, $1
+; MIPSR6-N32-NEXT:    fexdo.w $w0, $w0, $w0
 ; MIPSR6-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-N32-NEXT:    copy_s.h $2, $w0[0]
+; MIPSR6-N32-NEXT:    sll $1, $4, 0
+; MIPSR6-N32-NEXT:    copy_u.h $2, $w0[0]
+; MIPSR6-N32-NEXT:    sh $2, 0($1)
 ; MIPSR6-N32-NEXT:    jr $ra
 ; MIPSR6-N32-NEXT:    addiu $sp, $sp, 16
 ;
@@ -3413,15 +3656,17 @@ define half @uitofp_i32_f16(i32 %x) {
 ; MIPSR6-N64-NEXT:    daddiu $1, $1, %lo(%neg(%gp_rel(uitofp_i32_f16)))
 ; MIPSR6-N64-NEXT:    lui $2, 17200
 ; MIPSR6-N64-NEXT:    sw $2, 12($sp)
-; MIPSR6-N64-NEXT:    sw $4, 8($sp)
+; MIPSR6-N64-NEXT:    sw $5, 8($sp)
 ; MIPSR6-N64-NEXT:    ld $1, %got_page(.LCPI37_0)($1)
 ; MIPSR6-N64-NEXT:    ldc1 $f0, %got_ofst(.LCPI37_0)($1)
 ; MIPSR6-N64-NEXT:    ldc1 $f1, 8($sp)
 ; MIPSR6-N64-NEXT:    sub.d $f0, $f1, $f0
-; MIPSR6-N64-NEXT:    cvt.s.d $f0, $f0
-; MIPSR6-N64-NEXT:    splati.w $w0, $w0[0]
+; MIPSR6-N64-NEXT:    dmfc1 $1, $f0
+; MIPSR6-N64-NEXT:    fill.d $w0, $1
+; MIPSR6-N64-NEXT:    fexdo.w $w0, $w0, $w0
 ; MIPSR6-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-N64-NEXT:    copy_s.h $2, $w0[0]
+; MIPSR6-N64-NEXT:    copy_u.h $1, $w0[0]
+; MIPSR6-N64-NEXT:    sh $1, 0($4)
 ; MIPSR6-N64-NEXT:    jr $ra
 ; MIPSR6-N64-NEXT:    daddiu $sp, $sp, 16
 entry:
@@ -3430,248 +3675,172 @@ entry:
 }
 
 define half @uitofp_i64_f16(i64 %x) {
-; MIPS32-O32-LABEL: uitofp_i64_f16:
-; MIPS32-O32:       # %bb.0: # %entry
-; MIPS32-O32-NEXT:    lui $2, %hi(_gp_disp)
-; MIPS32-O32-NEXT:    addiu $2, $2, %lo(_gp_disp)
-; MIPS32-O32-NEXT:    addiu $sp, $sp, -24
-; MIPS32-O32-NEXT:    .cfi_def_cfa_offset 24
-; MIPS32-O32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
-; MIPS32-O32-NEXT:    .cfi_offset 31, -4
-; MIPS32-O32-NEXT:    addu $gp, $2, $25
-; MIPS32-O32-NEXT:    lw $25, %call16(__floatundisf)($gp)
-; MIPS32-O32-NEXT:    jalr $25
-; MIPS32-O32-NEXT:    nop
-; MIPS32-O32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-O32-NEXT:    splati.w $w0, $w0[0]
-; MIPS32-O32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-O32-NEXT:    copy_s.h $2, $w0[0]
-; MIPS32-O32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
-; MIPS32-O32-NEXT:    jr $ra
-; MIPS32-O32-NEXT:    addiu $sp, $sp, 24
-;
-; MIPS64R5-N32-LABEL: uitofp_i64_f16:
-; MIPS64R5-N32:       # %bb.0: # %entry
-; MIPS64R5-N32-NEXT:    dsrl $1, $4, 1
-; MIPS64R5-N32-NEXT:    andi $2, $4, 1
-; MIPS64R5-N32-NEXT:    or $1, $2, $1
-; MIPS64R5-N32-NEXT:    dmtc1 $1, $f0
-; MIPS64R5-N32-NEXT:    cvt.s.l $f0, $f0
-; MIPS64R5-N32-NEXT:    add.s $f0, $f0, $f0
-; MIPS64R5-N32-NEXT:    slti $1, $4, 0
-; MIPS64R5-N32-NEXT:    dmtc1 $4, $f1
-; MIPS64R5-N32-NEXT:    cvt.s.l $f1, $f1
-; MIPS64R5-N32-NEXT:    movn.s $f1, $f0, $1
-; MIPS64R5-N32-NEXT:    splati.w $w0, $w1[0]
-; MIPS64R5-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64R5-N32-NEXT:    jr $ra
-; MIPS64R5-N32-NEXT:    copy_s.h $2, $w0[0]
-;
-; MIPS64R5-N64-LABEL: uitofp_i64_f16:
-; MIPS64R5-N64:       # %bb.0: # %entry
-; MIPS64R5-N64-NEXT:    dsrl $1, $4, 1
-; MIPS64R5-N64-NEXT:    andi $2, $4, 1
-; MIPS64R5-N64-NEXT:    or $1, $2, $1
-; MIPS64R5-N64-NEXT:    dmtc1 $1, $f0
-; MIPS64R5-N64-NEXT:    cvt.s.l $f0, $f0
-; MIPS64R5-N64-NEXT:    add.s $f0, $f0, $f0
-; MIPS64R5-N64-NEXT:    slti $1, $4, 0
-; MIPS64R5-N64-NEXT:    dmtc1 $4, $f1
-; MIPS64R5-N64-NEXT:    cvt.s.l $f1, $f1
-; MIPS64R5-N64-NEXT:    movn.s $f1, $f0, $1
-; MIPS64R5-N64-NEXT:    splati.w $w0, $w1[0]
-; MIPS64R5-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64R5-N64-NEXT:    jr $ra
-; MIPS64R5-N64-NEXT:    copy_s.h $2, $w0[0]
-;
-; MIPSR6-O32-LABEL: uitofp_i64_f16:
-; MIPSR6-O32:       # %bb.0: # %entry
-; MIPSR6-O32-NEXT:    lui $2, %hi(_gp_disp)
-; MIPSR6-O32-NEXT:    addiu $2, $2, %lo(_gp_disp)
-; MIPSR6-O32-NEXT:    addiu $sp, $sp, -24
-; MIPSR6-O32-NEXT:    .cfi_def_cfa_offset 24
-; MIPSR6-O32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
-; MIPSR6-O32-NEXT:    .cfi_offset 31, -4
-; MIPSR6-O32-NEXT:    addu $gp, $2, $25
-; MIPSR6-O32-NEXT:    lw $25, %call16(__floatundisf)($gp)
-; MIPSR6-O32-NEXT:    jalrc $25
-; MIPSR6-O32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPSR6-O32-NEXT:    splati.w $w0, $w0[0]
-; MIPSR6-O32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-O32-NEXT:    copy_s.h $2, $w0[0]
-; MIPSR6-O32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
-; MIPSR6-O32-NEXT:    jr $ra
-; MIPSR6-O32-NEXT:    addiu $sp, $sp, 24
+; MIPS32-LABEL: uitofp_i64_f16:
+; MIPS32:       # %bb.0: # %entry
+; MIPS32-NEXT:    lui $2, %hi(_gp_disp)
+; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; MIPS32-NEXT:    addiu $sp, $sp, -32
+; MIPS32-NEXT:    .cfi_def_cfa_offset 32
+; MIPS32-NEXT:    sw $ra, 28($sp) # 4-byte Folded Spill
+; MIPS32-NEXT:    sw $16, 24($sp) # 4-byte Folded Spill
+; MIPS32-NEXT:    .cfi_offset 31, -4
+; MIPS32-NEXT:    .cfi_offset 16, -8
+; MIPS32-NEXT:    addu $gp, $2, $25
+; MIPS32-NEXT:    move $16, $4
+; MIPS32-NEXT:    lw $25, %call16(__floatundihf)($gp)
+; MIPS32-NEXT:    jalr $25
+; MIPS32-NEXT:    addiu $4, $sp, 22
+; MIPS32-NEXT:    lh $1, 22($sp)
+; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
+; MIPS32-NEXT:    sh $1, 0($16)
+; MIPS32-NEXT:    lw $16, 24($sp) # 4-byte Folded Reload
+; MIPS32-NEXT:    lw $ra, 28($sp) # 4-byte Folded Reload
+; MIPS32-NEXT:    jr $ra
+; MIPS32-NEXT:    addiu $sp, $sp, 32
 ;
-; MIPSR6-N32-LABEL: uitofp_i64_f16:
-; MIPSR6-N32:       # %bb.0: # %entry
-; MIPSR6-N32-NEXT:    dsrl $1, $4, 1
-; MIPSR6-N32-NEXT:    andi $2, $4, 1
-; MIPSR6-N32-NEXT:    or $1, $2, $1
-; MIPSR6-N32-NEXT:    dmtc1 $1, $f0
-; MIPSR6-N32-NEXT:    cvt.s.l $f0, $f0
-; MIPSR6-N32-NEXT:    add.s $f0, $f0, $f0
-; MIPSR6-N32-NEXT:    slti $1, $4, 0
-; MIPSR6-N32-NEXT:    dmtc1 $4, $f1
-; MIPSR6-N32-NEXT:    cvt.s.l $f1, $f1
-; MIPSR6-N32-NEXT:    mtc1 $1, $f2
-; MIPSR6-N32-NEXT:    sel.s $f2, $f1, $f0
-; MIPSR6-N32-NEXT:    splati.w $w0, $w2[0]
-; MIPSR6-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-N32-NEXT:    jr $ra
-; MIPSR6-N32-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N32-LABEL: uitofp_i64_f16:
+; MIPS64-N32:       # %bb.0: # %entry
+; MIPS64-N32-NEXT:    addiu $sp, $sp, -32
+; MIPS64-N32-NEXT:    .cfi_def_cfa_offset 32
+; MIPS64-N32-NEXT:    sd $ra, 24($sp) # 8-byte Folded Spill
+; MIPS64-N32-NEXT:    sd $gp, 16($sp) # 8-byte Folded Spill
+; MIPS64-N32-NEXT:    sd $16, 8($sp) # 8-byte Folded Spill
+; MIPS64-N32-NEXT:    .cfi_offset 31, -8
+; MIPS64-N32-NEXT:    .cfi_offset 28, -16
+; MIPS64-N32-NEXT:    .cfi_offset 16, -24
+; MIPS64-N32-NEXT:    lui $1, %hi(%neg(%gp_rel(uitofp_i64_f16)))
+; MIPS64-N32-NEXT:    addu $1, $1, $25
+; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(uitofp_i64_f16)))
+; MIPS64-N32-NEXT:    move $16, $4
+; MIPS64-N32-NEXT:    lw $25, %call16(__floatundihf)($gp)
+; MIPS64-N32-NEXT:    jalr $25
+; MIPS64-N32-NEXT:    addiu $4, $sp, 6
+; MIPS64-N32-NEXT:    sll $1, $16, 0
+; MIPS64-N32-NEXT:    lh $2, 6($sp)
+; MIPS64-N32-NEXT:    fill.h $w0, $2
+; MIPS64-N32-NEXT:    copy_u.h $2, $w0[0]
+; MIPS64-N32-NEXT:    sh $2, 0($1)
+; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
+; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
+; MIPS64-N32-NEXT:    ld $ra, 24($sp) # 8-byte Folded Reload
+; MIPS64-N32-NEXT:    jr $ra
+; MIPS64-N32-NEXT:    addiu $sp, $sp, 32
 ;
-; MIPSR6-N64-LABEL: uitofp_i64_f16:
-; MIPSR6-N64:       # %bb.0: # %entry
-; MIPSR6-N64-NEXT:    dsrl $1, $4, 1
-; MIPSR6-N64-NEXT:    andi $2, $4, 1
-; MIPSR6-N64-NEXT:    or $1, $2, $1
-; MIPSR6-N64-NEXT:    dmtc1 $1, $f0
-; MIPSR6-N64-NEXT:    cvt.s.l $f0, $f0
-; MIPSR6-N64-NEXT:    add.s $f0, $f0, $f0
-; MIPSR6-N64-NEXT:    slti $1, $4, 0
-; MIPSR6-N64-NEXT:    dmtc1 $4, $f1
-; MIPSR6-N64-NEXT:    cvt.s.l $f1, $f1
-; MIPSR6-N64-NEXT:    mtc1 $1, $f2
-; MIPSR6-N64-NEXT:    sel.s $f2, $f1, $f0
-; MIPSR6-N64-NEXT:    splati.w $w0, $w2[0]
-; MIPSR6-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-N64-NEXT:    jr $ra
-; MIPSR6-N64-NEXT:    copy_s.h $2, $w0[0]
+; MIPS64-N64-LABEL: uitofp_i64_f16:
+; MIPS64-N64:       # %bb.0: # %entry
+; MIPS64-N64-NEXT:    daddiu $sp, $sp, -32
+; MIPS64-N64-NEXT:    .cfi_def_cfa_offset 32
+; MIPS64-N64-NEXT:    sd $ra, 24($sp) # 8-byte Folded Spill
+; MIPS64-N64-NEXT:    sd $gp, 16($sp) # 8-byte Folded Spill
+; MIPS64-N64-NEXT:    sd $16, 8($sp) # 8-byte Folded Spill
+; MIPS64-N64-NEXT:    .cfi_offset 31, -8
+; MIPS64-N64-NEXT:    .cfi_offset 28, -16
+; MIPS64-N64-NEXT:    .cfi_offset 16, -24
+; MIPS64-N64-NEXT:    lui $1, %hi(%neg(%gp_rel(uitofp_i64_f16)))
+; MIPS64-N64-NEXT:    daddu $1, $1, $25
+; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(uitofp_i64_f16)))
+; MIPS64-N64-NEXT:    move $16, $4
+; MIPS64-N64-NEXT:    ld $25, %call16(__floatundihf)($gp)
+; MIPS64-N64-NEXT:    jalr $25
+; MIPS64-N64-NEXT:    daddiu $4, $sp, 6
+; MIPS64-N64-NEXT:    lh $1, 6($sp)
+; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
+; MIPS64-N64-NEXT:    sh $1, 0($16)
+; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
+; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
+; MIPS64-N64-NEXT:    ld $ra, 24($sp) # 8-byte Folded Reload
+; MIPS64-N64-NEXT:    jr $ra
+; MIPS64-N64-NEXT:    daddiu $sp, $sp, 32
 entry:
   %r = uitofp i64 %x to half
   ret half %r
 }
 
 define half @uitofp_i128_f16(i128 %x) {
-; MIPS32-O32-LABEL: uitofp_i128_f16:
-; MIPS32-O32:       # %bb.0: # %entry
-; MIPS32-O32-NEXT:    lui $2, %hi(_gp_disp)
-; MIPS32-O32-NEXT:    addiu $2, $2, %lo(_gp_disp)
-; MIPS32-O32-NEXT:    addiu $sp, $sp, -24
-; MIPS32-O32-NEXT:    .cfi_def_cfa_offset 24
-; MIPS32-O32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
-; MIPS32-O32-NEXT:    .cfi_offset 31, -4
-; MIPS32-O32-NEXT:    addu $gp, $2, $25
-; MIPS32-O32-NEXT:    lw $25, %call16(__floatuntisf)($gp)
-; MIPS32-O32-NEXT:    jalr $25
-; MIPS32-O32-NEXT:    nop
-; MIPS32-O32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS32-O32-NEXT:    splati.w $w0, $w0[0]
-; MIPS32-O32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS32-O32-NEXT:    copy_s.h $2, $w0[0]
-; MIPS32-O32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
-; MIPS32-O32-NEXT:    jr $ra
-; MIPS32-O32-NEXT:    addiu $sp, $sp, 24
-;
-; MIPS64R5-N32-LABEL: uitofp_i128_f16:
-; MIPS64R5-N32:       # %bb.0: # %entry
-; MIPS64R5-N32-NEXT:    addiu $sp, $sp, -16
-; MIPS64R5-N32-NEXT:    .cfi_def_cfa_offset 16
-; MIPS64R5-N32-NEXT:    sd $ra, 8($sp) # 8-byte Folded Spill
-; MIPS64R5-N32-NEXT:    sd $gp, 0($sp) # 8-byte Folded Spill
-; MIPS64R5-N32-NEXT:    .cfi_offset 31, -8
-; MIPS64R5-N32-NEXT:    .cfi_offset 28, -16
-; MIPS64R5-N32-NEXT:    lui $1, %hi(%neg(%gp_rel(uitofp_i128_f16)))
-; MIPS64R5-N32-NEXT:    addu $1, $1, $25
-; MIPS64R5-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(uitofp_i128_f16)))
-; MIPS64R5-N32-NEXT:    lw $25, %call16(__floatuntisf)($gp)
-; MIPS64R5-N32-NEXT:    jalr $25
-; MIPS64R5-N32-NEXT:    nop
-; MIPS64R5-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64R5-N32-NEXT:    splati.w $w0, $w0[0]
-; MIPS64R5-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64R5-N32-NEXT:    copy_s.h $2, $w0[0]
-; MIPS64R5-N32-NEXT:    ld $gp, 0($sp) # 8-byte Folded Reload
-; MIPS64R5-N32-NEXT:    ld $ra, 8($sp) # 8-byte Folded Reload
-; MIPS64R5-N32-NEXT:    jr $ra
-; MIPS64R5-N32-NEXT:    addiu $sp, $sp, 16
-;
-; MIPS64R5-N64-LABEL: uitofp_i128_f16:
-; MIPS64R5-N64:       # %bb.0: # %entry
-; MIPS64R5-N64-NEXT:    daddiu $sp, $sp, -16
-; MIPS64R5-N64-NEXT:    .cfi_def_cfa_offset 16
-; MIPS64R5-N64-NEXT:    sd $ra, 8($sp) # 8-byte Folded Spill
-; MIPS64R5-N64-NEXT:    sd $gp, 0($sp) # 8-byte Folded Spill
-; MIPS64R5-N64-NEXT:    .cfi_offset 31, -8
-; MIPS64R5-N64-NEXT:    .cfi_offset 28, -16
-; MIPS64R5-N64-NEXT:    lui $1, %hi(%neg(%gp_rel(uitofp_i128_f16)))
-; MIPS64R5-N64-NEXT:    daddu $1, $1, $25
-; MIPS64R5-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(uitofp_i128_f16)))
-; MIPS64R5-N64-NEXT:    ld $25, %call16(__floatuntisf)($gp)
-; MIPS64R5-N64-NEXT:    jalr $25
-; MIPS64R5-N64-NEXT:    nop
-; MIPS64R5-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPS64R5-N64-NEXT:    splati.w $w0, $w0[0]
-; MIPS64R5-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPS64R5-N64-NEXT:    copy_s.h $2, $w0[0]
-; MIPS64R5-N64-NEXT:    ld $gp, 0($sp) # 8-byte Folded Reload
-; MIPS64R5-N64-NEXT:    ld $ra, 8($sp) # 8-byte Folded Reload
-; MIPS64R5-N64-NEXT:    jr $ra
-; MIPS64R5-N64-NEXT:    daddiu $sp, $sp, 16
-;
-; MIPSR6-O32-LABEL: uitofp_i128_f16:
-; MIPSR6-O32:       # %bb.0: # %entry
-; MIPSR6-O32-NEXT:    lui $2, %hi(_gp_disp)
-; MIPSR6-O32-NEXT:    addiu $2, $2, %lo(_gp_disp)
-; MIPSR6-O32-NEXT:    addiu $sp, $sp, -24
-; MIPSR6-O32-NEXT:    .cfi_def_cfa_offset 24
-; MIPSR6-O32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
-; MIPSR6-O32-NEXT:    .cfi_offset 31, -4
-; MIPSR6-O32-NEXT:    addu $gp, $2, $25
-; MIPSR6-O32-NEXT:    lw $25, %call16(__floatuntisf)($gp)
-; MIPSR6-O32-NEXT:    jalrc $25
-; MIPSR6-O32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPSR6-O32-NEXT:    splati.w $w0, $w0[0]
-; MIPSR6-O32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-O32-NEXT:    copy_s.h $2, $w0[0]
-; MIPSR6-O32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
-; MIPSR6-O32-NEXT:    jr $ra
-; MIPSR6-O32-NEXT:    addiu $sp, $sp, 24
+; MIPS32-LABEL: uitofp_i128_f16:
+; MIPS32:       # %bb.0: # %entry
+; MIPS32-NEXT:    lui $2, %hi(_gp_disp)
+; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
+; MIPS32-NEXT:    addiu $sp, $sp, -40
+; MIPS32-NEXT:    .cfi_def_cfa_offset 40
+; MIPS32-NEXT:    sw $ra, 36($sp) # 4-byte Folded Spill
+; MIPS32-NEXT:    sw $16, 32($sp) # 4-byte Folded Spill
+; MIPS32-NEXT:    .cfi_offset 31, -4
+; MIPS32-NEXT:    .cfi_offset 16, -8
+; MIPS32-NEXT:    addu $gp, $2, $25
+; MIPS32-NEXT:    move $16, $4
+; MIPS32-NEXT:    lw $1, 60($sp)
+; MIPS32-NEXT:    sw $1, 20($sp)
+; MIPS32-NEXT:    lw $1, 56($sp)
+; MIPS32-NEXT:    sw $1, 16($sp)
+; MIPS32-NEXT:    lw $25, %call16(__floatuntihf)($gp)
+; MIPS32-NEXT:    jalr $25
+; MIPS32-NEXT:    addiu $4, $sp, 30
+; MIPS32-NEXT:    lh $1, 30($sp)
+; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    copy_u.h $1, $w0[0]
+; MIPS32-NEXT:    sh $1, 0($16)
+; MIPS32-NEXT:    lw $16, 32($sp) # 4-byte Folded Reload
+; MIPS32-NEXT:    lw $ra, 36($sp) # 4-byte Folded Reload
+; MIPS32-NEXT:    jr $ra
+; MIPS32-NEXT:    addiu $sp, $sp, 40
 ;
-; MIPSR6-N32-LABEL: uitofp_i128_f16:
-; MIPSR6-N32:       # %bb.0: # %entry
-; MIPSR6-N32-NEXT:    addiu $sp, $sp, -16
-; MIPSR6-N32-NEXT:    .cfi_def_cfa_offset 16
-; MIPSR6-N32-NEXT:    sd $ra, 8($sp) # 8-byte Folded Spill
-; MIPSR6-N32-NEXT:    sd $gp, 0($sp) # 8-byte Folded Spill
-; MIPSR6-N32-NEXT:    .cfi_offset 31, -8
-; MIPSR6-N32-NEXT:    .cfi_offset 28, -16
-; MIPSR6-N32-NEXT:    lui $1, %hi(%neg(%gp_rel(uitofp_i128_f16)))
-; MIPSR6-N32-NEXT:    addu $1, $1, $25
-; MIPSR6-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(uitofp_i128_f16)))
-; MIPSR6-N32-NEXT:    lw $25, %call16(__floatuntisf)($gp)
-; MIPSR6-N32-NEXT:    jialc $25, 0
-; MIPSR6-N32-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPSR6-N32-NEXT:    splati.w $w0, $w0[0]
-; MIPSR6-N32-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-N32-NEXT:    copy_s.h $2, $w0[0]
-; MIPSR6-N32-NEXT:    ld $gp, 0($sp) # 8-byte Folded Reload
-; MIPSR6-N32-NEXT:    ld $ra, 8($sp) # 8-byte Folded Reload
-; MIPSR6-N32-NEXT:    jr $ra
-; MIPSR6-N32-NEXT:    addiu $sp, $sp, 16
+; MIPS64-N32-LABEL: uitofp_i128_f16:
+; MIPS64-N32:       # %bb.0: # %entry
+; MIPS64-N32-NEXT:    addiu $sp, $sp, -32
+; MIPS64-N32-NEXT:    .cfi_def_cfa_offset 32
+; MIPS64-N32-NEXT:    sd $ra, 24($sp) # 8-byte Folded Spill
+; MIPS64-N32-NEXT:    sd $gp, 16($sp) # 8-byte Folded Spill
+; MIPS64-N32-NEXT:    sd $16, 8($sp) # 8-byte Folded Spill
+; MIPS64-N32-NEXT:    .cfi_offset 31, -8
+; MIPS64-N32-NEXT:    .cfi_offset 28, -16
+; MIPS64-N32-NEXT:    .cfi_offset 16, -24
+; MIPS64-N32-NEXT:    lui $1, %hi(%neg(%gp_rel(uitofp_i128_f16)))
+; MIPS64-N32-NEXT:    addu $1, $1, $25
+; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(uitofp_i128_f16)))
+; MIPS64-N32-NEXT:    move $16, $4
+; MIPS64-N32-NEXT:    lw $25, %call16(__floatuntihf)($gp)
+; MIPS64-N32-NEXT:    jalr $25
+; MIPS64-N32-NEXT:    addiu $4, $sp, 6
+; MIPS64-N32-NEXT:    sll $1, $16, 0
+; MIPS64-N32-NEXT:    lh $2, 6($sp)
+; MIPS64-N32-NEXT:    fill.h $w0, $2
+; MIPS64-N32-NEXT:    copy_u.h $2, $w0[0]
+; MIPS64-N32-NEXT:    sh $2, 0($1)
+; MIPS64-N32-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
+; MIPS64-N32-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
+; MIPS64-N32-NEXT:    ld $ra, 24($sp) # 8-byte Folded Reload
+; MIPS64-N32-NEXT:    jr $ra
+; MIPS64-N32-NEXT:    addiu $sp, $sp, 32
 ;
-; MIPSR6-N64-LABEL: uitofp_i128_f16:
-; MIPSR6-N64:       # %bb.0: # %entry
-; MIPSR6-N64-NEXT:    daddiu $sp, $sp, -16
-; MIPSR6-N64-NEXT:    .cfi_def_cfa_offset 16
-; MIPSR6-N64-NEXT:    sd $ra, 8($sp) # 8-byte Folded Spill
-; MIPSR6-N64-NEXT:    sd $gp, 0($sp) # 8-byte Folded Spill
-; MIPSR6-N64-NEXT:    .cfi_offset 31, -8
-; MIPSR6-N64-NEXT:    .cfi_offset 28, -16
-; MIPSR6-N64-NEXT:    lui $1, %hi(%neg(%gp_rel(uitofp_i128_f16)))
-; MIPSR6-N64-NEXT:    daddu $1, $1, $25
-; MIPSR6-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(uitofp_i128_f16)))
-; MIPSR6-N64-NEXT:    ld $25, %call16(__floatuntisf)($gp)
-; MIPSR6-N64-NEXT:    jalrc $25
-; MIPSR6-N64-NEXT:    # kill: def $f0 killed $f0 def $w0
-; MIPSR6-N64-NEXT:    splati.w $w0, $w0[0]
-; MIPSR6-N64-NEXT:    fexdo.h $w0, $w0, $w0
-; MIPSR6-N64-NEXT:    copy_s.h $2, $w0[0]
-; MIPSR6-N64-NEXT:    ld $gp, 0($sp) # 8-byte Folded Reload
-; MIPSR6-N64-NEXT:    ld $ra, 8($sp) # 8-byte Folded Reload
-; MIPSR6-N64-NEXT:    jr $ra
-; MIPSR6-N64-NEXT:    daddiu $sp, $sp, 16
+; MIPS64-N64-LABEL: uitofp_i128_f16:
+; MIPS64-N64:       # %bb.0: # %entry
+; MIPS64-N64-NEXT:    daddiu $sp, $sp, -32
+; MIPS64-N64-NEXT:    .cfi_def_cfa_offset 32
+; MIPS64-N64-NEXT:    sd $ra, 24($sp) # 8-byte Folded Spill
+; MIPS64-N64-NEXT:    sd $gp, 16($sp) # 8-byte Folded Spill
+; MIPS64-N64-NEXT:    sd $16, 8($sp) # 8-byte Folded Spill
+; MIPS64-N64-NEXT:    .cfi_offset 31, -8
+; MIPS64-N64-NEXT:    .cfi_offset 28, -16
+; MIPS64-N64-NEXT:    .cfi_offset 16, -24
+; MIPS64-N64-NEXT:    lui $1, %hi(%neg(%gp_rel(uitofp_i128_f16)))
+; MIPS64-N64-NEXT:    daddu $1, $1, $25
+; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(uitofp_i128_f16)))
+; MIPS64-N64-NEXT:    move $16, $4
+; MIPS64-N64-NEXT:    ld $25, %call16(__floatuntihf)($gp)
+; MIPS64-N64-NEXT:    jalr $25
+; MIPS64-N64-NEXT:    daddiu $4, $sp, 6
+; MIPS64-N64-NEXT:    lh $1, 6($sp)
+; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    copy_u.h $1, $w0[0]
+; MIPS64-N64-NEXT:    sh $1, 0($16)
+; MIPS64-N64-NEXT:    ld $16, 8($sp) # 8-byte Folded Reload
+; MIPS64-N64-NEXT:    ld $gp, 16($sp) # 8-byte Folded Reload
+; MIPS64-N64-NEXT:    ld $ra, 24($sp) # 8-byte Folded Reload
+; MIPS64-N64-NEXT:    jr $ra
+; MIPS64-N64-NEXT:    daddiu $sp, $sp, 32
 entry:
   %r = uitofp i128 %x to half
   ret half %r
@@ -3680,9 +3849,11 @@ entry:
 define i32 @fptosi_f16_i32(ptr %p) {
 ; MIPS32-LABEL: fptosi_f16_i32:
 ; MIPS32:       # %bb.0: # %entry
-; MIPS32-NEXT:    lhu $1, 0($4)
+; MIPS32-NEXT:    lh $1, 0($4)
 ; MIPS32-NEXT:    fill.h $w0, $1
 ; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f0
 ; MIPS32-NEXT:    trunc.w.s $f0, $f0
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    mfc1 $2, $f0
@@ -3690,18 +3861,22 @@ define i32 @fptosi_f16_i32(ptr %p) {
 ; MIPS64-N32-LABEL: fptosi_f16_i32:
 ; MIPS64-N32:       # %bb.0: # %entry
 ; MIPS64-N32-NEXT:    sll $1, $4, 0
-; MIPS64-N32-NEXT:    lhu $1, 0($1)
+; MIPS64-N32-NEXT:    lh $1, 0($1)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
 ; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f0
 ; MIPS64-N32-NEXT:    trunc.w.s $f0, $f0
 ; MIPS64-N32-NEXT:    jr $ra
 ; MIPS64-N32-NEXT:    mfc1 $2, $f0
 ;
 ; MIPS64-N64-LABEL: fptosi_f16_i32:
 ; MIPS64-N64:       # %bb.0: # %entry
-; MIPS64-N64-NEXT:    lhu $1, 0($4)
+; MIPS64-N64-NEXT:    lh $1, 0($4)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
 ; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f0
 ; MIPS64-N64-NEXT:    trunc.w.s $f0, $f0
 ; MIPS64-N64-NEXT:    jr $ra
 ; MIPS64-N64-NEXT:    mfc1 $2, $f0
@@ -3714,9 +3889,11 @@ entry:
 define i32 @fptoui_f16_i32(ptr %p) {
 ; MIPS32-LABEL: fptoui_f16_i32:
 ; MIPS32:       # %bb.0: # %entry
-; MIPS32-NEXT:    lhu $1, 0($4)
+; MIPS32-NEXT:    lh $1, 0($4)
 ; MIPS32-NEXT:    fill.h $w0, $1
 ; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
+; MIPS32-NEXT:    mtc1 $1, $f0
 ; MIPS32-NEXT:    trunc.w.s $f0, $f0
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    mfc1 $2, $f0
@@ -3724,18 +3901,22 @@ define i32 @fptoui_f16_i32(ptr %p) {
 ; MIPS64-N32-LABEL: fptoui_f16_i32:
 ; MIPS64-N32:       # %bb.0: # %entry
 ; MIPS64-N32-NEXT:    sll $1, $4, 0
-; MIPS64-N32-NEXT:    lhu $1, 0($1)
+; MIPS64-N32-NEXT:    lh $1, 0($1)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
 ; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f0
 ; MIPS64-N32-NEXT:    trunc.w.s $f0, $f0
 ; MIPS64-N32-NEXT:    jr $ra
 ; MIPS64-N32-NEXT:    mfc1 $2, $f0
 ;
 ; MIPS64-N64-LABEL: fptoui_f16_i32:
 ; MIPS64-N64:       # %bb.0: # %entry
-; MIPS64-N64-NEXT:    lhu $1, 0($4)
+; MIPS64-N64-NEXT:    lh $1, 0($4)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
 ; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f0
 ; MIPS64-N64-NEXT:    trunc.w.s $f0, $f0
 ; MIPS64-N64-NEXT:    jr $ra
 ; MIPS64-N64-NEXT:    mfc1 $2, $f0
@@ -3755,11 +3936,13 @@ define i64 @fptosi_f16_i64(ptr %p) {
 ; MIPS32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
 ; MIPS32-NEXT:    .cfi_offset 31, -4
 ; MIPS32-NEXT:    addu $gp, $2, $25
-; MIPS32-NEXT:    lhu $1, 0($4)
+; MIPS32-NEXT:    lh $1, 0($4)
 ; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS32-NEXT:    lw $25, %call16(__fixsfdi)($gp)
 ; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    fexupr.w $w12, $w0
+; MIPS32-NEXT:    mtc1 $1, $f12
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    addiu $sp, $sp, 24
@@ -3767,18 +3950,22 @@ define i64 @fptosi_f16_i64(ptr %p) {
 ; MIPS64-N32-LABEL: fptosi_f16_i64:
 ; MIPS64-N32:       # %bb.0: # %entry
 ; MIPS64-N32-NEXT:    sll $1, $4, 0
-; MIPS64-N32-NEXT:    lhu $1, 0($1)
+; MIPS64-N32-NEXT:    lh $1, 0($1)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
 ; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f0
 ; MIPS64-N32-NEXT:    trunc.l.s $f0, $f0
 ; MIPS64-N32-NEXT:    jr $ra
 ; MIPS64-N32-NEXT:    dmfc1 $2, $f0
 ;
 ; MIPS64-N64-LABEL: fptosi_f16_i64:
 ; MIPS64-N64:       # %bb.0: # %entry
-; MIPS64-N64-NEXT:    lhu $1, 0($4)
+; MIPS64-N64-NEXT:    lh $1, 0($4)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
 ; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f0
 ; MIPS64-N64-NEXT:    trunc.l.s $f0, $f0
 ; MIPS64-N64-NEXT:    jr $ra
 ; MIPS64-N64-NEXT:    dmfc1 $2, $f0
@@ -3798,11 +3985,13 @@ define i64 @fptoui_f16_i64(ptr %p) {
 ; MIPS32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
 ; MIPS32-NEXT:    .cfi_offset 31, -4
 ; MIPS32-NEXT:    addu $gp, $2, $25
-; MIPS32-NEXT:    lhu $1, 0($4)
+; MIPS32-NEXT:    lh $1, 0($4)
 ; MIPS32-NEXT:    fill.h $w0, $1
-; MIPS32-NEXT:    lw $25, %call16(__fixunssfdi)($gp)
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
+; MIPS32-NEXT:    lw $25, %call16(__fixsfdi)($gp)
 ; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    fexupr.w $w12, $w0
+; MIPS32-NEXT:    mtc1 $1, $f12
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    addiu $sp, $sp, 24
@@ -3810,18 +3999,22 @@ define i64 @fptoui_f16_i64(ptr %p) {
 ; MIPS64-N32-LABEL: fptoui_f16_i64:
 ; MIPS64-N32:       # %bb.0: # %entry
 ; MIPS64-N32-NEXT:    sll $1, $4, 0
-; MIPS64-N32-NEXT:    lhu $1, 0($1)
+; MIPS64-N32-NEXT:    lh $1, 0($1)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
 ; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
+; MIPS64-N32-NEXT:    mtc1 $1, $f0
 ; MIPS64-N32-NEXT:    trunc.l.s $f0, $f0
 ; MIPS64-N32-NEXT:    jr $ra
 ; MIPS64-N32-NEXT:    dmfc1 $2, $f0
 ;
 ; MIPS64-N64-LABEL: fptoui_f16_i64:
 ; MIPS64-N64:       # %bb.0: # %entry
-; MIPS64-N64-NEXT:    lhu $1, 0($4)
+; MIPS64-N64-NEXT:    lh $1, 0($4)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
 ; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
+; MIPS64-N64-NEXT:    mtc1 $1, $f0
 ; MIPS64-N64-NEXT:    trunc.l.s $f0, $f0
 ; MIPS64-N64-NEXT:    jr $ra
 ; MIPS64-N64-NEXT:    dmfc1 $2, $f0
@@ -3841,11 +4034,13 @@ define i128 @fptosi_f16_i128(ptr %p) {
 ; MIPS32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
 ; MIPS32-NEXT:    .cfi_offset 31, -4
 ; MIPS32-NEXT:    addu $gp, $2, $25
-; MIPS32-NEXT:    lhu $1, 0($4)
+; MIPS32-NEXT:    lh $1, 0($4)
 ; MIPS32-NEXT:    fill.h $w0, $1
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS32-NEXT:    lw $25, %call16(__fixsfti)($gp)
 ; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    fexupr.w $w12, $w0
+; MIPS32-NEXT:    mtc1 $1, $f12
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    addiu $sp, $sp, 24
@@ -3862,11 +4057,13 @@ define i128 @fptosi_f16_i128(ptr %p) {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(fptosi_f16_i128)))
 ; MIPS64-N32-NEXT:    sll $1, $4, 0
-; MIPS64-N32-NEXT:    lhu $1, 0($1)
+; MIPS64-N32-NEXT:    lh $1, 0($1)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N32-NEXT:    lw $25, %call16(__fixsfti)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
 ; MIPS64-N32-NEXT:    ld $gp, 0($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $ra, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    jr $ra
@@ -3883,11 +4080,13 @@ define i128 @fptosi_f16_i128(ptr %p) {
 ; MIPS64-N64-NEXT:    lui $1, %hi(%neg(%gp_rel(fptosi_f16_i128)))
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(fptosi_f16_i128)))
-; MIPS64-N64-NEXT:    lhu $1, 0($4)
+; MIPS64-N64-NEXT:    lh $1, 0($4)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
 ; MIPS64-N64-NEXT:    ld $25, %call16(__fixsfti)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
 ; MIPS64-N64-NEXT:    ld $gp, 0($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $ra, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    jr $ra
@@ -3908,11 +4107,13 @@ define i128 @fptoui_f16_i128(ptr %p) {
 ; MIPS32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
 ; MIPS32-NEXT:    .cfi_offset 31, -4
 ; MIPS32-NEXT:    addu $gp, $2, $25
-; MIPS32-NEXT:    lhu $1, 0($4)
+; MIPS32-NEXT:    lh $1, 0($4)
 ; MIPS32-NEXT:    fill.h $w0, $1
-; MIPS32-NEXT:    lw $25, %call16(__fixunssfti)($gp)
+; MIPS32-NEXT:    fexupr.w $w0, $w0
+; MIPS32-NEXT:    copy_s.w $1, $w0[0]
+; MIPS32-NEXT:    lw $25, %call16(__fixsfti)($gp)
 ; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    fexupr.w $w12, $w0
+; MIPS32-NEXT:    mtc1 $1, $f12
 ; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
 ; MIPS32-NEXT:    jr $ra
 ; MIPS32-NEXT:    addiu $sp, $sp, 24
@@ -3929,11 +4130,13 @@ define i128 @fptoui_f16_i128(ptr %p) {
 ; MIPS64-N32-NEXT:    addu $1, $1, $25
 ; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(fptoui_f16_i128)))
 ; MIPS64-N32-NEXT:    sll $1, $4, 0
-; MIPS64-N32-NEXT:    lhu $1, 0($1)
+; MIPS64-N32-NEXT:    lh $1, 0($1)
 ; MIPS64-N32-NEXT:    fill.h $w0, $1
-; MIPS64-N32-NEXT:    lw $25, %call16(__fixunssfti)($gp)
+; MIPS64-N32-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N32-NEXT:    copy_s.w $1, $w0[0]
+; MIPS64-N32-NEXT:    lw $25, %call16(__fixsfti)($gp)
 ; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    fexupr.w $w12, $w0
+; MIPS64-N32-NEXT:    mtc1 $1, $f12
 ; MIPS64-N32-NEXT:    ld $gp, 0($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    ld $ra, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N32-NEXT:    jr $ra
@@ -3950,11 +4153,13 @@ define i128 @fptoui_f16_i128(ptr %p) {
 ; MIPS64-N64-NEXT:    lui $1, %hi(%neg(%gp_rel(fptoui_f16_i128)))
 ; MIPS64-N64-NEXT:    daddu $1, $1, $25
 ; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(fptoui_f16_i128)))
-; MIPS64-N64-NEXT:    lhu $1, 0($4)
+; MIPS64-N64-NEXT:    lh $1, 0($4)
 ; MIPS64-N64-NEXT:    fill.h $w0, $1
-; MIPS64-N64-NEXT:    ld $25, %call16(__fixunssfti)($gp)
+; MIPS64-N64-NEXT:    fexupr.w $w0, $w0
+; MIPS64-N64-NEXT:    copy_s.w $1, $w0[0]
+; MIPS64-N64-NEXT:    ld $25, %call16(__fixsfti)($gp)
 ; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    fexupr.w $w12, $w0
+; MIPS64-N64-NEXT:    mtc1 $1, $f12
 ; MIPS64-N64-NEXT:    ld $gp, 0($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    ld $ra, 8($sp) # 8-byte Folded Reload
 ; MIPS64-N64-NEXT:    jr $ra
@@ -3965,70 +4170,4 @@ entry:
   ret i128 %r
 }
 
-define void @pass_f16_argument(ptr align 2 %p) {
-; MIPS32-LABEL: pass_f16_argument:
-; MIPS32:       # %bb.0: # %entry
-; MIPS32-NEXT:    lui $2, %hi(_gp_disp)
-; MIPS32-NEXT:    addiu $2, $2, %lo(_gp_disp)
-; MIPS32-NEXT:    addiu $sp, $sp, -24
-; MIPS32-NEXT:    .cfi_def_cfa_offset 24
-; MIPS32-NEXT:    sw $ra, 20($sp) # 4-byte Folded Spill
-; MIPS32-NEXT:    .cfi_offset 31, -4
-; MIPS32-NEXT:    addu $gp, $2, $25
-; MIPS32-NEXT:    lhu $4, 0($4)
-; MIPS32-NEXT:    lw $25, %call16(accept_f16_argument)($gp)
-; MIPS32-NEXT:    jalr $25
-; MIPS32-NEXT:    addiu $5, $zero, 1
-; MIPS32-NEXT:    lw $ra, 20($sp) # 4-byte Folded Reload
-; MIPS32-NEXT:    jr $ra
-; MIPS32-NEXT:    addiu $sp, $sp, 24
-;
-; MIPS64-N32-LABEL: pass_f16_argument:
-; MIPS64-N32:       # %bb.0: # %entry
-; MIPS64-N32-NEXT:    addiu $sp, $sp, -16
-; MIPS64-N32-NEXT:    .cfi_def_cfa_offset 16
-; MIPS64-N32-NEXT:    sd $ra, 8($sp) # 8-byte Folded Spill
-; MIPS64-N32-NEXT:    sd $gp, 0($sp) # 8-byte Folded Spill
-; MIPS64-N32-NEXT:    .cfi_offset 31, -8
-; MIPS64-N32-NEXT:    .cfi_offset 28, -16
-; MIPS64-N32-NEXT:    lui $1, %hi(%neg(%gp_rel(pass_f16_argument)))
-; MIPS64-N32-NEXT:    addu $1, $1, $25
-; MIPS64-N32-NEXT:    addiu $gp, $1, %lo(%neg(%gp_rel(pass_f16_argument)))
-; MIPS64-N32-NEXT:    sll $1, $4, 0
-; MIPS64-N32-NEXT:    lh $4, 0($1)
-; MIPS64-N32-NEXT:    lw $25, %call16(accept_f16_argument)($gp)
-; MIPS64-N32-NEXT:    jalr $25
-; MIPS64-N32-NEXT:    daddiu $5, $zero, 1
-; MIPS64-N32-NEXT:    ld $gp, 0($sp) # 8-byte Folded Reload
-; MIPS64-N32-NEXT:    ld $ra, 8($sp) # 8-byte Folded Reload
-; MIPS64-N32-NEXT:    jr $ra
-; MIPS64-N32-NEXT:    addiu $sp, $sp, 16
-;
-; MIPS64-N64-LABEL: pass_f16_argument:
-; MIPS64-N64:       # %bb.0: # %entry
-; MIPS64-N64-NEXT:    daddiu $sp, $sp, -16
-; MIPS64-N64-NEXT:    .cfi_def_cfa_offset 16
-; MIPS64-N64-NEXT:    sd $ra, 8($sp) # 8-byte Folded Spill
-; MIPS64-N64-NEXT:    sd $gp, 0($sp) # 8-byte Folded Spill
-; MIPS64-N64-NEXT:    .cfi_offset 31, -8
-; MIPS64-N64-NEXT:    .cfi_offset 28, -16
-; MIPS64-N64-NEXT:    lui $1, %hi(%neg(%gp_rel(pass_f16_argument)))
-; MIPS64-N64-NEXT:    daddu $1, $1, $25
-; MIPS64-N64-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(pass_f16_argument)))
-; MIPS64-N64-NEXT:    lh $4, 0($4)
-; MIPS64-N64-NEXT:    ld $25, %call16(accept_f16_argument)($gp)
-; MIPS64-N64-NEXT:    jalr $25
-; MIPS64-N64-NEXT:    daddiu $5, $zero, 1
-; MIPS64-N64-NEXT:    ld $gp, 0($sp) # 8-byte Folded Reload
-; MIPS64-N64-NEXT:    ld $ra, 8($sp) # 8-byte Folded Reload
-; MIPS64-N64-NEXT:    jr $ra
-; MIPS64-N64-NEXT:    daddiu $sp, $sp, 16
-entry:
-  %h = load half, ptr %p, align 2
-  call void @accept_f16_argument( half %h, i32 1)
-  ret void
-}
-
-declare void @accept_f16_argument(half, i32 )
-
 attributes #0 = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }


        


More information about the llvm-branch-commits mailing list