Index: lib/Target/PowerPC/PPCInstrVSX.td =================================================================== --- lib/Target/PowerPC/PPCInstrVSX.td +++ lib/Target/PowerPC/PPCInstrVSX.td @@ -2534,9 +2534,16 @@ def XSCVSDQP : X_VT5_XO5_VB5_TyVB<63, 10, 836, "xscvsdqp", vfrc, []>; def : Pat<(f128 (sint_to_fp i64:$src)), (f128 (XSCVSDQP (COPY_TO_REGCLASS $src, VFRC)))>; + def : Pat<(f128 (sint_to_fp (i64 (PPCmfvsr f64:$src)))), + (f128 (XSCVSDQP $src))>; + def : Pat<(f128 (sint_to_fp (i32 (PPCmfvsr f64:$src)))), + (f128 (XSCVSDQP (VEXTSW2Ds $src)))>; + def XSCVUDQP : X_VT5_XO5_VB5_TyVB<63, 2, 836, "xscvudqp", vfrc, []>; def : Pat<(f128 (uint_to_fp i64:$src)), (f128 (XSCVUDQP (COPY_TO_REGCLASS $src, VFRC)))>; + def : Pat<(f128 (uint_to_fp (i64 (PPCmfvsr f64:$src)))), + (f128 (XSCVUDQP $src))>; // Convert (Un)Signed Word -> QP. def : Pat<(f128 (sint_to_fp i32:$src)), @@ -3206,6 +3213,11 @@ (f128 (XSCVUDQP (EXTRACT_SUBREG (VEXTRACTUB Idx, $src), sub_64)))>; } + + // Unsiged int in vsx register -> QP + def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))), + (f128 (XSCVUDQP + (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 4)))>; } // IsBigEndian, HasP9Vector let Predicates = [IsLittleEndian, HasP9Vector] in { @@ -3272,6 +3284,11 @@ (EXTRACT_SUBREG (VEXTRACTUB !head(!tail(Idx)), $src), sub_64)))>; } + + // Unsiged int in vsx register -> QP + def : Pat<(f128 (uint_to_fp (i32 (PPCmfvsr f64:$src)))), + (f128 (XSCVUDQP + (XXEXTRACTUW (SUBREG_TO_REG (i64 1), $src, sub_64), 8)))>; } // IsLittleEndian, HasP9Vector // Convert (Un)Signed DWord in memory -> QP Index: test/CodeGen/PowerPC/f128-conv.ll =================================================================== --- test/CodeGen/PowerPC/f128-conv.ll +++ test/CodeGen/PowerPC/f128-conv.ll @@ -398,3 +398,129 @@ ; CHECK-NEXT: stxv [[CONV]], 0(3) ; CHECK-NEXT: blr } + +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + +; Function Attrs: norecurse nounwind +define void @cvdp2sw2qp(double %val, fp128* nocapture %res) { +; CHECK-LABEL: cvdp2sw2qp: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xscvdpsxws 2, 1 +; CHECK-NEXT: vextsw2d 2, 2 +; CHECK-NEXT: xscvsdqp 2, 2 +; CHECK-NEXT: stxv 2, 0(4) +; CHECK-NEXT: blr +entry: + %conv = fptosi double %val to i32 + %conv1 = sitofp i32 %conv to fp128 + store fp128 %conv1, fp128* %res, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @cvdp2sdw2qp(double %val, fp128* nocapture %res) { +; CHECK-LABEL: cvdp2sdw2qp: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xscvdpsxds 2, 1 +; CHECK-NEXT: xscvsdqp 2, 2 +; CHECK-NEXT: stxv 2, 0(4) +; CHECK-NEXT: blr +entry: + %conv = fptosi double %val to i64 + %conv1 = sitofp i64 %conv to fp128 + store fp128 %conv1, fp128* %res, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @cvsp2sw2qp(float %val, fp128* nocapture %res) { +; CHECK-LABEL: cvsp2sw2qp: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xscvdpsxws 2, 1 +; CHECK-NEXT: vextsw2d 2, 2 +; CHECK-NEXT: xscvsdqp 2, 2 +; CHECK-NEXT: stxv 2, 0(4) +; CHECK-NEXT: blr +entry: + %conv = fptosi float %val to i32 + %conv1 = sitofp i32 %conv to fp128 + store fp128 %conv1, fp128* %res, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @cvsp2sdw2qp(float %val, fp128* nocapture %res) { +; CHECK-LABEL: cvsp2sdw2qp: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xscvdpsxds 2, 1 +; CHECK-NEXT: xscvsdqp 2, 2 +; CHECK-NEXT: stxv 2, 0(4) +; CHECK-NEXT: blr +entry: + %conv = fptosi float %val to i64 + %conv1 = sitofp i64 %conv to fp128 + store fp128 %conv1, fp128* %res, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @cvdp2uw2qp(double %val, fp128* nocapture %res) { +; CHECK-LABEL: cvdp2uw2qp: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xscvdpuxws 0, 1 +; CHECK-NEXT: xxextractuw 2, 0, 8 +; CHECK-NEXT: xscvudqp 2, 2 +; CHECK-NEXT: stxv 2, 0(4) +; CHECK-NEXT: blr +entry: + %conv = fptoui double %val to i32 + %conv1 = uitofp i32 %conv to fp128 + store fp128 %conv1, fp128* %res, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @cvdp2udw2qp(double %val, fp128* nocapture %res) { +; CHECK-LABEL: cvdp2udw2qp: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xscvdpuxds 2, 1 +; CHECK-NEXT: xscvudqp 2, 2 +; CHECK-NEXT: stxv 2, 0(4) +; CHECK-NEXT: blr +entry: + %conv = fptoui double %val to i64 + %conv1 = uitofp i64 %conv to fp128 + store fp128 %conv1, fp128* %res, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @cvsp2uw2qp(float %val, fp128* nocapture %res) { +; CHECK-LABEL: cvsp2uw2qp: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xscvdpuxws 0, 1 +; CHECK-NEXT: xxextractuw 2, 0, 8 +; CHECK-NEXT: xscvudqp 2, 2 +; CHECK-NEXT: stxv 2, 0(4) +; CHECK-NEXT: blr +entry: + %conv = fptoui float %val to i32 + %conv1 = uitofp i32 %conv to fp128 + store fp128 %conv1, fp128* %res, align 16 + ret void +} + +; Function Attrs: norecurse nounwind +define void @cvsp2udw2qp(float %val, fp128* nocapture %res) { +; CHECK-LABEL: cvsp2udw2qp: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: xscvdpuxds 2, 1 +; CHECK-NEXT: xscvudqp 2, 2 +; CHECK-NEXT: stxv 2, 0(4) +; CHECK-NEXT: blr +entry: + %conv = fptoui float %val to i64 + %conv1 = uitofp i64 %conv to fp128 + store fp128 %conv1, fp128* %res, align 16 + ret void +}