Index: llvm/trunk/lib/Target/Mips/MipsLegalizerInfo.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MipsLegalizerInfo.cpp +++ llvm/trunk/lib/Target/Mips/MipsLegalizerInfo.cpp @@ -152,6 +152,7 @@ getActionDefinitionsBuilder(G_UITOFP) .libcallForCartesianProduct({s64, s32}, {s64}) + .customForCartesianProduct({s64, s32}, {s32}) .minScalar(1, s32); getActionDefinitionsBuilder(G_SEXT_INREG).lower(); @@ -168,8 +169,54 @@ using namespace TargetOpcode; MIRBuilder.setInstr(MI); + const MipsSubtarget &STI = + static_cast(MIRBuilder.getMF().getSubtarget()); + const LLT s32 = LLT::scalar(32); + const LLT s64 = LLT::scalar(64); + + switch (MI.getOpcode()) { + case G_UITOFP: { + Register Dst = MI.getOperand(0).getReg(); + Register Src = MI.getOperand(1).getReg(); + LLT DstTy = MRI.getType(Dst); + LLT SrcTy = MRI.getType(Src); + + if (SrcTy != s32) + return false; + if (DstTy != s32 && DstTy != s64) + return false; + + // Let 0xABCDEFGH be given unsigned in MI.getOperand(1). First let's convert + // unsigned to double. Mantissa has 52 bits so we use following trick: + // First make floating point bit mask 0x43300000ABCDEFGH. + // Mask represents 2^52 * 0x1.00000ABCDEFGH i.e. 0x100000ABCDEFGH.0 . + // Next, subtract 2^52 * 0x1.0000000000000 i.e. 0x10000000000000.0 from it. + // Done. Trunc double to float if needed. + + MachineInstrBuilder Bitcast = MIRBuilder.buildInstr( + STI.isFP64bit() ? Mips::BuildPairF64_64 : Mips::BuildPairF64, {s64}, + {Src, MIRBuilder.buildConstant(s32, UINT32_C(0x43300000))}); + Bitcast.constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(), + *STI.getRegBankInfo()); + + MachineInstrBuilder TwoP52FP = MIRBuilder.buildFConstant( + s64, BitsToDouble(UINT64_C(0x4330000000000000))); + + if (DstTy == s64) + MIRBuilder.buildFSub(Dst, Bitcast, TwoP52FP); + else { + MachineInstrBuilder ResF64 = MIRBuilder.buildFSub(s64, Bitcast, TwoP52FP); + MIRBuilder.buildFPTrunc(Dst, ResF64); + } - return false; + MI.eraseFromParent(); + break; + } + default: + return false; + } + + return true; } bool MipsLegalizerInfo::legalizeIntrinsic(MachineInstr &MI, MachineRegisterInfo &MRI, Index: llvm/trunk/test/CodeGen/Mips/GlobalISel/legalizer/sitofp_and_uitofp.mir =================================================================== --- llvm/trunk/test/CodeGen/Mips/GlobalISel/legalizer/sitofp_and_uitofp.mir +++ llvm/trunk/test/CodeGen/Mips/GlobalISel/legalizer/sitofp_and_uitofp.mir @@ -12,7 +12,13 @@ define void @i16tof64() {entry: ret void} define void @i8tof64() {entry: ret void} define void @u64tof32() {entry: ret void} + define void @u32tof32() {entry: ret void} + define void @u16tof32() {entry: ret void} + define void @u8tof32() {entry: ret void} define void @u64tof64() {entry: ret void} + define void @u32tof64() {entry: ret void} + define void @u16tof64() {entry: ret void} + define void @u8tof64() {entry: ret void} ... --- @@ -328,6 +334,124 @@ ... --- +name: u32tof32 +alignment: 2 +tracksRegLiveness: true +body: | + bb.1.entry: + liveins: $a0 + + ; FP32-LABEL: name: u32tof32 + ; FP32: liveins: $a0 + ; FP32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0 + ; FP32: [[C:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200 + ; FP32: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]](s32) + ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 [[COPY1]], [[C]](s32) + ; FP32: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000 + ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_]], [[C1]] + ; FP32: [[FPTRUNC:%[0-9]+]]:_(s32) = G_FPTRUNC [[FSUB]](s64) + ; FP32: $f0 = COPY [[FPTRUNC]](s32) + ; FP32: RetRA implicit $f0 + ; FP64-LABEL: name: u32tof32 + ; FP64: liveins: $a0 + ; FP64: [[COPY:%[0-9]+]]:_(s32) = COPY $a0 + ; FP64: [[C:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200 + ; FP64: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]](s32) + ; FP64: [[BuildPairF64_64_:%[0-9]+]]:fgr64(s64) = BuildPairF64_64 [[COPY1]], [[C]](s32) + ; FP64: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000 + ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_64_]], [[C1]] + ; FP64: [[FPTRUNC:%[0-9]+]]:_(s32) = G_FPTRUNC [[FSUB]](s64) + ; FP64: $f0 = COPY [[FPTRUNC]](s32) + ; FP64: RetRA implicit $f0 + %0:_(s32) = COPY $a0 + %1:_(s32) = G_UITOFP %0(s32) + $f0 = COPY %1(s32) + RetRA implicit $f0 + +... +--- +name: u16tof32 +alignment: 2 +tracksRegLiveness: true +body: | + bb.1.entry: + liveins: $a0 + + ; FP32-LABEL: name: u16tof32 + ; FP32: liveins: $a0 + ; FP32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0 + ; FP32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535 + ; FP32: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32) + ; FP32: [[AND:%[0-9]+]]:gpr32(s32) = G_AND [[COPY1]], [[C]] + ; FP32: [[C1:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200 + ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 [[AND]](s32), [[C1]](s32) + ; FP32: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000 + ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_]], [[C2]] + ; FP32: [[FPTRUNC:%[0-9]+]]:_(s32) = G_FPTRUNC [[FSUB]](s64) + ; FP32: $f0 = COPY [[FPTRUNC]](s32) + ; FP32: RetRA implicit $f0 + ; FP64-LABEL: name: u16tof32 + ; FP64: liveins: $a0 + ; FP64: [[COPY:%[0-9]+]]:_(s32) = COPY $a0 + ; FP64: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535 + ; FP64: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32) + ; FP64: [[AND:%[0-9]+]]:gpr32(s32) = G_AND [[COPY1]], [[C]] + ; FP64: [[C1:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200 + ; FP64: [[BuildPairF64_64_:%[0-9]+]]:fgr64(s64) = BuildPairF64_64 [[AND]](s32), [[C1]](s32) + ; FP64: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000 + ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_64_]], [[C2]] + ; FP64: [[FPTRUNC:%[0-9]+]]:_(s32) = G_FPTRUNC [[FSUB]](s64) + ; FP64: $f0 = COPY [[FPTRUNC]](s32) + ; FP64: RetRA implicit $f0 + %1:_(s32) = COPY $a0 + %0:_(s16) = G_TRUNC %1(s32) + %2:_(s32) = G_UITOFP %0(s16) + $f0 = COPY %2(s32) + RetRA implicit $f0 + +... +--- +name: u8tof32 +alignment: 2 +tracksRegLiveness: true +body: | + bb.1.entry: + liveins: $a0 + + ; FP32-LABEL: name: u8tof32 + ; FP32: liveins: $a0 + ; FP32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0 + ; FP32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255 + ; FP32: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32) + ; FP32: [[AND:%[0-9]+]]:gpr32(s32) = G_AND [[COPY1]], [[C]] + ; FP32: [[C1:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200 + ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 [[AND]](s32), [[C1]](s32) + ; FP32: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000 + ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_]], [[C2]] + ; FP32: [[FPTRUNC:%[0-9]+]]:_(s32) = G_FPTRUNC [[FSUB]](s64) + ; FP32: $f0 = COPY [[FPTRUNC]](s32) + ; FP32: RetRA implicit $f0 + ; FP64-LABEL: name: u8tof32 + ; FP64: liveins: $a0 + ; FP64: [[COPY:%[0-9]+]]:_(s32) = COPY $a0 + ; FP64: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255 + ; FP64: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32) + ; FP64: [[AND:%[0-9]+]]:gpr32(s32) = G_AND [[COPY1]], [[C]] + ; FP64: [[C1:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200 + ; FP64: [[BuildPairF64_64_:%[0-9]+]]:fgr64(s64) = BuildPairF64_64 [[AND]](s32), [[C1]](s32) + ; FP64: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000 + ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_64_]], [[C2]] + ; FP64: [[FPTRUNC:%[0-9]+]]:_(s32) = G_FPTRUNC [[FSUB]](s64) + ; FP64: $f0 = COPY [[FPTRUNC]](s32) + ; FP64: RetRA implicit $f0 + %1:_(s32) = COPY $a0 + %0:_(s8) = G_TRUNC %1(s32) + %2:_(s32) = G_UITOFP %0(s8) + $f0 = COPY %2(s32) + RetRA implicit $f0 + +... +--- name: u64tof64 alignment: 2 tracksRegLiveness: true @@ -367,3 +491,115 @@ RetRA implicit $d0 ... +--- +name: u32tof64 +alignment: 2 +tracksRegLiveness: true +body: | + bb.1.entry: + liveins: $a0 + + ; FP32-LABEL: name: u32tof64 + ; FP32: liveins: $a0 + ; FP32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0 + ; FP32: [[C:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200 + ; FP32: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]](s32) + ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 [[COPY1]], [[C]](s32) + ; FP32: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000 + ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_]], [[C1]] + ; FP32: $d0 = COPY [[FSUB]](s64) + ; FP32: RetRA implicit $d0 + ; FP64-LABEL: name: u32tof64 + ; FP64: liveins: $a0 + ; FP64: [[COPY:%[0-9]+]]:_(s32) = COPY $a0 + ; FP64: [[C:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200 + ; FP64: [[COPY1:%[0-9]+]]:gpr32 = COPY [[COPY]](s32) + ; FP64: [[BuildPairF64_64_:%[0-9]+]]:fgr64(s64) = BuildPairF64_64 [[COPY1]], [[C]](s32) + ; FP64: [[C1:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000 + ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_64_]], [[C1]] + ; FP64: $d0 = COPY [[FSUB]](s64) + ; FP64: RetRA implicit $d0 + %0:_(s32) = COPY $a0 + %1:_(s64) = G_UITOFP %0(s32) + $d0 = COPY %1(s64) + RetRA implicit $d0 + +... +--- +name: u16tof64 +alignment: 2 +tracksRegLiveness: true +body: | + bb.1.entry: + liveins: $a0 + + ; FP32-LABEL: name: u16tof64 + ; FP32: liveins: $a0 + ; FP32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0 + ; FP32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535 + ; FP32: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32) + ; FP32: [[AND:%[0-9]+]]:gpr32(s32) = G_AND [[COPY1]], [[C]] + ; FP32: [[C1:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200 + ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 [[AND]](s32), [[C1]](s32) + ; FP32: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000 + ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_]], [[C2]] + ; FP32: $d0 = COPY [[FSUB]](s64) + ; FP32: RetRA implicit $d0 + ; FP64-LABEL: name: u16tof64 + ; FP64: liveins: $a0 + ; FP64: [[COPY:%[0-9]+]]:_(s32) = COPY $a0 + ; FP64: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535 + ; FP64: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32) + ; FP64: [[AND:%[0-9]+]]:gpr32(s32) = G_AND [[COPY1]], [[C]] + ; FP64: [[C1:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200 + ; FP64: [[BuildPairF64_64_:%[0-9]+]]:fgr64(s64) = BuildPairF64_64 [[AND]](s32), [[C1]](s32) + ; FP64: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000 + ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_64_]], [[C2]] + ; FP64: $d0 = COPY [[FSUB]](s64) + ; FP64: RetRA implicit $d0 + %1:_(s32) = COPY $a0 + %0:_(s16) = G_TRUNC %1(s32) + %2:_(s64) = G_UITOFP %0(s16) + $d0 = COPY %2(s64) + RetRA implicit $d0 + +... +--- +name: u8tof64 +alignment: 2 +tracksRegLiveness: true +body: | + bb.1.entry: + liveins: $a0 + + ; FP32-LABEL: name: u8tof64 + ; FP32: liveins: $a0 + ; FP32: [[COPY:%[0-9]+]]:_(s32) = COPY $a0 + ; FP32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255 + ; FP32: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32) + ; FP32: [[AND:%[0-9]+]]:gpr32(s32) = G_AND [[COPY1]], [[C]] + ; FP32: [[C1:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200 + ; FP32: [[BuildPairF64_:%[0-9]+]]:afgr64(s64) = BuildPairF64 [[AND]](s32), [[C1]](s32) + ; FP32: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000 + ; FP32: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_]], [[C2]] + ; FP32: $d0 = COPY [[FSUB]](s64) + ; FP32: RetRA implicit $d0 + ; FP64-LABEL: name: u8tof64 + ; FP64: liveins: $a0 + ; FP64: [[COPY:%[0-9]+]]:_(s32) = COPY $a0 + ; FP64: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255 + ; FP64: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32) + ; FP64: [[AND:%[0-9]+]]:gpr32(s32) = G_AND [[COPY1]], [[C]] + ; FP64: [[C1:%[0-9]+]]:gpr32(s32) = G_CONSTANT i32 1127219200 + ; FP64: [[BuildPairF64_64_:%[0-9]+]]:fgr64(s64) = BuildPairF64_64 [[AND]](s32), [[C1]](s32) + ; FP64: [[C2:%[0-9]+]]:_(s64) = G_FCONSTANT double 0x4330000000000000 + ; FP64: [[FSUB:%[0-9]+]]:_(s64) = G_FSUB [[BuildPairF64_64_]], [[C2]] + ; FP64: $d0 = COPY [[FSUB]](s64) + ; FP64: RetRA implicit $d0 + %1:_(s32) = COPY $a0 + %0:_(s8) = G_TRUNC %1(s32) + %2:_(s64) = G_UITOFP %0(s8) + $d0 = COPY %2(s64) + RetRA implicit $d0 + +... Index: llvm/trunk/test/CodeGen/Mips/GlobalISel/llvm-ir/sitofp_and_uitofp.ll =================================================================== --- llvm/trunk/test/CodeGen/Mips/GlobalISel/llvm-ir/sitofp_and_uitofp.ll +++ llvm/trunk/test/CodeGen/Mips/GlobalISel/llvm-ir/sitofp_and_uitofp.ll @@ -136,6 +136,114 @@ ret float %conv } + +define float @u32tof32(i32 zeroext %a) { +; FP32-LABEL: u32tof32: +; FP32: # %bb.0: # %entry +; FP32-NEXT: lui $1, 17200 +; FP32-NEXT: mtc1 $4, $f0 +; FP32-NEXT: mtc1 $1, $f1 +; FP32-NEXT: lui $1, 17200 +; FP32-NEXT: ori $2, $zero, 0 +; FP32-NEXT: mtc1 $2, $f2 +; FP32-NEXT: mtc1 $1, $f3 +; FP32-NEXT: sub.d $f0, $f0, $f2 +; FP32-NEXT: cvt.s.d $f0, $f0 +; FP32-NEXT: jr $ra +; FP32-NEXT: nop +; +; FP64-LABEL: u32tof32: +; FP64: # %bb.0: # %entry +; FP64-NEXT: lui $1, 17200 +; FP64-NEXT: mtc1 $4, $f0 +; FP64-NEXT: mthc1 $1, $f0 +; FP64-NEXT: lui $1, 17200 +; FP64-NEXT: ori $2, $zero, 0 +; FP64-NEXT: mtc1 $2, $f1 +; FP64-NEXT: mthc1 $1, $f1 +; FP64-NEXT: sub.d $f0, $f0, $f1 +; FP64-NEXT: cvt.s.d $f0, $f0 +; FP64-NEXT: jr $ra +; FP64-NEXT: nop +entry: + %conv = uitofp i32 %a to float + ret float %conv +} + +define float @u16tof32(i16 zeroext %a) { +; FP32-LABEL: u16tof32: +; FP32: # %bb.0: # %entry +; FP32-NEXT: ori $1, $zero, 65535 +; FP32-NEXT: and $1, $4, $1 +; FP32-NEXT: lui $2, 17200 +; FP32-NEXT: mtc1 $1, $f0 +; FP32-NEXT: mtc1 $2, $f1 +; FP32-NEXT: lui $1, 17200 +; FP32-NEXT: ori $2, $zero, 0 +; FP32-NEXT: mtc1 $2, $f2 +; FP32-NEXT: mtc1 $1, $f3 +; FP32-NEXT: sub.d $f0, $f0, $f2 +; FP32-NEXT: cvt.s.d $f0, $f0 +; FP32-NEXT: jr $ra +; FP32-NEXT: nop +; +; FP64-LABEL: u16tof32: +; FP64: # %bb.0: # %entry +; FP64-NEXT: ori $1, $zero, 65535 +; FP64-NEXT: and $1, $4, $1 +; FP64-NEXT: lui $2, 17200 +; FP64-NEXT: mtc1 $1, $f0 +; FP64-NEXT: mthc1 $2, $f0 +; FP64-NEXT: lui $1, 17200 +; FP64-NEXT: ori $2, $zero, 0 +; FP64-NEXT: mtc1 $2, $f1 +; FP64-NEXT: mthc1 $1, $f1 +; FP64-NEXT: sub.d $f0, $f0, $f1 +; FP64-NEXT: cvt.s.d $f0, $f0 +; FP64-NEXT: jr $ra +; FP64-NEXT: nop +entry: + %conv = uitofp i16 %a to float + ret float %conv +} + +define float @u8tof32(i8 zeroext %a) { +; FP32-LABEL: u8tof32: +; FP32: # %bb.0: # %entry +; FP32-NEXT: ori $1, $zero, 255 +; FP32-NEXT: and $1, $4, $1 +; FP32-NEXT: lui $2, 17200 +; FP32-NEXT: mtc1 $1, $f0 +; FP32-NEXT: mtc1 $2, $f1 +; FP32-NEXT: lui $1, 17200 +; FP32-NEXT: ori $2, $zero, 0 +; FP32-NEXT: mtc1 $2, $f2 +; FP32-NEXT: mtc1 $1, $f3 +; FP32-NEXT: sub.d $f0, $f0, $f2 +; FP32-NEXT: cvt.s.d $f0, $f0 +; FP32-NEXT: jr $ra +; FP32-NEXT: nop +; +; FP64-LABEL: u8tof32: +; FP64: # %bb.0: # %entry +; FP64-NEXT: ori $1, $zero, 255 +; FP64-NEXT: and $1, $4, $1 +; FP64-NEXT: lui $2, 17200 +; FP64-NEXT: mtc1 $1, $f0 +; FP64-NEXT: mthc1 $2, $f0 +; FP64-NEXT: lui $1, 17200 +; FP64-NEXT: ori $2, $zero, 0 +; FP64-NEXT: mtc1 $2, $f1 +; FP64-NEXT: mthc1 $1, $f1 +; FP64-NEXT: sub.d $f0, $f0, $f1 +; FP64-NEXT: cvt.s.d $f0, $f0 +; FP64-NEXT: jr $ra +; FP64-NEXT: nop +entry: + %conv = uitofp i8 %a to float + ret float %conv +} + define double @u64tof64(i64 zeroext %a) { ; MIPS32-LABEL: u64tof64: ; MIPS32: # %bb.0: # %entry @@ -153,3 +261,104 @@ %conv = uitofp i64 %a to double ret double %conv } + +define double @u32tof64(i32 zeroext %a) { +; FP32-LABEL: u32tof64: +; FP32: # %bb.0: # %entry +; FP32-NEXT: lui $1, 17200 +; FP32-NEXT: mtc1 $4, $f0 +; FP32-NEXT: mtc1 $1, $f1 +; FP32-NEXT: lui $1, 17200 +; FP32-NEXT: ori $2, $zero, 0 +; FP32-NEXT: mtc1 $2, $f2 +; FP32-NEXT: mtc1 $1, $f3 +; FP32-NEXT: sub.d $f0, $f0, $f2 +; FP32-NEXT: jr $ra +; FP32-NEXT: nop +; +; FP64-LABEL: u32tof64: +; FP64: # %bb.0: # %entry +; FP64-NEXT: lui $1, 17200 +; FP64-NEXT: mtc1 $4, $f0 +; FP64-NEXT: mthc1 $1, $f0 +; FP64-NEXT: lui $1, 17200 +; FP64-NEXT: ori $2, $zero, 0 +; FP64-NEXT: mtc1 $2, $f1 +; FP64-NEXT: mthc1 $1, $f1 +; FP64-NEXT: sub.d $f0, $f0, $f1 +; FP64-NEXT: jr $ra +; FP64-NEXT: nop +entry: + %conv = uitofp i32 %a to double + ret double %conv +} + +define double @u16tof64(i16 zeroext %a) { +; FP32-LABEL: u16tof64: +; FP32: # %bb.0: # %entry +; FP32-NEXT: ori $1, $zero, 65535 +; FP32-NEXT: and $1, $4, $1 +; FP32-NEXT: lui $2, 17200 +; FP32-NEXT: mtc1 $1, $f0 +; FP32-NEXT: mtc1 $2, $f1 +; FP32-NEXT: lui $1, 17200 +; FP32-NEXT: ori $2, $zero, 0 +; FP32-NEXT: mtc1 $2, $f2 +; FP32-NEXT: mtc1 $1, $f3 +; FP32-NEXT: sub.d $f0, $f0, $f2 +; FP32-NEXT: jr $ra +; FP32-NEXT: nop +; +; FP64-LABEL: u16tof64: +; FP64: # %bb.0: # %entry +; FP64-NEXT: ori $1, $zero, 65535 +; FP64-NEXT: and $1, $4, $1 +; FP64-NEXT: lui $2, 17200 +; FP64-NEXT: mtc1 $1, $f0 +; FP64-NEXT: mthc1 $2, $f0 +; FP64-NEXT: lui $1, 17200 +; FP64-NEXT: ori $2, $zero, 0 +; FP64-NEXT: mtc1 $2, $f1 +; FP64-NEXT: mthc1 $1, $f1 +; FP64-NEXT: sub.d $f0, $f0, $f1 +; FP64-NEXT: jr $ra +; FP64-NEXT: nop +entry: + %conv = uitofp i16 %a to double + ret double %conv +} + +define double @u8tof64(i8 zeroext %a) { +; FP32-LABEL: u8tof64: +; FP32: # %bb.0: # %entry +; FP32-NEXT: ori $1, $zero, 255 +; FP32-NEXT: and $1, $4, $1 +; FP32-NEXT: lui $2, 17200 +; FP32-NEXT: mtc1 $1, $f0 +; FP32-NEXT: mtc1 $2, $f1 +; FP32-NEXT: lui $1, 17200 +; FP32-NEXT: ori $2, $zero, 0 +; FP32-NEXT: mtc1 $2, $f2 +; FP32-NEXT: mtc1 $1, $f3 +; FP32-NEXT: sub.d $f0, $f0, $f2 +; FP32-NEXT: jr $ra +; FP32-NEXT: nop +; +; FP64-LABEL: u8tof64: +; FP64: # %bb.0: # %entry +; FP64-NEXT: ori $1, $zero, 255 +; FP64-NEXT: and $1, $4, $1 +; FP64-NEXT: lui $2, 17200 +; FP64-NEXT: mtc1 $1, $f0 +; FP64-NEXT: mthc1 $2, $f0 +; FP64-NEXT: lui $1, 17200 +; FP64-NEXT: ori $2, $zero, 0 +; FP64-NEXT: mtc1 $2, $f1 +; FP64-NEXT: mthc1 $1, $f1 +; FP64-NEXT: sub.d $f0, $f0, $f1 +; FP64-NEXT: jr $ra +; FP64-NEXT: nop +entry: + %conv = uitofp i8 %a to double + ret double %conv +}