re PR target/79038 (Improve PowerPC ISA 3.0 conversion between integers and hardware...
authorMichael Meissner <meissner@linux.vnet.ibm.com>
Wed, 15 Mar 2017 21:17:35 +0000 (21:17 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Wed, 15 Mar 2017 21:17:35 +0000 (21:17 +0000)
[gcc]
2017-03-15  Michael Meissner  <meissner@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-03-15  Michael Meissner  <meissner@linux.vnet.ibm.com>

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

From-SVN: r246178

gcc/ChangeLog
gcc/config/rs6000/rs6000.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/pr79038-1.c [new file with mode: 0644]

index 13c5c0df2e1c6d931bde808e846639e7f14e5e96..c01d583faede943a5eb07077936ba402c4b52505 100644 (file)
@@ -1,3 +1,11 @@
+2017-03-15  Michael Meissner  <meissner@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.
+
 2017-03-15  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/80019
index 466075a8c7519fe9126e83d88496ecb18c54824a..000d84033c3faf5df7de941b14d32e40c66f3aaa 100644 (file)
     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
     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 e5ebdc69371f7dbd68148c2af814e7d15bade863..3ca7b5fc48397450ed1de9863156a11c29fd7414 100644 (file)
@@ -1,3 +1,8 @@
+2017-03-15  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       PR target/79038
+       * gcc.target/powerpc/pr79038-1.c: New test.
+
 2017-03-15  Segher Boessenkool  <segher@kernel.crashing.org>
 
        PR fortran/33271
diff --git a/gcc/testsuite/gcc.target/powerpc/pr79038-1.c b/gcc/testsuite/gcc.target/powerpc/pr79038-1.c
new file mode 100644 (file)
index 0000000..0b1fa5d
--- /dev/null
@@ -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}  } } */
+