aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Leoshkevich <iii@linux.ibm.com>2021-02-17 14:40:03 +0100
committerIlya Leoshkevich <iii@linux.ibm.com>2021-02-20 01:49:35 +0100
commitb6e446cb58183557a5a5d87dc866aae9613544f8 (patch)
tree25bbbd4050ab0c727c726222ee99e18b64892a83
parenta974b8a592e1f131a2b1698582e348666d1e2973 (diff)
downloadgcc-b6e446cb58183557a5a5d87dc866aae9613544f8.zip
gcc-b6e446cb58183557a5a5d87dc866aae9613544f8.tar.gz
gcc-b6e446cb58183557a5a5d87dc866aae9613544f8.tar.bz2
IBM Z: Fix long double <-> DFP conversions
When switching the s390 backend to store long doubles in vector registers, the patterns for long double <-> DFP conversions were forgotten. This did not cause observable problems so far, because libdfp calls are emitted instead of pfpo. However, when building libdfp itself, this leads to infinite recursion. gcc/ChangeLog: PR target/99134 * config/s390/vector.md (trunctf<DFP_ALL:mode>2_vr): New pattern. (trunctf<DFP_ALL:mode>2): Likewise. (trunctdtf2_vr): Likewise. (trunctdtf2): Likewise. (extend<DFP_ALL:mode>tf2_vr): Likewise. (extend<DFP_ALL:mode>tf2): Likewise. (extendtftd2_vr): Likewise. (extendtftd2): Likewise. gcc/testsuite/ChangeLog: PR target/99134 * gcc.target/s390/vector/long-double-from-decimal128.c: New test. * gcc.target/s390/vector/long-double-from-decimal32.c: New test. * gcc.target/s390/vector/long-double-from-decimal64.c: New test. * gcc.target/s390/vector/long-double-to-decimal128.c: New test. * gcc.target/s390/vector/long-double-to-decimal32.c: New test. * gcc.target/s390/vector/long-double-to-decimal64.c: New test.
-rw-r--r--gcc/config/s390/vector.md72
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-from-decimal128.c20
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-from-decimal32.c20
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-from-decimal64.c20
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-to-decimal128.c19
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-to-decimal32.c19
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/long-double-to-decimal64.c19
7 files changed, 189 insertions, 0 deletions
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index e48c965..bc52211 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -2480,6 +2480,42 @@
"HAVE_TF (trunctfsf2)"
{ EXPAND_TF (trunctfsf2, 2); })
+(define_expand "trunctf<DFP_ALL:mode>2_vr"
+ [(match_operand:DFP_ALL 0 "nonimmediate_operand" "")
+ (match_operand:TF 1 "nonimmediate_operand" "")]
+ "TARGET_HARD_DFP
+ && GET_MODE_SIZE (TFmode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)
+ && TARGET_VXE"
+{
+ rtx fprx2 = gen_reg_rtx (FPRX2mode);
+ emit_insn (gen_tf_to_fprx2 (fprx2, operands[1]));
+ emit_insn (gen_truncfprx2<DFP_ALL:mode>2 (operands[0], fprx2));
+ DONE;
+})
+
+(define_expand "trunctf<DFP_ALL:mode>2"
+ [(match_operand:DFP_ALL 0 "nonimmediate_operand" "")
+ (match_operand:TF 1 "nonimmediate_operand" "")]
+ "HAVE_TF (trunctf<DFP_ALL:mode>2)"
+ { EXPAND_TF (trunctf<DFP_ALL:mode>2, 2); })
+
+(define_expand "trunctdtf2_vr"
+ [(match_operand:TF 0 "nonimmediate_operand" "")
+ (match_operand:TD 1 "nonimmediate_operand" "")]
+ "TARGET_HARD_DFP && TARGET_VXE"
+{
+ rtx fprx2 = gen_reg_rtx (FPRX2mode);
+ emit_insn (gen_trunctdfprx22 (fprx2, operands[1]));
+ emit_insn (gen_fprx2_to_tf (operands[0], fprx2));
+ DONE;
+})
+
+(define_expand "trunctdtf2"
+ [(match_operand:TF 0 "nonimmediate_operand" "")
+ (match_operand:TD 1 "nonimmediate_operand" "")]
+ "HAVE_TF (trunctdtf2)"
+ { EXPAND_TF (trunctdtf2, 2); })
+
; load lengthened
(define_insn "extenddftf2_vr"
@@ -2511,6 +2547,42 @@
"HAVE_TF (extendsftf2)"
{ EXPAND_TF (extendsftf2, 2); })
+(define_expand "extend<DFP_ALL:mode>tf2_vr"
+ [(match_operand:TF 0 "nonimmediate_operand" "")
+ (match_operand:DFP_ALL 1 "nonimmediate_operand" "")]
+ "TARGET_HARD_DFP
+ && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (TFmode)
+ && TARGET_VXE"
+{
+ rtx fprx2 = gen_reg_rtx (FPRX2mode);
+ emit_insn (gen_extend<DFP_ALL:mode>fprx22 (fprx2, operands[1]));
+ emit_insn (gen_fprx2_to_tf (operands[0], fprx2));
+ DONE;
+})
+
+(define_expand "extend<DFP_ALL:mode>tf2"
+ [(match_operand:TF 0 "nonimmediate_operand" "")
+ (match_operand:DFP_ALL 1 "nonimmediate_operand" "")]
+ "HAVE_TF (extend<DFP_ALL:mode>tf2)"
+ { EXPAND_TF (extend<DFP_ALL:mode>tf2, 2); })
+
+(define_expand "extendtftd2_vr"
+ [(match_operand:TD 0 "nonimmediate_operand" "")
+ (match_operand:TF 1 "nonimmediate_operand" "")]
+ "TARGET_HARD_DFP && TARGET_VXE"
+{
+ rtx fprx2 = gen_reg_rtx (FPRX2mode);
+ emit_insn (gen_tf_to_fprx2 (fprx2, operands[1]));
+ emit_insn (gen_extendfprx2td2 (operands[0], fprx2));
+ DONE;
+})
+
+(define_expand "extendtftd2"
+ [(match_operand:TD 0 "nonimmediate_operand" "")
+ (match_operand:TF 1 "nonimmediate_operand" "")]
+ "HAVE_TF (extendtftd2)"
+ { EXPAND_TF (extendtftd2, 2); })
+
; test data class
(define_expand "signbittf2_vr"
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-from-decimal128.c b/gcc/testsuite/gcc.target/s390/vector/long-double-from-decimal128.c
new file mode 100644
index 0000000..3cd2c68
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-from-decimal128.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
+#include <assert.h>
+#include <stdint.h>
+
+__attribute__ ((noipa)) static long double
+long_double_from_decimal128 (_Decimal128 x)
+{
+ return x;
+}
+
+/* { dg-final { scan-assembler-times {\n\tpfpo\n} 1 } } */
+
+int
+main (void)
+{
+ assert (long_double_from_decimal128 ((_Decimal128) 42) == 42.L);
+ assert (long_double_from_decimal128 ((_Decimal128) -42) == -42.L);
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-from-decimal32.c b/gcc/testsuite/gcc.target/s390/vector/long-double-from-decimal32.c
new file mode 100644
index 0000000..84e3c4b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-from-decimal32.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
+#include <assert.h>
+#include <stdint.h>
+
+__attribute__ ((noipa)) static long double
+long_double_from_decimal32 (_Decimal32 x)
+{
+ return x;
+}
+
+/* { dg-final { scan-assembler-times {\n\tpfpo\n} 1 } } */
+
+int
+main (void)
+{
+ assert (long_double_from_decimal32 ((_Decimal32) 42) == 42.L);
+ assert (long_double_from_decimal32 ((_Decimal32) -42) == -42.L);
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-from-decimal64.c b/gcc/testsuite/gcc.target/s390/vector/long-double-from-decimal64.c
new file mode 100644
index 0000000..f855e4b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-from-decimal64.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
+#include <assert.h>
+#include <stdint.h>
+
+__attribute__ ((noipa)) static long double
+long_double_from_decimal64 (_Decimal64 x)
+{
+ return x;
+}
+
+/* { dg-final { scan-assembler-times {\n\tpfpo\n} 1 } } */
+
+int
+main (void)
+{
+ assert (long_double_from_decimal64 ((_Decimal64) 42) == 42.L);
+ assert (long_double_from_decimal64 ((_Decimal64) -42) == -42.L);
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-to-decimal128.c b/gcc/testsuite/gcc.target/s390/vector/long-double-to-decimal128.c
new file mode 100644
index 0000000..5f7833a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-to-decimal128.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
+#include <assert.h>
+
+__attribute__ ((noipa)) static _Decimal128
+long_double_to_decimal128 (long double x)
+{
+ return x;
+}
+
+/* { dg-final { scan-assembler-times {\n\tpfpo\n} 1 } } */
+
+int
+main (void)
+{
+ assert (long_double_to_decimal128 (42.L) == (_Decimal128) 42.);
+ assert (long_double_to_decimal128 (-42.L) == (_Decimal128) -42.);
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-to-decimal32.c b/gcc/testsuite/gcc.target/s390/vector/long-double-to-decimal32.c
new file mode 100644
index 0000000..f09288a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-to-decimal32.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
+#include <assert.h>
+
+__attribute__ ((noipa)) static _Decimal32
+long_double_to_decimal32 (long double x)
+{
+ return x;
+}
+
+/* { dg-final { scan-assembler-times {\n\tpfpo\n} 1 } } */
+
+int
+main (void)
+{
+ assert (long_double_to_decimal32 (42.L) == (_Decimal32) 42.);
+ assert (long_double_to_decimal32 (-42.L) == (_Decimal32) -42.);
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-to-decimal64.c b/gcc/testsuite/gcc.target/s390/vector/long-double-to-decimal64.c
new file mode 100644
index 0000000..08aecfe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/long-double-to-decimal64.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+/* { dg-do run { target { s390_z14_hw } } } */
+#include <assert.h>
+
+__attribute__ ((noipa)) static _Decimal64
+long_double_to_decimal64 (long double x)
+{
+ return x;
+}
+
+/* { dg-final { scan-assembler-times {\n\tpfpo\n} 1 } } */
+
+int
+main (void)
+{
+ assert (long_double_to_decimal64 (42.L) == (_Decimal64) 42.);
+ assert (long_double_to_decimal64 (-42.L) == (_Decimal64) -42.);
+}