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 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 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 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 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