On January 31st I commited a patch that improves conversion of signed/unsigned
char/short values to 32-bit and 64-bit floating point on Power9, particularly
when the values are coming from memory.  This adds similar support to
_Float128/__float128 (i.e. IEEE 128-bit floating point).  I have tested this
patch via bootstrap and make check and there were no regressions.  Can I check
this patch into the trunk?

[gcc]
2017-03-03  Michael Meissner  <meiss...@linux.vnet.ibm.com>

        PR target/79038
        * config/rs6000/rs6000.md (float<QHI:mode><IEEE128:mode>2): Define
        insns to convert from signed/unsigned char/short to IEEE 128-bit
        floating point.
        (floatuns<QHI:mode><IEEE128:mode>2): Likewise.

[gcc/testsuite]
2017-02-24  Michael Meissner  <meiss...@linux.vnet.ibm.com>

        PR target/79038
        * gcc.target/powerpc/pr79038-1.c: New test.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.vnet.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md (revision 245815)
+++ gcc/config/rs6000/rs6000.md (working copy)
@@ -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")
Index: gcc/testsuite/gcc.target/powerpc/pr79038-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr79038-1.c        (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr79038-1.c        (revision 0)
@@ -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}  } } */
+

Reply via email to