===================================================================
@@ -14467,6 +14467,43 @@ (define_insn_and_split "float_<mode>si2_
operands[2] = gen_reg_rtx (DImode);
})
+(define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
+ [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
+ (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
+ (clobber (match_scratch:DI 2 "=X,r,X"))]
+ "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ rtx dest = operands[0];
+ rtx src = operands[1];
+ rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
+
+ if (altivec_register_operand (src, <QHI:MODE>mode))
+ emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
+ else if (int_reg_operand (src, <QHI:MODE>mode))
+ {
+ rtx ext_di = operands[2];
+ emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
+ emit_move_insn (dest_di, ext_di);
+ }
+ else if (MEM_P (src))
+ {
+ rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
+ emit_move_insn (dest_qhi, src);
+ emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
+ }
+ else
+ gcc_unreachable ();
+
+ emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
+ DONE;
+}
+ [(set_attr "length" "8,12,12")
+ (set_attr "type" "vecfloat")
+ (set_attr "size" "128")])
+
(define_insn "floatuns_<mode>di2_hw"
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
(unsigned_float:IEEE128
@@ -14493,6 +14530,38 @@ (define_insn_and_split "floatuns_<mode>s
operands[2] = gen_reg_rtx (DImode);
})
+(define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
+ [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
+ (unsigned_float:IEEE128
+ (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
+ (clobber (match_scratch:DI 2 "=X,r,X"))]
+ "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ rtx dest = operands[0];
+ rtx src = operands[1];
+ rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
+
+ if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
+ emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
+ else if (int_reg_operand (src, <QHI:MODE>mode))
+ {
+ rtx ext_di = operands[2];
+ emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
+ emit_move_insn (dest_di, ext_di);
+ }
+ else
+ gcc_unreachable ();
+
+ emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
+ DONE;
+}
+ [(set_attr "length" "8,12,8")
+ (set_attr "type" "vecfloat")
+ (set_attr "size" "128")])
+
;; IEEE 128-bit instructions with round to odd semantics
(define_insn "*trunc<mode>df2_odd"
[(set (match_operand:DF 0 "vsx_register_operand" "=v")
===================================================================
@@ -0,0 +1,39 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-options "-mcpu=power9 -O2 -mfloat128" } */
+
+#ifndef TYPE
+#define TYPE _Float128
+#endif
+
+TYPE
+return_convert_uchar_to_float128_mem (unsigned char *p_uc)
+{
+ return (TYPE) p_uc[10];
+}
+
+TYPE
+return_convert_schar_to_float128_mem (signed char *p_sc)
+{
+ return (TYPE) p_sc[10];
+}
+
+TYPE
+return_convert_ushort_to_float128_mem (unsigned short *p_us)
+{
+ return (TYPE) p_us[10];
+}
+
+TYPE
+return_convert_sshort_to_float128_mem (short *p_ss)
+{
+ return (TYPE) p_ss[10];
+}
+
+/* { dg-final { scan-assembler {\mlxsi[bh]zx\M} } } */
+/* { dg-final { scan-assembler {\mvexts[bh]2d\M} } } */
+/* { dg-final { scan-assembler-not {\mextsb\M} } } */
+/* { dg-final { scan-assembler-not {\ml[bh][az]\M} } } */
+/* { dg-final { scan-assembler-not {\mmtvsrw[az]\M} } } */
+