From: Ilya Leoshkevich Date: Wed, 17 Feb 2021 13:40:03 +0000 (+0100) Subject: IBM Z: Fix long double <-> DFP conversions X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b6e446cb58183557a5a5d87dc866aae9613544f8;p=gcc.git 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 (trunctf2_vr): New pattern. (trunctf2): Likewise. (trunctdtf2_vr): Likewise. (trunctdtf2): Likewise. (extendtf2_vr): Likewise. (extendtf2): 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. --- diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md index e48c965db00..bc52211c55e 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 "trunctf2_vr" + [(match_operand:DFP_ALL 0 "nonimmediate_operand" "") + (match_operand:TF 1 "nonimmediate_operand" "")] + "TARGET_HARD_DFP + && GET_MODE_SIZE (TFmode) > GET_MODE_SIZE (mode) + && TARGET_VXE" +{ + rtx fprx2 = gen_reg_rtx (FPRX2mode); + emit_insn (gen_tf_to_fprx2 (fprx2, operands[1])); + emit_insn (gen_truncfprx22 (operands[0], fprx2)); + DONE; +}) + +(define_expand "trunctf2" + [(match_operand:DFP_ALL 0 "nonimmediate_operand" "") + (match_operand:TF 1 "nonimmediate_operand" "")] + "HAVE_TF (trunctf2)" + { EXPAND_TF (trunctf2, 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 "extendtf2_vr" + [(match_operand:TF 0 "nonimmediate_operand" "") + (match_operand:DFP_ALL 1 "nonimmediate_operand" "")] + "TARGET_HARD_DFP + && GET_MODE_SIZE (mode) < GET_MODE_SIZE (TFmode) + && TARGET_VXE" +{ + rtx fprx2 = gen_reg_rtx (FPRX2mode); + emit_insn (gen_extendfprx22 (fprx2, operands[1])); + emit_insn (gen_fprx2_to_tf (operands[0], fprx2)); + DONE; +}) + +(define_expand "extendtf2" + [(match_operand:TF 0 "nonimmediate_operand" "") + (match_operand:DFP_ALL 1 "nonimmediate_operand" "")] + "HAVE_TF (extendtf2)" + { EXPAND_TF (extendtf2, 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 00000000000..3cd2c68f5c6 --- /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 +#include + +__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 00000000000..84e3c4b11c0 --- /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 +#include + +__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 00000000000..f855e4b39c8 --- /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 +#include + +__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 00000000000..5f7833a66e7 --- /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 + +__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 00000000000..f09288a5177 --- /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 + +__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 00000000000..08aecfea43a --- /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 + +__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.); +}