Index: lib/Target/PowerPC/PPCInstrVSX.td =================================================================== --- lib/Target/PowerPC/PPCInstrVSX.td +++ lib/Target/PowerPC/PPCInstrVSX.td @@ -2514,11 +2514,20 @@ 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 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)))>; + // Convert (Un)Signed Word -> QP + def : Pat<(f128 (sint_to_fp i32:$src)), + (f128 (XSCVSDQP (MTVSRWA $src)))>; + def : Pat<(f128 (sint_to_fp (i32 (load xoaddr:$src)))), + (f128 (XSCVSDQP (LIWAX xoaddr:$src)))>; + def : Pat<(f128 (uint_to_fp i32:$src)), + (f128 (XSCVUDQP (MTVSRWZ $src)))>; + def : Pat<(f128 (uint_to_fp (i32 (load xoaddr:$src)))), + (f128 (XSCVUDQP (LIWZX xoaddr:$src)))>; + let UseVSXReg = 1 in { //===--------------------------------------------------------------------===// // Round to Floating-Point Integer Instructions Index: test/CodeGen/PowerPC/f128-conv.ll =================================================================== --- test/CodeGen/PowerPC/f128-conv.ll +++ test/CodeGen/PowerPC/f128-conv.ll @@ -4,6 +4,7 @@ @mem = global [5 x i64] [i64 56, i64 63, i64 3, i64 5, i64 6], align 8 @umem = global [5 x i64] [i64 560, i64 100, i64 34, i64 2, i64 5], align 8 @swMem = global [5 x i32] [i32 5, i32 2, i32 3, i32 4, i32 0], align 4 +@uwMem = global [5 x i32] [i32 5, i32 2, i32 3, i32 4, i32 0], align 4 ; Function Attrs: norecurse nounwind define void @sdwConv2qp(fp128* nocapture %a, i64 %b) { @@ -100,3 +101,120 @@ ; CHECK-NEXT: stxv [[REG0]], 0(3) ; CHECK-NEXT: blr } + +; Function Attrs: norecurse nounwind +define void @swConv2qp(fp128* nocapture %a, i32 signext %b) { +entry: + %conv = sitofp i32 %b to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void + +; CHECK-LABEL: swConv2qp +; CHECK-NOT: ld +; CHECK: mtvsrwa [[REG0:[0-9]+]], 4 +; CHECK-NEXT: xscvsdqp [[REG0]], [[REG0]] +; CHECK-NEXT: stxv [[REG0]], 0(3) +; CHECK-NEXT: blr +} + +; Function Attrs: norecurse nounwind +define void @swConv2qp_02(fp128* nocapture %a, i32* nocapture readonly %b) { +entry: + %0 = load i32, i32* %b, align 4 + %conv = sitofp i32 %0 to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void + +; CHECK-LABEL: swConv2qp_02 +; CHECK-NOT: ld +; CHECK: lxsiwax [[REG0:[0-9]+]], 0, 4 +; CHECK-NEXT: xscvsdqp [[REG0]], [[REG0]] +; CHECK-NEXT: stxv [[REG0]], 0(3) +; CHECK-NEXT: blr +} + +; Function Attrs: norecurse nounwind +define void @swConv2qp_03(fp128* nocapture %a) { +entry: + %0 = load i32, i32* getelementptr inbounds + ([5 x i32], [5 x i32]* @swMem, i64 0, i64 3), align 4 + %conv = sitofp i32 %0 to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void + +; CHECK-LABEL: swConv2qp_03 +; CHECK: addis [[REG:[0-9]+]], 2, .LC2@toc@ha +; CHECK: ld [[REG]], .LC2@toc@l([[REG]]) +; CHECK: lxsiwax [[REG0:[0-9]+]], 0, [[REG]] +; CHECK-NEXT: xscvsdqp [[REG0]], [[REG0]] +; CHECK-NEXT: stxv [[REG0]], 0(3) +; CHECK-NEXT: blr +} + +; Function Attrs: norecurse nounwind +define void @uwConv2qp(fp128* nocapture %a, i32 zeroext %b) { +entry: + %conv = uitofp i32 %b to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void + +; CHECK-LABEL: uwConv2qp +; CHECK-NOT: ld +; CHECK: mtvsrwz [[REG0:[0-9]+]], 4 +; CHECK-NEXT: xscvudqp [[REG0]], [[REG0]] +; CHECK-NEXT: stxv [[REG0]], 0(3) +; CHECK-NEXT: blr +} + +; Function Attrs: norecurse nounwind +define void @uwConv2qp_02(fp128* nocapture %a, i32* nocapture readonly %b) { +entry: + %0 = load i32, i32* %b, align 4 + %conv = uitofp i32 %0 to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void + +; CHECK-LABEL: uwConv2qp_02 +; CHECK-NOT: ld +; CHECK: lxsiwzx [[REG0:[0-9]+]], 0, 4 +; CHECK-NEXT: xscvudqp [[REG0]], [[REG0]] +; CHECK-NEXT: stxv [[REG0]], 0(3) +; CHECK-NEXT: blr +} + +; Function Attrs: norecurse nounwind +define void @uwConv2qp_03(fp128* nocapture %a) { +entry: + %0 = load i32, i32* getelementptr inbounds + ([5 x i32], [5 x i32]* @uwMem, i64 0, i64 3), align 4 + %conv = uitofp i32 %0 to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void + +; CHECK-LABEL: uwConv2qp_03 +; CHECK: addis [[REG:[0-9]+]], 2, .LC3@toc@ha +; CHECK: ld [[REG]], .LC3@toc@l([[REG]]) +; CHECK: lxsiwzx [[REG0:[0-9]+]], 0, [[REG]] +; CHECK-NEXT: xscvudqp [[REG0]], [[REG0]] +; CHECK-NEXT: stxv [[REG0]], 0(3) +; CHECK-NEXT: blr +} + +; Function Attrs: norecurse nounwind +define void @uwConv2qp_04(fp128* nocapture %a, + i32 zeroext %b, i32* nocapture readonly %c) { +entry: + %0 = load i32, i32* %c, align 4 + %add = add i32 %0, %b + %conv = uitofp i32 %add to fp128 + store fp128 %conv, fp128* %a, align 16 + ret void + +; CHECK-LABEL: uwConv2qp_04 +; CHECK: lwz [[REG:[0-9]+]], 0(5) +; CHECK-NEXT: add [[REG1:[0-9]+]], [[REG]], [[REG1]] +; CHECK-NEXT: mtvsrwz [[REG0:[0-9]+]], [[REG1]] +; CHECK-NEXT: xscvudqp [[REG0]], [[REG0]] +; CHECK-NEXT: stxv [[REG0]], 0(3) +; CHECK-NEXT: blr +}