Index: include/llvm/IR/IntrinsicsPowerPC.td =================================================================== --- include/llvm/IR/IntrinsicsPowerPC.td +++ include/llvm/IR/IntrinsicsPowerPC.td @@ -80,6 +80,12 @@ def int_ppc_fmaf128_round_to_odd : GCCBuiltin<"__builtin_fmaf128_round_to_odd">, Intrinsic <[llvm_f128_ty], [llvm_f128_ty,llvm_f128_ty,llvm_f128_ty], [IntrNoMem]>; + def int_ppc_scalar_extract_expq + : GCCBuiltin<"__builtin_vsx_scalar_extract_expq">, + Intrinsic <[llvm_i64_ty], [llvm_f128_ty], [IntrNoMem]>; + def int_ppc_scalar_insert_exp_qp + : GCCBuiltin<"__builtin_vsx_scalar_insert_exp_qp">, + Intrinsic <[llvm_f128_ty], [llvm_f128_ty, llvm_i64_ty], [IntrNoMem]>; } Index: lib/Target/PowerPC/PPCInstrVSX.td =================================================================== --- lib/Target/PowerPC/PPCInstrVSX.td +++ lib/Target/PowerPC/PPCInstrVSX.td @@ -2619,6 +2619,9 @@ def XSIEXPQP : XForm_18<63, 868, (outs vrrc:$vT), (ins vrrc:$vA, vsfrc:$vB), "xsiexpqp $vT, $vA, $vB", IIC_VecFP, []>; + def : Pat<(f128 (int_ppc_scalar_insert_exp_qp f128:$vA, i64:$vB)), + (f128 (XSIEXPQP $vA, (MTVSRD $vB)))>; + // Extract Exponent/Significand DP/QP def XSXEXPDP : XX2_RT5_XO5_XB6<60, 0, 347, "xsxexpdp", []>; def XSXSIGDP : XX2_RT5_XO5_XB6<60, 1, 347, "xsxsigdp", []>; @@ -2626,6 +2629,10 @@ def XSXEXPQP : X_VT5_XO5_VB5 <63, 2, 804, "xsxexpqp", []>; def XSXSIGQP : X_VT5_XO5_VB5 <63, 18, 804, "xsxsigqp", []>; + def : Pat<(i64 (int_ppc_scalar_extract_expq f128:$vA)), + (i64 (MFVSRD (EXTRACT_SUBREG + (v2i64 (XSXEXPQP $vA)), sub_64)))>; + // Vector Insert Word let UseVSXReg = 1 in { // XB NOTE: Only XB.dword[1] is used, but we use vsrc on XB. Index: test/CodeGen/PowerPC/builtins-ppc-p9-f128.ll =================================================================== --- test/CodeGen/PowerPC/builtins-ppc-p9-f128.ll +++ test/CodeGen/PowerPC/builtins-ppc-p9-f128.ll @@ -80,3 +80,32 @@ declare fp128 @llvm.ppc.divf128.round.to.odd(fp128, fp128) +; Function Attrs: noinline nounwind optnone +define fp128 @insert_exp_qp(i64 %b) { +entry: + %b.addr = alloca i64, align 8 + store i64 %b, i64* %b.addr, align 8 + %0 = load fp128, fp128* @A, align 16 + %1 = load i64, i64* %b.addr, align 8 + %2 = call fp128 @llvm.ppc.scalar.insert.exp.qp(fp128 %0, i64 %1) + ret fp128 %2 +; CHECK-LABEL: insert_exp_qp +; CHECK: xsiexpqp +} + +; Function Attrs: nounwind readnone +declare fp128 @llvm.ppc.scalar.insert.exp.qp(fp128, i64) + +; Function Attrs: noinline nounwind optnone +define i64 @extract_exp() { +entry: + %0 = load fp128, fp128* @A, align 16 + %1 = call i64 @llvm.ppc.scalar.extract.expq(fp128 %0) + ret i64 %1 +; CHECK-LABEL: extract_exp +; CHECK: xsxexpqp +} + +; Function Attrs: nounwind readnone +declare i64 @llvm.ppc.scalar.extract.expq(fp128) +