xref: /openbmc/qemu/tests/tcg/s390x/vfminmax.c (revision 2c471a8291c182130a77702d9bd4c910d987c6a9)
123f13e19SIlya Leoshkevich #define _GNU_SOURCE
223f13e19SIlya Leoshkevich #include <fenv.h>
323f13e19SIlya Leoshkevich #include <stdbool.h>
423f13e19SIlya Leoshkevich #include <stdio.h>
523f13e19SIlya Leoshkevich #include <string.h>
623f13e19SIlya Leoshkevich 
7*6dc29354SIlya Leoshkevich #include "float.h"
8*6dc29354SIlya Leoshkevich 
923f13e19SIlya Leoshkevich /*
1023f13e19SIlya Leoshkevich  * vfmin/vfmax instruction execution.
1123f13e19SIlya Leoshkevich  */
1223f13e19SIlya Leoshkevich #define VFMIN 0xEE
1323f13e19SIlya Leoshkevich #define VFMAX 0xEF
1423f13e19SIlya Leoshkevich 
1523f13e19SIlya Leoshkevich extern char insn[6];
1623f13e19SIlya Leoshkevich asm(".pushsection .rwx,\"awx\",@progbits\n"
1723f13e19SIlya Leoshkevich     ".globl insn\n"
1823f13e19SIlya Leoshkevich     /* e7 89 a0 00 2e ef */
1923f13e19SIlya Leoshkevich     "insn: vfmaxsb %v24,%v25,%v26,0\n"
2023f13e19SIlya Leoshkevich     ".popsection\n");
2123f13e19SIlya Leoshkevich 
vfminmax(unsigned int op,unsigned int m4,unsigned int m5,unsigned int m6,void * v1,const void * v2,const void * v3)2223f13e19SIlya Leoshkevich static void vfminmax(unsigned int op,
2323f13e19SIlya Leoshkevich                      unsigned int m4, unsigned int m5, unsigned int m6,
2423f13e19SIlya Leoshkevich                      void *v1, const void *v2, const void *v3)
2523f13e19SIlya Leoshkevich {
2623f13e19SIlya Leoshkevich     insn[3] = (m6 << 4) | m5;
2723f13e19SIlya Leoshkevich     insn[4] = (m4 << 4) | 0x0e;
2823f13e19SIlya Leoshkevich     insn[5] = op;
2923f13e19SIlya Leoshkevich 
3023f13e19SIlya Leoshkevich     asm("vl %%v25,%[v2]\n"
3123f13e19SIlya Leoshkevich         "vl %%v26,%[v3]\n"
3223f13e19SIlya Leoshkevich         "ex 0,%[insn]\n"
3323f13e19SIlya Leoshkevich         "vst %%v24,%[v1]\n"
3423f13e19SIlya Leoshkevich         : [v1] "=m" (*(char (*)[16])v1)
35*6dc29354SIlya Leoshkevich         : [v2] "m" (*(const char (*)[16])v2)
36*6dc29354SIlya Leoshkevich         , [v3] "m" (*(const char (*)[16])v3)
3723f13e19SIlya Leoshkevich         , [insn] "m" (insn)
3823f13e19SIlya Leoshkevich         : "v24", "v25", "v26");
3923f13e19SIlya Leoshkevich }
4023f13e19SIlya Leoshkevich 
4123f13e19SIlya Leoshkevich /*
4223f13e19SIlya Leoshkevich  * PoP tables as close to the original as possible.
4323f13e19SIlya Leoshkevich  */
4423f13e19SIlya Leoshkevich struct signed_test {
4523f13e19SIlya Leoshkevich     int op;
4623f13e19SIlya Leoshkevich     int m6;
4723f13e19SIlya Leoshkevich     const char *m6_desc;
4823f13e19SIlya Leoshkevich     const char *table[N_SIGNED_CLASSES][N_SIGNED_CLASSES];
4923f13e19SIlya Leoshkevich } signed_tests[] = {
5023f13e19SIlya Leoshkevich     {
5123f13e19SIlya Leoshkevich         .op = VFMIN,
5223f13e19SIlya Leoshkevich         .m6 = 0,
5323f13e19SIlya Leoshkevich         .m6_desc = "IEEE MinNum",
5423f13e19SIlya Leoshkevich         .table = {
5523f13e19SIlya Leoshkevich              /*         -inf         -Fn          -0           +0           +Fn          +inf         QNaN         SNaN     */
5623f13e19SIlya Leoshkevich             {/* -inf */ "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "Xi: T(b*)"},
5723f13e19SIlya Leoshkevich             {/* -Fn  */ "T(b)",      "T(M(a,b))", "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "Xi: T(b*)"},
5823f13e19SIlya Leoshkevich             {/* -0   */ "T(b)",      "T(b)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "Xi: T(b*)"},
5923f13e19SIlya Leoshkevich             {/* +0   */ "T(b)",      "T(b)",      "T(b)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "Xi: T(b*)"},
6023f13e19SIlya Leoshkevich             {/* +Fn  */ "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(M(a,b))", "T(a)",      "T(a)",      "Xi: T(b*)"},
6123f13e19SIlya Leoshkevich             {/* +inf */ "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(a)",      "T(a)",      "Xi: T(b*)"},
6223f13e19SIlya Leoshkevich             {/* QNaN */ "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(a)",      "Xi: T(b*)"},
6323f13e19SIlya Leoshkevich             {/* SNaN */ "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)"},
6423f13e19SIlya Leoshkevich         },
6523f13e19SIlya Leoshkevich     },
6623f13e19SIlya Leoshkevich     {
6723f13e19SIlya Leoshkevich         .op = VFMIN,
6823f13e19SIlya Leoshkevich         .m6 = 1,
6923f13e19SIlya Leoshkevich         .m6_desc = "JAVA Math.Min()",
7023f13e19SIlya Leoshkevich         .table = {
7123f13e19SIlya Leoshkevich              /*         -inf         -Fn          -0           +0           +Fn          +inf         QNaN         SNaN     */
7223f13e19SIlya Leoshkevich             {/* -inf */ "T(b)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(b)",      "Xi: T(b*)"},
7323f13e19SIlya Leoshkevich             {/* -Fn  */ "T(b)",      "T(M(a,b))", "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(b)",      "Xi: T(b*)"},
7423f13e19SIlya Leoshkevich             {/* -0   */ "T(b)",      "T(b)",      "T(b)",      "T(a)",      "T(a)",      "T(a)",      "T(b)",      "Xi: T(b*)"},
7523f13e19SIlya Leoshkevich             {/* +0   */ "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(a)",      "T(a)",      "T(b)",      "Xi: T(b*)"},
7623f13e19SIlya Leoshkevich             {/* +Fn  */ "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(M(a,b))", "T(a)",      "T(b)",      "Xi: T(b*)"},
7723f13e19SIlya Leoshkevich             {/* +inf */ "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(b)",      "Xi: T(b*)"},
7823f13e19SIlya Leoshkevich             {/* QNaN */ "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "Xi: T(b*)"},
7923f13e19SIlya Leoshkevich             {/* SNaN */ "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)"},
8023f13e19SIlya Leoshkevich         },
8123f13e19SIlya Leoshkevich     },
8223f13e19SIlya Leoshkevich     {
8323f13e19SIlya Leoshkevich         .op = VFMIN,
8423f13e19SIlya Leoshkevich         .m6 = 2,
8523f13e19SIlya Leoshkevich         .m6_desc = "C-style Min Macro",
8623f13e19SIlya Leoshkevich         .table = {
8723f13e19SIlya Leoshkevich              /*         -inf        -Fn          -0          +0          +Fn          +inf        QNaN        SNaN    */
8823f13e19SIlya Leoshkevich             {/* -inf */ "T(b)",     "T(a)",      "T(a)",     "T(a)",     "T(a)",      "T(a)",     "Xi: T(b)", "Xi: T(b)"},
8923f13e19SIlya Leoshkevich             {/* -Fn  */ "T(b)",     "T(M(a,b))", "T(a)",     "T(a)",     "T(a)",      "T(a)",     "Xi: T(b)", "Xi: T(b)"},
9023f13e19SIlya Leoshkevich             {/* -0   */ "T(b)",     "T(b)",      "T(b)",     "T(b)",     "T(a)",      "T(a)",     "Xi: T(b)", "Xi: T(b)"},
9123f13e19SIlya Leoshkevich             {/* +0   */ "T(b)",     "T(b)",      "T(b)",     "T(b)",     "T(a)",      "T(a)",     "Xi: T(b)", "Xi: T(b)"},
9223f13e19SIlya Leoshkevich             {/* +Fn  */ "T(b)",     "T(b)",      "T(b)",     "T(b)",     "T(M(a,b))", "T(a)",     "Xi: T(b)", "Xi: T(b)"},
9323f13e19SIlya Leoshkevich             {/* +inf */ "T(b)",     "T(b)",      "T(b)",     "T(b)",     "T(b)",      "T(a)",     "Xi: T(b)", "Xi: T(b)"},
9423f13e19SIlya Leoshkevich             {/* QNaN */ "Xi: T(b)", "Xi: T(b)",  "Xi: T(b)", "Xi: T(b)", "Xi: T(b)",  "Xi: T(b)", "Xi: T(b)", "Xi: T(b)"},
9523f13e19SIlya Leoshkevich             {/* SNaN */ "Xi: T(b)", "Xi: T(b)",  "Xi: T(b)", "Xi: T(b)", "Xi: T(b)",  "Xi: T(b)", "Xi: T(b)", "Xi: T(b)"},
9623f13e19SIlya Leoshkevich         },
9723f13e19SIlya Leoshkevich     },
9823f13e19SIlya Leoshkevich     {
9923f13e19SIlya Leoshkevich         .op = VFMIN,
10023f13e19SIlya Leoshkevich         .m6 = 3,
10123f13e19SIlya Leoshkevich         .m6_desc = "C++ algorithm.min()",
10223f13e19SIlya Leoshkevich         .table = {
10323f13e19SIlya Leoshkevich              /*         -inf        -Fn          -0          +0          +Fn          +inf        QNaN        SNaN    */
10423f13e19SIlya Leoshkevich             {/* -inf */ "T(b)",     "T(a)",      "T(a)",     "T(a)",     "T(a)",      "T(a)",     "Xi: T(a)", "Xi: T(a)"},
10523f13e19SIlya Leoshkevich             {/* -Fn  */ "T(b)",     "T(M(a,b))", "T(a)",     "T(a)",     "T(a)",      "T(a)",     "Xi: T(a)", "Xi: T(a)"},
10623f13e19SIlya Leoshkevich             {/* -0   */ "T(b)",     "T(b)",      "T(a)",     "T(a)",     "T(a)",      "T(a)",     "Xi: T(a)", "Xi: T(a)"},
10723f13e19SIlya Leoshkevich             {/* +0   */ "T(b)",     "T(b)",      "T(a)",     "T(a)",     "T(a)",      "T(a)",     "Xi: T(a)", "Xi: T(a)"},
10823f13e19SIlya Leoshkevich             {/* +Fn  */ "T(b)",     "T(b)",      "T(b)",     "T(b)",     "T(M(a,b))", "T(a)",     "Xi: T(a)", "Xi: T(a)"},
10923f13e19SIlya Leoshkevich             {/* +inf */ "T(b)",     "T(b)",      "T(b)",     "T(b)",     "T(b)",      "T(a)",     "Xi: T(a)", "Xi: T(a)"},
11023f13e19SIlya Leoshkevich             {/* QNaN */ "Xi: T(a)", "Xi: T(a)",  "Xi: T(a)", "Xi: T(a)", "Xi: T(a)",  "Xi: T(a)", "Xi: T(a)", "Xi: T(a)"},
11123f13e19SIlya Leoshkevich             {/* SNaN */ "Xi: T(a)", "Xi: T(a)",  "Xi: T(a)", "Xi: T(a)", "Xi: T(a)",  "Xi: T(a)", "Xi: T(a)", "Xi: T(a)"},
11223f13e19SIlya Leoshkevich         },
11323f13e19SIlya Leoshkevich     },
11423f13e19SIlya Leoshkevich     {
11523f13e19SIlya Leoshkevich         .op = VFMIN,
11623f13e19SIlya Leoshkevich         .m6 = 4,
11723f13e19SIlya Leoshkevich         .m6_desc = "fmin()",
11823f13e19SIlya Leoshkevich         .table = {
11923f13e19SIlya Leoshkevich              /*         -inf        -Fn          -0          +0          +Fn          +inf        QNaN        SNaN    */
12023f13e19SIlya Leoshkevich             {/* -inf */ "T(a)",     "T(a)",      "T(a)",     "T(a)",     "T(a)",      "T(a)",     "T(a)",     "Xi: T(a)"},
12123f13e19SIlya Leoshkevich             {/* -Fn  */ "T(b)",     "T(M(a,b))", "T(a)",     "T(a)",     "T(a)",      "T(a)",     "T(a)",     "Xi: T(a)"},
12223f13e19SIlya Leoshkevich             {/* -0   */ "T(b)",     "T(b)",      "T(a)",     "T(a)",     "T(a)",      "T(a)",     "T(a)",     "Xi: T(a)"},
12323f13e19SIlya Leoshkevich             {/* +0   */ "T(b)",     "T(b)",      "T(b)",     "T(a)",     "T(a)",      "T(a)",     "T(a)",     "Xi: T(a)"},
12423f13e19SIlya Leoshkevich             {/* +Fn  */ "T(b)",     "T(b)",      "T(b)",     "T(b)",     "T(M(a,b))", "T(a)",     "T(a)",     "Xi: T(a)"},
12523f13e19SIlya Leoshkevich             {/* +inf */ "T(b)",     "T(b)",      "T(b)",     "T(b)",     "T(b)",      "T(a)",     "T(a)",     "Xi: T(a)"},
12623f13e19SIlya Leoshkevich             {/* QNaN */ "T(b)",     "T(b)",      "T(b)",     "T(b)",     "T(b)",      "T(b)",     "T(a)",     "Xi: T(a)"},
12723f13e19SIlya Leoshkevich             {/* SNaN */ "Xi: T(b)", "Xi: T(b)",  "Xi: T(b)", "Xi: T(b)", "Xi: T(b)",  "Xi: T(b)", "Xi: T(a)", "Xi: T(a)"},
12823f13e19SIlya Leoshkevich         },
12923f13e19SIlya Leoshkevich     },
13023f13e19SIlya Leoshkevich 
13123f13e19SIlya Leoshkevich     {
13223f13e19SIlya Leoshkevich         .op = VFMAX,
13323f13e19SIlya Leoshkevich         .m6 = 0,
13423f13e19SIlya Leoshkevich         .m6_desc = "IEEE MaxNum",
13523f13e19SIlya Leoshkevich         .table = {
13623f13e19SIlya Leoshkevich              /*         -inf         -Fn          -0           +0           +Fn          +inf         QNaN         SNaN     */
13723f13e19SIlya Leoshkevich             {/* -inf */ "T(a)",      "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(a)",      "Xi: T(b*)"},
13823f13e19SIlya Leoshkevich             {/* -Fn  */ "T(a)",      "T(M(a,b))", "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(a)",      "Xi: T(b*)"},
13923f13e19SIlya Leoshkevich             {/* -0   */ "T(a)",      "T(a)",      "T(a)",      "T(b)",      "T(b)",      "T(b)",      "T(a)",      "Xi: T(b*)"},
14023f13e19SIlya Leoshkevich             {/* +0   */ "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(b)",      "T(b)",      "T(a)",      "Xi: T(b*)"},
14123f13e19SIlya Leoshkevich             {/* +Fn  */ "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(M(a,b))", "T(b)",      "T(a)",      "Xi: T(b*)"},
14223f13e19SIlya Leoshkevich             {/* +inf */ "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "Xi: T(b*)"},
14323f13e19SIlya Leoshkevich             {/* QNaN */ "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(a)",      "Xi: T(b*)"},
14423f13e19SIlya Leoshkevich             {/* SNaN */ "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)"},
14523f13e19SIlya Leoshkevich         },
14623f13e19SIlya Leoshkevich     },
14723f13e19SIlya Leoshkevich     {
14823f13e19SIlya Leoshkevich         .op = VFMAX,
14923f13e19SIlya Leoshkevich         .m6 = 1,
15023f13e19SIlya Leoshkevich         .m6_desc = "JAVA Math.Max()",
15123f13e19SIlya Leoshkevich         .table = {
15223f13e19SIlya Leoshkevich              /*         -inf         -Fn          -0           +0           +Fn          +inf         QNaN         SNaN     */
15323f13e19SIlya Leoshkevich             {/* -inf */ "T(a)",      "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(b)",      "Xi: T(b*)"},
15423f13e19SIlya Leoshkevich             {/* -Fn  */ "T(a)",      "T(M(a,b))", "T(b)",      "T(b)",      "T(b)",      "T(b)",      "T(b)",      "Xi: T(b*)"},
15523f13e19SIlya Leoshkevich             {/* -0   */ "T(a)",      "T(a)",      "T(a)",      "T(b)",      "T(b)",      "T(b)",      "T(b)",      "Xi: T(b*)"},
15623f13e19SIlya Leoshkevich             {/* +0   */ "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(b)",      "T(b)",      "T(b)",      "Xi: T(b*)"},
15723f13e19SIlya Leoshkevich             {/* +Fn  */ "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(M(a,b))", "T(b)",      "T(b)",      "Xi: T(b*)"},
15823f13e19SIlya Leoshkevich             {/* +inf */ "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(b)",      "Xi: T(b*)"},
15923f13e19SIlya Leoshkevich             {/* QNaN */ "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "T(a)",      "Xi: T(b*)"},
16023f13e19SIlya Leoshkevich             {/* SNaN */ "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)"},
16123f13e19SIlya Leoshkevich         },
16223f13e19SIlya Leoshkevich     },
16323f13e19SIlya Leoshkevich     {
16423f13e19SIlya Leoshkevich         .op = VFMAX,
16523f13e19SIlya Leoshkevich         .m6 = 2,
16623f13e19SIlya Leoshkevich         .m6_desc = "C-style Max Macro",
16723f13e19SIlya Leoshkevich         .table = {
16823f13e19SIlya Leoshkevich              /*         -inf        -Fn          -0          +0          +Fn          +inf        QNaN        SNaN    */
16923f13e19SIlya Leoshkevich             {/* -inf */ "T(b)",     "T(b)",      "T(b)",     "T(b)",     "T(b)",      "T(b)",     "Xi: T(b)", "Xi: T(b)"},
17023f13e19SIlya Leoshkevich             {/* -Fn  */ "T(a)",     "T(M(a,b))", "T(b)",     "T(b)",     "T(b)",      "T(b)",     "Xi: T(b)", "Xi: T(b)"},
17123f13e19SIlya Leoshkevich             {/* -0   */ "T(a)",     "T(a)",      "T(b)",     "T(b)",     "T(b)",      "T(b)",     "Xi: T(b)", "Xi: T(b)"},
17223f13e19SIlya Leoshkevich             {/* +0   */ "T(a)",     "T(a)",      "T(b)",     "T(b)",     "T(b)",      "T(b)",     "Xi: T(b)", "Xi: T(b)"},
17323f13e19SIlya Leoshkevich             {/* +Fn  */ "T(a)",     "T(a)",      "T(a)",     "T(a)",     "T(M(a,b))", "T(b)",     "Xi: T(b)", "Xi: T(b)"},
17423f13e19SIlya Leoshkevich             {/* +inf */ "T(a)",     "T(a)",      "T(a)",     "T(a)",     "T(a)",      "T(b)",     "Xi: T(b)", "Xi: T(b)"},
17523f13e19SIlya Leoshkevich             {/* QNaN */ "Xi: T(b)", "Xi: T(b)",  "Xi: T(b)", "Xi: T(b)", "Xi: T(b)",  "Xi: T(b)", "Xi: T(b)", "Xi: T(b)"},
17623f13e19SIlya Leoshkevich             {/* SNaN */ "Xi: T(b)", "Xi: T(b)",  "Xi: T(b)", "Xi: T(b)", "Xi: T(b)",  "Xi: T(b)", "Xi: T(b)", "Xi: T(b)"},
17723f13e19SIlya Leoshkevich         },
17823f13e19SIlya Leoshkevich     },
17923f13e19SIlya Leoshkevich     {
18023f13e19SIlya Leoshkevich         .op = VFMAX,
18123f13e19SIlya Leoshkevich         .m6 = 3,
18223f13e19SIlya Leoshkevich         .m6_desc = "C++ algorithm.max()",
18323f13e19SIlya Leoshkevich         .table = {
18423f13e19SIlya Leoshkevich              /*         -inf        -Fn          -0          +0          +Fn          +inf        QNaN        SNaN    */
18523f13e19SIlya Leoshkevich             {/* -inf */ "T(a)",     "T(b)",      "T(b)",     "T(b)",     "T(b)",      "T(b)",     "Xi: T(a)", "Xi: T(a)"},
18623f13e19SIlya Leoshkevich             {/* -Fn  */ "T(a)",     "T(M(a,b))", "T(b)",     "T(b)",     "T(b)",      "T(b)",     "Xi: T(a)", "Xi: T(a)"},
18723f13e19SIlya Leoshkevich             {/* -0   */ "T(a)",     "T(a)",      "T(a)",     "T(a)",     "T(b)",      "T(b)",     "Xi: T(a)", "Xi: T(a)"},
18823f13e19SIlya Leoshkevich             {/* +0   */ "T(a)",     "T(a)",      "T(a)",     "T(a)",     "T(b)",      "T(b)",     "Xi: T(a)", "Xi: T(a)"},
18923f13e19SIlya Leoshkevich             {/* +Fn  */ "T(a)",     "T(a)",      "T(a)",     "T(a)",     "T(M(a,b))", "T(b)",     "Xi: T(a)", "Xi: T(a)"},
19023f13e19SIlya Leoshkevich             {/* +inf */ "T(a)",     "T(a)",      "T(a)",     "T(a)",     "T(a)",      "T(a)",     "Xi: T(a)", "Xi: T(a)"},
19123f13e19SIlya Leoshkevich             {/* QNaN */ "Xi: T(a)", "Xi: T(a)",  "Xi: T(a)", "Xi: T(a)", "Xi: T(a)",  "Xi: T(a)", "Xi: T(a)", "Xi: T(a)"},
19223f13e19SIlya Leoshkevich             {/* SNaN */ "Xi: T(a)", "Xi: T(a)",  "Xi: T(a)", "Xi: T(a)", "Xi: T(a)",  "Xi: T(a)", "Xi: T(a)", "Xi: T(a)"},
19323f13e19SIlya Leoshkevich         },
19423f13e19SIlya Leoshkevich     },
19523f13e19SIlya Leoshkevich     {
19623f13e19SIlya Leoshkevich         .op = VFMAX,
19723f13e19SIlya Leoshkevich         .m6 = 4,
19823f13e19SIlya Leoshkevich         .m6_desc = "fmax()",
19923f13e19SIlya Leoshkevich         .table = {
20023f13e19SIlya Leoshkevich              /*         -inf        -Fn          -0          +0          +Fn          +inf        QNaN        SNaN    */
20123f13e19SIlya Leoshkevich             {/* -inf */ "T(a)",     "T(b)",      "T(b)",     "T(b)",     "T(b)",      "T(b)",     "T(a)",     "Xi: T(a)"},
20223f13e19SIlya Leoshkevich             {/* -Fn  */ "T(a)",     "T(M(a,b))", "T(b)",     "T(b)",     "T(b)",      "T(b)",     "T(a)",     "Xi: T(a)"},
20323f13e19SIlya Leoshkevich             {/* -0   */ "T(a)",     "T(a)",      "T(a)",     "T(b)",     "T(b)",      "T(b)",     "T(a)",     "Xi: T(a)"},
20423f13e19SIlya Leoshkevich             {/* +0   */ "T(a)",     "T(a)",      "T(a)",     "T(a)",     "T(b)",      "T(b)",     "T(a)",     "Xi: T(a)"},
20523f13e19SIlya Leoshkevich             {/* +Fn  */ "T(a)",     "T(a)",      "T(a)",     "T(a)",     "T(M(a,b))", "T(b)",     "T(a)",     "Xi: T(a)"},
20623f13e19SIlya Leoshkevich             {/* +inf */ "T(a)",     "T(a)",      "T(a)",     "T(a)",     "T(a)",      "T(a)",     "T(a)",     "Xi: T(a)"},
20723f13e19SIlya Leoshkevich             {/* QNaN */ "T(b)",     "T(b)",      "T(b)",     "T(b)",     "T(b)",      "T(b)",     "T(a)",     "Xi: T(a)"},
20823f13e19SIlya Leoshkevich             {/* SNaN */ "Xi: T(b)", "Xi: T(b)",  "Xi: T(b)", "Xi: T(b)", "Xi: T(b)",  "Xi: T(b)", "Xi: T(a)", "Xi: T(a)"},
20923f13e19SIlya Leoshkevich         },
21023f13e19SIlya Leoshkevich     },
21123f13e19SIlya Leoshkevich };
21223f13e19SIlya Leoshkevich 
signed_test(struct signed_test * test,int m4,int m5,const void * v1_exp,bool xi_exp,const void * v2,const void * v3)21323f13e19SIlya Leoshkevich static int signed_test(struct signed_test *test, int m4, int m5,
21423f13e19SIlya Leoshkevich                        const void *v1_exp, bool xi_exp,
21523f13e19SIlya Leoshkevich                        const void *v2, const void *v3)
21623f13e19SIlya Leoshkevich {
21723f13e19SIlya Leoshkevich     size_t n = (m5 & 8) ? float_sizes[m4 - 2] : 16;
21823f13e19SIlya Leoshkevich     char v1[16];
21923f13e19SIlya Leoshkevich     bool xi;
22023f13e19SIlya Leoshkevich 
22123f13e19SIlya Leoshkevich     feclearexcept(FE_ALL_EXCEPT);
22223f13e19SIlya Leoshkevich     vfminmax(test->op, m4, m5, test->m6, v1, v2, v3);
22323f13e19SIlya Leoshkevich     xi = fetestexcept(FE_ALL_EXCEPT) == FE_INVALID;
22423f13e19SIlya Leoshkevich 
22523f13e19SIlya Leoshkevich     if (memcmp(v1, v1_exp, n) != 0 || xi != xi_exp) {
22623f13e19SIlya Leoshkevich         fprintf(stderr, "[  FAILED  ] %s ", test->m6_desc);
22723f13e19SIlya Leoshkevich         dump_v(stderr, v2, n);
22823f13e19SIlya Leoshkevich         fprintf(stderr, ", ");
22923f13e19SIlya Leoshkevich         dump_v(stderr, v3, n);
23023f13e19SIlya Leoshkevich         fprintf(stderr, ", %d, %d, %d: actual=", m4, m5, test->m6);
23123f13e19SIlya Leoshkevich         dump_v(stderr, v1, n);
23223f13e19SIlya Leoshkevich         fprintf(stderr, "/%d, expected=", (int)xi);
23323f13e19SIlya Leoshkevich         dump_v(stderr, v1_exp, n);
23423f13e19SIlya Leoshkevich         fprintf(stderr, "/%d\n", (int)xi_exp);
23523f13e19SIlya Leoshkevich         return 1;
23623f13e19SIlya Leoshkevich     }
23723f13e19SIlya Leoshkevich 
23823f13e19SIlya Leoshkevich     return 0;
23923f13e19SIlya Leoshkevich }
24023f13e19SIlya Leoshkevich 
241*6dc29354SIlya Leoshkevich struct iter {
242*6dc29354SIlya Leoshkevich     int cls[2];
243*6dc29354SIlya Leoshkevich     int val[2];
244*6dc29354SIlya Leoshkevich };
245*6dc29354SIlya Leoshkevich 
iter_next(struct iter * it,int fmt)246*6dc29354SIlya Leoshkevich static bool iter_next(struct iter *it, int fmt)
24723f13e19SIlya Leoshkevich {
248*6dc29354SIlya Leoshkevich     int i;
249*6dc29354SIlya Leoshkevich 
250*6dc29354SIlya Leoshkevich     for (i = 1; i >= 0; i--) {
251*6dc29354SIlya Leoshkevich         if (++it->val[i] != signed_floats[fmt][it->cls[i]].n) {
252*6dc29354SIlya Leoshkevich             return true;
253*6dc29354SIlya Leoshkevich         }
254*6dc29354SIlya Leoshkevich         it->val[i] = 0;
255*6dc29354SIlya Leoshkevich 
256*6dc29354SIlya Leoshkevich         if (++it->cls[i] != N_SIGNED_CLASSES) {
257*6dc29354SIlya Leoshkevich             return true;
258*6dc29354SIlya Leoshkevich         }
259*6dc29354SIlya Leoshkevich         it->cls[i] = 0;
260*6dc29354SIlya Leoshkevich     }
261*6dc29354SIlya Leoshkevich 
262*6dc29354SIlya Leoshkevich     return false;
26323f13e19SIlya Leoshkevich }
26423f13e19SIlya Leoshkevich 
main(void)26523f13e19SIlya Leoshkevich int main(void)
26623f13e19SIlya Leoshkevich {
26723f13e19SIlya Leoshkevich     int ret = 0;
26823f13e19SIlya Leoshkevich     size_t i;
26923f13e19SIlya Leoshkevich 
27023f13e19SIlya Leoshkevich     for (i = 0; i < sizeof(signed_tests) / sizeof(signed_tests[0]); i++) {
27123f13e19SIlya Leoshkevich         struct signed_test *test = &signed_tests[i];
272*6dc29354SIlya Leoshkevich         int fmt;
27323f13e19SIlya Leoshkevich 
274*6dc29354SIlya Leoshkevich         for (fmt = 0; fmt < N_FORMATS; fmt++) {
275*6dc29354SIlya Leoshkevich             size_t float_size = float_sizes[fmt];
276*6dc29354SIlya Leoshkevich             int m4 = fmt + 2;
27723f13e19SIlya Leoshkevich             int m5;
27823f13e19SIlya Leoshkevich 
27923f13e19SIlya Leoshkevich             for (m5 = 0; m5 <= 8; m5 += 8) {
28023f13e19SIlya Leoshkevich                 char v1_exp[16], v2[16], v3[16];
28123f13e19SIlya Leoshkevich                 bool xi_exp = false;
282*6dc29354SIlya Leoshkevich                 struct iter it = {};
28323f13e19SIlya Leoshkevich                 int pos = 0;
28423f13e19SIlya Leoshkevich 
285*6dc29354SIlya Leoshkevich                 do {
286*6dc29354SIlya Leoshkevich                     const char *spec = test->table[it.cls[0]][it.cls[1]];
28723f13e19SIlya Leoshkevich 
288*6dc29354SIlya Leoshkevich                     memcpy(&v2[pos],
289*6dc29354SIlya Leoshkevich                            signed_floats[fmt][it.cls[0]].v[it.val[0]],
290*6dc29354SIlya Leoshkevich                            float_size);
291*6dc29354SIlya Leoshkevich                     memcpy(&v3[pos],
292*6dc29354SIlya Leoshkevich                            signed_floats[fmt][it.cls[1]].v[it.val[1]],
293*6dc29354SIlya Leoshkevich                            float_size);
29423f13e19SIlya Leoshkevich                     if (strcmp(spec, "T(a)") == 0 ||
29523f13e19SIlya Leoshkevich                         strcmp(spec, "Xi: T(a)") == 0) {
29623f13e19SIlya Leoshkevich                         memcpy(&v1_exp[pos], &v2[pos], float_size);
29723f13e19SIlya Leoshkevich                     } else if (strcmp(spec, "T(b)") == 0 ||
29823f13e19SIlya Leoshkevich                                strcmp(spec, "Xi: T(b)") == 0) {
29923f13e19SIlya Leoshkevich                         memcpy(&v1_exp[pos], &v3[pos], float_size);
30023f13e19SIlya Leoshkevich                     } else if (strcmp(spec, "Xi: T(a*)") == 0) {
30123f13e19SIlya Leoshkevich                         memcpy(&v1_exp[pos], &v2[pos], float_size);
302*6dc29354SIlya Leoshkevich                         snan_to_qnan(&v1_exp[pos], fmt);
30323f13e19SIlya Leoshkevich                     } else if (strcmp(spec, "Xi: T(b*)") == 0) {
30423f13e19SIlya Leoshkevich                         memcpy(&v1_exp[pos], &v3[pos], float_size);
305*6dc29354SIlya Leoshkevich                         snan_to_qnan(&v1_exp[pos], fmt);
30623f13e19SIlya Leoshkevich                     } else if (strcmp(spec, "T(M(a,b))") == 0) {
30723f13e19SIlya Leoshkevich                         /*
308*6dc29354SIlya Leoshkevich                          * Comparing floats is risky, since the compiler might
309*6dc29354SIlya Leoshkevich                          * generate the same instruction that we are testing.
310*6dc29354SIlya Leoshkevich                          * Compare ints instead. This works, because we get
311*6dc29354SIlya Leoshkevich                          * here only for +-Fn, and the corresponding test
312*6dc29354SIlya Leoshkevich                          * values have identical exponents.
31323f13e19SIlya Leoshkevich                          */
31423f13e19SIlya Leoshkevich                         int v2_int = *(int *)&v2[pos];
31523f13e19SIlya Leoshkevich                         int v3_int = *(int *)&v3[pos];
31623f13e19SIlya Leoshkevich 
31723f13e19SIlya Leoshkevich                         if ((v2_int < v3_int) ==
31823f13e19SIlya Leoshkevich                             ((test->op == VFMIN) != (v2_int < 0))) {
31923f13e19SIlya Leoshkevich                             memcpy(&v1_exp[pos], &v2[pos], float_size);
32023f13e19SIlya Leoshkevich                         } else {
32123f13e19SIlya Leoshkevich                             memcpy(&v1_exp[pos], &v3[pos], float_size);
32223f13e19SIlya Leoshkevich                         }
32323f13e19SIlya Leoshkevich                     } else {
32423f13e19SIlya Leoshkevich                         fprintf(stderr, "Unexpected spec: %s\n", spec);
32523f13e19SIlya Leoshkevich                         return 1;
32623f13e19SIlya Leoshkevich                     }
32723f13e19SIlya Leoshkevich                     xi_exp |= spec[0] == 'X';
32823f13e19SIlya Leoshkevich                     pos += float_size;
32923f13e19SIlya Leoshkevich 
33023f13e19SIlya Leoshkevich                     if ((m5 & 8) || pos == 16) {
33123f13e19SIlya Leoshkevich                         ret |= signed_test(test, m4, m5,
33223f13e19SIlya Leoshkevich                                            v1_exp, xi_exp, v2, v3);
33323f13e19SIlya Leoshkevich                         pos = 0;
33423f13e19SIlya Leoshkevich                         xi_exp = false;
33523f13e19SIlya Leoshkevich                     }
336*6dc29354SIlya Leoshkevich                 } while (iter_next(&it, fmt));
33723f13e19SIlya Leoshkevich 
33823f13e19SIlya Leoshkevich                 if (pos != 0) {
33923f13e19SIlya Leoshkevich                     ret |= signed_test(test, m4, m5, v1_exp, xi_exp, v2, v3);
34023f13e19SIlya Leoshkevich                 }
34123f13e19SIlya Leoshkevich             }
34223f13e19SIlya Leoshkevich         }
34323f13e19SIlya Leoshkevich     }
34423f13e19SIlya Leoshkevich 
34523f13e19SIlya Leoshkevich     return ret;
34623f13e19SIlya Leoshkevich }
347