]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add a testcase for floating point <-> signed conversion that
authorChristian Borntraeger <borntraeger@de.ibm.com>
Wed, 8 Aug 2012 07:50:10 +0000 (07:50 +0000)
committerChristian Borntraeger <borntraeger@de.ibm.com>
Wed, 8 Aug 2012 07:50:10 +0000 (07:50 +0000)
actually checks the condition code of the conversion instruction
(most programs dont do that)

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12859

none/tests/s390x/Makefile.am
none/tests/s390x/fpconv.c [new file with mode: 0644]

index 399a8295c7dcd863c32d48e068a31e57bfe8915f..04aaaf875e8d87579ba9ade211e3dff7523b3499 100644 (file)
@@ -8,7 +8,7 @@ INSN_TESTS = clc clcle cvb cvd icm lpr tcxb lam_stam xc mvst add sub mul \
              op_exception fgx stck stckf stcke stfle cksm mvcl clcl troo \
              trto trot trtt tr tre cij cgij clij clgij crj cgrj clrj clgrj \
              cs csg cds cdsg cu21 cu21_1 cu24 cu24_1 cu42 cu12 cu12_1 \
-             ex_sig ex_clone cu14 cu14_1 cu41
+             ex_sig ex_clone cu14 cu14_1 cu41 fpconv
 
 check_PROGRAMS = $(INSN_TESTS) \
                 allexec \
diff --git a/none/tests/s390x/fpconv.c b/none/tests/s390x/fpconv.c
new file mode 100644 (file)
index 0000000..c83749d
--- /dev/null
@@ -0,0 +1,147 @@
+/* basic float <-> signed int conversions available since z900 */
+#include <float.h>
+#include <stdio.h>
+#include "opcodes.h"
+
+#define I2F(insn,  initial, target,round)                                \
+({                                                                       \
+   register unsigned long source asm("2") =  initial;                    \
+   register typeof(target) _t asm("f0");                                 \
+   asm volatile(insn " 0,2\n\t" :"=f" (_t):"d"(source));                 \
+   _t;                                                                   \
+})
+
+#define F2L(insn, initial, type, round, cc)                              \
+({                                                                       \
+   register type source asm("f0") =  initial;                            \
+   register unsigned long target asm ("2") = 0;                          \
+   asm volatile(insn " 2," #round ",0\n\t"                               \
+                "ipm %1\n\t"                                             \
+                "srl %1,28\n\t"                                          \
+               :"=d" (target), "=d" (cc) :"f"(source):"cc");            \
+   target;                                                               \
+})
+
+
+#define DO_INSN_I2F32(insn, round)                                       \
+({                                                                       \
+   float f32;                                                            \
+   printf(#insn " %f\n", I2F(insn, 0, f32, round));                      \
+   printf(#insn " %f\n", I2F(insn, 1, f32, round));                      \
+   printf(#insn " %f\n", I2F(insn, 0xffffffffUL, f32, round));           \
+   printf(#insn " %f\n", I2F(insn, 0x80000000UL, f32, round));           \
+   printf(#insn " %f\n", I2F(insn, 0x7fffffffUL, f32, round));           \
+   printf(#insn " %f\n", I2F(insn, 0x100000000UL, f32, round));          \
+   printf(#insn " %f\n", I2F(insn, 0xffffffffffffffffUL, f32, round));   \
+   printf(#insn " %f\n", I2F(insn, 0x8000000000000000UL, f32, round));   \
+   printf(#insn " %f\n", I2F(insn, 0x7fffffffffffffffUL, f32, round));   \
+})
+
+#define DO_INSN_I2F64(insn, round)                                       \
+({                                                                       \
+   double f64;                                                           \
+   printf(#insn " %f\n", I2F(insn, 0, f64, round));                      \
+   printf(#insn " %f\n", I2F(insn, 1, f64, round));                      \
+   printf(#insn " %f\n", I2F(insn, 0xffffffffUL, f64, round));           \
+   printf(#insn " %f\n", I2F(insn, 0x80000000UL, f64, round));           \
+   printf(#insn " %f\n", I2F(insn, 0x7fffffffUL, f64, round));           \
+   printf(#insn " %f\n", I2F(insn, 0x100000000UL, f64, round));          \
+   printf(#insn " %f\n", I2F(insn, 0xffffffffffffffffUL, f64, round));   \
+   printf(#insn " %f\n", I2F(insn, 0x8000000000000000UL, f64, round));   \
+   printf(#insn " %f\n", I2F(insn, 0x7fffffffffffffffUL, f64, round));   \
+})
+
+#define DO_INSN_I2F128(insn, round)                                      \
+({                                                                       \
+   long double f128;                                                     \
+   printf(#insn " %Lf\n", I2F(insn, 0, f128, round));                    \
+   printf(#insn " %Lf\n", I2F(insn, 1, f128, round));                    \
+   printf(#insn " %Lf\n", I2F(insn, 0xffffffffUL, f128, round));         \
+   printf(#insn " %Lf\n", I2F(insn, 0x80000000UL, f128, round));         \
+   printf(#insn " %Lf\n", I2F(insn, 0x7fffffffUL, f128, round));         \
+   printf(#insn " %Lf\n", I2F(insn, 0x100000000UL, f128, round));        \
+   printf(#insn " %Lf\n", I2F(insn, 0xffffffffffffffffUL, f128, round)); \
+   printf(#insn " %Lf\n", I2F(insn, 0x8000000000000000UL, f128, round)); \
+   printf(#insn " %Lf\n", I2F(insn, 0x7fffffffffffffffUL, f128, round)); \
+})
+
+#define DO_INSN_F2L(insn, round, type)                                   \
+({                                                                       \
+   int cc;                                                               \
+   printf(#insn " %ld ", F2L(insn, -1.1, type, round, cc));              \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, 0, type, round, cc));                 \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, 1, type, round, cc));                 \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, 1.4, type, round, cc));               \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, 1.5, type, round, cc));               \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, 1.6, type, round, cc));               \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, 1.6E+4, type, round, cc));            \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, 1.6E+8, type, round, cc));            \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, 1.6E+12, type, round, cc));           \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, 1.6E+20, type, round, cc));           \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, 1.6E+200, type, round, cc));          \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, 1.6E+2000L, type, round, cc));        \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, 1.6E-4, type, round, cc));            \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, FLT_MIN, type, round, cc));           \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, FLT_MAX, type, round, cc));           \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, DBL_MIN, type, round, cc));           \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, DBL_MAX, type, round, cc));           \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, LDBL_MIN, type, round, cc));          \
+   printf("cc=%d\n", cc);                                                \
+   printf(#insn " %ld ", F2L(insn, LDBL_MAX, type, round, cc));          \
+   printf("cc=%d\n", cc);                                                \
+})
+
+#define DO_I2F(round)                                                    \
+({                                                                       \
+   DO_INSN_I2F32("cefbr", round);                                        \
+   DO_INSN_I2F32("cegbr", round);                                        \
+   DO_INSN_I2F64("cdfbr", round);                                        \
+   DO_INSN_I2F64("cdgbr", round);                                        \
+   DO_INSN_I2F128("cxfbr", round);                                       \
+   DO_INSN_I2F128("cxgbr", round);                                       \
+})
+
+#define DO_F2L(round)                                                    \
+({                                                                       \
+   DO_INSN_F2L("cfebr", round, float);                                   \
+   DO_INSN_F2L("cgebr", round, float);                                   \
+   DO_INSN_F2L("cfdbr", round, double);                                  \
+   DO_INSN_F2L("cgdbr", round, double);                                  \
+   DO_INSN_F2L("cfxbr", round, long double);                             \
+   DO_INSN_F2L("cgxbr", round, long double);                             \
+})
+
+
+int main()
+{
+   DO_I2F(4);
+   DO_F2L(4);
+
+   DO_I2F(5);
+   DO_F2L(5);
+
+   DO_I2F(6);
+   DO_F2L(6);
+
+   DO_I2F(7);
+   DO_F2L(7);
+
+   return 0;
+}