@@ -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"
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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.);
+}
new file mode 100644
@@ -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.);
+}
new file mode 100644
@@ -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.);
+}