Mark Wielaard 10e1dc
diff --git a/README.s390 b/README.s390
Mark Wielaard 10e1dc
index ac9485a62..7df386ef4 100644
Mark Wielaard 10e1dc
--- a/README.s390
Mark Wielaard 10e1dc
+++ b/README.s390
Mark Wielaard 10e1dc
@@ -11,7 +11,10 @@ Limitations
Mark Wielaard 10e1dc
 -----------
Mark Wielaard 10e1dc
 - 31-bit client programs are not supported.
Mark Wielaard 10e1dc
 - Hexadecimal floating point is not supported.
Mark Wielaard 10e1dc
-- Transactional memory is not supported.
Mark Wielaard 10e1dc
+- Transactional memory is not supported. The transactional-execution
Mark Wielaard 10e1dc
+  facility is masked off from HWCAP.
Mark Wielaard 10e1dc
+- FP signalling is not accurate. E.g., the "compare and signal"
Mark Wielaard 10e1dc
+  instructions behave like their non-signalling counterparts.
Mark Wielaard 10e1dc
 - memcheck, cachegrind, drd, helgrind, massif, lackey, and none are
Mark Wielaard 10e1dc
   supported. 
Mark Wielaard 10e1dc
 - On machine models predating z10, cachegrind will assume a z10 cache
Mark Wielaard 10e1dc
@@ -21,8 +24,6 @@ Limitations
Mark Wielaard 10e1dc
 - Some gcc versions use mvc to copy 4/8 byte values. This will affect
Mark Wielaard 10e1dc
   certain debug messages. For example, memcheck will complain about
Mark Wielaard 10e1dc
   4 one-byte reads/writes instead of just a single read/write.
Mark Wielaard 10e1dc
-- The transactional-execution facility is not supported; it is masked
Mark Wielaard 10e1dc
-  off from HWCAP.
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
 Hardware facilities
Mark Wielaard 10e1dc
diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c
Mark Wielaard 10e1dc
index a8f0d3a07..1f626f722 100644
Mark Wielaard 10e1dc
--- a/VEX/priv/guest_s390_toIR.c
Mark Wielaard 10e1dc
+++ b/VEX/priv/guest_s390_toIR.c
Mark Wielaard 10e1dc
@@ -1204,6 +1204,16 @@ get_dpr_dw0(UInt archreg)
Mark Wielaard 10e1dc
    return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
Mark Wielaard 10e1dc
 }
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
+/* Read a float of given type from an fpr. */
Mark Wielaard 10e1dc
+static IRExpr *
Mark Wielaard 10e1dc
+get_fpr_float(UInt archreg, IRType type)
Mark Wielaard 10e1dc
+{
Mark Wielaard 10e1dc
+   if (type == Ity_F128)
Mark Wielaard 10e1dc
+      return get_fpr_pair(archreg);
Mark Wielaard 10e1dc
+   else
Mark Wielaard 10e1dc
+      return IRExpr_Get(fpr_offset(archreg), type);
Mark Wielaard 10e1dc
+}
Mark Wielaard 10e1dc
+
Mark Wielaard 10e1dc
 /*------------------------------------------------------------*/
Mark Wielaard 10e1dc
 /*--- gpr registers                                        ---*/
Mark Wielaard 10e1dc
 /*------------------------------------------------------------*/
Mark Wielaard 10e1dc
@@ -14055,94 +14065,102 @@ s390_irgen_AXBR(UChar r1, UChar r2)
Mark Wielaard 10e1dc
    return "axbr";
Mark Wielaard 10e1dc
 }
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
+/* Helper for "compare" insns CEBR, CDBR, CXBR, and their signalling
Mark Wielaard 10e1dc
+   counterparts. */
Mark Wielaard 10e1dc
 static const HChar *
Mark Wielaard 10e1dc
-s390_irgen_CEBR(UChar r1, UChar r2)
Mark Wielaard 10e1dc
+s390_irgen_CxBR(const HChar *mnem, UChar r1, UChar r2, IRType type, IROp cmp_op)
Mark Wielaard 10e1dc
 {
Mark Wielaard 10e1dc
-   IRTemp op1 = newTemp(Ity_F32);
Mark Wielaard 10e1dc
-   IRTemp op2 = newTemp(Ity_F32);
Mark Wielaard 10e1dc
+   IRTemp op1 = newTemp(type);
Mark Wielaard 10e1dc
+   IRTemp op2 = newTemp(type);
Mark Wielaard 10e1dc
    IRTemp cc_vex  = newTemp(Ity_I32);
Mark Wielaard 10e1dc
    IRTemp cc_s390 = newTemp(Ity_I32);
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
-   assign(op1, get_fpr_w0(r1));
Mark Wielaard 10e1dc
-   assign(op2, get_fpr_w0(r2));
Mark Wielaard 10e1dc
-   assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
Mark Wielaard 10e1dc
+   assign(op1, get_fpr_float(r1, type));
Mark Wielaard 10e1dc
+   assign(op2, get_fpr_float(r2, type));
Mark Wielaard 10e1dc
+   assign(cc_vex, binop(cmp_op, mkexpr(op1), mkexpr(op2)));
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
    assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
Mark Wielaard 10e1dc
    s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
Mark Wielaard 10e1dc
+   return mnem;
Mark Wielaard 10e1dc
+}
Mark Wielaard 10e1dc
+
Mark Wielaard 10e1dc
+static const HChar *
Mark Wielaard 10e1dc
+s390_irgen_CEBR(UChar r1, UChar r2)
Mark Wielaard 10e1dc
+{
Mark Wielaard 10e1dc
+   return s390_irgen_CxBR("cebr", r1, r2, Ity_F32, Iop_CmpF32);
Mark Wielaard 10e1dc
+}
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
-   return "cebr";
Mark Wielaard 10e1dc
+static const HChar *
Mark Wielaard 10e1dc
+s390_irgen_KEBR(UChar r1, UChar r2)
Mark Wielaard 10e1dc
+{
Mark Wielaard 10e1dc
+   return s390_irgen_CxBR("kebr", r1, r2, Ity_F32, Iop_CmpF32);
Mark Wielaard 10e1dc
 }
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
 static const HChar *
Mark Wielaard 10e1dc
 s390_irgen_CDBR(UChar r1, UChar r2)
Mark Wielaard 10e1dc
 {
Mark Wielaard 10e1dc
-   IRTemp op1 = newTemp(Ity_F64);
Mark Wielaard 10e1dc
-   IRTemp op2 = newTemp(Ity_F64);
Mark Wielaard 10e1dc
-   IRTemp cc_vex  = newTemp(Ity_I32);
Mark Wielaard 10e1dc
-   IRTemp cc_s390 = newTemp(Ity_I32);
Mark Wielaard 10e1dc
+   return s390_irgen_CxBR("cdbr", r1, r2, Ity_F64, Iop_CmpF64);
Mark Wielaard 10e1dc
+}
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
-   assign(op1, get_fpr_dw0(r1));
Mark Wielaard 10e1dc
-   assign(op2, get_fpr_dw0(r2));
Mark Wielaard 10e1dc
-   assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
Mark Wielaard 10e1dc
+static const HChar *
Mark Wielaard 10e1dc
+s390_irgen_KDBR(UChar r1, UChar r2)
Mark Wielaard 10e1dc
+{
Mark Wielaard 10e1dc
+   return s390_irgen_CxBR("kdbr", r1, r2, Ity_F64, Iop_CmpF64);
Mark Wielaard 10e1dc
+}
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
-   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
Mark Wielaard 10e1dc
-   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
Mark Wielaard 10e1dc
+static const HChar *
Mark Wielaard 10e1dc
+s390_irgen_CXBR(UChar r1, UChar r2)
Mark Wielaard 10e1dc
+{
Mark Wielaard 10e1dc
+   return s390_irgen_CxBR("cxbr", r1, r2, Ity_F128, Iop_CmpF128);
Mark Wielaard 10e1dc
+}
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
-   return "cdbr";
Mark Wielaard 10e1dc
+static const HChar *
Mark Wielaard 10e1dc
+s390_irgen_KXBR(UChar r1, UChar r2)
Mark Wielaard 10e1dc
+{
Mark Wielaard 10e1dc
+   return s390_irgen_CxBR("kxbr", r1, r2, Ity_F128, Iop_CmpF128);
Mark Wielaard 10e1dc
 }
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
+/* Helper for "compare" insns CEB, CDB, and their signalling counterparts. */
Mark Wielaard 10e1dc
 static const HChar *
Mark Wielaard 10e1dc
-s390_irgen_CXBR(UChar r1, UChar r2)
Mark Wielaard 10e1dc
+s390_irgen_CxB(const HChar *mnem, UChar r1, IRTemp op2addr, IRType type, IROp cmp_op)
Mark Wielaard 10e1dc
 {
Mark Wielaard 10e1dc
-   IRTemp op1 = newTemp(Ity_F128);
Mark Wielaard 10e1dc
-   IRTemp op2 = newTemp(Ity_F128);
Mark Wielaard 10e1dc
+   IRTemp op1 = newTemp(type);
Mark Wielaard 10e1dc
+   IRTemp op2 = newTemp(type);
Mark Wielaard 10e1dc
    IRTemp cc_vex  = newTemp(Ity_I32);
Mark Wielaard 10e1dc
    IRTemp cc_s390 = newTemp(Ity_I32);
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
-   assign(op1, get_fpr_pair(r1));
Mark Wielaard 10e1dc
-   assign(op2, get_fpr_pair(r2));
Mark Wielaard 10e1dc
-   assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
Mark Wielaard 10e1dc
+   assign(op1, get_fpr_float(r1, type));
Mark Wielaard 10e1dc
+   assign(op2, load(type, mkexpr(op2addr)));
Mark Wielaard 10e1dc
+   assign(cc_vex,  binop(cmp_op, mkexpr(op1), mkexpr(op2)));
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
    assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
Mark Wielaard 10e1dc
    s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
Mark Wielaard 10e1dc
-
Mark Wielaard 10e1dc
-   return "cxbr";
Mark Wielaard 10e1dc
+   return mnem;
Mark Wielaard 10e1dc
 }
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
 static const HChar *
Mark Wielaard 10e1dc
 s390_irgen_CEB(UChar r1, IRTemp op2addr)
Mark Wielaard 10e1dc
 {
Mark Wielaard 10e1dc
-   IRTemp op1 = newTemp(Ity_F32);
Mark Wielaard 10e1dc
-   IRTemp op2 = newTemp(Ity_F32);
Mark Wielaard 10e1dc
-   IRTemp cc_vex  = newTemp(Ity_I32);
Mark Wielaard 10e1dc
-   IRTemp cc_s390 = newTemp(Ity_I32);
Mark Wielaard 10e1dc
-
Mark Wielaard 10e1dc
-   assign(op1, get_fpr_w0(r1));
Mark Wielaard 10e1dc
-   assign(op2, load(Ity_F32, mkexpr(op2addr)));
Mark Wielaard 10e1dc
-   assign(cc_vex,  binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
Mark Wielaard 10e1dc
-
Mark Wielaard 10e1dc
-   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
Mark Wielaard 10e1dc
-   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
Mark Wielaard 10e1dc
+   return s390_irgen_CxB("ceb", r1, op2addr, Ity_F32, Iop_CmpF32);
Mark Wielaard 10e1dc
+}
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
-   return "ceb";
Mark Wielaard 10e1dc
+static const HChar *
Mark Wielaard 10e1dc
+s390_irgen_KEB(UChar r1, IRTemp op2addr)
Mark Wielaard 10e1dc
+{
Mark Wielaard 10e1dc
+   return s390_irgen_CxB("keb", r1, op2addr, Ity_F32, Iop_CmpF32);
Mark Wielaard 10e1dc
+   return "keb";
Mark Wielaard 10e1dc
 }
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
 static const HChar *
Mark Wielaard 10e1dc
 s390_irgen_CDB(UChar r1, IRTemp op2addr)
Mark Wielaard 10e1dc
 {
Mark Wielaard 10e1dc
-   IRTemp op1 = newTemp(Ity_F64);
Mark Wielaard 10e1dc
-   IRTemp op2 = newTemp(Ity_F64);
Mark Wielaard 10e1dc
-   IRTemp cc_vex  = newTemp(Ity_I32);
Mark Wielaard 10e1dc
-   IRTemp cc_s390 = newTemp(Ity_I32);
Mark Wielaard 10e1dc
-
Mark Wielaard 10e1dc
-   assign(op1, get_fpr_dw0(r1));
Mark Wielaard 10e1dc
-   assign(op2, load(Ity_F64, mkexpr(op2addr)));
Mark Wielaard 10e1dc
-   assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
Mark Wielaard 10e1dc
-
Mark Wielaard 10e1dc
-   assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
Mark Wielaard 10e1dc
-   s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
Mark Wielaard 10e1dc
+   return s390_irgen_CxB("cdb", r1, op2addr, Ity_F64, Iop_CmpF64);
Mark Wielaard 10e1dc
+}
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
-   return "cdb";
Mark Wielaard 10e1dc
+static const HChar *
Mark Wielaard 10e1dc
+s390_irgen_KDB(UChar r1, IRTemp op2addr)
Mark Wielaard 10e1dc
+{
Mark Wielaard 10e1dc
+   return s390_irgen_CxB("kdb", r1, op2addr, Ity_F64, Iop_CmpF64);
Mark Wielaard 10e1dc
 }
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
 static const HChar *
Mark Wielaard 10e1dc
@@ -19270,7 +19288,8 @@ s390_decode_4byte_and_irgen(const UChar *bytes)
Mark Wielaard 10e1dc
    case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, RRE_r1(ovl),
Mark Wielaard 10e1dc
                                    RRE_r2(ovl));  goto ok;
Mark Wielaard 10e1dc
    case 0xb307: /* MXDBR */ goto unimplemented;
Mark Wielaard 10e1dc
-   case 0xb308: /* KEBR */ goto unimplemented;
Mark Wielaard 10e1dc
+   case 0xb308: s390_format_RRE_FF(s390_irgen_KEBR, RRE_r1(ovl),
Mark Wielaard 10e1dc
+                                   RRE_r2(ovl));  goto ok;
Mark Wielaard 10e1dc
    case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, RRE_r1(ovl),
Mark Wielaard 10e1dc
                                    RRE_r2(ovl));  goto ok;
Mark Wielaard 10e1dc
    case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, RRE_r1(ovl),
Mark Wielaard 10e1dc
@@ -19300,7 +19319,8 @@ s390_decode_4byte_and_irgen(const UChar *bytes)
Mark Wielaard 10e1dc
                                    RRE_r2(ovl));  goto ok;
Mark Wielaard 10e1dc
    case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, RRE_r1(ovl),
Mark Wielaard 10e1dc
                                    RRE_r2(ovl));  goto ok;
Mark Wielaard 10e1dc
-   case 0xb318: /* KDBR */ goto unimplemented;
Mark Wielaard 10e1dc
+   case 0xb318: s390_format_RRE_FF(s390_irgen_KDBR, RRE_r1(ovl),
Mark Wielaard 10e1dc
+                                   RRE_r2(ovl));  goto ok;
Mark Wielaard 10e1dc
    case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, RRE_r1(ovl),
Mark Wielaard 10e1dc
                                    RRE_r2(ovl));  goto ok;
Mark Wielaard 10e1dc
    case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, RRE_r1(ovl),
Mark Wielaard 10e1dc
@@ -19351,7 +19371,8 @@ s390_decode_4byte_and_irgen(const UChar *bytes)
Mark Wielaard 10e1dc
    case 0xb347: s390_format_RRF_UUFF(s390_irgen_FIXBRA, RRF2_m3(ovl),
Mark Wielaard 10e1dc
                                      RRF2_m4(ovl), RRF2_r1(ovl),
Mark Wielaard 10e1dc
                                      RRF2_r2(ovl));  goto ok;
Mark Wielaard 10e1dc
-   case 0xb348: /* KXBR */ goto unimplemented;
Mark Wielaard 10e1dc
+   case 0xb348: s390_format_RRE_FF(s390_irgen_KXBR, RRE_r1(ovl),
Mark Wielaard 10e1dc
+                                   RRE_r2(ovl));  goto ok;
Mark Wielaard 10e1dc
    case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, RRE_r1(ovl),
Mark Wielaard 10e1dc
                                    RRE_r2(ovl));  goto ok;
Mark Wielaard 10e1dc
    case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, RRE_r1(ovl),
Mark Wielaard 10e1dc
@@ -21408,7 +21429,9 @@ s390_decode_6byte_and_irgen(const UChar *bytes)
Mark Wielaard 10e1dc
                                                 RXE_x2(ovl), RXE_b2(ovl),
Mark Wielaard 10e1dc
                                                 RXE_d2(ovl));  goto ok;
Mark Wielaard 10e1dc
    case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
Mark Wielaard 10e1dc
-   case 0xed0000000008ULL: /* KEB */ goto unimplemented;
Mark Wielaard 10e1dc
+   case 0xed0000000008ULL: s390_format_RXE_FRRD(s390_irgen_KEB, RXE_r1(ovl),
Mark Wielaard 10e1dc
+                                                RXE_x2(ovl), RXE_b2(ovl),
Mark Wielaard 10e1dc
+                                                RXE_d2(ovl));  goto ok;
Mark Wielaard 10e1dc
    case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, RXE_r1(ovl),
Mark Wielaard 10e1dc
                                                 RXE_x2(ovl), RXE_b2(ovl),
Mark Wielaard 10e1dc
                                                 RXE_d2(ovl));  goto ok;
Mark Wielaard 10e1dc
@@ -21448,7 +21471,9 @@ s390_decode_6byte_and_irgen(const UChar *bytes)
Mark Wielaard 10e1dc
    case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, RXE_r1(ovl),
Mark Wielaard 10e1dc
                                                 RXE_x2(ovl), RXE_b2(ovl),
Mark Wielaard 10e1dc
                                                 RXE_d2(ovl));  goto ok;
Mark Wielaard 10e1dc
-   case 0xed0000000018ULL: /* KDB */ goto unimplemented;
Mark Wielaard 10e1dc
+   case 0xed0000000018ULL: s390_format_RXE_FRRD(s390_irgen_KDB, RXE_r1(ovl),
Mark Wielaard 10e1dc
+                                                RXE_x2(ovl), RXE_b2(ovl),
Mark Wielaard 10e1dc
+                                                RXE_d2(ovl));  goto ok;
Mark Wielaard 10e1dc
    case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, RXE_r1(ovl),
Mark Wielaard 10e1dc
                                                 RXE_x2(ovl), RXE_b2(ovl),
Mark Wielaard 10e1dc
                                                 RXE_d2(ovl));  goto ok;
Mark Wielaard 10e1dc
diff --git a/none/tests/s390x/bfp-4.c b/none/tests/s390x/bfp-4.c
Mark Wielaard 10e1dc
index c2d88818c..645421294 100644
Mark Wielaard 10e1dc
--- a/none/tests/s390x/bfp-4.c
Mark Wielaard 10e1dc
+++ b/none/tests/s390x/bfp-4.c
Mark Wielaard 10e1dc
@@ -1,61 +1,77 @@
Mark Wielaard 10e1dc
 #include <stdio.h>
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
-/* Test BFP comparison for  32/64-bit. */
Mark Wielaard 10e1dc
+#define TEST_CxBR(insn, fmt, v1, v2)            \
Mark Wielaard 10e1dc
+   do {                                         \
Mark Wielaard 10e1dc
+   int cc;                                      \
Mark Wielaard 10e1dc
+                                                \
Mark Wielaard 10e1dc
+   __asm__ volatile(insn " %[r1],%[r2]\n\t"                             \
Mark Wielaard 10e1dc
+                    "ipm   %[psw]\n\t"                                  \
Mark Wielaard 10e1dc
+                    "srl   %[psw],28\n\t"                               \
Mark Wielaard 10e1dc
+                    : [psw]"=d"(cc) : [r1]"f"(v1), [r2]"f"(v2) : "cc"); \
Mark Wielaard 10e1dc
+   if (cc == 0)                                                         \
Mark Wielaard 10e1dc
+      printf(insn ":  " fmt " == " fmt "\n", v1, v2);                   \
Mark Wielaard 10e1dc
+   else if (cc == 1)                                                    \
Mark Wielaard 10e1dc
+      printf(insn ":  " fmt " < " fmt "\n", v1, v2);                    \
Mark Wielaard 10e1dc
+   else if (cc == 2)                                                    \
Mark Wielaard 10e1dc
+      printf(insn ":  " fmt " > " fmt "\n", v1, v2);                    \
Mark Wielaard 10e1dc
+   else                                                                 \
Mark Wielaard 10e1dc
+      printf(insn ":  " fmt " ?? " fmt "\n", v1, v2);                   \
Mark Wielaard 10e1dc
+   } while (0)
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
-void cebr(float v1, float v2)
Mark Wielaard 10e1dc
+/* Test BFP comparison for 32/64/128-bit. */
Mark Wielaard 10e1dc
+
Mark Wielaard 10e1dc
+void cebr(float a, float b)
Mark Wielaard 10e1dc
+{
Mark Wielaard 10e1dc
+   TEST_CxBR("cebr", "%g", a, b);
Mark Wielaard 10e1dc
+}
Mark Wielaard 10e1dc
+
Mark Wielaard 10e1dc
+void cdbr(double a, double b)
Mark Wielaard 10e1dc
+{
Mark Wielaard 10e1dc
+   TEST_CxBR("cdbr", "%g", a, b);
Mark Wielaard 10e1dc
+}
Mark Wielaard 10e1dc
+
Mark Wielaard 10e1dc
+void cxbr(long double a, long double b)
Mark Wielaard 10e1dc
 {
Mark Wielaard 10e1dc
-   int cc;
Mark Wielaard 10e1dc
+   TEST_CxBR("cxbr", "%Lg", a, b);
Mark Wielaard 10e1dc
+}
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
-   __asm__ volatile("cebr %[r1],%[r2]\n\t"
Mark Wielaard 10e1dc
-                    "ipm   %[psw]\n\t"
Mark Wielaard 10e1dc
-                    "srl   %[psw],28\n\t"
Mark Wielaard 10e1dc
-                    : [psw]"=d"(cc) : [r1]"f"(v1), [r2]"f"(v2) : "cc");
Mark Wielaard 10e1dc
-   if (cc == 0)
Mark Wielaard 10e1dc
-      printf("cfebr:  %f == %f\n", v1, v2);
Mark Wielaard 10e1dc
-   if (cc == 1)
Mark Wielaard 10e1dc
-      printf("cfebr:  %f < %f\n", v1, v2);
Mark Wielaard 10e1dc
-   if (cc == 2)
Mark Wielaard 10e1dc
-      printf("cfebr:  %f > %f\n", v1, v2);
Mark Wielaard 10e1dc
+void kebr(float a, float b)
Mark Wielaard 10e1dc
+{
Mark Wielaard 10e1dc
+   TEST_CxBR("kebr", "%g", a, b);
Mark Wielaard 10e1dc
 }
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
-void cdbr(double v1, double v2)
Mark Wielaard 10e1dc
+void kdbr(double a, double b)
Mark Wielaard 10e1dc
 {
Mark Wielaard 10e1dc
-   int cc;
Mark Wielaard 10e1dc
+   TEST_CxBR("kdbr", "%g", a, b);
Mark Wielaard 10e1dc
+}
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
-   __asm__ volatile("cdbr %[r1],%[r2]\n\t"
Mark Wielaard 10e1dc
-                    "ipm   %[psw]\n\t"
Mark Wielaard 10e1dc
-                    "srl   %[psw],28\n\t"
Mark Wielaard 10e1dc
-                    : [psw]"=d"(cc) : [r1]"f"(v1), [r2]"f"(v2) : "cc");
Mark Wielaard 10e1dc
-   if (cc == 0)
Mark Wielaard 10e1dc
-      printf("cdebr:  %f == %f\n", v1, v2);
Mark Wielaard 10e1dc
-   if (cc == 1)
Mark Wielaard 10e1dc
-      printf("cdebr:  %f < %f\n", v1, v2);
Mark Wielaard 10e1dc
-   if (cc == 2)
Mark Wielaard 10e1dc
-      printf("cdebr:  %f > %f\n", v1, v2);
Mark Wielaard 10e1dc
+void kxbr(long double a, long double b)
Mark Wielaard 10e1dc
+{
Mark Wielaard 10e1dc
+   TEST_CxBR("kxbr", "%Lg", a, b);
Mark Wielaard 10e1dc
+}
Mark Wielaard 10e1dc
+
Mark Wielaard 10e1dc
+void do_compare(float a, float b)
Mark Wielaard 10e1dc
+{
Mark Wielaard 10e1dc
+   cebr(a, b);
Mark Wielaard 10e1dc
+   kebr(a, b);
Mark Wielaard 10e1dc
+   cdbr((double) a, (double) b);
Mark Wielaard 10e1dc
+   kdbr((double) a, (double) b);
Mark Wielaard 10e1dc
+   cxbr((long double) a, (long double) b);
Mark Wielaard 10e1dc
+   kxbr((long double) a, (long double) b);
Mark Wielaard 10e1dc
 }
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
 int main(void)
Mark Wielaard 10e1dc
 {
Mark Wielaard 10e1dc
-   float f1, f2;
Mark Wielaard 10e1dc
-   float d1, d2;
Mark Wielaard 10e1dc
-
Mark Wielaard 10e1dc
-   // compare 4 bytes
Mark Wielaard 10e1dc
-   f1 = 3.14f;
Mark Wielaard 10e1dc
-   f2 = f1;
Mark Wielaard 10e1dc
-   cebr(f1, f2);
Mark Wielaard 10e1dc
-   f2 = f1 + 10.;
Mark Wielaard 10e1dc
-   cebr(f1, f2);
Mark Wielaard 10e1dc
-   f2 = f1 - 100.;
Mark Wielaard 10e1dc
-   cebr(f1, f2);
Mark Wielaard 10e1dc
-
Mark Wielaard 10e1dc
-   // compare 8 bytes
Mark Wielaard 10e1dc
-   d1 = 2.78;
Mark Wielaard 10e1dc
-   d2 = d1;
Mark Wielaard 10e1dc
-   cdbr(d1, d2);
Mark Wielaard 10e1dc
-   d2 = d1 + 10.;
Mark Wielaard 10e1dc
-   cdbr(d1, d2);
Mark Wielaard 10e1dc
-   d2 = d1 - 100.;
Mark Wielaard 10e1dc
-   cdbr(d1, d2);
Mark Wielaard 10e1dc
+   float inf = 1.f / 0.;
Mark Wielaard 10e1dc
+   float neg_inf = -1.f / 0.;
Mark Wielaard 10e1dc
 
Mark Wielaard 10e1dc
+   do_compare(3.14f, 3.14f);
Mark Wielaard 10e1dc
+   do_compare(-2.78f, 2.78f);
Mark Wielaard 10e1dc
+   do_compare(inf, inf);
Mark Wielaard 10e1dc
+   do_compare(inf, neg_inf);
Mark Wielaard 10e1dc
+   do_compare(neg_inf, neg_inf);
Mark Wielaard 10e1dc
+   do_compare(inf, 1.f);
Mark Wielaard 10e1dc
+   do_compare(neg_inf, -1.f);
Mark Wielaard 10e1dc
+   do_compare(1.f / inf, -1.f / inf);
Mark Wielaard 10e1dc
    return 0;
Mark Wielaard 10e1dc
 }
Mark Wielaard 10e1dc
diff --git a/none/tests/s390x/bfp-4.stdout.exp b/none/tests/s390x/bfp-4.stdout.exp
Mark Wielaard 10e1dc
index eff136654..027b1587a 100644
Mark Wielaard 10e1dc
--- a/none/tests/s390x/bfp-4.stdout.exp
Mark Wielaard 10e1dc
+++ b/none/tests/s390x/bfp-4.stdout.exp
Mark Wielaard 10e1dc
@@ -1,6 +1,48 @@
Mark Wielaard 10e1dc
-cfebr:  3.140000 == 3.140000
Mark Wielaard 10e1dc
-cfebr:  3.140000 < 13.140000
Mark Wielaard 10e1dc
-cfebr:  3.140000 > -96.860001
Mark Wielaard 10e1dc
-cdebr:  2.780000 == 2.780000
Mark Wielaard 10e1dc
-cdebr:  2.780000 < 12.780000
Mark Wielaard 10e1dc
-cdebr:  2.780000 > -97.220001
Mark Wielaard 10e1dc
+cebr:  3.14 == 3.14
Mark Wielaard 10e1dc
+kebr:  3.14 == 3.14
Mark Wielaard 10e1dc
+cdbr:  3.14 == 3.14
Mark Wielaard 10e1dc
+kdbr:  3.14 == 3.14
Mark Wielaard 10e1dc
+cxbr:  3.14 == 3.14
Mark Wielaard 10e1dc
+kxbr:  3.14 == 3.14
Mark Wielaard 10e1dc
+cebr:  -2.78 < 2.78
Mark Wielaard 10e1dc
+kebr:  -2.78 < 2.78
Mark Wielaard 10e1dc
+cdbr:  -2.78 < 2.78
Mark Wielaard 10e1dc
+kdbr:  -2.78 < 2.78
Mark Wielaard 10e1dc
+cxbr:  -2.78 < 2.78
Mark Wielaard 10e1dc
+kxbr:  -2.78 < 2.78
Mark Wielaard 10e1dc
+cebr:  inf == inf
Mark Wielaard 10e1dc
+kebr:  inf == inf
Mark Wielaard 10e1dc
+cdbr:  inf == inf
Mark Wielaard 10e1dc
+kdbr:  inf == inf
Mark Wielaard 10e1dc
+cxbr:  inf == inf
Mark Wielaard 10e1dc
+kxbr:  inf == inf
Mark Wielaard 10e1dc
+cebr:  inf > -inf
Mark Wielaard 10e1dc
+kebr:  inf > -inf
Mark Wielaard 10e1dc
+cdbr:  inf > -inf
Mark Wielaard 10e1dc
+kdbr:  inf > -inf
Mark Wielaard 10e1dc
+cxbr:  inf > -inf
Mark Wielaard 10e1dc
+kxbr:  inf > -inf
Mark Wielaard 10e1dc
+cebr:  -inf == -inf
Mark Wielaard 10e1dc
+kebr:  -inf == -inf
Mark Wielaard 10e1dc
+cdbr:  -inf == -inf
Mark Wielaard 10e1dc
+kdbr:  -inf == -inf
Mark Wielaard 10e1dc
+cxbr:  -inf == -inf
Mark Wielaard 10e1dc
+kxbr:  -inf == -inf
Mark Wielaard 10e1dc
+cebr:  inf > 1
Mark Wielaard 10e1dc
+kebr:  inf > 1
Mark Wielaard 10e1dc
+cdbr:  inf > 1
Mark Wielaard 10e1dc
+kdbr:  inf > 1
Mark Wielaard 10e1dc
+cxbr:  inf > 1
Mark Wielaard 10e1dc
+kxbr:  inf > 1
Mark Wielaard 10e1dc
+cebr:  -inf < -1
Mark Wielaard 10e1dc
+kebr:  -inf < -1
Mark Wielaard 10e1dc
+cdbr:  -inf < -1
Mark Wielaard 10e1dc
+kdbr:  -inf < -1
Mark Wielaard 10e1dc
+cxbr:  -inf < -1
Mark Wielaard 10e1dc
+kxbr:  -inf < -1
Mark Wielaard 10e1dc
+cebr:  0 == -0
Mark Wielaard 10e1dc
+kebr:  0 == -0
Mark Wielaard 10e1dc
+cdbr:  0 == -0
Mark Wielaard 10e1dc
+kdbr:  0 == -0
Mark Wielaard 10e1dc
+cxbr:  0 == -0
Mark Wielaard 10e1dc
+kxbr:  0 == -0