16429Svs195195 /*
26429Svs195195 * CDDL HEADER START
36429Svs195195 *
46429Svs195195 * The contents of this file are subject to the terms of the
56429Svs195195 * Common Development and Distribution License (the "License").
66429Svs195195 * You may not use this file except in compliance with the License.
76429Svs195195 *
86429Svs195195 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96429Svs195195 * or http://www.opensolaris.org/os/licensing.
106429Svs195195 * See the License for the specific language governing permissions
116429Svs195195 * and limitations under the License.
126429Svs195195 *
136429Svs195195 * When distributing Covered Code, include this CDDL HEADER in each
146429Svs195195 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156429Svs195195 * If applicable, add the following below this CDDL HEADER, with the
166429Svs195195 * fields enclosed by brackets "[]" replaced with your own identifying
176429Svs195195 * information: Portions Copyright [yyyy] [name of copyright owner]
186429Svs195195 *
196429Svs195195 * CDDL HEADER END
206429Svs195195 */
216429Svs195195
226429Svs195195 /*
236491Sia112686 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
246429Svs195195 * Use is subject to license terms.
256429Svs195195 */
266429Svs195195
276429Svs195195 #pragma ident "%Z%%M% %I% %E% SMI"
286429Svs195195
296429Svs195195 #include <sys/types.h>
306429Svs195195 #include <sys/file.h>
316429Svs195195 #include <signal.h>
326429Svs195195 #include <ucontext.h>
336429Svs195195 #include <stdio.h>
346429Svs195195 #include <floatingpoint.h>
356429Svs195195 #include <locale.h>
366429Svs195195 #include <unistd.h>
376429Svs195195 #include <fp.h>
386429Svs195195 #include <externs.h>
396429Svs195195 #include <fps_ereport.h>
406429Svs195195
416429Svs195195 #define FPU_ID_MASK 0xCFF02FFF
426429Svs195195
436429Svs195195 extern int FPU_cpu;
446429Svs195195 static int check_conv();
456429Svs195195 uint_t trap_flag = 0x0;
466429Svs195195 unsigned long fsr_at_trap;
476429Svs195195
486429Svs195195 extern unsigned long long_float_d(unsigned long);
496429Svs195195 extern unsigned long float_long_d(unsigned long);
506429Svs195195 int fpu_sysdiag(struct fps_test_ereport *report);
516429Svs195195 int restore_signals();
526429Svs195195 static int addition_test_dp(struct fps_test_ereport *report);
536429Svs195195 static int addition_test_sp(struct fps_test_ereport *report);
546429Svs195195 static int branching(struct fps_test_ereport *report);
556429Svs195195 static int chain_dp_test(struct fps_test_ereport *report);
566429Svs195195 static int chain_sp_test(struct fps_test_ereport *report);
576429Svs195195 static int check_conv(struct fps_test_ereport *report);
586429Svs195195 static int compare_dp(struct fps_test_ereport *report);
596429Svs195195 static int compare_dp_except(struct fps_test_ereport *report);
606429Svs195195 static int compare_sp(struct fps_test_ereport *report);
616429Svs195195 static int compare_sp_except(struct fps_test_ereport *report);
626429Svs195195 static int data_path_dp(struct fps_test_ereport *report);
636429Svs195195 static int data_path_sp(struct fps_test_ereport *report);
646429Svs195195 static int division_test_dp(struct fps_test_ereport *report);
656429Svs195195 static int division_test_sp(struct fps_test_ereport *report);
666429Svs195195 static int double_sing(struct fps_test_ereport *report);
676429Svs195195 static int fabs_ins_dp(struct fps_test_ereport *report);
686429Svs195195 static int fabs_ins_sp(struct fps_test_ereport *report);
696429Svs195195 static int float_to_integer_dp(struct fps_test_ereport *report);
706429Svs195195 static int float_to_integer_sp(struct fps_test_ereport *report);
716429Svs195195 static int float_to_long_dp(struct fps_test_ereport *report);
726429Svs195195 static int float_to_long_sp(struct fps_test_ereport *report);
736429Svs195195 static int get_negative_value_pn_dp(struct fps_test_ereport *report);
746429Svs195195 static int get_negative_value_pn_sp(struct fps_test_ereport *report);
756429Svs195195 static int get_negative_value_np_dp(struct fps_test_ereport *report);
766429Svs195195 static int get_negative_value_np_sp(struct fps_test_ereport *report);
776429Svs195195 static int fmovs_ins(struct fps_test_ereport *report);
786429Svs195195 static int integer_to_float_dp(struct fps_test_ereport *report);
796429Svs195195 static int integer_to_float_sp(struct fps_test_ereport *report);
806429Svs195195 static int long_to_float_dp(struct fps_test_ereport *report);
816429Svs195195 static int long_to_float_sp(struct fps_test_ereport *report);
826429Svs195195 static int multiplication_test_dp(struct fps_test_ereport *report);
836429Svs195195 static int multiplication_test_sp(struct fps_test_ereport *report);
846429Svs195195 static int no_branching(struct fps_test_ereport *report);
856429Svs195195 static int registers_four(struct fps_test_ereport *report);
866429Svs195195 static int registers_four_dp(struct fps_test_ereport *report);
876429Svs195195 static int registers_one(struct fps_test_ereport *report);
886429Svs195195 static int registers_one_dp(struct fps_test_ereport *report);
896429Svs195195 static int registers_two(struct fps_test_ereport *report);
906429Svs195195 static int registers_two_dp(struct fps_test_ereport *report);
916429Svs195195 static int single_doub(struct fps_test_ereport *report);
926429Svs195195 static int squareroot_test_dp(struct fps_test_ereport *report);
936429Svs195195 static int squareroot_test_sp(struct fps_test_ereport *report);
946429Svs195195 static int subtraction_test_dp(struct fps_test_ereport *report);
956429Svs195195 static int subtraction_test_sp(struct fps_test_ereport *report);
966429Svs195195 static int timing_test(struct fps_test_ereport *report);
976429Svs195195 static void fail_trap(struct fps_test_ereport *report, int flag_num);
986429Svs195195
996429Svs195195 /* SIGFPE */
1006429Svs195195 static void sigfpe_handler(int, siginfo_t *, ucontext_t *);
1016429Svs195195 static struct sigaction oldfpe, newfpe;
1026429Svs195195
1036429Svs195195 /* SIGSEGV */
1046429Svs195195 static void sigsegv_handler(int, siginfo_t *, ucontext_t *);
1056429Svs195195 static struct sigaction oldsegv, newsegv;
1066429Svs195195
1076429Svs195195 /* SIGILL */
1086429Svs195195 static void sigill_handler(int, siginfo_t *, ucontext_t *);
1096429Svs195195 static struct sigaction oldill, newill;
1106429Svs195195
1116429Svs195195 /* SIGBUS */
1126429Svs195195 static void sigbus_handler(int, siginfo_t *, ucontext_t *);
1136429Svs195195 static struct sigaction oldbus, newbus;
1146429Svs195195
1156429Svs195195 static unsigned int pat[] = {
1166429Svs195195 0x00000000,
1176429Svs195195 0x55555555,
1186429Svs195195 0xAAAAAAAA,
1196429Svs195195 0xCCCCCCCC,
1206429Svs195195 0x33333333,
1216429Svs195195 0xFFFFFFFF,
1226429Svs195195 0xA5A5A5A5,
1236429Svs195195 0x3C3C3C3C,
1246429Svs195195 0xF0F0F0F0,
1256429Svs195195 0xEEEEEEEE,
1266429Svs195195 0xDDDDDDDD,
1276429Svs195195 0xBBBBBBBB,
1286429Svs195195 0x77777777,
1296429Svs195195 0x11111111,
1306429Svs195195 0x22222222,
1316429Svs195195 0x44444444,
1326429Svs195195 0x88888888,
1336429Svs195195 0x66666666,
1346429Svs195195 0x99999999,
1356429Svs195195 0x00FF00FF,
1366429Svs195195 0xFF00FF00,
1376429Svs195195 0xFFFF0000,
1386429Svs195195 0x0000FFFF,
1396429Svs195195
1406429Svs195195 };
1416429Svs195195
1426429Svs195195 #define PAT_NUM (sizeof (pat)/sizeof (*pat))
1436429Svs195195
1446429Svs195195 /*
1456429Svs195195 * Double precision patterns
1466429Svs195195 */
1476429Svs195195 static uint64_t pat_dp[] = {
1486429Svs195195 0x0000000000000000UL,
1496429Svs195195 0x5555555555555555UL,
1506429Svs195195 0xAAAAAAAAAAAAAAAAUL,
1516429Svs195195 0xCCCCCCCCCCCCCCCCUL,
1526429Svs195195 0x3333333333333333UL,
1536429Svs195195 0xFFFFFFFFFFFFFFFFUL,
1546429Svs195195 0xA5A5A5A5A5A5A5A5UL,
1556429Svs195195 0x3C3C3C3C3C3C3C3CUL,
1566429Svs195195 0xF0F0F0F0F0F0F0F0UL,
1576429Svs195195 0xEEEEEEEEEEEEEEEEUL,
1586429Svs195195 0xDDDDDDDDDDDDDDDDUL,
1596429Svs195195 0xBBBBBBBBBBBBBBBBUL,
1606429Svs195195 0x7777777777777777UL,
1616429Svs195195 0x1111111111111111UL,
1626429Svs195195 0x2222222222222222UL,
1636429Svs195195 0x4444444444444444UL,
1646429Svs195195 0x8888888888888888UL,
1656429Svs195195 0x6666666666666666UL,
1666429Svs195195 0x9999999999999999UL,
1676429Svs195195 0x00000000FFFFFFFFUL,
1686429Svs195195 0xFFFFFFFF00000000UL,
1696429Svs195195 0x0000FFFF0000FFFFUL,
1706429Svs195195 0xFFFF0000FFFF0000UL
1716429Svs195195 };
1726429Svs195195
1736429Svs195195 #define PAT_DP_NUM (sizeof (pat_dp)/sizeof (*pat_dp))
1746429Svs195195
1756429Svs195195 struct value {
1766429Svs195195 unsigned long floatsingle;
1776429Svs195195 uint64_t floatdouble;
1786429Svs195195 uint64_t floatquad_u;
1796429Svs195195 uint64_t floatquad_l;
1806429Svs195195 };
1816429Svs195195
1826429Svs195195 #define N_VALS (sizeof (val)/sizeof (*val))
1836429Svs195195
1846429Svs195195 static struct value val[] = {
1856429Svs195195 0, 0, 0, 0,
1866429Svs195195 0x3F800000, 0x3FF0000000000000, 0x3FFF000000000000, 0,
1876429Svs195195 0x40000000, 0x4000000000000000, 0x4000000000000000, 0,
1886429Svs195195 0x40400000, 0x4008000000000000, 0x4000800000000000, 0,
1896429Svs195195 0x40800000, 0x4010000000000000, 0x4001000000000000, 0,
1906429Svs195195 0x40A00000, 0x4014000000000000, 0x4001400000000000, 0,
1916429Svs195195 0x40C00000, 0x4018000000000000, 0x4001800000000000, 0,
1926429Svs195195 0x40E00000, 0x401C000000000000, 0x4001C00000000000, 0,
1936429Svs195195 0x41000000, 0x4020000000000000, 0x4002000000000000, 0,
1946429Svs195195 0x41100000, 0x4022000000000000, 0x4002200000000000, 0,
1956429Svs195195 0x41200000, 0x4024000000000000, 0x4002400000000000, 0,
1966429Svs195195 0x41300000, 0x4026000000000000, 0x4002600000000000, 0,
1976429Svs195195 0x41400000, 0x4028000000000000, 0x4002800000000000, 0,
1986429Svs195195 0x41500000, 0x402A000000000000, 0x4002A00000000000, 0,
1996429Svs195195 0x41600000, 0x402C000000000000, 0x4002C00000000000, 0,
2006429Svs195195 0x41700000, 0x402E000000000000, 0x4002E00000000000, 0,
2016429Svs195195 0x41800000, 0x4030000000000000, 0x4003000000000000, 0,
2026429Svs195195 0x41880000, 0x4031000000000000, 0x4003100000000000, 0,
2036429Svs195195 0x41900000, 0x4032000000000000, 0x4003200000000000, 0,
2046429Svs195195 0x41980000, 0x4033000000000000, 0x4003300000000000, 0,
2056429Svs195195 0x41a00000, 0x4034000000000000, 0x4003400000000000, 0,
2066429Svs195195 0x41a80000, 0x4035000000000000, 0x4003500000000000, 0,
2076429Svs195195 0x41b00000, 0x4036000000000000, 0x4003600000000000, 0,
2086429Svs195195 0x41b80000, 0x4037000000000000, 0x4003700000000000, 0,
2096429Svs195195 0x41c00000, 0x4038000000000000, 0x4003800000000000, 0,
2106429Svs195195 0x41c80000, 0x4039000000000000, 0x4003900000000000, 0,
2116429Svs195195 0x41d00000, 0x403a000000000000, 0x4003a00000000000, 0,
2126429Svs195195 0x41d80000, 0x403b000000000000, 0x4003b00000000000, 0,
2136429Svs195195 0x41e00000, 0x403c000000000000, 0x4003c00000000000, 0,
2146429Svs195195 0x41e80000, 0x403d000000000000, 0x4003d00000000000, 0,
2156429Svs195195 0x41f00000, 0x403e000000000000, 0x4003e00000000000, 0,
2166429Svs195195 0x41f80000, 0x403f000000000000, 0x4003f00000000000, 0,
2176429Svs195195 0x42000000, 0x4040000000000000, 0x4004000000000000, 0,
2186429Svs195195 0x42040000, 0x4040800000000000, 0x4004080000000000, 0,
2196429Svs195195 0x42080000, 0x4041000000000000, 0x4004100000000000, 0,
2206429Svs195195 0x420c0000, 0x4041800000000000, 0x4004180000000000, 0,
2216429Svs195195 0x42100000, 0x4042000000000000, 0x4004200000000000, 0,
2226429Svs195195 0x42140000, 0x4042800000000000, 0x4004280000000000, 0,
2236429Svs195195 0x42180000, 0x4043000000000000, 0x4004300000000000, 0,
2246429Svs195195 0x421c0000, 0x4043800000000000, 0x4004380000000000, 0,
2256429Svs195195 0x42200000, 0x4044000000000000, 0x4004400000000000, 0,
2266429Svs195195 0x42240000, 0x4044800000000000, 0x4004480000000000, 0,
2276429Svs195195 0x42280000, 0x4045000000000000, 0x4004500000000000, 0,
2286429Svs195195 0x422c0000, 0x4045800000000000, 0x4004580000000000, 0,
2296429Svs195195 0x42300000, 0x4046000000000000, 0x4004600000000000, 0,
2306429Svs195195 0x42340000, 0x4046800000000000, 0x4004680000000000, 0,
2316429Svs195195 0x42380000, 0x4047000000000000, 0x4004700000000000, 0,
2326429Svs195195 0x423c0000, 0x4047800000000000, 0x4004780000000000, 0,
2336429Svs195195 0x42400000, 0x4048000000000000, 0x4004800000000000, 0,
2346429Svs195195 0x42440000, 0x4048800000000000, 0x4004880000000000, 0,
2356429Svs195195 0x42480000, 0x4049000000000000, 0x4004900000000000, 0,
2366429Svs195195 0x424c0000, 0x4049800000000000, 0x4004980000000000, 0,
2376429Svs195195 0x42500000, 0x404a000000000000, 0x4004a00000000000, 0,
2386429Svs195195 0x42540000, 0x404a800000000000, 0x4004a80000000000, 0,
2396429Svs195195 0x42580000, 0x404b000000000000, 0x4004b00000000000, 0,
2406429Svs195195 0x425c0000, 0x404b800000000000, 0x4004b80000000000, 0,
2416429Svs195195 0x42600000, 0x404c000000000000, 0x4004c00000000000, 0,
2426429Svs195195 0x42640000, 0x404c800000000000, 0x4004c80000000000, 0,
2436429Svs195195 0x42680000, 0x404d000000000000, 0x4004d00000000000, 0,
2446429Svs195195 0x426c0000, 0x404d800000000000, 0x4004d80000000000, 0,
2456429Svs195195 0x42700000, 0x404e000000000000, 0x4004e00000000000, 0,
2466429Svs195195 0x42740000, 0x404e800000000000, 0x4004e80000000000, 0,
2476429Svs195195 0x42780000, 0x404f000000000000, 0x4004f00000000000, 0,
2486429Svs195195 0x427c0000, 0x404f800000000000, 0x4004f80000000000, 0,
2496429Svs195195 0x42800000, 0x4050000000000000, 0x4005000000000000, 0,
2506429Svs195195 0x42820000, 0x4050400000000000, 0x4005040000000000, 0,
2516429Svs195195 0x42840000, 0x4050800000000000, 0x4005080000000000, 0,
2526429Svs195195 0x42860000, 0x4050c00000000000, 0x40050c0000000000, 0,
2536429Svs195195 0x42880000, 0x4051000000000000, 0x4005100000000000, 0,
2546429Svs195195 0x428a0000, 0x4051400000000000, 0x4005140000000000, 0,
2556429Svs195195 0x428c0000, 0x4051800000000000, 0x4005180000000000, 0,
2566429Svs195195 0x428e0000, 0x4051c00000000000, 0x40051c0000000000, 0,
2576429Svs195195 0x42900000, 0x4052000000000000, 0x4005200000000000, 0,
2586429Svs195195 0x42920000, 0x4052400000000000, 0x4005240000000000, 0,
2596429Svs195195 0x42940000, 0x4052800000000000, 0x4005280000000000, 0,
2606429Svs195195 0x42960000, 0x4052c00000000000, 0x40052c0000000000, 0,
2616429Svs195195 0x42980000, 0x4053000000000000, 0x4005300000000000, 0,
2626429Svs195195 0x429a0000, 0x4053400000000000, 0x4005340000000000, 0,
2636429Svs195195 0x429c0000, 0x4053800000000000, 0x4005380000000000, 0,
2646429Svs195195 0x429e0000, 0x4053c00000000000, 0x40053c0000000000, 0,
2656429Svs195195 0x42a00000, 0x4054000000000000, 0x4005400000000000, 0,
2666429Svs195195 0x42a20000, 0x4054400000000000, 0x4005440000000000, 0,
2676429Svs195195 0x42a40000, 0x4054800000000000, 0x4005480000000000, 0,
2686429Svs195195 0x42a60000, 0x4054c00000000000, 0x40054c0000000000, 0,
2696429Svs195195 0x42a80000, 0x4055000000000000, 0x4005500000000000, 0,
2706429Svs195195 0x42aa0000, 0x4055400000000000, 0x4005540000000000, 0,
2716429Svs195195 0x42ac0000, 0x4055800000000000, 0x4005580000000000, 0,
2726429Svs195195 0x42ae0000, 0x4055c00000000000, 0x40055c0000000000, 0,
2736429Svs195195 0x42b00000, 0x4056000000000000, 0x4005600000000000, 0,
2746429Svs195195 0x42b20000, 0x4056400000000000, 0x4005640000000000, 0,
2756429Svs195195 0x42b40000, 0x4056800000000000, 0x4005680000000000, 0,
2766429Svs195195 0x42b60000, 0x4056c00000000000, 0x40056c0000000000, 0,
2776429Svs195195 0x42b80000, 0x4057000000000000, 0x4005700000000000, 0,
2786429Svs195195 0x42ba0000, 0x4057400000000000, 0x4005740000000000, 0,
2796429Svs195195 0x42bc0000, 0x4057800000000000, 0x4005780000000000, 0,
2806429Svs195195 0x42be0000, 0x4057c00000000000, 0x40057c0000000000, 0,
2816429Svs195195 0x42c00000, 0x4058000000000000, 0x4005800000000000, 0,
2826429Svs195195 0x42c20000, 0x4058400000000000, 0x4005840000000000, 0,
2836429Svs195195 0x42c40000, 0x4058800000000000, 0x4005880000000000, 0,
2846429Svs195195 0x42c60000, 0x4058c00000000000, 0x40058c0000000000, 0,
2856429Svs195195 0x42c80000, 0x4059000000000000, 0x4005900000000000, 0,
2866429Svs195195 0x42ca0000, 0x4059400000000000, 0x4005940000000000, 0,
2876429Svs195195 0x42cc0000, 0x4059800000000000, 0x4005980000000000, 0,
2886429Svs195195 0x42ce0000, 0x4059c00000000000, 0x40059c0000000000, 0,
2896429Svs195195 0x42d00000, 0x405a000000000000, 0x4005a00000000000, 0,
2906429Svs195195 0x42d20000, 0x405a400000000000, 0x4005a40000000000, 0,
2916429Svs195195 0x42d40000, 0x405a800000000000, 0x4005a80000000000, 0,
2926429Svs195195 0x42d60000, 0x405ac00000000000, 0x4005ac0000000000, 0,
2936429Svs195195 0x42d80000, 0x405b000000000000, 0x4005b00000000000, 0,
2946429Svs195195 0x42da0000, 0x405b400000000000, 0x4005b40000000000, 0,
2956429Svs195195 0x42dc0000, 0x405b800000000000, 0x4005b80000000000, 0,
2966429Svs195195 0x42de0000, 0x405bc00000000000, 0x4005bc0000000000, 0,
2976429Svs195195 0x42e00000, 0x405c000000000000, 0x4005c00000000000, 0,
2986429Svs195195 0x42e20000, 0x405c400000000000, 0x4005c40000000000, 0,
2996429Svs195195 0x42e40000, 0x405c800000000000, 0x4005c80000000000, 0,
3006429Svs195195 0x42e60000, 0x405cc00000000000, 0x4005cc0000000000, 0,
3016429Svs195195 0x42e80000, 0x405d000000000000, 0x4005d00000000000, 0,
3026429Svs195195 0x42ea0000, 0x405d400000000000, 0x4005d40000000000, 0,
3036429Svs195195 0x42ec0000, 0x405d800000000000, 0x4005d80000000000, 0,
3046429Svs195195 0x42ee0000, 0x405dc00000000000, 0x4005dc0000000000, 0,
3056429Svs195195 0x42f00000, 0x405e000000000000, 0x4005e00000000000, 0,
3066429Svs195195 0x42f20000, 0x405e400000000000, 0x4005e40000000000, 0,
3076429Svs195195 0x42f40000, 0x405e800000000000, 0x4005e80000000000, 0,
3086429Svs195195 0x42f60000, 0x405ec00000000000, 0x4005ec0000000000, 0,
3096429Svs195195 0x42f80000, 0x405f000000000000, 0x4005f00000000000, 0,
3106429Svs195195 0x42fa0000, 0x405f400000000000, 0x4005f40000000000, 0,
3116429Svs195195 0x42fc0000, 0x405f800000000000, 0x4005f80000000000, 0,
3126429Svs195195 0x42fe0000, 0x405fc00000000000, 0x4005fc0000000000, 0,
3136429Svs195195 0x43000000, 0x4060000000000000, 0x4006000000000000, 0,
3146429Svs195195 0x43010000, 0x4060200000000000, 0x4006020000000000, 0,
3156429Svs195195 0x43020000, 0x4060400000000000, 0x4006040000000000, 0,
3166429Svs195195 0x43030000, 0x4060600000000000, 0x4006060000000000, 0,
3176429Svs195195 0x43040000, 0x4060800000000000, 0x4006080000000000, 0,
3186429Svs195195 0x43050000, 0x4060a00000000000, 0x40060a0000000000, 0,
3196429Svs195195 0x43060000, 0x4060c00000000000, 0x40060c0000000000, 0,
3206429Svs195195 0x43070000, 0x4060e00000000000, 0x40060e0000000000, 0,
3216429Svs195195 0x43080000, 0x4061000000000000, 0x4006100000000000, 0,
3226429Svs195195 0x43090000, 0x4061200000000000, 0x4006120000000000, 0,
3236429Svs195195 0x430a0000, 0x4061400000000000, 0x4006140000000000, 0,
3246429Svs195195 0x430b0000, 0x4061600000000000, 0x4006160000000000, 0,
3256429Svs195195 0x430c0000, 0x4061800000000000, 0x4006180000000000, 0,
3266429Svs195195 0x430d0000, 0x4061a00000000000, 0x40061a0000000000, 0,
3276429Svs195195 0x430e0000, 0x4061c00000000000, 0x40061c0000000000, 0,
3286429Svs195195 0x430f0000, 0x4061e00000000000, 0x40061e0000000000, 0,
3296429Svs195195 0x43100000, 0x4062000000000000, 0x4006200000000000, 0,
3306429Svs195195 0x43110000, 0x4062200000000000, 0x4006220000000000, 0,
3316429Svs195195 0x43120000, 0x4062400000000000, 0x4006240000000000, 0,
3326429Svs195195 0x43130000, 0x4062600000000000, 0x4006260000000000, 0,
3336429Svs195195 0x43140000, 0x4062800000000000, 0x4006280000000000, 0,
3346429Svs195195 0x43150000, 0x4062a00000000000, 0x40062a0000000000, 0,
3356429Svs195195 0x43160000, 0x4062c00000000000, 0x40062c0000000000, 0,
3366429Svs195195 0x43170000, 0x4062e00000000000, 0x40062e0000000000, 0,
3376429Svs195195 0x43180000, 0x4063000000000000, 0x4006300000000000, 0,
3386429Svs195195 0x43190000, 0x4063200000000000, 0x4006320000000000, 0,
3396429Svs195195 0x431a0000, 0x4063400000000000, 0x4006340000000000, 0,
3406429Svs195195 0x431b0000, 0x4063600000000000, 0x4006360000000000, 0,
3416429Svs195195 0x431c0000, 0x4063800000000000, 0x4006380000000000, 0,
3426429Svs195195 0x431d0000, 0x4063a00000000000, 0x40063a0000000000, 0,
3436429Svs195195 0x431e0000, 0x4063c00000000000, 0x40063c0000000000, 0,
3446429Svs195195 0x431f0000, 0x4063e00000000000, 0x40063e0000000000, 0,
3456429Svs195195 0x43200000, 0x4064000000000000, 0x4006400000000000, 0,
3466429Svs195195 0x43210000, 0x4064200000000000, 0x4006420000000000, 0,
3476429Svs195195 0x43220000, 0x4064400000000000, 0x4006440000000000, 0,
3486429Svs195195 0x43230000, 0x4064600000000000, 0x4006460000000000, 0,
3496429Svs195195 0x43240000, 0x4064800000000000, 0x4006480000000000, 0,
3506429Svs195195 0x43250000, 0x4064a00000000000, 0x40064a0000000000, 0,
3516429Svs195195 0x43260000, 0x4064c00000000000, 0x40064c0000000000, 0,
3526429Svs195195 0x43270000, 0x4064e00000000000, 0x40064e0000000000, 0,
3536429Svs195195 0x43280000, 0x4065000000000000, 0x4006500000000000, 0,
3546429Svs195195 0x43290000, 0x4065200000000000, 0x4006520000000000, 0,
3556429Svs195195 0x432a0000, 0x4065400000000000, 0x4006540000000000, 0,
3566429Svs195195 0x432b0000, 0x4065600000000000, 0x4006560000000000, 0,
3576429Svs195195 0x432c0000, 0x4065800000000000, 0x4006580000000000, 0,
3586429Svs195195 0x432d0000, 0x4065a00000000000, 0x40065a0000000000, 0,
3596429Svs195195 0x432e0000, 0x4065c00000000000, 0x40065c0000000000, 0,
3606429Svs195195 0x432f0000, 0x4065e00000000000, 0x40065e0000000000, 0,
3616429Svs195195 0x43300000, 0x4066000000000000, 0x4006600000000000, 0,
3626429Svs195195 0x43310000, 0x4066200000000000, 0x4006620000000000, 0,
3636429Svs195195 0x43320000, 0x4066400000000000, 0x4006640000000000, 0,
3646429Svs195195 0x43330000, 0x4066600000000000, 0x4006660000000000, 0,
3656429Svs195195 0x43340000, 0x4066800000000000, 0x4006680000000000, 0,
3666429Svs195195 0x43350000, 0x4066a00000000000, 0x40066a0000000000, 0,
3676429Svs195195 0x43360000, 0x4066c00000000000, 0x40066c0000000000, 0,
3686429Svs195195 0x43370000, 0x4066e00000000000, 0x40066e0000000000, 0,
3696429Svs195195 0x43380000, 0x4067000000000000, 0x4006700000000000, 0,
3706429Svs195195 0x43390000, 0x4067200000000000, 0x4006720000000000, 0,
3716429Svs195195 0x433a0000, 0x4067400000000000, 0x4006740000000000, 0,
3726429Svs195195 0x433b0000, 0x4067600000000000, 0x4006760000000000, 0,
3736429Svs195195 0x433c0000, 0x4067800000000000, 0x4006780000000000, 0,
3746429Svs195195 0x433d0000, 0x4067a00000000000, 0x40067a0000000000, 0,
3756429Svs195195 0x433e0000, 0x4067c00000000000, 0x40067c0000000000, 0,
3766429Svs195195 0x433f0000, 0x4067e00000000000, 0x40067e0000000000, 0,
3776429Svs195195 0x43400000, 0x4068000000000000, 0x4006800000000000, 0,
3786429Svs195195 0x43410000, 0x4068200000000000, 0x4006820000000000, 0,
3796429Svs195195 0x43420000, 0x4068400000000000, 0x4006840000000000, 0,
3806429Svs195195 0x43430000, 0x4068600000000000, 0x4006860000000000, 0,
3816429Svs195195 0x43440000, 0x4068800000000000, 0x4006880000000000, 0,
3826429Svs195195 0x43450000, 0x4068a00000000000, 0x40068a0000000000, 0,
3836429Svs195195 0x43460000, 0x4068c00000000000, 0x40068c0000000000, 0,
3846429Svs195195 0x43470000, 0x4068e00000000000, 0x40068e0000000000, 0,
3856429Svs195195 0x43480000, 0x4069000000000000, 0x4006900000000000, 0,
3866429Svs195195 0x43490000, 0x4069200000000000, 0x4006920000000000, 0,
3876429Svs195195 0x434a0000, 0x4069400000000000, 0x4006940000000000, 0,
3886429Svs195195 0x434b0000, 0x4069600000000000, 0x4006960000000000, 0,
3896429Svs195195 0x434c0000, 0x4069800000000000, 0x4006980000000000, 0,
3906429Svs195195 0x434d0000, 0x4069a00000000000, 0x40069a0000000000, 0,
3916429Svs195195 0x434e0000, 0x4069c00000000000, 0x40069c0000000000, 0,
3926429Svs195195 0x434f0000, 0x4069e00000000000, 0x40069e0000000000, 0,
3936429Svs195195 0x43500000, 0x406a000000000000, 0x4006a00000000000, 0,
3946429Svs195195 0x43510000, 0x406a200000000000, 0x4006a20000000000, 0,
3956429Svs195195 0x43520000, 0x406a400000000000, 0x4006a40000000000, 0,
3966429Svs195195 0x43530000, 0x406a600000000000, 0x4006a60000000000, 0,
3976429Svs195195 0x43540000, 0x406a800000000000, 0x4006a80000000000, 0,
3986429Svs195195 0x43550000, 0x406aa00000000000, 0x4006aa0000000000, 0,
3996429Svs195195 0x43560000, 0x406ac00000000000, 0x4006ac0000000000, 0,
4006429Svs195195 0x43570000, 0x406ae00000000000, 0x4006ae0000000000, 0,
4016429Svs195195 0x43580000, 0x406b000000000000, 0x4006b00000000000, 0,
4026429Svs195195 0x43590000, 0x406b200000000000, 0x4006b20000000000, 0,
4036429Svs195195 0x435a0000, 0x406b400000000000, 0x4006b40000000000, 0,
4046429Svs195195 0x435b0000, 0x406b600000000000, 0x4006b60000000000, 0,
4056429Svs195195 0x435c0000, 0x406b800000000000, 0x4006b80000000000, 0,
4066429Svs195195 0x435d0000, 0x406ba00000000000, 0x4006ba0000000000, 0,
4076429Svs195195 0x435e0000, 0x406bc00000000000, 0x4006bc0000000000, 0,
4086429Svs195195 0x435f0000, 0x406be00000000000, 0x4006be0000000000, 0,
4096429Svs195195 0x43600000, 0x406c000000000000, 0x4006c00000000000, 0,
4106429Svs195195 0x43610000, 0x406c200000000000, 0x4006c20000000000, 0,
4116429Svs195195 0x43620000, 0x406c400000000000, 0x4006c40000000000, 0,
4126429Svs195195 0x43630000, 0x406c600000000000, 0x4006c60000000000, 0,
4136429Svs195195 0x43640000, 0x406c800000000000, 0x4006c80000000000, 0,
4146429Svs195195 0x43650000, 0x406ca00000000000, 0x4006ca0000000000, 0,
4156429Svs195195 0x43660000, 0x406cc00000000000, 0x4006cc0000000000, 0,
4166429Svs195195 0x43670000, 0x406ce00000000000, 0x4006ce0000000000, 0,
4176429Svs195195 0x43680000, 0x406d000000000000, 0x4006d00000000000, 0,
4186429Svs195195 0x43690000, 0x406d200000000000, 0x4006d20000000000, 0,
4196429Svs195195 0x436a0000, 0x406d400000000000, 0x4006d40000000000, 0,
4206429Svs195195 0x436b0000, 0x406d600000000000, 0x4006d60000000000, 0,
4216429Svs195195 0x436c0000, 0x406d800000000000, 0x4006d80000000000, 0,
4226429Svs195195 0x436d0000, 0x406da00000000000, 0x4006da0000000000, 0,
4236429Svs195195 0x436e0000, 0x406dc00000000000, 0x4006dc0000000000, 0,
4246429Svs195195 0x436f0000, 0x406de00000000000, 0x4006de0000000000, 0,
4256429Svs195195 0x43700000, 0x406e000000000000, 0x4006e00000000000, 0,
4266429Svs195195 0x43710000, 0x406e200000000000, 0x4006e20000000000, 0,
4276429Svs195195 0x43720000, 0x406e400000000000, 0x4006e40000000000, 0,
4286429Svs195195 0x43730000, 0x406e600000000000, 0x4006e60000000000, 0,
4296429Svs195195 0x43740000, 0x406e800000000000, 0x4006e80000000000, 0,
4306429Svs195195 0x43750000, 0x406ea00000000000, 0x4006ea0000000000, 0,
4316429Svs195195 0x43760000, 0x406ec00000000000, 0x4006ec0000000000, 0,
4326429Svs195195 0x43770000, 0x406ee00000000000, 0x4006ee0000000000, 0,
4336429Svs195195 0x43780000, 0x406f000000000000, 0x4006f00000000000, 0,
4346429Svs195195 0x43790000, 0x406f200000000000, 0x4006f20000000000, 0,
4356429Svs195195 0x437a0000, 0x406f400000000000, 0x4006f40000000000, 0,
4366429Svs195195 0x437b0000, 0x406f600000000000, 0x4006f60000000000, 0,
4376429Svs195195 0x437c0000, 0x406f800000000000, 0x4006f80000000000, 0,
4386429Svs195195 0x437d0000, 0x406fa00000000000, 0x4006fa0000000000, 0,
4396429Svs195195 0x437e0000, 0x406fc00000000000, 0x4006fc0000000000, 0,
4406429Svs195195 0x437f0000, 0x406fe00000000000, 0x4006fe0000000000, 0,
4416429Svs195195 };
4426429Svs195195
4436429Svs195195 /* -ve of the values in val[] above */
4446429Svs195195 static unsigned long neg_val_sp[N_VALS];
4456429Svs195195 static uint64_t neg_val_dp[N_VALS];
4466429Svs195195
4476429Svs195195 /*
4486429Svs195195 * data_path_sp(struct fps_test_ereport *report)checks the data path
4496429Svs195195 * between registers and memory, between memory and an floating
4506429Svs195195 * registers, and between floating registers and the weitek chips.
4516429Svs195195 * All the bits are covered including the sign bit. If an error is
4526429Svs195195 * found, all relevant data is stored in report.
4536429Svs195195 */
4546429Svs195195 #ifndef i86pc
4556429Svs195195 static int
data_path_sp(struct fps_test_ereport * report)4566429Svs195195 data_path_sp(struct fps_test_ereport *report)
4576429Svs195195 {
4586429Svs195195 int i;
4596429Svs195195 int j;
4606429Svs195195 int k;
4616429Svs195195 uint64_t expected;
4626429Svs195195 uint64_t observed;
4636429Svs195195 unsigned long prev_fsr;
4646429Svs195195 unsigned long result;
4656429Svs195195 unsigned long value;
4666429Svs195195
4676429Svs195195 prev_fsr = get_fsr();
4686429Svs195195 init_regs(0);
4696429Svs195195
4706429Svs195195 for (i = 0; i < 2; i++) {
4716429Svs195195 for (j = 1; j < 255; j++) {
4726429Svs195195 for (k = 0; k < 23; k++) {
4736429Svs195195 value = (i << 31) | (j << 23) | (1 << k);
4746429Svs195195
4756429Svs195195 if (result = datap_add(value)) {
4766429Svs195195 observed = (uint64_t)result;
4776429Svs195195 expected = (uint64_t)0;
4786429Svs195195 setup_fps_test_struct(
4796429Svs195195 NO_EREPORT_INFO,
4806429Svs195195 report, 6217, &observed,
4816429Svs195195 &expected, 1, 1);
4826429Svs195195
4836429Svs195195 return (-1);
4846429Svs195195 }
4856429Svs195195 if (result = datap_mult(value)) {
4866429Svs195195 observed = (uint64_t)result;
4876429Svs195195 expected = (uint64_t)0;
4886429Svs195195 setup_fps_test_struct(
4896429Svs195195 NO_EREPORT_INFO,
4906429Svs195195 report, 6218, &observed,
4916429Svs195195 &expected, 1, 1);
4926429Svs195195
4936429Svs195195 return (-1);
4946429Svs195195 }
4956429Svs195195 }
4966429Svs195195 }
4976429Svs195195 }
4986429Svs195195
4996429Svs195195 set_fsr(prev_fsr);
5006429Svs195195
5016429Svs195195 return (0);
5026429Svs195195 }
5036429Svs195195
5046429Svs195195 /*
5056429Svs195195 * data_path_dp(struct fps_test_ereport *report) performs the
5066429Svs195195 * same function as data_path_sp except it's double precision
5076429Svs195195 * instead of single. If an error is found, all relevant data
5086429Svs195195 * is stored in report.
5096429Svs195195 */
5106429Svs195195 static int
data_path_dp(struct fps_test_ereport * report)5116429Svs195195 data_path_dp(struct fps_test_ereport *report)
5126429Svs195195 {
5136429Svs195195 int i;
5146429Svs195195 int j;
5156429Svs195195 int k;
5166429Svs195195 int l;
5176429Svs195195 uint64_t observed[2];
5186429Svs195195 uint64_t expected[2];
5196429Svs195195 unsigned long prev_fsr;
5206429Svs195195 unsigned long result_lsw = 0;
5216429Svs195195 unsigned long result_msw = 0;
5226429Svs195195 unsigned long value_lsw;
5236429Svs195195 unsigned long value_msw;
5246429Svs195195
5256429Svs195195 prev_fsr = get_fsr();
5266429Svs195195 init_regs(0);
5276429Svs195195
5286429Svs195195 for (i = 0; i < 2; i++) {
5296429Svs195195 for (j = 1; j < 2047; j++) {
5306429Svs195195 for (k = 0; k < 52; k++) {
5316429Svs195195 value_lsw = (1 << k);
5326429Svs195195
5336429Svs195195 if (k > 32)
5346429Svs195195 l = k - 32;
5356429Svs195195 else
5366429Svs195195 l = 32;
5376429Svs195195
5386429Svs195195 value_msw = (i << 31) | (j << 20) | (1 << l);
5396429Svs195195
5406429Svs195195 if (datap_add_dp(value_msw, value_lsw)) {
5416429Svs195195 observed[0] = (uint64_t)result_msw;
5426429Svs195195 observed[1] = (uint64_t)result_lsw;
5436429Svs195195 expected[0] = (uint64_t)value_msw;
5446429Svs195195 expected[1] = (uint64_t)value_lsw;
5456429Svs195195 setup_fps_test_struct(
5466429Svs195195 NO_EREPORT_INFO, report,
5476429Svs195195 6219, observed, expected,
5486429Svs195195 2, 2);
5496429Svs195195
5506429Svs195195 return (-1);
5516429Svs195195 }
5526429Svs195195
5536429Svs195195 if (datap_mult_dp(value_msw, value_lsw)) {
5546429Svs195195 observed[0] = (uint64_t)result_msw;
5556429Svs195195 observed[1] = (uint64_t)result_lsw;
5566429Svs195195 expected[0] = (uint64_t)value_msw;
5576429Svs195195 expected[1] = (uint64_t)value_lsw;
5586429Svs195195 setup_fps_test_struct(
5596429Svs195195 NO_EREPORT_INFO, report,
5606429Svs195195 6220, observed, expected,
5616429Svs195195 2, 2);
5626429Svs195195
5636429Svs195195 return (-1);
5646429Svs195195 }
5656429Svs195195 }
5666429Svs195195 }
5676429Svs195195 }
5686429Svs195195
5696429Svs195195 set_fsr(prev_fsr);
5706429Svs195195
5716429Svs195195 return (0);
5726429Svs195195 }
5736429Svs195195
5746429Svs195195 /*
5756429Svs195195 * timing_test(struct fps_test_ereport *report) does 10 add
5766429Svs195195 * operations continuously and 10 multiply operations
5776429Svs195195 * continusously. If an error is found, relevant data is
5786429Svs195195 * stored in report.
5796429Svs195195 */
5806429Svs195195 static int
timing_test(struct fps_test_ereport * report)5816429Svs195195 timing_test(struct fps_test_ereport *report)
5826429Svs195195 {
5836429Svs195195 int i;
5846429Svs195195 uint64_t expected;
5856429Svs195195 uint64_t observed;
5866429Svs195195 unsigned long result;
5876429Svs195195 unsigned long prev_fsr;
5886429Svs195195
5896429Svs195195 prev_fsr = get_fsr();
5906429Svs195195
5916429Svs195195 for (i = 0; i < 1000; i++) {
5926429Svs195195 init_regs(0);
5936429Svs195195 if (result = timing_add_sp()) {
5946429Svs195195 observed = (uint64_t)result;
5956429Svs195195 expected = (uint64_t)0;
5966429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
5976429Svs195195 report, 6221, &observed, &expected, 1, 1);
5986429Svs195195
5996429Svs195195 return (-1);
6006429Svs195195 }
6016429Svs195195
6026429Svs195195 init_regs(0);
6036429Svs195195
6046429Svs195195 if (result = timing_mult_sp()) {
6056429Svs195195 observed = (uint64_t)result;
6066429Svs195195 expected = (uint64_t)0;
6076429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
6086429Svs195195 report, 6222, &observed, &expected, 1, 1);
6096429Svs195195
6106429Svs195195 return (-1);
6116429Svs195195 }
6126429Svs195195
6136429Svs195195 init_regs(0);
6146429Svs195195
6156429Svs195195 if (result = timing_add_dp()) {
6166429Svs195195 observed = (uint64_t)result;
6176429Svs195195 expected = (uint64_t)0;
6186429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
6196429Svs195195 report, 6223, &observed, &expected, 1, 1);
6206429Svs195195
6216429Svs195195 return (-1);
6226429Svs195195 }
6236429Svs195195
6246429Svs195195 init_regs(0);
6256429Svs195195
6266429Svs195195 if (result = timing_mult_dp()) {
6276429Svs195195 observed = (uint64_t)result;
6286429Svs195195 expected = (uint64_t)0;
6296429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
6306429Svs195195 report, 6224, &observed, &expected, 1, 1);
6316429Svs195195
6326429Svs195195 return (-1);
6336429Svs195195 }
6346429Svs195195 }
6356429Svs195195
6366429Svs195195 set_fsr(prev_fsr);
6376429Svs195195
6386429Svs195195 return (0);
6396429Svs195195 }
6406429Svs195195
6416429Svs195195 /*
6426429Svs195195 * chain_sp_test(struct fps_test_ereport *report)
6436429Svs195195 * performs a series of single precision chaining
6446429Svs195195 * tests. If an error is found, relevant data is
6456429Svs195195 * stored in report.
6466429Svs195195 */
6476429Svs195195 static int
chain_sp_test(struct fps_test_ereport * report)6486429Svs195195 chain_sp_test(struct fps_test_ereport *report)
6496429Svs195195 {
6506429Svs195195 char err_data[MAX_INFO_SIZE];
6516429Svs195195 int i;
6526429Svs195195 uint64_t result;
6536429Svs195195 uint64_t expected;
6546429Svs195195 uint64_t observed;
6556429Svs195195 unsigned long prev_fsr;
6566429Svs195195
6576429Svs195195 prev_fsr = get_fsr();
6586429Svs195195 init_regs(0);
6596429Svs195195 set_fsr(0);
6606429Svs195195
6616429Svs195195 for (i = 1; i < 60; i++) {
6626429Svs195195 if ((result = chain_sp(i)) != (unsigned long) i) {
6636429Svs195195 observed = (uint64_t)result;
6646429Svs195195 expected = (uint64_t)i;
665*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
6666429Svs195195 "\nExpected: %d\nObserved: %d", i, result);
6676429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
6686429Svs195195 report, 6225, &observed, &expected, 1, 1,
6696429Svs195195 err_data);
6706429Svs195195
6716429Svs195195 return (-1);
6726429Svs195195 }
6736429Svs195195 }
6746429Svs195195
6756429Svs195195 set_fsr(prev_fsr);
6766429Svs195195
6776429Svs195195 return (0);
6786429Svs195195 }
6796429Svs195195
6806429Svs195195 /*
6816429Svs195195 * chain_dp_test(struct fps_test_ereport *report)
6826429Svs195195 * performs a series of double precision chaining
6836429Svs195195 * tests. If an error is found, relevant data is
6846429Svs195195 * stored in report.
6856429Svs195195 */
6866429Svs195195 static int
chain_dp_test(struct fps_test_ereport * report)6876429Svs195195 chain_dp_test(struct fps_test_ereport *report)
6886429Svs195195 {
6896429Svs195195 char err_data[MAX_INFO_SIZE];
6906429Svs195195 int i;
6916429Svs195195 uint64_t result;
6926429Svs195195 uint64_t expected;
6936429Svs195195 uint64_t observed;
6946429Svs195195 unsigned long prev_fsr;
6956429Svs195195
6966429Svs195195 prev_fsr = get_fsr();
6976429Svs195195 init_regs(0);
6986429Svs195195 set_fsr(0);
6996429Svs195195
7006429Svs195195 for (i = 1; i < 60; i++) {
7016429Svs195195 if ((result = chain_dp(i)) != (unsigned long) i) {
7026429Svs195195 observed = (uint64_t)result;
7036429Svs195195 expected = (uint64_t)i;
704*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
7056429Svs195195 "\nExpected: %d\nObserved: %d", i, result);
7066429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
7076429Svs195195 report, 6226, &observed, &expected, 1, 1,
7086429Svs195195 err_data);
7096429Svs195195
7106429Svs195195 return (-1);
7116429Svs195195 }
7126429Svs195195 }
7136429Svs195195
7146429Svs195195 set_fsr(prev_fsr);
7156429Svs195195
7166429Svs195195 return (0);
7176429Svs195195 }
7186429Svs195195
7196429Svs195195 /*
7206429Svs195195 * integer_to_float_sp(struct fps_test_ereport *report)
7216429Svs195195 * does continuous integer to float, single precision
7226429Svs195195 * conversions. If an error is found, relevant data is stored
7236429Svs195195 * in report.
7246429Svs195195 */
7256429Svs195195 static int
integer_to_float_sp(struct fps_test_ereport * report)7266429Svs195195 integer_to_float_sp(struct fps_test_ereport *report)
7276429Svs195195 {
7286429Svs195195 char err_data[MAX_INFO_SIZE];
7296429Svs195195 int i;
7306429Svs195195 uint64_t expected;
7316429Svs195195 uint64_t observed;
7326429Svs195195 unsigned long prev_fsr;
7336429Svs195195 unsigned long result;
7346429Svs195195
7356429Svs195195 prev_fsr = get_fsr();
7366429Svs195195 init_regs(0);
7376429Svs195195
7386429Svs195195 for (i = 0; i < N_VALS; i++) {
7396429Svs195195 result = int_float_s(i);
7406429Svs195195 if (result != val[i].floatsingle) {
7416429Svs195195 observed = (uint64_t)result;
7426429Svs195195 expected = (uint64_t)val[i].floatsingle;
743*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
7446429Svs195195 "Val Entry[%d]\nExpected: %d"
7456429Svs195195 "\nObserved: %d", i, val[i].floatsingle,
7466429Svs195195 result);
7476429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
7486429Svs195195 report, 6227, &observed, &expected, 1, 1,
7496429Svs195195 err_data);
7506429Svs195195
7516429Svs195195 return (-1);
7526429Svs195195 }
7536429Svs195195 }
7546429Svs195195
7556429Svs195195 set_fsr(prev_fsr);
7566429Svs195195
7576429Svs195195 return (0);
7586429Svs195195 }
7596429Svs195195
7606429Svs195195 /*
7616429Svs195195 * integer_to_float_dp(struct fps_test_ereport *report)
7626429Svs195195 * does continuous integer to float, double precision
7636429Svs195195 * conversions. If an error is found, relevant data is stored
7646429Svs195195 * in report.
7656429Svs195195 */
7666429Svs195195 static int
integer_to_float_dp(struct fps_test_ereport * report)7676429Svs195195 integer_to_float_dp(struct fps_test_ereport *report)
7686429Svs195195 {
7696429Svs195195 char err_data[MAX_INFO_SIZE];
7706429Svs195195 int i;
7716429Svs195195 uint64_t expected;
7726429Svs195195 uint64_t observed;
7736429Svs195195 unsigned long prev_fsr;
7746429Svs195195 unsigned long result;
7756429Svs195195
7766429Svs195195 prev_fsr = get_fsr();
7776429Svs195195 init_regs(0);
7786429Svs195195
7796429Svs195195 for (i = 0; i < N_VALS; i++) {
7806429Svs195195 result = int_float_d(i);
7816429Svs195195 if (result != val[i].floatdouble) {
7826429Svs195195 observed = (uint64_t)result;
7836429Svs195195 expected = (uint64_t)val[i].floatdouble;
784*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
7856429Svs195195 "Val Entry[%d]\nExpected: %lld"
7866429Svs195195 "\nObserved: %lld", i, val[i].floatdouble,
7876429Svs195195 result);
7886429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
7896429Svs195195 report, 6228, &observed, &expected, 1, 1,
7906429Svs195195 err_data);
7916429Svs195195
7926429Svs195195 return (-1);
7936429Svs195195 }
7946429Svs195195 }
7956429Svs195195
7966429Svs195195 set_fsr(prev_fsr);
7976429Svs195195
7986429Svs195195 return (0);
7996429Svs195195 }
8006429Svs195195
8016429Svs195195 /*
8026429Svs195195 * long_to_float_sp(struct fps_test_ereport *report)
8036429Svs195195 * performs continuous, single precision, unsigned
8046429Svs195195 * long to float conversions. If an error is found,
8056429Svs195195 * relevant data is stored in report.
8066429Svs195195 */
8076429Svs195195 static int
long_to_float_sp(struct fps_test_ereport * report)8086429Svs195195 long_to_float_sp(struct fps_test_ereport *report)
8096429Svs195195 {
8106429Svs195195 char err_data[MAX_INFO_SIZE];
8116429Svs195195 uint64_t expected;
8126429Svs195195 uint64_t observed;
8136429Svs195195 unsigned long i;
8146429Svs195195 unsigned long prev_fsr;
8156429Svs195195 unsigned long result;
8166429Svs195195
8176429Svs195195 prev_fsr = get_fsr();
8186429Svs195195 init_regs(0);
8196429Svs195195
8206429Svs195195 for (i = 0; i < N_VALS; i++) {
8216429Svs195195 result = long_float_s(i);
8226429Svs195195 if (result != val[i].floatsingle) {
8236429Svs195195 observed = (uint64_t)result;
8246429Svs195195 expected = (uint64_t)val[i].floatsingle;
825*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
8266429Svs195195 "Val Entry[%d]\nExpected: %d"
8276429Svs195195 "\nObserved: %d", i, val[i].floatdouble,
8286429Svs195195 result);
8296429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
8306429Svs195195 report, 6353, &observed, &expected, 1, 1,
8316429Svs195195 err_data);
8326429Svs195195
8336429Svs195195 return (-1);
8346429Svs195195 }
8356429Svs195195 }
8366429Svs195195
8376429Svs195195 set_fsr(prev_fsr);
8386429Svs195195
8396429Svs195195 return (0);
8406429Svs195195 }
8416429Svs195195
8426429Svs195195 /*
8436429Svs195195 * long_to_float_dp(struct fps_test_ereport *report)
8446429Svs195195 * performs continuous, double precision, unsigned
8456429Svs195195 * long to float conversions. If an error is found,
8466429Svs195195 * relevant data is stored in report.
8476429Svs195195 */
8486429Svs195195 static int
long_to_float_dp(struct fps_test_ereport * report)8496429Svs195195 long_to_float_dp(struct fps_test_ereport *report)
8506429Svs195195 {
8516429Svs195195 char err_data[MAX_INFO_SIZE];
8526429Svs195195 uint64_t expected;
8536429Svs195195 uint64_t observed;
8546429Svs195195 unsigned long i;
8556429Svs195195 unsigned long prev_fsr;
8566429Svs195195 unsigned long res1;
8576429Svs195195
8586429Svs195195 prev_fsr = get_fsr();
8596429Svs195195 init_regs(0);
8606429Svs195195
8616429Svs195195 for (i = 0; i < N_VALS; i++) {
8626429Svs195195 res1 = long_float_d(i);
8636429Svs195195 if (res1 != val[i].floatdouble) {
8646429Svs195195 observed = (uint64_t)res1;
8656429Svs195195 expected = (uint64_t)val[i].floatdouble;
866*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
8676429Svs195195 "Val Entry[%d]\nExpected: %lld"
8686429Svs195195 "\nObserved: %lld", i, val[i].floatdouble,
8696429Svs195195 res1);
8706429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
8716429Svs195195 report, 6354, &observed, &expected, 1, 1,
8726429Svs195195 err_data);
8736429Svs195195
8746429Svs195195 return (-1);
8756429Svs195195 }
8766429Svs195195 }
8776429Svs195195
8786429Svs195195 set_fsr(prev_fsr);
8796429Svs195195
8806429Svs195195 return (0);
8816429Svs195195 }
8826429Svs195195
8836429Svs195195 /*
8846429Svs195195 * float_to_integer_sp(struct fps_test_ereport *report)
8856429Svs195195 * performs continuous, single precision float to
8866429Svs195195 * integer conversions. If an error is found, relevant
8876429Svs195195 * data is stored in report.
8886429Svs195195 */
8896429Svs195195 static int
float_to_integer_sp(struct fps_test_ereport * report)8906429Svs195195 float_to_integer_sp(struct fps_test_ereport *report)
8916429Svs195195 {
8926429Svs195195 char err_data[MAX_INFO_SIZE];
8936429Svs195195 uint64_t i;
8946429Svs195195 unsigned long prev_fsr;
8956429Svs195195 unsigned long result;
8966429Svs195195 uint64_t observed;
8976429Svs195195 uint64_t expected;
8986429Svs195195
8996429Svs195195 prev_fsr = get_fsr();
9006429Svs195195
9016429Svs195195 init_regs(0);
9026429Svs195195
9036429Svs195195 for (i = 0; i < N_VALS; i++) {
9046429Svs195195 result = float_int_s(val[i].floatsingle);
9056429Svs195195 if (result != i) {
9066429Svs195195 observed = (uint64_t)result;
9076429Svs195195 expected = (uint64_t)i;
908*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
9096429Svs195195 "Val Entry[%d]\nExpected: %d"
9106429Svs195195 "\nObserved: %d", i, i,
9116429Svs195195 result);
9126429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
9136429Svs195195 report, 6229, &observed, &expected, 1, 1,
9146429Svs195195 err_data);
9156429Svs195195
9166429Svs195195 return (-1);
9176429Svs195195 }
9186429Svs195195 }
9196429Svs195195
9206429Svs195195 /*
9216429Svs195195 * Value greater than highest representable value in int has to raise
9226429Svs195195 * an invalid exception.
9236429Svs195195 *
9246429Svs195195 * Highest possible value in int (assume uint) is 2^32; Use 2^33 for a
9256429Svs195195 * value greater.
9266429Svs195195 */
9276429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
9286429Svs195195
9296429Svs195195 /* Set trap flag to solicited */
9306429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
9316429Svs195195
932*7186Skk158166 (void) float_int_s(0x50000000);
9336429Svs195195
9346429Svs195195 if (trap_flag) {
9356429Svs195195 observed = (uint64_t)trap_flag;
9366429Svs195195 expected = (uint64_t)0;
937*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
9386429Svs195195 "fstoi max value exception not raised, "
9396429Svs195195 "fp val=%lx, fsr=%lx",
9406429Svs195195 0x50000000, fsr_at_trap);
9416429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
9426429Svs195195 report, 5307, &observed, &expected, 1, 1,
9436429Svs195195 err_data);
9446429Svs195195
9456429Svs195195 return (-1);
9466429Svs195195 }
9476429Svs195195
9486429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
9496429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
9506429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
951*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
9526429Svs195195 "fstoi max value exception not raised, "
9536429Svs195195 "fp val=%lx, fsr=%lx",
9546429Svs195195 0x50000000, fsr_at_trap);
9556429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
9566429Svs195195 report, 5308, &observed, &expected, 1, 1,
9576429Svs195195 err_data);
9586429Svs195195
9596429Svs195195 return (-1);
9606429Svs195195 }
9616429Svs195195
9626429Svs195195 /* NaNs should raise an exception when converted */
9636429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
9646429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
9656429Svs195195
966*7186Skk158166 (void) float_int_s(nan_sp);
9676429Svs195195
9686429Svs195195 if (trap_flag) {
9696429Svs195195 observed = (uint64_t)trap_flag;
9706429Svs195195 expected = (uint64_t)0;
971*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
9726429Svs195195 "fstoi NaN exception not raised, "
9736429Svs195195 "fp val=%lx, fsr=%lx",
9746429Svs195195 nan_sp, fsr_at_trap);
9756429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
9766429Svs195195 report, 5309, &observed, &expected, 1, 1,
9776429Svs195195 err_data);
9786429Svs195195
9796429Svs195195 return (-1);
9806429Svs195195 }
9816429Svs195195
9826429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
9836429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
9846429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
985*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
9866429Svs195195 "fstoi NaN exception not raised, "
9876429Svs195195 "fp val=%lx, fsr=%lx",
9886429Svs195195 nan_sp, fsr_at_trap);
9896429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
9906429Svs195195 report, 5310, &observed, &expected, 1, 1,
9916429Svs195195 err_data);
9926429Svs195195
9936429Svs195195 return (-1);
9946429Svs195195 }
9956429Svs195195
9966429Svs195195 /* + infinity exceptions */
9976429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
9986429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
9996429Svs195195
1000*7186Skk158166 (void) float_int_s(PLUS_INF_SP);
10016429Svs195195
10026429Svs195195 if (trap_flag) {
10036429Svs195195 observed = (uint64_t)trap_flag;
10046429Svs195195 expected = (uint64_t)0;
1005*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
10066429Svs195195 "fstoi +infinity exception not raised, "
10076429Svs195195 "fp val=%lx, fsr=%lx",
10086429Svs195195 PLUS_INF_SP, fsr_at_trap);
10096429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
10106429Svs195195 report, 5311, &observed, &expected, 1, 1,
10116429Svs195195 err_data);
10126429Svs195195
10136429Svs195195 return (-1);
10146429Svs195195 }
10156429Svs195195
10166429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
10176429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
10186429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
1019*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
10206429Svs195195 "fstoi +infinity exception not raised, "
10216429Svs195195 "fp val=%lx, fsr=%lx",
10226429Svs195195 PLUS_INF_SP, fsr_at_trap);
10236429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
10246429Svs195195 report, 5312, &observed, &expected, 1, 1,
10256429Svs195195 err_data);
10266429Svs195195
10276429Svs195195 return (-1);
10286429Svs195195 }
10296429Svs195195
10306429Svs195195 /* - infinity exceptions */
10316429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
10326429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
10336429Svs195195
1034*7186Skk158166 (void) float_int_s(MINUS_INF_SP);
10356429Svs195195
10366429Svs195195 if (trap_flag) {
10376429Svs195195 observed = (uint64_t)trap_flag;
10386429Svs195195 expected = (uint64_t)0;
1039*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
10406429Svs195195 "fstoi -infinity exception not raised, "
10416429Svs195195 "fp val=%lx, fsr=%lx",
10426429Svs195195 MINUS_INF_SP, fsr_at_trap);
10436429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
10446429Svs195195 report, 5313, &observed, &expected, 1, 1,
10456429Svs195195 err_data);
10466429Svs195195
10476429Svs195195 return (-1);
10486429Svs195195 }
10496429Svs195195
10506429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
10516429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
10526429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
1053*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
10546429Svs195195 "fstoi -infinity exception not raised, "
10556429Svs195195 "fp val=%lx, fsr=%lx",
10566429Svs195195 MINUS_INF_SP, fsr_at_trap);
10576429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
10586429Svs195195 report, 5314, &observed, &expected, 1, 1, err_data);
10596429Svs195195
10606429Svs195195 return (-1);
10616429Svs195195 }
10626429Svs195195
10636429Svs195195 /* Check for inexact exception raised because of fractions */
10646429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NX);
10656429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
10666429Svs195195
1067*7186Skk158166 (void) float_int_s(pi_sp);
10686429Svs195195
10696429Svs195195 if (trap_flag) {
10706429Svs195195 observed = (uint64_t)trap_flag;
10716429Svs195195 expected = (uint64_t)0;
1072*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
10736429Svs195195 "fstoi inexact exception not raised, "
10746429Svs195195 "fp val=%lx, fsr=%lx",
10756429Svs195195 pi_sp, fsr_at_trap);
10766429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
10776429Svs195195 report, 5315, &observed, &expected, 1, 1, err_data);
10786429Svs195195
10796429Svs195195 return (-1);
10806429Svs195195 }
10816429Svs195195
10826429Svs195195 if ((fsr_at_trap & FSR_CEXC_NX) != FSR_CEXC_NX) {
10836429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NX;
10846429Svs195195 expected = (uint64_t)FSR_CEXC_NX;
1085*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
10866429Svs195195 "fstoi inexact exception not raised, "
10876429Svs195195 "fp val=%lx, fsr=%lx",
10886429Svs195195 pi_sp, fsr_at_trap);
10896429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
10906429Svs195195 report, 5316, &observed, &expected, 1, 1, err_data);
10916429Svs195195
10926429Svs195195 return (-1);
10936429Svs195195 }
10946429Svs195195
10956429Svs195195 set_fsr(prev_fsr);
10966429Svs195195 return (0);
10976429Svs195195 }
10986429Svs195195
10996429Svs195195 /*
11006429Svs195195 * float_to_integer_dp(struct fps_test_ereport *report)
11016429Svs195195 * performs continuous, double precision float to
11026429Svs195195 * integer conversions. If an error is found, relevant
11036429Svs195195 * data is stored in report.
11046429Svs195195 */
11056429Svs195195 static int
float_to_integer_dp(struct fps_test_ereport * report)11066429Svs195195 float_to_integer_dp(struct fps_test_ereport *report)
11076429Svs195195 {
11086429Svs195195 char err_data[MAX_INFO_SIZE];
11096429Svs195195 uint64_t i;
11106429Svs195195 uint64_t expected;
11116429Svs195195 uint64_t observed;
11126429Svs195195 unsigned long prev_fsr;
11136429Svs195195 unsigned long res1;
11146429Svs195195
11156429Svs195195 prev_fsr = get_fsr();
11166429Svs195195
11176429Svs195195 init_regs(0);
11186429Svs195195 for (i = 0; i < N_VALS; i++) {
11196429Svs195195 res1 = float_int_d(val[i].floatdouble);
11206429Svs195195
11216429Svs195195 if (res1 != i) {
11226429Svs195195 observed = (uint64_t)res1;
11236429Svs195195 expected = (uint64_t)i;
1124*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
11256429Svs195195 "Val Entry[%d]\nExpected: %d"
11266429Svs195195 "\nObserved: %d", i, i,
11276429Svs195195 res1);
11286429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
11296429Svs195195 report, 6230, &observed, &expected, 1,
11306429Svs195195 1, err_data);
11316429Svs195195
11326429Svs195195 return (-1);
11336429Svs195195 }
11346429Svs195195 }
11356429Svs195195
11366429Svs195195 /*
11376429Svs195195 * Value greater than highest representable value in int has to raise
11386429Svs195195 * an invalid exception.
11396429Svs195195 *
11406429Svs195195 * Highest possible value in int (assume uint) is 2^32; Use 2^33 for a
11416429Svs195195 * value greater.
11426429Svs195195 */
11436429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
11446429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
11456429Svs195195
1146*7186Skk158166 (void) float_int_d(0x4200000000000000);
11476429Svs195195
11486429Svs195195 if (trap_flag) {
11496429Svs195195 observed = (uint64_t)trap_flag;
11506429Svs195195 expected = (uint64_t)0;
1151*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
11526429Svs195195 "fdtoi max value exception not raised, "
11536429Svs195195 "fp val=%llx, fsr=%lx",
11546429Svs195195 0x4200000000000000, fsr_at_trap);
11556429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
11566429Svs195195 report, 5317, &observed, &expected, 1,
11576429Svs195195 1, err_data);
11586429Svs195195
11596429Svs195195 return (-1);
11606429Svs195195 }
11616429Svs195195
11626429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
11636429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
11646429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
1165*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
11666429Svs195195 "fdtoi max value exception not raised, "
11676429Svs195195 "fp val=%llx, fsr=%lx",
11686429Svs195195 0x4200000000000000, fsr_at_trap);
11696429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
11706429Svs195195 report, 5318, &observed, &expected, 1,
11716429Svs195195 1, err_data);
11726429Svs195195
11736429Svs195195 return (-1);
11746429Svs195195 }
11756429Svs195195
11766429Svs195195 /* NaNs should raise an exception when converted */
11776429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
11786429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
11796429Svs195195
1180*7186Skk158166 (void) float_int_d(nan_dp);
11816429Svs195195
11826429Svs195195 if (trap_flag) {
11836429Svs195195 observed = (uint64_t)trap_flag;
11846429Svs195195 expected = (uint64_t)0;
1185*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
11866429Svs195195 "fdtoi NaN exception not raised, "
11876429Svs195195 "fp val=%llx, fsr=%lx",
11886429Svs195195 nan_dp, fsr_at_trap);
11896429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
11906429Svs195195 report, 5319, &observed, &expected, 1,
11916429Svs195195 1, err_data);
11926429Svs195195
11936429Svs195195 return (-1);
11946429Svs195195 }
11956429Svs195195
11966429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
11976429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
11986429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
1199*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
12006429Svs195195 "fdtoi NaN exception not raised, "
12016429Svs195195 "fp val=%llx, fsr=%lx",
12026429Svs195195 nan_dp, fsr_at_trap);
12036429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
12046429Svs195195 report, 5320, &observed, &expected, 1,
12056429Svs195195 1, err_data);
12066429Svs195195
12076429Svs195195 return (-1);
12086429Svs195195 }
12096429Svs195195
12106429Svs195195 /* + infinity exceptions */
12116429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
12126429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
12136429Svs195195
1214*7186Skk158166 (void) float_int_d(PLUS_INF_DP);
12156429Svs195195
12166429Svs195195 if (trap_flag) {
12176429Svs195195 observed = (uint64_t)trap_flag;
12186429Svs195195 expected = (uint64_t)0;
1219*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
12206429Svs195195 "fdtoi +infinity exception not raised, "
12216429Svs195195 "fp val=%llx, fsr=%lx",
12226429Svs195195 PLUS_INF_DP, fsr_at_trap);
12236429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
12246429Svs195195 report, 5321, &observed, &expected, 1,
12256429Svs195195 1, err_data);
12266429Svs195195
12276429Svs195195 return (-1);
12286429Svs195195 }
12296429Svs195195
12306429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
12316429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
12326429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
1233*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
12346429Svs195195 "fdtoi +infinity exception not raised, "
12356429Svs195195 "fp val=%llx, fsr=%lx",
12366429Svs195195 PLUS_INF_DP, fsr_at_trap);
12376429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
12386429Svs195195 report, 5322, &observed, &expected, 1,
12396429Svs195195 1, err_data);
12406429Svs195195
12416429Svs195195 return (-1);
12426429Svs195195 }
12436429Svs195195
12446429Svs195195 /* - infinity exceptions */
12456429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
12466429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
12476429Svs195195
1248*7186Skk158166 (void) float_int_d(MINUS_INF_DP);
12496429Svs195195
12506429Svs195195 if (trap_flag) {
12516429Svs195195 observed = (uint64_t)trap_flag;
12526429Svs195195 expected = (uint64_t)0;
1253*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
12546429Svs195195 "fdtoi -infinity exception not raised, "
12556429Svs195195 "fp val=%llx, fsr=%lx",
12566429Svs195195 MINUS_INF_DP, fsr_at_trap);
12576429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
12586429Svs195195 report, 5323, &observed, &expected, 1,
12596429Svs195195 1, err_data);
12606429Svs195195
12616429Svs195195 return (-1);
12626429Svs195195 }
12636429Svs195195
12646429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
12656429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
12666429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
1267*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
12686429Svs195195 "fdtoi -infinity exception not raised, "
12696429Svs195195 "fp val=%llx, fsr=%lx",
12706429Svs195195 MINUS_INF_DP, fsr_at_trap);
12716429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
12726429Svs195195 report, 5324, &observed, &expected, 1,
12736429Svs195195 1, err_data);
12746429Svs195195
12756429Svs195195 return (-1);
12766429Svs195195 }
12776429Svs195195
12786429Svs195195 /* Check for inexact exception raised because of fractions */
12796429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NX);
12806429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
12816429Svs195195
1282*7186Skk158166 (void) float_int_d(pi_dp);
12836429Svs195195 if (trap_flag) {
12846429Svs195195 observed = (uint64_t)trap_flag;
12856429Svs195195 expected = (uint64_t)0;
1286*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
12876429Svs195195 "fdtoi inexact exception not raised, "
12886429Svs195195 "fp val=%llx, fsr=%lx",
12896429Svs195195 pi_dp, fsr_at_trap);
12906429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
12916429Svs195195 report, 5325, &observed, &expected, 1,
12926429Svs195195 1, err_data);
12936429Svs195195
12946429Svs195195 return (-1);
12956429Svs195195 }
12966429Svs195195
12976429Svs195195 if ((fsr_at_trap & FSR_CEXC_NX) != FSR_CEXC_NX) {
12986429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NX;
12996429Svs195195 expected = (uint64_t)FSR_CEXC_NX;
1300*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
13016429Svs195195 "fdtoi inexact exception not raised, "
13026429Svs195195 "fp val=%llx, fsr=%lx",
13036429Svs195195 pi_dp, fsr_at_trap);
13046429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
13056429Svs195195 report, 5326, &observed, &expected, 1,
13066429Svs195195 1, err_data);
13076429Svs195195
13086429Svs195195 return (-1);
13096429Svs195195 }
13106429Svs195195
13116429Svs195195 set_fsr(prev_fsr);
13126429Svs195195
13136429Svs195195 return (0);
13146429Svs195195 }
13156429Svs195195
13166429Svs195195 /*
13176429Svs195195 * float_to_long_sp(struct fps_test_ereport *report)
13186429Svs195195 * does continuous, single precision, float to long
13196429Svs195195 * conversions. If an error is found, relevant data
13206429Svs195195 * is stored in report.
13216429Svs195195 */
13226429Svs195195 static int
float_to_long_sp(struct fps_test_ereport * report)13236429Svs195195 float_to_long_sp(struct fps_test_ereport *report)
13246429Svs195195 {
13256429Svs195195 char err_data[MAX_INFO_SIZE];
13266429Svs195195 uint64_t i;
13276429Svs195195 uint64_t expected;
13286429Svs195195 uint64_t observed;
13296429Svs195195 unsigned long prev_fsr;
13306429Svs195195 unsigned long result;
13316429Svs195195
13326429Svs195195 prev_fsr = get_fsr();
13336429Svs195195
13346429Svs195195 init_regs(0);
13356429Svs195195
13366429Svs195195 for (i = 0; i < N_VALS; i++) {
13376429Svs195195 result = float_long_s(val[i].floatsingle);
13386429Svs195195
13396429Svs195195 if (result != i) {
13406429Svs195195 observed = (uint64_t)result;
13416429Svs195195 expected = (uint64_t)i;
1342*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
13436429Svs195195 "Val Entry[%d]\nExpected: %d"
13446429Svs195195 "\nObserved: %d", i, i,
13456429Svs195195 result);
13466429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
13476429Svs195195 report, 6352, &observed, &expected, 1,
13486429Svs195195 1, err_data);
13496429Svs195195
13506429Svs195195 return (-1);
13516429Svs195195 }
13526429Svs195195 }
13536429Svs195195
13546429Svs195195 /*
13556429Svs195195 * Value greater than highest representable value in int has to raise
13566429Svs195195 * an invalid exception.
13576429Svs195195 *
13586429Svs195195 * Highest possible value in int (assume uint) is 2^64; Use 2^65 for a
13596429Svs195195 * value greater.
13606429Svs195195 */
13616429Svs195195
13626429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
13636429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
13646429Svs195195
1365*7186Skk158166 (void) float_long_s(0x60000000);
13666429Svs195195
13676429Svs195195 if (trap_flag) {
13686429Svs195195 observed = (uint64_t)trap_flag;
13696429Svs195195 expected = (uint64_t)0;
1370*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
13716429Svs195195 "fstox max value exception not raised, "
13726429Svs195195 "fp val=%lx, fsr=%lx",
13736429Svs195195 0x60000000, fsr_at_trap);
13746429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
13756429Svs195195 report, 5327, &observed, &expected, 1,
13766429Svs195195 1, err_data);
13776429Svs195195
13786429Svs195195 return (-1);
13796429Svs195195 }
13806429Svs195195
13816429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
13826429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
13836429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
1384*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
13856429Svs195195 "fstox max value exception not raised, "
13866429Svs195195 "fp val=%lx, fsr=%lx",
13876429Svs195195 0x50000000, fsr_at_trap);
13886429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
13896429Svs195195 report, 5328, &observed, &expected, 1,
13906429Svs195195 1, err_data);
13916429Svs195195
13926429Svs195195 return (-1);
13936429Svs195195 }
13946429Svs195195
13956429Svs195195 /* NaNs should raise an exception when converted */
13966429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
13976429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
13986429Svs195195
1399*7186Skk158166 (void) float_long_s(nan_sp);
14006429Svs195195
14016429Svs195195 if (trap_flag) {
14026429Svs195195 observed = (uint64_t)trap_flag;
14036429Svs195195 expected = (uint64_t)0;
1404*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
14056429Svs195195 "fstox NaN exception not raised, "
14066429Svs195195 "fp val=%lx, fsr=%lx",
14076429Svs195195 nan_sp, fsr_at_trap);
14086429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
14096429Svs195195 report, 5329, &observed, &expected, 1, 1,
14106429Svs195195 err_data);
14116429Svs195195
14126429Svs195195 return (-1);
14136429Svs195195 }
14146429Svs195195
14156429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
14166429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
14176429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
1418*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
14196429Svs195195 "fstox NaN exception not raised, "
14206429Svs195195 "fp val=%lx, fsr=%lx",
14216429Svs195195 nan_sp, fsr_at_trap);
14226429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
14236429Svs195195 report, 5330, &observed, &expected, 1, 1,
14246429Svs195195 err_data);
14256429Svs195195
14266429Svs195195 return (-1);
14276429Svs195195 }
14286429Svs195195
14296429Svs195195 /* + infinity exceptions */
14306429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
14316429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
14326429Svs195195
1433*7186Skk158166 (void) float_long_s(PLUS_INF_SP);
14346429Svs195195
14356429Svs195195 if (trap_flag) {
14366429Svs195195 observed = (uint64_t)trap_flag;
14376429Svs195195 expected = (uint64_t)0;
1438*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
14396429Svs195195 "fstox +infinity exception not raised, "
14406429Svs195195 "fp val=%lx, fsr=%lx",
14416429Svs195195 PLUS_INF_SP, fsr_at_trap);
14426429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
14436429Svs195195 report, 5331, &observed, &expected, 1,
14446429Svs195195 1, err_data);
14456429Svs195195
14466429Svs195195 return (-1);
14476429Svs195195 }
14486429Svs195195
14496429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
14506429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
14516429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
1452*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
14536429Svs195195 "fstox +infinity exception not raised, "
14546429Svs195195 "fp val=%lx, fsr=%lx",
14556429Svs195195 PLUS_INF_SP, fsr_at_trap);
14566429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
14576429Svs195195 report, 5332, &observed, &expected, 1,
14586429Svs195195 1, err_data);
14596429Svs195195
14606429Svs195195 return (-1);
14616429Svs195195 }
14626429Svs195195
14636429Svs195195 /* - infinity exceptions */
14646429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
14656429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
14666429Svs195195
1467*7186Skk158166 (void) float_long_s(MINUS_INF_SP);
14686429Svs195195
14696429Svs195195 if (trap_flag) {
14706429Svs195195 observed = (uint64_t)trap_flag;
14716429Svs195195 expected = (uint64_t)0;
1472*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
14736429Svs195195 "fstox -infinity exception not raised, "
14746429Svs195195 "fp val=%lx, fsr=%lx",
14756429Svs195195 MINUS_INF_SP, fsr_at_trap);
14766429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
14776429Svs195195 report, 5333, &observed, &expected, 1,
14786429Svs195195 1, err_data);
14796429Svs195195
14806429Svs195195 return (-1);
14816429Svs195195 }
14826429Svs195195
14836429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
14846429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
14856429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
1486*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
14876429Svs195195 "fstox -infinity exception not raised, "
14886429Svs195195 "fp val=%lx, fsr=%lx",
14896429Svs195195 MINUS_INF_SP, fsr_at_trap);
14906429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
14916429Svs195195 report, 5334, &observed, &expected, 1,
14926429Svs195195 1, err_data);
14936429Svs195195
14946429Svs195195 return (-1);
14956429Svs195195 }
14966429Svs195195
14976429Svs195195 /* Check for inexact exception raised because of fractions */
14986429Svs195195
14996429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NX);
15006429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
15016429Svs195195
1502*7186Skk158166 (void) float_int_s(pi_sp);
15036429Svs195195
15046429Svs195195 if (trap_flag) {
15056429Svs195195 observed = (uint64_t)trap_flag;
15066429Svs195195 expected = (uint64_t)0;
1507*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
15086429Svs195195 "fstox inexact exception not raised, "
15096429Svs195195 "fp val=%lx, fsr=%lx",
15106429Svs195195 pi_sp, fsr_at_trap);
15116429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
15126429Svs195195 report, 5335, &observed, &expected, 1,
15136429Svs195195 1, err_data);
15146429Svs195195
15156429Svs195195 return (-1);
15166429Svs195195 }
15176429Svs195195
15186429Svs195195 if ((fsr_at_trap & FSR_CEXC_NX) != FSR_CEXC_NX) {
15196429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NX;
15206429Svs195195 expected = (uint64_t)FSR_CEXC_NX;
1521*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
15226429Svs195195 "fstox inexact exception not raised, "
15236429Svs195195 "fp val=%lx, fsr=%lx",
15246429Svs195195 pi_sp, fsr_at_trap);
15256429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
15266429Svs195195 report, 5336, &observed, &expected, 1,
15276429Svs195195 1, err_data);
15286429Svs195195
15296429Svs195195 return (-1);
15306429Svs195195 }
15316429Svs195195
15326429Svs195195 set_fsr(prev_fsr);
15336429Svs195195 return (0);
15346429Svs195195 }
15356429Svs195195
15366429Svs195195 /*
15376429Svs195195 * float_to_long_dp(struct fps_test_ereport *report)
15386429Svs195195 * does continuous, double precision, float to long
15396429Svs195195 * conversions. If an error is found, relevant data
15406429Svs195195 * is stored in report.
15416429Svs195195 */
15426429Svs195195 static int
float_to_long_dp(struct fps_test_ereport * report)15436429Svs195195 float_to_long_dp(struct fps_test_ereport *report)
15446429Svs195195 {
15456429Svs195195 char err_data[MAX_INFO_SIZE];
15466429Svs195195 uint64_t i;
15476429Svs195195 uint64_t expected;
15486429Svs195195 uint64_t observed;
15496429Svs195195 unsigned long prev_fsr;
15506429Svs195195 unsigned long res1;
15516429Svs195195
15526429Svs195195 prev_fsr = get_fsr();
15536429Svs195195
15546429Svs195195 init_regs(0);
15556429Svs195195
15566429Svs195195 for (i = 0; i < N_VALS; i++) {
15576429Svs195195 res1 = float_long_d(val[i].floatdouble);
15586429Svs195195
15596429Svs195195 if (res1 != i) {
15606429Svs195195 observed = (uint64_t)res1;
15616429Svs195195 expected = (uint64_t)i;
1562*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
15636429Svs195195 "Val Entry[%d]\nExpected: %d"
15646429Svs195195 "\nObserved: %d", i, i,
15656429Svs195195 res1);
15666429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
15676429Svs195195 report, 6351, &observed, &expected, 1,
15686429Svs195195 1, err_data);
15696429Svs195195
15706429Svs195195 return (-1);
15716429Svs195195 }
15726429Svs195195 }
15736429Svs195195
15746429Svs195195 /*
15756429Svs195195 * Value greater than highest representable value in long has to
15766429Svs195195 * raise an invalid exception.
15776429Svs195195 *
15786429Svs195195 * Highest possible value in long (assume ulong) is 2^64; Use 2^65 for a
15796429Svs195195 * value greater.
15806429Svs195195 */
15816429Svs195195
15826429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
15836429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
15846429Svs195195
1585*7186Skk158166 (void) float_long_d(0x4400000000000000);
15866429Svs195195
15876429Svs195195 if (trap_flag) {
15886429Svs195195 observed = (uint64_t)trap_flag;
15896429Svs195195 expected = (uint64_t)0;
1590*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
15916429Svs195195 "fdtox max value exception not raised, "
15926429Svs195195 "fp val=%lx, fsr=%lx",
15936429Svs195195 0x4400000000000000, fsr_at_trap);
15946429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
15956429Svs195195 report, 5337, &observed, &expected, 1,
15966429Svs195195 1, err_data);
15976429Svs195195
15986429Svs195195 return (-1);
15996429Svs195195 }
16006429Svs195195
16016429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
16026429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
16036429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
1604*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
16056429Svs195195 "fdtox max value exception not raised, "
16066429Svs195195 "fp val=%lx, fsr=%lx",
16076429Svs195195 0x4200000000000000, fsr_at_trap);
16086429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
16096429Svs195195 report, 5338, &observed, &expected, 1,
16106429Svs195195 1, err_data);
16116429Svs195195
16126429Svs195195 return (-1);
16136429Svs195195 }
16146429Svs195195
16156429Svs195195 /* NaNs should raise an exception when converted */
16166429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
16176429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
16186429Svs195195
1619*7186Skk158166 (void) float_long_d(nan_dp);
16206429Svs195195
16216429Svs195195 if (trap_flag) {
16226429Svs195195 observed = (uint64_t)trap_flag;
16236429Svs195195 expected = (uint64_t)0;
1624*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
16256429Svs195195 "fdtox NaN exception not raised, "
16266429Svs195195 "fp val=%lx, fsr=%lx",
16276429Svs195195 nan_dp, fsr_at_trap);
16286429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
16296429Svs195195 report, 5339, &observed, &expected, 1,
16306429Svs195195 1, err_data);
16316429Svs195195
16326429Svs195195 return (-1);
16336429Svs195195 }
16346429Svs195195
16356429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
16366429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
16376429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
1638*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
16396429Svs195195 "fdtox NaN exception not raised, "
16406429Svs195195 "fp val=%lx, fsr=%lx",
16416429Svs195195 nan_dp, fsr_at_trap);
16426429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
16436429Svs195195 report, 5340, &observed, &expected, 1,
16446429Svs195195 1, err_data);
16456429Svs195195
16466429Svs195195 return (-1);
16476429Svs195195 }
16486429Svs195195
16496429Svs195195 /* + infinity exceptions */
16506429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
16516429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
16526429Svs195195
1653*7186Skk158166 (void) float_long_d(PLUS_INF_DP);
16546429Svs195195
16556429Svs195195 if (trap_flag) {
16566429Svs195195 observed = (uint64_t)trap_flag;
16576429Svs195195 expected = (uint64_t)0;
1658*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
16596429Svs195195 "fdtox +infinity exception not raised, "
16606429Svs195195 "fp val=%lx, fsr=%lx",
16616429Svs195195 PLUS_INF_DP, fsr_at_trap);
16626429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
16636429Svs195195 report, 5341, &observed, &expected, 1,
16646429Svs195195 1, err_data);
16656429Svs195195
16666429Svs195195 return (-1);
16676429Svs195195 }
16686429Svs195195
16696429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
16706429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
16716429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
1672*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
16736429Svs195195 "fdtox +infinity exception not raised, "
16746429Svs195195 "fp val=%lx, fsr=%lx",
16756429Svs195195 PLUS_INF_DP, fsr_at_trap);
16766429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
16776429Svs195195 report, 5342, &observed, &expected, 1,
16786429Svs195195 1, err_data);
16796429Svs195195
16806429Svs195195 return (-1);
16816429Svs195195 }
16826429Svs195195
16836429Svs195195 /* - infinity exceptions */
16846429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
16856429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
16866429Svs195195
1687*7186Skk158166 (void) float_long_d(MINUS_INF_DP);
16886429Svs195195
16896429Svs195195 if (trap_flag) {
16906429Svs195195 observed = (uint64_t)trap_flag;
16916429Svs195195 expected = (uint64_t)0;
1692*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
16936429Svs195195 "fdtox -infinity exception not raised, "
16946429Svs195195 "fp val=%lx, fsr=%lx",
16956429Svs195195 MINUS_INF_DP, fsr_at_trap);
16966429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
16976429Svs195195 report, 5343, &observed, &expected, 1,
16986429Svs195195 1, err_data);
16996429Svs195195
17006429Svs195195 return (-1);
17016429Svs195195 }
17026429Svs195195
17036429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
17046429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
17056429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
1706*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
17076429Svs195195 "fdtox -infinity exception not raised, "
17086429Svs195195 "fp val=%lx, fsr=%lx",
17096429Svs195195 MINUS_INF_DP, fsr_at_trap);
17106429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
17116429Svs195195 report, 5344, &observed, &expected, 1,
17126429Svs195195 1, err_data);
17136429Svs195195
17146429Svs195195 return (-1);
17156429Svs195195 }
17166429Svs195195
17176429Svs195195 /* Check for inexact exception raised because of fractions */
17186429Svs195195
17196429Svs195195 set_fsr(prev_fsr | FSR_ENABLE_TEM_NX);
17206429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
17216429Svs195195
1722*7186Skk158166 (void) float_long_d(pi_dp);
17236429Svs195195
17246429Svs195195 if (trap_flag) {
17256429Svs195195 observed = (uint64_t)trap_flag;
17266429Svs195195 expected = (uint64_t)0;
1727*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
17286429Svs195195 "fdtox inexact exception not raised, "
17296429Svs195195 "fp val=%lx, fsr=%lx",
17306429Svs195195 pi_dp, fsr_at_trap);
17316429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
17326429Svs195195 report, 5345, &observed, &expected, 1,
17336429Svs195195 1, err_data);
17346429Svs195195
17356429Svs195195 return (-1);
17366429Svs195195 }
17376429Svs195195
17386429Svs195195 if ((fsr_at_trap & FSR_CEXC_NX) != FSR_CEXC_NX) {
17396429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NX;
17406429Svs195195 expected = (uint64_t)FSR_CEXC_NX;
1741*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
17426429Svs195195 "fdtox inexact exception not raised, "
17436429Svs195195 "fp val=%lx, fsr=%lx",
17446429Svs195195 pi_dp, fsr_at_trap);
17456429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
17466429Svs195195 report, 5346, &observed, &expected, 1,
17476429Svs195195 1, err_data);
17486429Svs195195
17496429Svs195195 return (-1);
17506429Svs195195 }
17516429Svs195195
17526429Svs195195 set_fsr(prev_fsr);
17536429Svs195195
17546429Svs195195 return (0);
17556429Svs195195 }
17566429Svs195195
17576429Svs195195 /*
17586429Svs195195 * single_doub(struct fps_test_ereport *report)
17596429Svs195195 * does continues single to double conversion.
17606429Svs195195 * If an error is found, relevant data is stored
17616429Svs195195 * in report.
17626429Svs195195 */
17636429Svs195195 static int
single_doub(struct fps_test_ereport * report)17646429Svs195195 single_doub(struct fps_test_ereport *report)
17656429Svs195195 {
17666429Svs195195 char err_data[MAX_INFO_SIZE];
17676429Svs195195 int i;
17686429Svs195195 uint64_t expected;
17696429Svs195195 uint64_t observed;
17706429Svs195195 unsigned long prev_fsr;
17716429Svs195195 unsigned long result;
17726429Svs195195
17736429Svs195195
17746429Svs195195 prev_fsr = get_fsr();
17756429Svs195195
17766429Svs195195 init_regs(0);
17776429Svs195195
17786429Svs195195 for (i = 0; i < N_VALS; i++) {
17796429Svs195195 result = convert_sp_dp(val[i].floatsingle);
17806429Svs195195
17816429Svs195195 if (result != val[i].floatdouble) {
17826429Svs195195 observed = (uint64_t)result;
17836429Svs195195 expected = (uint64_t)val[i].floatdouble;
1784*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
17856429Svs195195 "Val Entry[%d]\nExpected: %lld"
17866429Svs195195 "\nObserved: %lld", i,
17876429Svs195195 val[i].floatdouble, result);
17886429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
17896429Svs195195 report, 6231, &observed, &expected, 1,
17906429Svs195195 1, err_data);
17916429Svs195195
17926429Svs195195 return (-1);
17936429Svs195195 }
17946429Svs195195 }
17956429Svs195195
17966429Svs195195 set_fsr(prev_fsr);
17976429Svs195195
17986429Svs195195 return (0);
17996429Svs195195 }
18006429Svs195195
18016429Svs195195 /*
18026429Svs195195 * double_sing(struct fps_test_ereport *report)
18036429Svs195195 * does continues double to single conversion.
18046429Svs195195 * If an error is found, relevant data is stored
18056429Svs195195 * in report.
18066429Svs195195 */
18076429Svs195195 static int
double_sing(struct fps_test_ereport * report)18086429Svs195195 double_sing(struct fps_test_ereport *report)
18096429Svs195195 {
18106429Svs195195 char err_data[MAX_INFO_SIZE];
18116429Svs195195 int i;
18126429Svs195195 uint64_t expected;
18136429Svs195195 uint64_t observed;
18146429Svs195195 unsigned long result;
18156429Svs195195 unsigned long prev_fsr;
18166429Svs195195
18176429Svs195195 prev_fsr = get_fsr();
18186429Svs195195
18196429Svs195195 init_regs(0);
18206429Svs195195
18216429Svs195195 for (i = 0; i < N_VALS; i++) {
18226429Svs195195 result = convert_dp_sp(val[i].floatdouble);
18236429Svs195195
18246429Svs195195 if (result != val[i].floatsingle) {
18256429Svs195195 observed = (uint64_t)result;
18266429Svs195195 expected = (uint64_t)val[i].floatsingle;
1827*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
18286429Svs195195 "Val Entry[%d]\nExpected: %d"
18296429Svs195195 "\nObserved: %d", i,
18306429Svs195195 val[i].floatsingle, result);
18316429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
18326429Svs195195 report, 6232, &observed, &expected, 1,
18336429Svs195195 1, err_data);
18346429Svs195195
18356429Svs195195 return (-1);
18366429Svs195195 }
18376429Svs195195 }
18386429Svs195195
18396429Svs195195 set_fsr(prev_fsr);
18406429Svs195195 return (0);
18416429Svs195195 }
18426429Svs195195
18436429Svs195195 /*
18446429Svs195195 * fmovs_ins(struct fps_test_ereport *report)
18456429Svs195195 * moves a value through the floating point
18466429Svs195195 * registers. If an error is found, relevant
18476429Svs195195 * data is stored
18486429Svs195195 * in report.
18496429Svs195195 */
18506429Svs195195 static int
fmovs_ins(struct fps_test_ereport * report)18516429Svs195195 fmovs_ins(struct fps_test_ereport *report)
18526429Svs195195 {
18536429Svs195195 char err_data[MAX_INFO_SIZE];
18546429Svs195195 uint64_t observed;
18556429Svs195195 uint64_t expected;
18566429Svs195195 unsigned long result;
18576429Svs195195 unsigned long prev_fsr;
18586429Svs195195
18596429Svs195195 prev_fsr = get_fsr();
18606429Svs195195
18616429Svs195195 init_regs(0);
18626429Svs195195
18636429Svs195195 if ((result = move_regs(0x3F800000)) != 0x3F800000) {
18646429Svs195195 observed = (uint64_t)result;
18656429Svs195195 expected = (uint64_t)0x3F800000;
1866*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
18676429Svs195195 "Wrote to f0, read from f31");
18686429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
18696429Svs195195 report, 6233, &observed, &expected, 1,
18706429Svs195195 1, err_data);
18716429Svs195195
18726429Svs195195 return (-1);
18736429Svs195195 }
18746429Svs195195
18756429Svs195195 set_fsr(prev_fsr);
18766429Svs195195 return (0);
18776429Svs195195 }
18786429Svs195195
18796429Svs195195 /*
18806429Svs195195 * get_negative_value_pn_sp(struct fps_test_ereport *report)
18816429Svs195195 * converts single precision postive to negative values.
18826429Svs195195 * If an error is found, relevant data is stored
18836429Svs195195 * in report.
18846429Svs195195 */
18856429Svs195195 static int
get_negative_value_pn_sp(struct fps_test_ereport * report)18866429Svs195195 get_negative_value_pn_sp(struct fps_test_ereport *report)
18876429Svs195195 {
18886429Svs195195 char err_data[MAX_INFO_SIZE];
18896429Svs195195 int i;
18906429Svs195195 uint64_t observed;
18916429Svs195195 uint64_t expected;
18926429Svs195195 unsigned long prev_fsr;
18936429Svs195195 unsigned long result;
18946429Svs195195
18956429Svs195195 prev_fsr = get_fsr();
18966429Svs195195
18976429Svs195195 init_regs(0);
18986429Svs195195
18996429Svs195195 for (i = 0; i < N_VALS; i++) {
19006429Svs195195 result = negate_value_sp(val[i].floatsingle);
19016429Svs195195 if (result != neg_val_sp[i]) {
19026429Svs195195 observed = (uint64_t)result;
19036429Svs195195 expected = (uint64_t)neg_val_sp[i];
1904*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
19056429Svs195195 "Val Entry[%d]\nExpected: %d"
19066429Svs195195 "\nObserved: %d", i, neg_val_sp[i],
19076429Svs195195 result);
19086429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
19096429Svs195195 report, 6234, &observed, &expected, 1,
19106429Svs195195 1, err_data);
19116429Svs195195
19126429Svs195195 return (-1);
19136429Svs195195 }
19146429Svs195195 }
19156429Svs195195
19166429Svs195195 set_fsr(prev_fsr);
19176429Svs195195 return (0);
19186429Svs195195 }
19196429Svs195195
19206429Svs195195 /*
19216429Svs195195 * get_negative_value_pn_dp(struct fps_test_ereport *report)
19226429Svs195195 * converts double precision postive to negative values.
19236429Svs195195 * If an error is found, relevant data is stored
19246429Svs195195 * in report.
19256429Svs195195 */
19266429Svs195195 static int
get_negative_value_pn_dp(struct fps_test_ereport * report)19276429Svs195195 get_negative_value_pn_dp(struct fps_test_ereport *report)
19286429Svs195195 {
19296429Svs195195 char err_data[MAX_INFO_SIZE];
19306429Svs195195 int i;
19316429Svs195195 uint64_t expected;
19326429Svs195195 uint64_t observed;
19336429Svs195195 uint64_t result;
19346429Svs195195
19356429Svs195195 init_regs_dp(0);
19366429Svs195195
19376429Svs195195 for (i = 0; i < N_VALS; i++) {
19386429Svs195195 result = negate_value_dp(val[i].floatdouble);
19396429Svs195195 if (result != neg_val_dp[i]) {
19406429Svs195195 observed = (uint64_t)result;
19416429Svs195195 expected = (uint64_t)neg_val_dp[i];
1942*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
19436429Svs195195 "Val Entry[%d]\nExpected: %lld"
19446429Svs195195 "\nObserved: %lld", i, neg_val_dp[i],
19456429Svs195195 result);
19466429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
19476429Svs195195 report, 6362, &observed, &expected, 1,
19486429Svs195195 1, err_data);
19496429Svs195195
19506429Svs195195 return (-1);
19516429Svs195195 }
19526429Svs195195 }
19536429Svs195195
19546429Svs195195 return (0);
19556429Svs195195 }
19566429Svs195195
19576429Svs195195 /*
19586429Svs195195 * get_negative_value_np_sp(struct fps_test_ereport *report)
19596429Svs195195 * converts single precision negative to positive values.
19606429Svs195195 * If an error is found, relevant data is stored
19616429Svs195195 * in report.
19626429Svs195195 */
19636429Svs195195 static int
get_negative_value_np_sp(struct fps_test_ereport * report)19646429Svs195195 get_negative_value_np_sp(struct fps_test_ereport *report)
19656429Svs195195 {
19666429Svs195195 char err_data[MAX_INFO_SIZE];
19676429Svs195195 int i;
19686429Svs195195 uint64_t observed;
19696429Svs195195 uint64_t expected;
19706429Svs195195 unsigned long result;
19716429Svs195195 unsigned long prev_fsr;
19726429Svs195195
19736429Svs195195 prev_fsr = get_fsr();
19746429Svs195195
19756429Svs195195 init_regs(0);
19766429Svs195195
19776429Svs195195 for (i = 0; i < N_VALS; i++) {
19786429Svs195195 result = negate_value_sp(neg_val_sp[i]);
19796429Svs195195
19806429Svs195195 if (result != val[i].floatsingle) {
19816429Svs195195 observed = (uint64_t)result;
19826429Svs195195 expected = (uint64_t)val[i].floatsingle;
1983*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
19846429Svs195195 "Val Entry[%d]\nExpected: %d"
19856429Svs195195 "\nObserved: %d", i, val[i].floatsingle,
19866429Svs195195 result);
19876429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
19886429Svs195195 report, 6235, &observed, &expected, 1,
19896429Svs195195 1, err_data);
19906429Svs195195
19916429Svs195195 return (-1);
19926429Svs195195 }
19936429Svs195195 }
19946429Svs195195
19956429Svs195195 set_fsr(prev_fsr);
19966429Svs195195 return (0);
19976429Svs195195 }
19986429Svs195195
19996429Svs195195 /*
20006429Svs195195 * get_negative_value_np_dp(struct fps_test_ereport *report)
20016429Svs195195 * converts double precision negative to positive values.
20026429Svs195195 * If an error is found, relevant data is stored
20036429Svs195195 * in report.
20046429Svs195195 */
20056429Svs195195 static int
get_negative_value_np_dp(struct fps_test_ereport * report)20066429Svs195195 get_negative_value_np_dp(struct fps_test_ereport *report)
20076429Svs195195 {
20086429Svs195195 char err_data[MAX_INFO_SIZE];
20096429Svs195195 int i;
20106429Svs195195 uint64_t expected;
20116429Svs195195 uint64_t observed;
20126429Svs195195 uint64_t result;
20136429Svs195195
20146429Svs195195 init_regs_dp(0);
20156429Svs195195
20166429Svs195195 for (i = 0; i < N_VALS; i++) {
20176429Svs195195 result = negate_value_dp(neg_val_dp[i]);
20186429Svs195195
20196429Svs195195 if (result != val[i].floatdouble) {
20206429Svs195195 observed = (uint64_t)result;
20216429Svs195195 expected = (uint64_t)val[i].floatdouble;
2022*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
20236429Svs195195 "Val Entry[%d]\nExpected: %lld"
20246429Svs195195 "\nObserved: %lld", i, val[i].floatdouble,
20256429Svs195195 result);
20266429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
20276429Svs195195 report, 6363, &observed, &expected, 1,
20286429Svs195195 1, err_data);
20296429Svs195195
20306429Svs195195 return (-1);
20316429Svs195195 }
20326429Svs195195 }
20336429Svs195195
20346429Svs195195 return (0);
20356429Svs195195 }
20366429Svs195195
20376429Svs195195 /*
20386429Svs195195 * fabs_ins_sp(struct fps_test_ereport *report)
20396429Svs195195 * does single precision absolute value testing.
20406429Svs195195 * If an error is found, relevant data is stored
20416429Svs195195 * in report.
20426429Svs195195 */
20436429Svs195195 static int
fabs_ins_sp(struct fps_test_ereport * report)20446429Svs195195 fabs_ins_sp(struct fps_test_ereport *report)
20456429Svs195195 {
20466429Svs195195 char err_data[MAX_INFO_SIZE];
20476429Svs195195 int i;
20486429Svs195195 uint64_t expected;
20496429Svs195195 uint64_t observed;
20506429Svs195195 unsigned long result;
20516429Svs195195 unsigned long prev_fsr;
20526429Svs195195
20536429Svs195195 prev_fsr = get_fsr();
20546429Svs195195
20556429Svs195195 init_regs(0);
20566429Svs195195 for (i = 0; i < N_VALS; i++) {
20576429Svs195195 result = absolute_value_sp(neg_val_sp[i]);
20586429Svs195195 if (result != val[i].floatsingle) {
20596429Svs195195 observed = *(uint64_t *)&result;
20606429Svs195195 expected = *(uint64_t *)&(val[i].floatsingle);
2061*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
20626429Svs195195 "Val Entry[%d]\nExpected: %d"
20636429Svs195195 "\nObserved: %d", i, val[i].floatsingle,
20646429Svs195195 result);
20656429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
20666429Svs195195 report, 6236, &observed, &expected, 1,
20676429Svs195195 1, err_data);
20686429Svs195195
20696429Svs195195 return (-1);
20706429Svs195195 }
20716429Svs195195 }
20726429Svs195195
20736429Svs195195 set_fsr(prev_fsr);
20746429Svs195195 return (0);
20756429Svs195195 }
20766429Svs195195
20776429Svs195195 /*
20786429Svs195195 * fabs_ins_dp(struct fps_test_ereport *report)
20796429Svs195195 * does double precision absolute value testing.
20806429Svs195195 * If an error is found, relevant data is stored
20816429Svs195195 * in report.
20826429Svs195195 */
20836429Svs195195 static int
fabs_ins_dp(struct fps_test_ereport * report)20846429Svs195195 fabs_ins_dp(struct fps_test_ereport *report)
20856429Svs195195 {
20866429Svs195195 char err_data[MAX_INFO_SIZE];
20876429Svs195195 int i;
20886429Svs195195 uint64_t expected;
20896429Svs195195 uint64_t observed;
20906429Svs195195 uint64_t result;
20916429Svs195195
20926429Svs195195 init_regs_dp(0);
20936429Svs195195
20946429Svs195195 for (i = 0; i < N_VALS; i++) {
20956429Svs195195 result = absolute_value_dp(neg_val_dp[i]);
20966429Svs195195
20976429Svs195195 if (result != val[i].floatdouble) {
20986429Svs195195 observed = (uint64_t)result;
20996429Svs195195 expected = (uint64_t)val[i].floatdouble;
2100*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
21016429Svs195195 "Val Entry[%d]\nExpected: %lld"
21026429Svs195195 "\nObserved: %lld", i, val[i].floatdouble,
21036429Svs195195 result);
21046429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
21056429Svs195195 report, 6361, &observed, &expected, 1,
21066429Svs195195 1, err_data);
21076429Svs195195
21086429Svs195195 return (-1);
21096429Svs195195 }
21106429Svs195195 }
21116429Svs195195
21126429Svs195195 return (0);
21136429Svs195195 }
21146429Svs195195
21156429Svs195195 /*
21166429Svs195195 * addition_test_sp(struct fps_test_ereport *report)
21176429Svs195195 * tests single precision addition using floating
21186429Svs195195 * point registers (f4=f0+f2).
21196429Svs195195 * If an error is found, relevant data is stored
21206429Svs195195 * in report.
21216429Svs195195 */
21226429Svs195195 static int
addition_test_sp(struct fps_test_ereport * report)21236429Svs195195 addition_test_sp(struct fps_test_ereport *report)
21246429Svs195195 {
21256429Svs195195 char err_data[MAX_INFO_SIZE];
21266429Svs195195 int i;
21276429Svs195195 unsigned long result;
21286429Svs195195 unsigned long prev_fsr;
21296429Svs195195 uint64_t observed;
21306429Svs195195 uint64_t expected;
21316429Svs195195
21326429Svs195195 prev_fsr = get_fsr();
21336429Svs195195
21346429Svs195195 init_regs(0);
21356429Svs195195 for (i = 0; i < (N_VALS - 1); i++) {
21366429Svs195195 result = add_sp(val[i].floatsingle, val[1].floatsingle);
21376429Svs195195
21386429Svs195195 if (result != (val[i + 1].floatsingle)) {
21396429Svs195195
21406429Svs195195 observed = (uint64_t)result;
21416429Svs195195 expected = (uint64_t)val[i + 1].floatsingle;
2142*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
21436429Svs195195 "Val Entry[%d], reg f4=f0+f2"
21446429Svs195195 "\nExpected: %d\nObserved: %d",
21456429Svs195195 i, val[i + 1].floatsingle, result);
21466429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
21476429Svs195195 report, 6237, &observed, &expected, 1,
21486429Svs195195 1, err_data);
21496429Svs195195
21506429Svs195195 return (-1);
21516429Svs195195 }
21526429Svs195195 }
21536429Svs195195
21546429Svs195195 set_fsr(prev_fsr);
21556429Svs195195 return (0);
21566429Svs195195 }
21576429Svs195195
21586429Svs195195 /*
21596429Svs195195 * addition_test_dp(struct fps_test_ereport *report)
21606429Svs195195 * tests double precision addition using floating
21616429Svs195195 * point registers (f4=f0+f2).
21626429Svs195195 * If an error is found, relevant data is stored
21636429Svs195195 * in report.
21646429Svs195195 */
21656429Svs195195 static int
addition_test_dp(struct fps_test_ereport * report)21666429Svs195195 addition_test_dp(struct fps_test_ereport *report)
21676429Svs195195 {
21686429Svs195195 char err_data[MAX_INFO_SIZE];
21696429Svs195195 int i;
21706429Svs195195 unsigned long result;
21716429Svs195195 unsigned long prev_fsr;
21726429Svs195195 uint64_t observed;
21736429Svs195195 uint64_t expected;
21746429Svs195195
21756429Svs195195 prev_fsr = get_fsr();
21766429Svs195195
21776429Svs195195 init_regs(0);
21786429Svs195195
21796429Svs195195 for (i = 0; i < (N_VALS - 1); i++) {
21806429Svs195195 result = add_dp(val[i].floatdouble, val[1].floatdouble);
21816429Svs195195
21826429Svs195195 if (result != (val[i + 1].floatdouble)) {
21836429Svs195195 observed = (uint64_t)result;
21846429Svs195195 expected = (uint64_t)val[i + 1].floatdouble;
2185*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
21866429Svs195195 "Val Entry[%d], reg f4=f0+f2"
21876429Svs195195 "\nExpected: %lld\nObserved: %lld",
21886429Svs195195 i, val[i + 1].floatdouble, result);
21896429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
21906429Svs195195 report, 6238, &observed, &expected, 1,
21916429Svs195195 1, err_data);
21926429Svs195195
21936429Svs195195 return (-1);
21946429Svs195195 }
21956429Svs195195 }
21966429Svs195195
21976429Svs195195 set_fsr(prev_fsr);
21986429Svs195195 return (0);
21996429Svs195195 }
22006429Svs195195
22016429Svs195195 /*
22026429Svs195195 * subtraction_test_sp(struct fps_test_ereport *report)
22036429Svs195195 * tests single precision subtaction using floating
22046429Svs195195 * point registers (f4=f0-f2).
22056429Svs195195 * If an error is found, relevant data is stored
22066429Svs195195 * in report.
22076429Svs195195 */
22086429Svs195195 static int
subtraction_test_sp(struct fps_test_ereport * report)22096429Svs195195 subtraction_test_sp(struct fps_test_ereport *report)
22106429Svs195195 {
22116429Svs195195 char err_data[MAX_INFO_SIZE];
22126429Svs195195 int i;
22136429Svs195195 unsigned long result;
22146429Svs195195 unsigned long prev_fsr;
22156429Svs195195 uint64_t observed;
22166429Svs195195 uint64_t expected;
22176429Svs195195
22186429Svs195195 prev_fsr = get_fsr();
22196429Svs195195
22206429Svs195195 init_regs(0);
22216429Svs195195 for (i = 1; i < N_VALS; i++) {
22226429Svs195195 result = sub_sp(val[i].floatsingle, val[i - 1].floatsingle);
22236429Svs195195
22246429Svs195195 if (result != val[1].floatsingle) {
22256429Svs195195 observed = (uint64_t)result;
22266429Svs195195 expected = (uint64_t)val[1].floatsingle;
2227*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
22286429Svs195195 "Val Entry[%d], reg f4=f0-f2"
22296429Svs195195 "\nExpected: %d\nObserved: %d",
22306429Svs195195 i, val[1].floatsingle, result);
22316429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
22326429Svs195195 report, 6239, &observed, &expected, 1,
22336429Svs195195 1, err_data);
22346429Svs195195
22356429Svs195195 return (-1);
22366429Svs195195 }
22376429Svs195195 }
22386429Svs195195
22396429Svs195195 set_fsr(prev_fsr);
22406429Svs195195 return (0);
22416429Svs195195 }
22426429Svs195195
22436429Svs195195 /*
22446429Svs195195 * subtraction_test_dp(struct fps_test_ereport *report)
22456429Svs195195 * tests double precision subtaction using floating
22466429Svs195195 * point registers (f4=f0-f2).
22476429Svs195195 * If an error is found, relevant data is stored
22486429Svs195195 * in report.
22496429Svs195195 */
22506429Svs195195 static int
subtraction_test_dp(struct fps_test_ereport * report)22516429Svs195195 subtraction_test_dp(struct fps_test_ereport *report)
22526429Svs195195 {
22536429Svs195195 char err_data[MAX_INFO_SIZE];
22546429Svs195195 int i;
22556429Svs195195 unsigned long result;
22566429Svs195195 unsigned long prev_fsr;
22576429Svs195195 uint64_t observed;
22586429Svs195195 uint64_t expected;
22596429Svs195195
22606429Svs195195 prev_fsr = get_fsr();
22616429Svs195195
22626429Svs195195 init_regs(0);
22636429Svs195195
22646429Svs195195 for (i = 1; i < N_VALS; i++) {
22656429Svs195195 result = sub_dp(val[i].floatdouble, val[i - 1].floatdouble);
22666429Svs195195
22676429Svs195195 if (result != val[1].floatdouble) {
22686429Svs195195 observed = (uint64_t)result;
22696429Svs195195 expected = (uint64_t)val[1].floatdouble;
2270*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
22716429Svs195195 "Val Entry[%d], reg f4=f0-f2"
22726429Svs195195 "\nExpected: %lld\nObserved: %lld",
22736429Svs195195 i, val[1].floatdouble, result);
22746429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
22756429Svs195195 report, 6240, &observed, &expected, 1,
22766429Svs195195 1, err_data);
22776429Svs195195
22786429Svs195195 return (-1);
22796429Svs195195 }
22806429Svs195195 }
22816429Svs195195
22826429Svs195195 set_fsr(prev_fsr);
22836429Svs195195 return (0);
22846429Svs195195 }
22856429Svs195195
22866429Svs195195 /*
22876429Svs195195 * squareroot_test_sp(struct fps_test_ereport *report)
22886429Svs195195 * tests single precision squareroot.
22896429Svs195195 * If an error is found, relevant data is stored
22906429Svs195195 * in report.
22916429Svs195195 */
22926429Svs195195 static int
squareroot_test_sp(struct fps_test_ereport * report)22936429Svs195195 squareroot_test_sp(struct fps_test_ereport *report)
22946429Svs195195 {
22956429Svs195195 char err_data[MAX_INFO_SIZE];
22966429Svs195195 int i;
22976429Svs195195 uint64_t observed;
22986429Svs195195 uint64_t expected;
22996429Svs195195 unsigned long result, workvalue;
23006429Svs195195 unsigned long prev_fsr;
23016429Svs195195
23026429Svs195195 prev_fsr = get_fsr();
23036429Svs195195
23046429Svs195195 init_regs(0);
23056429Svs195195
23066429Svs195195 for (i = 1; i < N_VALS; i++) {
23076429Svs195195 workvalue = val[i].floatsingle;
23086429Svs195195 result = sqrt_sp(mult_sp(workvalue, workvalue));
23096429Svs195195 if (result != workvalue) {
23106429Svs195195 observed = (uint64_t)result;
23116429Svs195195 expected = (uint64_t)workvalue;
2312*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
23136429Svs195195 "\nExpected: %d\nObserved: %d", workvalue,
23146429Svs195195 result);
23156429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
23166429Svs195195 report, 6241, &observed, &expected, 1, 1);
23176429Svs195195
23186429Svs195195 return (-1);
23196429Svs195195 }
23206429Svs195195 }
23216429Svs195195
23226429Svs195195 /* fsqrt(x), where x>0, should be positive */
23236429Svs195195 result = sqrt_sp(half_sp);
23246429Svs195195
23256429Svs195195 if (result & SIGN_FLAG_SP) {
23266429Svs195195 observed = (uint64_t)result & SIGN_FLAG_SP;
23276429Svs195195 expected = (uint64_t)0;
23286429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
23296429Svs195195 report, 8241, &observed, &expected, 1, 1);
23306429Svs195195
23316429Svs195195 return (-1);
23326429Svs195195 }
23336429Svs195195
23346429Svs195195 /* fsqrt(-0)=-0. */
23356429Svs195195 result = sqrt_sp(MINUS_ZERO_SP);
23366429Svs195195
23376429Svs195195 if (!(result & MINUS_ZERO_SP)) {
23386429Svs195195 observed = (uint64_t)0;
23396429Svs195195 expected = (uint64_t)1;
23406429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
23416429Svs195195 report, 8242, &observed, &expected, 1, 1);
23426429Svs195195
23436429Svs195195 return (-1);
23446429Svs195195 }
23456429Svs195195
23466429Svs195195 set_fsr(prev_fsr);
23476429Svs195195 return (0);
23486429Svs195195 }
23496429Svs195195
23506429Svs195195 /*
23516429Svs195195 * squareroot_test_dp(struct fps_test_ereport *report)
23526429Svs195195 * tests double precision squareroot.
23536429Svs195195 * If an error is found, relevant data is stored
23546429Svs195195 * in report.
23556429Svs195195 */
23566429Svs195195 static int
squareroot_test_dp(struct fps_test_ereport * report)23576429Svs195195 squareroot_test_dp(struct fps_test_ereport *report)
23586429Svs195195 {
23596429Svs195195 char err_data[MAX_INFO_SIZE];
23606429Svs195195 int i;
23616429Svs195195 uint64_t observed;
23626429Svs195195 uint64_t expected;
23636429Svs195195 unsigned long half_dp;
23646429Svs195195 unsigned long result;
23656429Svs195195 unsigned long workvalue;
23666429Svs195195 unsigned long prev_fsr;
23676429Svs195195
23686429Svs195195 prev_fsr = get_fsr();
23696429Svs195195
23706429Svs195195 init_regs(0);
23716429Svs195195
23726429Svs195195 for (i = 1; i < N_VALS; i++) {
23736429Svs195195 workvalue = val[i].floatdouble;
23746429Svs195195 result = sqrt_dp(mult_dp(workvalue, workvalue));
23756429Svs195195
23766429Svs195195 if (result != workvalue) {
23776429Svs195195 observed = (uint64_t)result;
23786429Svs195195 expected = (uint64_t)workvalue;
2379*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
23806429Svs195195 "\nExpected: %lld\nObserved: %lld", workvalue,
23816429Svs195195 result);
23826429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
23836429Svs195195 report, 6242, &observed, &expected, 1, 1);
23846429Svs195195
23856429Svs195195 return (-1);
23866429Svs195195 }
23876429Svs195195 }
23886429Svs195195
23896429Svs195195 /* fsqrt(x), where x>0, should be positive */
23906429Svs195195 workvalue = half_msw;
23916429Svs195195 half_dp = workvalue << 32;
23926429Svs195195 half_dp = half_dp | half_lsw;
23936429Svs195195 result = sqrt_dp(half_dp);
23946429Svs195195
23956429Svs195195 if (result & SIGN_FLAG_DP) {
23966429Svs195195 observed = (uint64_t)result & SIGN_FLAG_DP;
23976429Svs195195 expected = (uint64_t)0;
23986429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
23996429Svs195195 report, 8243, &observed, &expected, 1, 1);
24006429Svs195195
24016429Svs195195 return (-1);
24026429Svs195195 }
24036429Svs195195
24046429Svs195195 /* fsqrt(-0)=-0 */
24056429Svs195195 result = sqrt_dp(MINUS_ZERO_DP);
24066429Svs195195
24076429Svs195195 if (!(result & MINUS_ZERO_DP)) {
24086429Svs195195 observed = (uint64_t)0;
24096429Svs195195 expected = (uint64_t)1;
24106429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
24116429Svs195195 report, 8244, &observed, &expected, 1, 1);
24126429Svs195195
24136429Svs195195 return (-1);
24146429Svs195195 }
24156429Svs195195
24166429Svs195195 set_fsr(prev_fsr);
24176429Svs195195 return (0);
24186429Svs195195 }
24196429Svs195195
24206429Svs195195 /*
24216429Svs195195 * division_test_sp(struct fps_test_ereport *report)
24226429Svs195195 * tests single precision division through registers.
24236429Svs195195 * (reg f4=f0/f2). If an error is found, relevant data
24246429Svs195195 * is stored in report.
24256429Svs195195 */
24266429Svs195195 static int
division_test_sp(struct fps_test_ereport * report)24276429Svs195195 division_test_sp(struct fps_test_ereport *report)
24286429Svs195195 {
24296429Svs195195 char err_data[MAX_INFO_SIZE];
24306429Svs195195 int i;
24316429Svs195195 unsigned long result;
24326429Svs195195 unsigned long prev_fsr;
24336429Svs195195 uint64_t observed;
24346429Svs195195 uint64_t expected;
24356429Svs195195
24366429Svs195195 prev_fsr = get_fsr();
24376429Svs195195
24386429Svs195195 init_regs(0);
24396429Svs195195 for (i = 1; i < N_VALS; i++) {
24406429Svs195195 result = div_sp(val[i].floatsingle, val[1].floatsingle);
24416429Svs195195
24426429Svs195195 if (result != val[i].floatsingle) {
24436429Svs195195 observed = (uint64_t)result;
24446429Svs195195 expected = (uint64_t)val[i].floatsingle;
2445*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
24466429Svs195195 "Val Entry[%d], reg f4=f0/f2"
24476429Svs195195 "\nExpected: %d\nObserved: %d",
24486429Svs195195 i, val[i].floatsingle, result);
24496429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
24506429Svs195195 report, 6243, &observed, &expected, 1,
24516429Svs195195 1, err_data);
24526429Svs195195
24536429Svs195195 return (-1);
24546429Svs195195 }
24556429Svs195195 }
24566429Svs195195
24576429Svs195195 set_fsr(prev_fsr);
24586429Svs195195 return (0);
24596429Svs195195 }
24606429Svs195195
24616429Svs195195 /*
24626429Svs195195 * division_test_dp(struct fps_test_ereport *report)
24636429Svs195195 * tests double precision division through registers.
24646429Svs195195 * (reg f4=f0/f2). If an error is found, relevant data
24656429Svs195195 * is stored in report.
24666429Svs195195 */
24676429Svs195195 static int
division_test_dp(struct fps_test_ereport * report)24686429Svs195195 division_test_dp(struct fps_test_ereport *report)
24696429Svs195195 {
24706429Svs195195 char err_data[MAX_INFO_SIZE];
24716429Svs195195 int i;
24726429Svs195195 unsigned long result;
24736429Svs195195 unsigned long prev_fsr;
24746429Svs195195 uint64_t observed;
24756429Svs195195 uint64_t expected;
24766429Svs195195
24776429Svs195195 prev_fsr = get_fsr();
24786429Svs195195
24796429Svs195195 init_regs(0);
24806429Svs195195 for (i = 1; i < N_VALS; i++) {
24816429Svs195195 result = div_dp(val[i].floatdouble, val[1].floatdouble);
24826429Svs195195
24836429Svs195195 if (result != val[i].floatdouble) {
24846429Svs195195 observed = (uint64_t)result;
24856429Svs195195 expected = (uint64_t)val[i].floatdouble;
2486*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
24876429Svs195195 "Val Entry[%d], reg f4=f0/f2"
24886429Svs195195 "\nExpected: %lld\nObserved: %lld",
24896429Svs195195 i, val[i].floatdouble, result);
24906429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
24916429Svs195195 report, 6244, &observed, &expected, 1, 1,
24926429Svs195195 err_data);
24936429Svs195195
24946429Svs195195 return (-1);
24956429Svs195195 }
24966429Svs195195 }
24976429Svs195195
24986429Svs195195 set_fsr(prev_fsr);
24996429Svs195195 return (0);
25006429Svs195195 }
25016429Svs195195
25026429Svs195195 /*
25036429Svs195195 * multiplication_test_sp(struct fps_test_ereport *report)
25046429Svs195195 * tests single precision multiplication through registers.
25056429Svs195195 * (reg f4=f0*f2). If an error is found, relevant data
25066429Svs195195 * is stored in report.
25076429Svs195195 */
25086429Svs195195 static int
multiplication_test_sp(struct fps_test_ereport * report)25096429Svs195195 multiplication_test_sp(struct fps_test_ereport *report)
25106429Svs195195 {
25116429Svs195195 char err_data[MAX_INFO_SIZE];
25126429Svs195195 int i;
25136429Svs195195 unsigned long result;
25146429Svs195195 unsigned long prev_fsr;
25156429Svs195195 uint64_t observed;
25166429Svs195195 uint64_t expected;
25176429Svs195195
25186429Svs195195 prev_fsr = get_fsr();
25196429Svs195195
25206429Svs195195 init_regs(0);
25216429Svs195195 for (i = 0; i < N_VALS; i++) {
25226429Svs195195 result = mult_sp(val[i].floatsingle, val[1].floatsingle);
25236429Svs195195
25246429Svs195195 if (result != val[i].floatsingle) {
25256429Svs195195 observed = (uint64_t)result;
25266429Svs195195 expected = (uint64_t)val[i].floatsingle;
2527*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
25286429Svs195195 "Val Entry[%d], reg f4=f0*f2"
25296429Svs195195 "\nExpected: %d\nObserved: %d",
25306429Svs195195 i, val[i].floatsingle, result);
25316429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO, report,
25326429Svs195195 6245, &observed, &expected, 1, 1, err_data);
25336429Svs195195
25346429Svs195195 return (-1);
25356429Svs195195 }
25366429Svs195195 }
25376429Svs195195
25386429Svs195195 set_fsr(prev_fsr);
25396429Svs195195 return (0);
25406429Svs195195 }
25416429Svs195195
25426429Svs195195 /*
25436429Svs195195 * multiplication_test_dp(struct fps_test_ereport *report)
25446429Svs195195 * tests double precision multiplication through registers.
25456429Svs195195 * (reg f4=f0*f2). If an error is found, relevant data
25466429Svs195195 * is stored in report.
25476429Svs195195 */
25486429Svs195195 static int
multiplication_test_dp(struct fps_test_ereport * report)25496429Svs195195 multiplication_test_dp(struct fps_test_ereport *report)
25506429Svs195195 {
25516429Svs195195 char err_data[MAX_INFO_SIZE];
25526429Svs195195 int i;
25536429Svs195195 uint64_t observed;
25546429Svs195195 uint64_t expected;
25556429Svs195195 unsigned long result;
25566429Svs195195 unsigned long prev_fsr;
25576429Svs195195
25586429Svs195195 prev_fsr = get_fsr();
25596429Svs195195
25606429Svs195195 init_regs(0);
25616429Svs195195 for (i = 0; i < N_VALS; i++) {
25626429Svs195195 result = mult_dp(val[i].floatdouble, val[1].floatdouble);
25636429Svs195195
25646429Svs195195 if (result != val[i].floatdouble) {
25656429Svs195195 observed = (uint64_t)result;
25666429Svs195195 expected = (uint64_t)val[i].floatdouble;
2567*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
25686429Svs195195 "Val Entry[%d], reg f4=f0*f2"
25696429Svs195195 "\nExpected: %lld\nObserved: %lld",
25706429Svs195195 i, val[i].floatdouble, result);
25716429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
25726429Svs195195 report, 6246, &observed, &expected, 1, 1,
25736429Svs195195 err_data);
25746429Svs195195
25756429Svs195195 return (-1);
25766429Svs195195 }
25776429Svs195195 }
25786429Svs195195
25796429Svs195195 set_fsr(prev_fsr);
25806429Svs195195 return (0);
25816429Svs195195 }
25826429Svs195195
25836429Svs195195 /*
25846429Svs195195 * compare_sp(struct fps_test_ereport *report)
25856429Svs195195 * performs single precision comparison tests.
25866429Svs195195 * If an error is found, relevant data is stored
25876429Svs195195 * in report.
25886429Svs195195 */
25896429Svs195195 static int
compare_sp(struct fps_test_ereport * report)25906429Svs195195 compare_sp(struct fps_test_ereport *report)
25916429Svs195195 {
25926429Svs195195 char err_data[MAX_INFO_SIZE];
25936429Svs195195 int i;
25946429Svs195195 uint64_t expected;
25956429Svs195195 uint64_t observed;
25966429Svs195195 unsigned long prev_fsr;
25976429Svs195195 unsigned long result = 0;
25986429Svs195195
25996429Svs195195 prev_fsr = get_fsr();
26006429Svs195195 set_fsr(prev_fsr & FSR_DISABLE_TEM);
26016429Svs195195 init_regs(0);
26026429Svs195195
26036429Svs195195 for (i = 0; i < (N_VALS - 1); i++) {
26046429Svs195195 #ifndef __lint
26056429Svs195195 result = fcmps_fcc(val[i].floatsingle, val[i].floatsingle, 0);
26066429Svs195195 #endif
26076429Svs195195
26086429Svs195195 if ((result & 0xc00) != 0) {
26096429Svs195195 observed = (uint64_t)result & 0xc00;
26106429Svs195195 expected = (uint64_t)0;
2611*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
26126429Svs195195 "f0= %d, f2= %d", i, i);
26136429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO, report,
26146429Svs195195 6247, &observed, &expected, 1, 1, err_data);
26156429Svs195195
26166429Svs195195 return (-1);
26176429Svs195195 }
26186429Svs195195
26196429Svs195195 #ifndef __lint
26206429Svs195195 result = fcmps_fcc(val[i].floatsingle,
26216429Svs195195 val[i + 1].floatsingle, 0);
26226429Svs195195 #endif
26236429Svs195195 if ((result & 0xc00) != 0x400) {
26246429Svs195195 observed = (uint64_t)result & 0xc00;
26256429Svs195195 expected = (uint64_t)0x400;
2626*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
26276429Svs195195 "f0= %d, f2= %d", i, i+1);
26286429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO, report,
26296429Svs195195 6248, &observed, &expected, 1, 1, err_data);
26306429Svs195195
26316429Svs195195 return (-1);
26326429Svs195195 }
26336429Svs195195
26346429Svs195195 #ifndef __lint
26356429Svs195195 result = fcmps_fcc(val[i + 1].floatsingle,
26366429Svs195195 val[i].floatsingle, 0);
26376429Svs195195 #endif
26386429Svs195195
26396429Svs195195 if ((result & 0xc00) != 0x800) {
26406429Svs195195 observed = (uint64_t)result & 0xc00;
26416429Svs195195 expected = (uint64_t)0x800;
2642*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
26436429Svs195195 "f0= %d, f2= %d", i+1, i);
26446429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO, report,
26456429Svs195195 6249, &observed, &expected, 1, 1, err_data);
26466429Svs195195
26476429Svs195195 return (-1);
26486429Svs195195 }
26496429Svs195195
26506429Svs195195 set_fsr(prev_fsr & FSR_DISABLE_TEM);
26516429Svs195195 #ifndef __lint
26526429Svs195195 result = fcmps_fcc(val[i].floatsingle, 0x7f800400, 0);
26536429Svs195195 #endif
26546429Svs195195
26556429Svs195195 if ((result & 0xc00) != 0xc00) {
26566429Svs195195 observed = (uint64_t)result & 0xc00;
26576429Svs195195 expected = (uint64_t)0xc00;
2658*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
26596429Svs195195 "f0= %d, f2= NaN", i);
26606429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO, report,
26616429Svs195195 6250, &observed, &expected, 1, 1, err_data);
26626429Svs195195
26636429Svs195195 return (-1);
26646429Svs195195 }
26656429Svs195195 }
26666429Svs195195
26676429Svs195195 /* Compare +/-zero and check if the comparision is okay */
26686429Svs195195
26696429Svs195195 result = fcmps_fcc(MINUS_ZERO_SP, PLUS_ZERO_SP, 0);
26706429Svs195195
26716429Svs195195 if (result & 0xc00) {
26726429Svs195195 observed = (uint64_t)result & 0xc00;
26736429Svs195195 expected = (uint64_t)0;
2674*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
26756429Svs195195 "f0= %d, f2= %d", +0, -0);
26766429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO, report,
26776429Svs195195 8251, &observed, &expected, 1, 1, err_data);
26786429Svs195195
26796429Svs195195 return (-1);
26806429Svs195195 }
26816429Svs195195
26826429Svs195195 set_fsr(prev_fsr);
26836429Svs195195 return (0);
26846429Svs195195 }
26856429Svs195195
26866429Svs195195 /*
26876429Svs195195 * compare_dp(struct fps_test_ereport *report)
26886429Svs195195 * performs double precision comparison tests.
26896429Svs195195 * If an error is found, relevant data is stored
26906429Svs195195 * in report.
26916429Svs195195 */
26926429Svs195195 static int
compare_dp(struct fps_test_ereport * report)26936429Svs195195 compare_dp(struct fps_test_ereport *report)
26946429Svs195195 {
26956429Svs195195 char err_data[MAX_INFO_SIZE];
26966429Svs195195 int i;
26976429Svs195195 unsigned long result;
26986429Svs195195 unsigned long prev_fsr;
26996429Svs195195 uint64_t observed;
27006429Svs195195 uint64_t expected;
27016429Svs195195
27026429Svs195195 prev_fsr = get_fsr();
27036429Svs195195 set_fsr(prev_fsr & FSR_DISABLE_TEM);
27046429Svs195195
27056429Svs195195 init_regs(0);
27066429Svs195195
27076429Svs195195 for (i = 0; i < (N_VALS - 1); i++) {
27086429Svs195195 result = fcmpd_fcc(val[i].floatdouble, val[i].floatdouble, 0);
27096429Svs195195 if ((result & 0xc00) != 0) {
27106429Svs195195 observed = (uint64_t)result & 0xc00;
27116429Svs195195 expected = (uint64_t)0;
2712*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
27136429Svs195195 "f0= %d, f2= %d", i, i);
27146429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO, report,
27156429Svs195195 6251, &observed, &expected, 1, 1, err_data);
27166429Svs195195
27176429Svs195195 return (-1);
27186429Svs195195 }
27196429Svs195195
27206429Svs195195 result = fcmpd_fcc(val[i].floatdouble,
27216429Svs195195 val[i + 1].floatdouble, 0);
27226429Svs195195
27236429Svs195195 if ((result & 0xc00) != 0x400) {
27246429Svs195195 observed = (uint64_t)result & 0xc00;
27256429Svs195195 expected = (uint64_t)0x400;
2726*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
27276429Svs195195 "f0= %d, f2= %d", i, i+1);
27286429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO, report,
27296429Svs195195 6252, &observed, &expected, 1, 1, err_data);
27306429Svs195195
27316429Svs195195 return (-1);
27326429Svs195195 }
27336429Svs195195
27346429Svs195195 result = fcmpd_fcc(val[i + 1].floatdouble,
27356429Svs195195 val[i].floatdouble, 0);
27366429Svs195195
27376429Svs195195 if ((result & 0xc00) != 0x800) {
27386429Svs195195 observed = (uint64_t)result & 0xc00;
27396429Svs195195 expected = (uint64_t)0x800;
2740*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
27416429Svs195195 "f0= %d, f2= %d", i+1, i);
27426429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO, report,
27436429Svs195195 6253, &observed, &expected, 1, 1, err_data);
27446429Svs195195
27456429Svs195195 return (-1);
27466429Svs195195 }
27476429Svs195195
27486429Svs195195 set_fsr(prev_fsr & FSR_DISABLE_TEM);
27496429Svs195195 result = fcmpd_fcc(val[i].floatdouble, 0x7ff0008000000000, 0);
27506429Svs195195
27516429Svs195195 if ((result & 0xc00) != 0xc00) {
27526429Svs195195 observed = (uint64_t)result & 0xc00;
27536429Svs195195 expected = (uint64_t)0xc00;
2754*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
27556429Svs195195 "f0= %d, f2=NaN", i);
27566429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO, report,
27576429Svs195195 6254, &observed, &expected, 1, 1, err_data);
27586429Svs195195
27596429Svs195195 return (-1);
27606429Svs195195 }
27616429Svs195195 }
27626429Svs195195 /* Compare +/-zero and check if the comparision is okay */
27636429Svs195195
27646429Svs195195 result = fcmpd_fcc(MINUS_ZERO_DP, PLUS_ZERO_DP, 0);
27656429Svs195195
27666429Svs195195 if (result & 0xc00) {
27676429Svs195195 observed = (uint64_t)result & 0xc00;
27686429Svs195195 expected = (uint64_t)0;
2769*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
27706429Svs195195 "f0= %d, f2= %d", +0, -0);
27716429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO, report,
27726429Svs195195 8252, &observed, &expected, 1, 1, err_data);
27736429Svs195195
27746429Svs195195 return (-1);
27756429Svs195195 }
27766429Svs195195
27776429Svs195195 set_fsr(prev_fsr);
27786429Svs195195 return (0);
27796429Svs195195 }
27806429Svs195195
27816429Svs195195 /*
27826429Svs195195 * branching(struct fps_test_ereport *report)
27836429Svs195195 * performs branch testing. If an error is found,
27846429Svs195195 * relevant data is stored in report.
27856429Svs195195 */
27866429Svs195195 static int
branching(struct fps_test_ereport * report)27876429Svs195195 branching(struct fps_test_ereport *report)
27886429Svs195195 {
27896429Svs195195 char err_data[MAX_INFO_SIZE];
27906429Svs195195 int i;
27916429Svs195195 unsigned long result;
27926429Svs195195 unsigned long prev_status;
27936429Svs195195 uint64_t observed;
27946429Svs195195 uint64_t expected;
27956429Svs195195
27966429Svs195195 prev_status = get_fsr();
27976429Svs195195 init_regs(0);
27986429Svs195195 result = get_fsr();
27996429Svs195195 result = result & 0xC0400000; /* set all exception bits to zero */
28006429Svs195195 set_fsr(result);
28016429Svs195195
28026429Svs195195 for (i = 0; i < 64; i++) {
28036429Svs195195 if (result = branches(0, val[i].floatsingle, 0x7f800400)) {
28046429Svs195195 observed = (uint64_t)result;
28056429Svs195195 expected = (uint64_t)0;
28066429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
28076429Svs195195 report, 6255, &observed, &expected, 1, 1);
28086429Svs195195
28096429Svs195195 return (-1);
28106429Svs195195 }
28116429Svs195195
28126429Svs195195 if (result = branches(1, val[i + 1].floatsingle,
28136429Svs195195 val[i].floatsingle)) {
28146429Svs195195 observed = (uint64_t)result;
28156429Svs195195 expected = (uint64_t)0;
2816*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
28176429Svs195195 "reg f0= %d, f2= %d ", i+1, i);
28186429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
28196429Svs195195 report, 6256, &observed, &expected, 1, 1,
28206429Svs195195 err_data);
28216429Svs195195
28226429Svs195195 return (-1);
28236429Svs195195 }
28246429Svs195195
28256429Svs195195 if (result = branches(2, val[i].floatsingle, 0x7f800400)) {
28266429Svs195195 observed = (uint64_t)result;
28276429Svs195195 expected = (uint64_t)0;
28286429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
28296429Svs195195 report, 6257, &observed, &expected, 1, 1);
28306429Svs195195
28316429Svs195195 return (-1);
28326429Svs195195 }
28336429Svs195195
28346429Svs195195 if (result = branches(2, val[i + 1].floatsingle,
28356429Svs195195 val[i].floatsingle)) {
28366429Svs195195 observed = (uint64_t)result;
28376429Svs195195 expected = (uint64_t)0;
2838*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
28396429Svs195195 "reg f0= %d, f2= %d ", i+1, i);
28406429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
28416429Svs195195 report, 6258, &observed, &expected, 1, 1,
28426429Svs195195 err_data);
28436429Svs195195
28446429Svs195195 return (-1);
28456429Svs195195 }
28466429Svs195195
28476429Svs195195 if (result = branches(3, val[i].floatsingle,
28486429Svs195195 val[i + 1].floatsingle)) {
28496429Svs195195 observed = (uint64_t)result;
28506429Svs195195 expected = (uint64_t)0;
2851*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
28526429Svs195195 "reg f0= %d and f2= %d ", i, i+1);
28536429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
28546429Svs195195 report, 6259, &observed, &expected, 1, 1,
28556429Svs195195 err_data);
28566429Svs195195
28576429Svs195195 return (-1);
28586429Svs195195 }
28596429Svs195195
28606429Svs195195 if (result = branches(4, val[i].floatsingle, 0x7f800400)) {
28616429Svs195195 observed = (uint64_t)result;
28626429Svs195195 expected = (uint64_t)0;
28636429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
28646429Svs195195 report, 6260, &observed, &expected, 1, 1);
28656429Svs195195
28666429Svs195195 return (-1);
28676429Svs195195 }
28686429Svs195195
28696429Svs195195 if (result = branches(4, val[i].floatsingle,
28706429Svs195195 val[i + 1].floatsingle)) {
28716429Svs195195 observed = (uint64_t)result;
28726429Svs195195 expected = (uint64_t)0;
2873*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
28746429Svs195195 "reg f0= %d, f2= %d ", i, i+1);
28756429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
28766429Svs195195 report, 6261, &observed, &expected, 1, 1,
28776429Svs195195 err_data);
28786429Svs195195
28796429Svs195195 return (-1);
28806429Svs195195 }
28816429Svs195195
28826429Svs195195 if (result = branches(5, val[i].floatsingle,
28836429Svs195195 val[i + 1].floatsingle)) {
28846429Svs195195 observed = (uint64_t)result;
28856429Svs195195 expected = (uint64_t)0;
2886*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
28876429Svs195195 "reg f0= %d, f2= %d ", i, i+1);
28886429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
28896429Svs195195 report, 6262, &observed, &expected, 1, 1,
28906429Svs195195 err_data);
28916429Svs195195
28926429Svs195195 return (-1);
28936429Svs195195 }
28946429Svs195195
28956429Svs195195 if (result = branches(5, val[i + 1].floatsingle,
28966429Svs195195 val[i].floatsingle)) {
28976429Svs195195 observed = (uint64_t)result;
28986429Svs195195 expected = (uint64_t)0;
2899*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
29006429Svs195195 "reg f0= %d, f2= %d ", i+1, i);
29016429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
29026429Svs195195 report, 6263, &observed, &expected, 1, 1,
29036429Svs195195 err_data);
29046429Svs195195
29056429Svs195195 return (-1);
29066429Svs195195 }
29076429Svs195195
29086429Svs195195 if (result = branches(6, val[i].floatsingle,
29096429Svs195195 val[i + 1].floatsingle)) {
29106429Svs195195 observed = (uint64_t)result;
29116429Svs195195 expected = (uint64_t)0;
2912*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
29136429Svs195195 "reg f0= %d, f2= %d ", i, i+1);
29146429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
29156429Svs195195 report, 6264, &observed, &expected, 1, 1,
29166429Svs195195 err_data);
29176429Svs195195
29186429Svs195195 return (-1);
29196429Svs195195 }
29206429Svs195195
29216429Svs195195 if (result = branches(7, val[i].floatsingle,
29226429Svs195195 val[i].floatsingle)) {
29236429Svs195195 observed = (uint64_t)result;
29246429Svs195195 expected = (uint64_t)0;
2925*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
29266429Svs195195 "reg f0= %d, f2= %d ", i, i);
29276429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
29286429Svs195195 report, 6265, &observed, &expected, 1, 1,
29296429Svs195195 err_data);
29306429Svs195195
29316429Svs195195 return (-1);
29326429Svs195195 }
29336429Svs195195
29346429Svs195195 if (result = branches(8, val[i].floatsingle, 0x7f800400)) {
29356429Svs195195 observed = (uint64_t)result;
29366429Svs195195 expected = (uint64_t)0;
29376429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
29386429Svs195195 report, 6266, &observed, &expected, 1, 1);
29396429Svs195195
29406429Svs195195 return (-1);
29416429Svs195195 }
29426429Svs195195
29436429Svs195195 if (result = branches(8, val[i].floatsingle,
29446429Svs195195 val[i].floatsingle)) {
29456429Svs195195 observed = (uint64_t)result;
29466429Svs195195 expected = (uint64_t)0;
2947*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
29486429Svs195195 "reg f0= %d, f2= %d ", i, i);
29496429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
29506429Svs195195 report, 6267, &observed, &expected, 1, 1,
29516429Svs195195 err_data);
29526429Svs195195
29536429Svs195195 return (-1);
29546429Svs195195 }
29556429Svs195195 if (result = branches(9, val[i].floatsingle,
29566429Svs195195 val[i].floatsingle)) {
29576429Svs195195 observed = (uint64_t)result;
29586429Svs195195 expected = (uint64_t)0;
2959*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
29606429Svs195195 "reg f0= %d, f2= %d ", i, i);
29616429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
29626429Svs195195 report, 6268, &observed, &expected, 1, 1,
29636429Svs195195 err_data);
29646429Svs195195
29656429Svs195195 return (-1);
29666429Svs195195 }
29676429Svs195195 if (result = branches(9, val[i + 1].floatsingle,
29686429Svs195195 val[i].floatsingle)) {
29696429Svs195195 observed = (uint64_t)result;
29706429Svs195195 expected = (uint64_t)0;
2971*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
29726429Svs195195 "reg f0= %d, f2= %d ", i+1, i);
29736429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
29746429Svs195195 report, 6269, &observed, &expected, 1, 1,
29756429Svs195195 err_data);
29766429Svs195195
29776429Svs195195 return (-1);
29786429Svs195195 }
29796429Svs195195
29806429Svs195195 if (result = branches(10, val[i].floatsingle, 0x7f800400)) {
29816429Svs195195 observed = (uint64_t)result;
29826429Svs195195 expected = (uint64_t)0;
29836429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
29846429Svs195195 report, 6270, &observed, &expected, 1, 1);
29856429Svs195195
29866429Svs195195 return (-1);
29876429Svs195195 }
29886429Svs195195
29896429Svs195195 if (result = branches(10, val[i].floatsingle,
29906429Svs195195 val[i].floatsingle)) {
29916429Svs195195 observed = (uint64_t)result;
29926429Svs195195 expected = (uint64_t)0;
2993*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
29946429Svs195195 "reg f0= %d, f2= %d", i, i);
29956429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
29966429Svs195195 report, 6271, &observed, &expected, 1, 1,
29976429Svs195195 err_data);
29986429Svs195195
29996429Svs195195 return (-1);
30006429Svs195195 }
30016429Svs195195
30026429Svs195195 if (result = branches(10, val[i + 1].floatsingle,
30036429Svs195195 val[i].floatsingle)) {
30046429Svs195195 observed = (uint64_t)result;
30056429Svs195195 expected = (uint64_t)0;
3006*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
30076429Svs195195 "reg f0= %d, f2= %d", i+1, i);
30086429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
30096429Svs195195 report, 6272, &observed, &expected, 1, 1,
30106429Svs195195 err_data);
30116429Svs195195
30126429Svs195195 return (-1);
30136429Svs195195 }
30146429Svs195195
30156429Svs195195 if (result = branches(11, val[i].floatsingle,
30166429Svs195195 val[i + 1].floatsingle)) {
30176429Svs195195 observed = (uint64_t)result;
30186429Svs195195 expected = (uint64_t)0;
3019*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
30206429Svs195195 "reg f0= %d, f2= %d", i, i+1);
30216429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
30226429Svs195195 report, 6273, &observed, &expected, 1, 1,
30236429Svs195195 err_data);
30246429Svs195195
30256429Svs195195 return (-1);
30266429Svs195195 }
30276429Svs195195
30286429Svs195195 if (result = branches(11, val[i].floatsingle,
30296429Svs195195 val[i].floatsingle)) {
30306429Svs195195 observed = (uint64_t)result;
30316429Svs195195 expected = (uint64_t)0;
3032*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
30336429Svs195195 "reg f0= %d, f2= %d", i, i);
30346429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
30356429Svs195195 report, 6274, &observed, &expected, 1, 1,
30366429Svs195195 err_data);
30376429Svs195195
30386429Svs195195 return (-1);
30396429Svs195195 }
30406429Svs195195
30416429Svs195195 if (result = branches(12, val[i].floatsingle, 0x7f800400)) {
30426429Svs195195 observed = (uint64_t)result;
30436429Svs195195 expected = (uint64_t)0;
30446429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
30456429Svs195195 report, 6275, &observed, &expected, 1, 1);
30466429Svs195195
30476429Svs195195 return (-1);
30486429Svs195195 }
30496429Svs195195
30506429Svs195195 if (result = branches(12, val[i].floatsingle,
30516429Svs195195 val[i + 1].floatsingle)) {
30526429Svs195195 observed = (uint64_t)result;
30536429Svs195195 expected = (uint64_t)0;
3054*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
30556429Svs195195 "reg f0= %d, f2= %d", i, i+1);
30566429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
30576429Svs195195 report, 6276, &observed, &expected, 1, 1,
30586429Svs195195 err_data);
30596429Svs195195
30606429Svs195195 return (-1);
30616429Svs195195 }
30626429Svs195195
30636429Svs195195 if (result = branches(12, val[i].floatsingle,
30646429Svs195195 val[i].floatsingle)) {
30656429Svs195195 observed = (uint64_t)result;
30666429Svs195195 expected = (uint64_t)0;
3067*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
30686429Svs195195 "reg f0= %d, f2= %d", i, i);
30696429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
30706429Svs195195 report, 6277, &observed, &expected, 1, 1,
30716429Svs195195 err_data);
30726429Svs195195
30736429Svs195195 return (-1);
30746429Svs195195 }
30756429Svs195195
30766429Svs195195 if (result = branches(13, val[i].floatsingle,
30776429Svs195195 val[i + 1].floatsingle)) {
30786429Svs195195 observed = (uint64_t)result;
30796429Svs195195 expected = (uint64_t)0;
3080*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
30816429Svs195195 "reg f0= %d, f2= %d", i, i+1);
30826429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
30836429Svs195195 report, 6278, &observed, &expected, 1, 1,
30846429Svs195195 err_data);
30856429Svs195195
30866429Svs195195 return (-1);
30876429Svs195195 }
30886429Svs195195
30896429Svs195195 if (result = branches(14, val[i].floatsingle,
30906429Svs195195 val[i + 1].floatsingle)) {
30916429Svs195195 observed = (uint64_t)result;
30926429Svs195195 expected = (uint64_t)0;
3093*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
30946429Svs195195 "reg f0= %d, f2= %d", i, i+1);
30956429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
30966429Svs195195 report, 6279, &observed, &expected, 1, 1,
30976429Svs195195 err_data);
30986429Svs195195
30996429Svs195195 return (-1);
31006429Svs195195 }
31016429Svs195195
31026429Svs195195 if (result = branches(15, val[i].floatsingle,
31036429Svs195195 val[i + 1].floatsingle)) {
31046429Svs195195 observed = (uint64_t)result;
31056429Svs195195 expected = (uint64_t)0;
3106*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
31076429Svs195195 "reg f0= %d, f2= %d ", i, i+1);
31086429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
31096429Svs195195 report, 6280, &observed, &expected, 1, 1,
31106429Svs195195 err_data);
31116429Svs195195
31126429Svs195195 return (-1);
31136429Svs195195 }
31146429Svs195195 }
31156429Svs195195
31166429Svs195195 set_fsr(prev_status);
31176429Svs195195 return (0);
31186429Svs195195
31196429Svs195195 }
31206429Svs195195
31216429Svs195195 /*
31226429Svs195195 * branching(struct fps_test_ereport *report)
31236429Svs195195 * performs negative branch testing. If an error is found,
31246429Svs195195 * relevant data is stored in report.
31256429Svs195195 */
31266429Svs195195 static int
no_branching(struct fps_test_ereport * report)31276429Svs195195 no_branching(struct fps_test_ereport *report)
31286429Svs195195 {
31296429Svs195195 char err_data[MAX_INFO_SIZE];
31306429Svs195195 int i;
31316429Svs195195 uint64_t observed;
31326429Svs195195 uint64_t expected;
31336429Svs195195 unsigned long result;
31346429Svs195195 unsigned long prev_status;
31356429Svs195195
31366429Svs195195 prev_status = get_fsr();
31376429Svs195195 init_regs(0);
31386429Svs195195 result = get_fsr();
31396429Svs195195 result = result & 0xC0400000; /* set all exception bits to zero */
31406429Svs195195 set_fsr(result);
31416429Svs195195
31426429Svs195195 for (i = 0; i < 64; i++) {
31436429Svs195195 if (!(branches(0, val[i].floatsingle,
31446429Svs195195 val[i].floatsingle))) {
31456429Svs195195 observed = (uint64_t)0;
31466429Svs195195 expected = (uint64_t)1;
31476429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
31486429Svs195195 report, 6281, &observed, &expected, 1, 1);
31496429Svs195195
31506429Svs195195 return (-1);
31516429Svs195195 }
31526429Svs195195
31536429Svs195195 if (!(branches(1, val[i].floatsingle,
31546429Svs195195 val[i].floatsingle))) {
31556429Svs195195 observed = (uint64_t)0;
31566429Svs195195 expected = (uint64_t)1;
3157*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
31586429Svs195195 "reg f0= %d, f2= %d", i, i);
31596429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
31606429Svs195195 report, 6282, &observed, &expected, 1, 1,
31616429Svs195195 err_data);
31626429Svs195195
31636429Svs195195 return (-1);
31646429Svs195195 }
31656429Svs195195
31666429Svs195195 if (!(branches(2, val[i].floatsingle,
31676429Svs195195 val[i].floatsingle))) {
31686429Svs195195 observed = (uint64_t)0;
31696429Svs195195 expected = (uint64_t)1;
3170*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
31716429Svs195195 "reg f0= %d, f2= %d", i, i);
31726429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
31736429Svs195195 report, 6283, &observed, &expected, 1, 1,
31746429Svs195195 err_data);
31756429Svs195195
31766429Svs195195 return (-1);
31776429Svs195195 }
31786429Svs195195
31796429Svs195195 if (!(branches(3, val[i].floatsingle,
31806429Svs195195 val[i].floatsingle))) {
31816429Svs195195 observed = (uint64_t)0;
31826429Svs195195 expected = (uint64_t)1;
3183*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
31846429Svs195195 "reg f0= %d, f2= %d", i, i);
31856429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
31866429Svs195195 report, 6284, &observed, &expected, 1, 1,
31876429Svs195195 err_data);
31886429Svs195195
31896429Svs195195 return (-1);
31906429Svs195195 }
31916429Svs195195
31926429Svs195195 if (!(branches(4, val[i].floatsingle,
31936429Svs195195 val[i].floatsingle))) {
31946429Svs195195 observed = (uint64_t)0;
31956429Svs195195 expected = (uint64_t)1;
3196*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
31976429Svs195195 "reg f0= %d, f2= %d", i, i);
31986429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
31996429Svs195195 report, 6285, &observed, &expected, 1, 1,
32006429Svs195195 err_data);
32016429Svs195195
32026429Svs195195 return (-1);
32036429Svs195195 }
32046429Svs195195
32056429Svs195195 if (!(branches(5, val[i].floatsingle,
32066429Svs195195 val[i].floatsingle))) {
32076429Svs195195 observed = (uint64_t)0;
32086429Svs195195 expected = (uint64_t)1;
3209*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
32106429Svs195195 "reg f0= %d, f2= %d", i, i);
32116429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
32126429Svs195195 report, 6286, &observed, &expected, 1, 1,
32136429Svs195195 err_data);
32146429Svs195195
32156429Svs195195 return (-1);
32166429Svs195195 }
32176429Svs195195
32186429Svs195195 if (!(branches(6, val[i].floatsingle,
32196429Svs195195 val[i].floatsingle))) {
32206429Svs195195 observed = (uint64_t)0;
32216429Svs195195 expected = (uint64_t)1;
3222*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
32236429Svs195195 "reg f0= %d, f2= %d", i, i);
32246429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
32256429Svs195195 report, 6287, &observed, &expected, 1, 1,
32266429Svs195195 err_data);
32276429Svs195195
32286429Svs195195 return (-1);
32296429Svs195195 }
32306429Svs195195
32316429Svs195195 if (!(branches(7, val[i + 1].floatsingle,
32326429Svs195195 val[i].floatsingle))) {
32336429Svs195195 observed = (uint64_t)0;
32346429Svs195195 expected = (uint64_t)1;
3235*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
32366429Svs195195 "reg f0= %d, f2= %d", i+1, i);
32376429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
32386429Svs195195 report, 6288, &observed, &expected, 1, 1,
32396429Svs195195 err_data);
32406429Svs195195
32416429Svs195195 return (-1);
32426429Svs195195 }
32436429Svs195195
32446429Svs195195 if (!(branches(8, val[i + 1].floatsingle,
32456429Svs195195 val[i].floatsingle))) {
32466429Svs195195 observed = (uint64_t)0;
32476429Svs195195 expected = (uint64_t)1;
3248*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
32496429Svs195195 "reg f0= %d, f2= %d", i+1, i);
32506429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
32516429Svs195195 report, 6289, &observed, &expected, 1, 1,
32526429Svs195195 err_data);
32536429Svs195195
32546429Svs195195 return (-1);
32556429Svs195195 }
32566429Svs195195
32576429Svs195195 if (!(branches(9, val[i].floatsingle,
32586429Svs195195 val[i + 1].floatsingle))) {
32596429Svs195195 observed = (uint64_t)0;
32606429Svs195195 expected = (uint64_t)1;
3261*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
32626429Svs195195 "reg f0= %d, f2= %d", i, i+1);
32636429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
32646429Svs195195 report, 6290, &observed, &expected, 1, 1,
32656429Svs195195 err_data);
32666429Svs195195
32676429Svs195195 return (-1);
32686429Svs195195 }
32696429Svs195195
32706429Svs195195 if (!(branches(10, val[i].floatsingle,
32716429Svs195195 val[i + 1].floatsingle))) {
32726429Svs195195 observed = (uint64_t)0;
32736429Svs195195 expected = (uint64_t)1;
3274*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
32756429Svs195195 "reg f0= %d, f2= %d", i, i+1);
32766429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
32776429Svs195195 report, 6291, &observed, &expected, 1, 1,
32786429Svs195195 err_data);
32796429Svs195195
32806429Svs195195 return (-1);
32816429Svs195195 }
32826429Svs195195
32836429Svs195195 if (!(branches(11, val[i + 1].floatsingle,
32846429Svs195195 val[i].floatsingle))) {
32856429Svs195195 observed = (uint64_t)0;
32866429Svs195195 expected = (uint64_t)1;
3287*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
32886429Svs195195 "reg f0= %d, f2= %d", i+1, i);
32896429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
32906429Svs195195 report, 6292, &observed, &expected, 1, 1,
32916429Svs195195 err_data);
32926429Svs195195
32936429Svs195195 return (-1);
32946429Svs195195 }
32956429Svs195195
32966429Svs195195 if (!(branches(12, val[i + 1].floatsingle,
32976429Svs195195 val[i].floatsingle))) {
32986429Svs195195 observed = (uint64_t)0;
32996429Svs195195 expected = (uint64_t)1;
3300*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
33016429Svs195195 "reg f0= %d, f2= %d", i+1, i);
33026429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
33036429Svs195195 report, 6293, &observed, &expected, 1, 1,
33046429Svs195195 err_data);
33056429Svs195195
33066429Svs195195 return (-1);
33076429Svs195195 }
33086429Svs195195
33096429Svs195195 if (!(result = branches(13, val[i].floatsingle, 0x7f800400))) {
33106429Svs195195 observed = (uint64_t)0;
33116429Svs195195 expected = (uint64_t)1;
33126429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO,
33136429Svs195195 report, 6294, &observed, &expected, 1, 1);
33146429Svs195195
33156429Svs195195 return (-1);
33166429Svs195195 }
33176429Svs195195
33186429Svs195195 }
33196429Svs195195
33206429Svs195195 set_fsr(prev_status);
33216429Svs195195
33226429Svs195195 return (0);
33236429Svs195195 }
33246429Svs195195
33256429Svs195195 /*
33266429Svs195195 * compare_sp_except(struct fps_test_ereport *report)
33276429Svs195195 * does single precision exception testing.
33286429Svs195195 * If an error is found, relevant data is stored
33296429Svs195195 * in report.
33306429Svs195195 */
33316429Svs195195 static int
compare_sp_except(struct fps_test_ereport * report)33326429Svs195195 compare_sp_except(struct fps_test_ereport *report)
33336429Svs195195 {
33346429Svs195195 char err_data[MAX_INFO_SIZE];
33356429Svs195195 int i;
33366429Svs195195 unsigned long result;
33376429Svs195195 unsigned long prev_status;
33386429Svs195195 uint64_t observed;
33396429Svs195195 uint64_t expected;
33406429Svs195195
33416429Svs195195 prev_status = get_fsr();
33426429Svs195195 init_regs(0);
33436429Svs195195 result = get_fsr();
33446429Svs195195 result = result | FSR_ENABLE_TEM_NV;
33456429Svs195195
33466429Svs195195 set_fsr(result);
33476429Svs195195
33486429Svs195195 for (i = 0; i < N_VALS; i++) {
33496429Svs195195
33506429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
33516429Svs195195 result = cmp_s_ex(val[i].floatsingle, 0x7fbfffff);
33526429Svs195195 if (trap_flag) {
33536429Svs195195 observed = (uint64_t)trap_flag;
33546429Svs195195 expected = (uint64_t)0;
3355*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
33566429Svs195195 "fcmpxs exception did not occur, fsr=%lo",
33576429Svs195195 fsr_at_trap);
33586429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
33596429Svs195195 report, 6295, &observed, &expected, 1, 1,
33606429Svs195195 err_data);
33616429Svs195195
33626429Svs195195 return (-1);
33636429Svs195195 }
33646429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
33656429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
33666429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
3367*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
33686429Svs195195 "fcmpxs exception did not occur, fsr=%lo",
33696429Svs195195 fsr_at_trap);
33706429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
33716429Svs195195 report, 6296, &observed, &expected, 1, 1,
33726429Svs195195 err_data);
33736429Svs195195
33746429Svs195195 return (-1);
33756429Svs195195 }
33766429Svs195195 }
33776429Svs195195
33786429Svs195195 set_fsr(prev_status);
33796429Svs195195 return (0);
33806429Svs195195 }
33816429Svs195195
33826429Svs195195 /*
33836429Svs195195 * compare_dp_except(struct fps_test_ereport *report)
33846429Svs195195 * does double precision exception testing.
33856429Svs195195 * If an error is found, relevant data is stored
33866429Svs195195 * in report.
33876429Svs195195 */
33886429Svs195195 static int
compare_dp_except(struct fps_test_ereport * report)33896429Svs195195 compare_dp_except(struct fps_test_ereport *report)
33906429Svs195195 {
33916429Svs195195 char err_data[MAX_INFO_SIZE];
33926429Svs195195 int i;
33936429Svs195195 unsigned long result;
33946429Svs195195 unsigned long prev_status;
33956429Svs195195 uint64_t observed;
33966429Svs195195 uint64_t expected;
33976429Svs195195
33986429Svs195195 prev_status = get_fsr();
33996429Svs195195 init_regs(0);
34006429Svs195195 result = get_fsr();
34016429Svs195195 result = result | FSR_ENABLE_TEM_NV;
34026429Svs195195 set_fsr(result);
34036429Svs195195
34046429Svs195195 for (i = 0; i < 199; i++) {
34056429Svs195195
34066429Svs195195 trap_flag = trap_flag | TRAP_SOLICITED;
34076429Svs195195 result = cmp_d_ex(val[i].floatdouble, 0x7ff0008000000000);
34086429Svs195195 if (trap_flag) {
34096429Svs195195 observed = (uint64_t)trap_flag;
34106429Svs195195 expected = (uint64_t)0;
3411*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
34126429Svs195195 "fcmpxd exception did not occur, fsr=%lo",
34136429Svs195195 fsr_at_trap);
34146429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
34156429Svs195195 report, 6297, &observed, &expected, 1, 1,
34166429Svs195195 err_data);
34176429Svs195195
34186429Svs195195 return (-1);
34196429Svs195195 }
34206429Svs195195 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
34216429Svs195195 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
34226429Svs195195 expected = (uint64_t)FSR_CEXC_NV;
3423*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
34246429Svs195195 "fcmpxd exception did not occur, fsr=%lo",
34256429Svs195195 fsr_at_trap);
34266429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
34276429Svs195195 report, 6298, &observed, &expected, 1, 1,
34286429Svs195195 err_data);
34296429Svs195195
34306429Svs195195 return (-1);
34316429Svs195195 }
34326429Svs195195 }
34336429Svs195195
34346429Svs195195 set_fsr(prev_status);
34356429Svs195195 return (0);
34366429Svs195195 }
34376429Svs195195
34386429Svs195195 /*
34396429Svs195195 * Patterns used in the registers functions that are.
34406429Svs195195 * loaded into all registers.
34416429Svs195195 */
34426429Svs195195
34436429Svs195195 #define ALLZEROES_DP 0x0000000000000000UL
34446429Svs195195 #define ALLZEROES_SP 0x00000000U
34456429Svs195195 #define ALLONES_DP 0xFFFFFFFFFFFFFFFFUL
34466429Svs195195 #define ALLONES_SP 0xFFFFFFFFU
34476429Svs195195
34486429Svs195195 /*
34496429Svs195195 * registers_four(struct fps_test_ereport *report)
34506429Svs195195 * loads each nibble with 0xf on all the available FP
34516429Svs195195 * registers in single precision.
34526429Svs195195 * If an error is found, relevant data is stored
34536429Svs195195 * in report.
34546429Svs195195 */
34556429Svs195195 static int
registers_four(struct fps_test_ereport * report)34566429Svs195195 registers_four(struct fps_test_ereport *report)
34576429Svs195195 {
34586429Svs195195 char err_data[MAX_INFO_SIZE];
34596429Svs195195 int i;
34606429Svs195195 unsigned int result = 0;
34616429Svs195195 uint64_t observed;
34626429Svs195195 uint64_t expected;
34636429Svs195195
34646429Svs195195 #define ARB_VAL 4
34656429Svs195195
34666429Svs195195 for (i = 0; i < ARB_VAL; i++) {
34676429Svs195195 init_regs(ALLZEROES_SP);
34686429Svs195195 init_regs(ALLONES_SP);
34696429Svs195195 }
34706429Svs195195
34716429Svs195195 init_regs(ALLZEROES_SP);
34726429Svs195195 for (i = 0; i < 32; i++) {
34736429Svs195195 read_fpreg(&result, i);
34746429Svs195195 if (result != ALLZEROES_SP) {
34756429Svs195195 observed = (uint64_t)result;
34766429Svs195195 expected = (uint64_t)ALLZEROES_SP;
3477*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
34786429Svs195195 "Reg: %d\nExpected: %d\nObserved: %d",
34796429Svs195195 i, ALLZEROES_SP, result);
34806429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
34816429Svs195195 report, 6345, &observed, &expected, 1, 1,
34826429Svs195195 err_data);
34836429Svs195195
34846429Svs195195 return (-1);
34856429Svs195195 }
34866429Svs195195 }
34876429Svs195195
34886429Svs195195 init_regs(ALLONES_SP);
34896429Svs195195
34906429Svs195195 for (i = 0; i < 32; i++) {
34916429Svs195195 read_fpreg(&result, i);
34926429Svs195195 if (result != ALLONES_SP) {
34936429Svs195195 observed = (uint64_t)result;
34946429Svs195195 expected = (uint64_t)ALLONES_SP;
3495*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
34966429Svs195195 "Reg: %d\nExpected: %d\nObserved: %d",
34976429Svs195195 i, ALLONES_SP, result);
34986429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
34996429Svs195195 report, 8345, &observed, &expected, 1, 1,
35006429Svs195195 err_data);
35016429Svs195195
35026429Svs195195 return (-1);
35036429Svs195195 }
35046429Svs195195 }
35056429Svs195195
35066429Svs195195 return (0);
35076429Svs195195 }
35086429Svs195195
35096429Svs195195 /*
35106429Svs195195 * registers_four_dp(struct fps_test_ereport *report)
35116429Svs195195 * loads each nibble with 0xf on all the available FP
35126429Svs195195 * registers in double precision.
35136429Svs195195 * If an error is found, relevant data is stored
35146429Svs195195 * in report.
35156429Svs195195 */
35166429Svs195195 static int
registers_four_dp(struct fps_test_ereport * report)35176429Svs195195 registers_four_dp(struct fps_test_ereport *report)
35186429Svs195195 {
35196429Svs195195 char err_data[MAX_INFO_SIZE];
35206429Svs195195 int i;
35216429Svs195195 uint64_t expected;
35226429Svs195195 uint64_t observed;
35236429Svs195195 unsigned long result;
35246429Svs195195
35256429Svs195195 #define ARB_VAL 4
35266429Svs195195
35276429Svs195195 for (i = 0; i < ARB_VAL; i++) {
35286429Svs195195 init_regs_dp(ALLZEROES_DP);
35296429Svs195195 init_regs_dp(ALLONES_DP);
35306429Svs195195 }
35316429Svs195195
35326429Svs195195 init_regs_dp(16);
35336429Svs195195 read_fpreg_dp(&result, 2);
35346429Svs195195 init_regs_dp(ALLZEROES_DP);
35356429Svs195195 for (i = 0; i < 64; i = i + 2) {
35366429Svs195195 result = ALLONES_DP;
35376429Svs195195 read_fpreg_dp(&result, i);
35386429Svs195195 if (result != ALLZEROES_DP) {
35396429Svs195195 observed = (uint64_t)result;
35406429Svs195195 expected = (uint64_t)ALLZEROES_DP;
3541*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
35426429Svs195195 "Reg: %d\nExpected: %lld\nObserved: %lld",
35436429Svs195195 i, ALLZEROES_DP, result);
35446429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
35456429Svs195195 report, 6346, &observed, &expected, 1, 1,
35466429Svs195195 err_data);
35476429Svs195195
35486429Svs195195 return (-1);
35496429Svs195195 }
35506429Svs195195 }
35516429Svs195195
35526429Svs195195 init_regs_dp(ALLONES_DP);
35536429Svs195195
35546429Svs195195 for (i = 30; i < 64; i = i + 2) {
35556429Svs195195 read_fpreg_dp(&result, i);
35566429Svs195195 if (result != ALLONES_DP) {
35576429Svs195195 observed = (uint64_t)result;
35586429Svs195195 expected = (uint64_t)ALLONES_DP;
3559*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
35606429Svs195195 "Reg: %d\nExpected: %lld\nObserved: %lld",
35616429Svs195195 i, ALLONES_DP, result);
35626429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
35636429Svs195195 report, 8346, &observed, &expected, 1, 1,
35646429Svs195195 err_data);
35656429Svs195195
35666429Svs195195 return (-1);
35676429Svs195195 }
35686429Svs195195 }
35696429Svs195195
35706429Svs195195 return (0);
35716429Svs195195 }
35726429Svs195195
35736429Svs195195 /*
35746429Svs195195 * registers_two(struct fps_test_ereport *report)
35756429Svs195195 * tests single precision rotating ones through the
35766429Svs195195 * floating point registers. If an error is found,
35776429Svs195195 * relevant data is stored in report.
35786429Svs195195 */
35796429Svs195195 static int
registers_two(struct fps_test_ereport * report)35806429Svs195195 registers_two(struct fps_test_ereport *report)
35816429Svs195195 {
35826429Svs195195 char err_data[MAX_INFO_SIZE];
35836429Svs195195 int i;
35846429Svs195195 int j;
35856429Svs195195 uint64_t expected;
35866429Svs195195 uint64_t observed;
35876429Svs195195 unsigned int result;
35886429Svs195195 unsigned int value;
35896429Svs195195
35906429Svs195195 for (j = 0; j < 32; j++) {
35916429Svs195195 for (i = 0; i < 32; i++) {
35926429Svs195195 value = (1 << i);
35936429Svs195195 if ((result = register_test(j, value)) != value) {
35946429Svs195195 observed = (uint64_t)result;
35956429Svs195195 expected = (uint64_t)value;
3596*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
35976429Svs195195 "Reg: %d\nExpected: %d\nObserved: %d",
35986429Svs195195 j, value, result);
35996429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
36006429Svs195195 report, 6301, &observed, &expected, 1,
36016429Svs195195 1, err_data);
36026429Svs195195
36036429Svs195195 return (-1);
36046429Svs195195 }
36056429Svs195195 }
36066429Svs195195 }
36076429Svs195195
36086429Svs195195 return (0);
36096429Svs195195 }
36106429Svs195195
36116429Svs195195 /*
36126429Svs195195 * registers_two_dp(struct fps_test_ereport *report)
36136429Svs195195 * tests double precision rotating ones through the
36146429Svs195195 * floating point registers. If an error is found,
36156429Svs195195 * relevant data is stored in report.
36166429Svs195195 */
36176429Svs195195 static int
registers_two_dp(struct fps_test_ereport * report)36186429Svs195195 registers_two_dp(struct fps_test_ereport *report)
36196429Svs195195 {
36206429Svs195195 char err_data[MAX_INFO_SIZE];
36216429Svs195195 int i;
36226429Svs195195 int j;
36236429Svs195195 uint64_t observed;
36246429Svs195195 uint64_t expected;
36256429Svs195195 unsigned long result;
36266429Svs195195 unsigned long value;
36276429Svs195195
36286429Svs195195 for (j = 0; j < 32; j = j + 2) {
36296429Svs195195 for (i = 0; i < 64; i++) {
36306429Svs195195 value = (1 << i);
36316429Svs195195 result = register_test_dp(j, value);
36326429Svs195195
36336429Svs195195 if (result != value) {
36346429Svs195195 observed = (*(uint64_t *)&result);
36356429Svs195195 expected = (*(uint64_t *)&value);
3636*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
36376429Svs195195 "Reg: %d\nExpected: %lld\nObserved: %lld",
36386429Svs195195 j, value, result);
36396429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
36406429Svs195195 report, 5301, &observed, &expected, 1,
36416429Svs195195 1, err_data);
36426429Svs195195 return (-1);
36436429Svs195195 }
36446429Svs195195 }
36456429Svs195195 }
36466429Svs195195
36476429Svs195195 return (0);
36486429Svs195195 }
36496429Svs195195
36506429Svs195195 /*
36516429Svs195195 * registers_one(struct fps_test_ereport *report)
36526429Svs195195 * passes a single precision pattern through the
36536429Svs195195 * floating point registers. If an error is found,
36546429Svs195195 * relevant data is stored in report.
36556429Svs195195 */
36566429Svs195195 static int
registers_one(struct fps_test_ereport * report)36576429Svs195195 registers_one(struct fps_test_ereport *report)
36586429Svs195195 {
36596429Svs195195 char err_data[MAX_INFO_SIZE];
36606429Svs195195 int i;
36616429Svs195195 int j;
36626429Svs195195 unsigned int result;
36636429Svs195195
36646429Svs195195 uint64_t observed;
36656429Svs195195 uint64_t expected;
36666429Svs195195
36676429Svs195195 for (i = 0; i < 32; i++) {
36686429Svs195195 for (j = 0; j < PAT_NUM; j++) {
36696429Svs195195 result = register_test(i, pat[j]);
36706429Svs195195 if (result != pat[j]) {
36716429Svs195195 observed = (uint64_t)result;
36726429Svs195195 expected = (uint64_t)pat[j];
3673*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
36746429Svs195195 "Reg: %d\nExpected: %d\nObserved: %d",
36756429Svs195195 i, pat[j], result);
36766429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
36776429Svs195195 report, 6302, &observed, &expected, 1,
36786429Svs195195 1, err_data);
36796429Svs195195
36806429Svs195195 return (-1);
36816429Svs195195 }
36826429Svs195195 }
36836429Svs195195 }
36846429Svs195195
36856429Svs195195 return (0);
36866429Svs195195 }
36876429Svs195195
36886429Svs195195 /*
36896429Svs195195 * registers_one_dp(struct fps_test_ereport *report)
36906429Svs195195 * passes a double precision pattern through the
36916429Svs195195 * floating point registers. If an error is found,
36926429Svs195195 * relevant data is stored in report.
36936429Svs195195 */
36946429Svs195195 static int
registers_one_dp(struct fps_test_ereport * report)36956429Svs195195 registers_one_dp(struct fps_test_ereport *report)
36966429Svs195195 {
36976429Svs195195 char err_data[MAX_INFO_SIZE];
36986429Svs195195 int i;
36996429Svs195195 int j;
37006429Svs195195 unsigned long result;
37016429Svs195195
37026429Svs195195 uint64_t observed;
37036429Svs195195 uint64_t expected;
37046429Svs195195
37056429Svs195195 for (i = 0; i < 64; i = i + 2) {
37066429Svs195195 for (j = 0; j < PAT_DP_NUM; j++) {
37076429Svs195195 result = register_test_dp(i, pat_dp[j]);
37086429Svs195195 if (result != pat_dp[j]) {
37096429Svs195195 observed = (uint64_t)result;
37106429Svs195195 expected = (uint64_t)pat[j];
3711*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
37126429Svs195195 "Reg: %d\nExpected: %lld"
37136429Svs195195 "\nObserved: %lld",
37146429Svs195195 i, pat[j], result);
37156429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO,
37166429Svs195195 report, 5302, &observed, &expected, 1,
37176429Svs195195 1, err_data);
37186429Svs195195
37196429Svs195195 return (-1);
37206429Svs195195 }
37216429Svs195195 }
37226429Svs195195 }
37236429Svs195195
37246429Svs195195 return (0);
37256429Svs195195 }
37266429Svs195195
37276429Svs195195 /*
37286429Svs195195 * sigsegv_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
37296429Svs195195 * sets up the sigsegv signal handler. If reached during
37306429Svs195195 * non-negative testing, application exits.
37316429Svs195195 */
37326429Svs195195 /* ARGSUSED */
37336429Svs195195 static void
sigsegv_handler(int sig,siginfo_t * sip,ucontext_t * ucp)37346429Svs195195 sigsegv_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
37356429Svs195195 {
37366429Svs195195 ucp->uc_mcontext.fpregs.fpu_qcnt = 0;
37376429Svs195195
37386429Svs195195 fsr_at_trap = ucp->uc_mcontext.fpregs.fpu_fsr;
37396429Svs195195 if (trap_flag == (trap_flag | TRAP_SOLICITED)) {
37406429Svs195195 trap_flag = trap_flag & (~TRAP_SOLICITED);
37416429Svs195195 return;
37426429Svs195195 }
37436429Svs195195 trap_flag = trap_flag | TRAP_UNSOLICITED;
37446429Svs195195
37456429Svs195195 _exit(FPU_SIG_SEGV);
37466429Svs195195 }
37476429Svs195195
37486429Svs195195 /*
37496429Svs195195 * sigbus_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
37506429Svs195195 * sets up the sigbus signal handler. If reached during
37516429Svs195195 * non-negative testing, application exits.
37526429Svs195195 */
37536429Svs195195 /* ARGSUSED */
37546429Svs195195 static void
sigbus_handler(int sig,siginfo_t * sip,ucontext_t * ucp)37556429Svs195195 sigbus_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
37566429Svs195195 {
37576429Svs195195 ucp->uc_mcontext.fpregs.fpu_qcnt = 0;
37586429Svs195195
37596429Svs195195 fsr_at_trap = ucp->uc_mcontext.fpregs.fpu_fsr;
37606429Svs195195 if (trap_flag == (trap_flag | TRAP_SOLICITED)) {
37616429Svs195195 trap_flag = trap_flag & (~TRAP_SOLICITED);
37626429Svs195195 return;
37636429Svs195195 }
37646429Svs195195 trap_flag = trap_flag | TRAP_UNSOLICITED;
37656429Svs195195
37666429Svs195195 _exit(FPU_SIG_BUS);
37676429Svs195195
37686429Svs195195 }
37696429Svs195195
37706429Svs195195 /*
37716429Svs195195 * sigfpe_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
37726429Svs195195 * sets up the sigfpe signal handler. If reached during
37736429Svs195195 * non-negative testing, application exits.
37746429Svs195195 */
37756429Svs195195 /* ARGSUSED */
37766429Svs195195 static void
sigfpe_handler(int sig,siginfo_t * sip,ucontext_t * ucp)37776429Svs195195 sigfpe_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
37786429Svs195195 {
37796429Svs195195 ucp->uc_mcontext.fpregs.fpu_qcnt = 0;
37806429Svs195195
37816429Svs195195 fsr_at_trap = ucp->uc_mcontext.fpregs.fpu_fsr;
37826429Svs195195 if (trap_flag == (trap_flag | TRAP_SOLICITED)) {
37836429Svs195195 trap_flag = trap_flag & (~TRAP_SOLICITED);
37846429Svs195195 return;
37856429Svs195195 }
37866429Svs195195 trap_flag = trap_flag | TRAP_UNSOLICITED;
37876429Svs195195
37886429Svs195195 _exit(FPU_SIG_FPE);
37896429Svs195195 }
37906429Svs195195
37916429Svs195195 /*
37926429Svs195195 * sigill_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
37936429Svs195195 * sets up the sigill signal handler. If reached during
37946429Svs195195 * non-negative testing, application exits.
37956429Svs195195 */
37966429Svs195195 /* ARGSUSED */
37976429Svs195195 static void
sigill_handler(int sig,siginfo_t * sip,ucontext_t * ucp)37986429Svs195195 sigill_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
37996429Svs195195 {
38006429Svs195195 ucp->uc_mcontext.fpregs.fpu_qcnt = 0;
38016429Svs195195
38026429Svs195195 fsr_at_trap = ucp->uc_mcontext.fpregs.fpu_fsr;
38036429Svs195195 if (trap_flag == (trap_flag | TRAP_SOLICITED)) {
38046429Svs195195 trap_flag = trap_flag & (~TRAP_SOLICITED);
38056429Svs195195 return;
38066429Svs195195 }
38076429Svs195195 trap_flag = trap_flag | TRAP_UNSOLICITED;
38086429Svs195195
38096429Svs195195 _exit(FPU_SIG_ILL);
38106429Svs195195 }
38116429Svs195195
38126429Svs195195 /*
38136429Svs195195 * winitfp() sets the signal handlers used
38146429Svs195195 * for negative testing. If sigaction fails,
38156429Svs195195 * the program exits.
38166429Svs195195 */
38176429Svs195195 int
winitfp()38186429Svs195195 winitfp()
38196429Svs195195 {
3820*7186Skk158166 (void) sigemptyset(&newfpe.sa_mask);
38216429Svs195195 newfpe.sa_flags = SA_SIGINFO;
38226429Svs195195 newfpe.sa_handler = sigfpe_handler;
38236429Svs195195 if (sigaction(SIGFPE, &newfpe, &oldfpe)) {
38246429Svs195195 _exit(FPU_SYSCALL_FAIL);
38256429Svs195195 }
38266429Svs195195
3827*7186Skk158166 (void) sigemptyset(&newill.sa_mask);
38286429Svs195195 newill.sa_flags = SA_SIGINFO;
38296429Svs195195 newill.sa_handler = sigill_handler;
38306429Svs195195 if (sigaction(SIGILL, &newill, &oldill)) {
38316429Svs195195 _exit(FPU_SYSCALL_FAIL);
38326429Svs195195 }
38336429Svs195195
3834*7186Skk158166 (void) sigemptyset(&newbus.sa_mask);
38356429Svs195195 newbus.sa_flags = SA_SIGINFO;
38366429Svs195195 newbus.sa_handler = sigbus_handler;
38376429Svs195195 if (sigaction(SIGBUS, &newbus, &oldbus)) {
38386429Svs195195 _exit(FPU_SYSCALL_FAIL);
38396429Svs195195 }
38406429Svs195195
3841*7186Skk158166 (void) sigemptyset(&newsegv.sa_mask);
38426429Svs195195 newsegv.sa_flags = SA_SIGINFO;
38436429Svs195195 newsegv.sa_handler = sigsegv_handler;
38446429Svs195195 if (sigaction(SIGSEGV, &newsegv, &oldsegv)) {
38456429Svs195195 _exit(FPU_SYSCALL_FAIL);
38466429Svs195195 }
38476429Svs195195
38486429Svs195195 return (0);
38496429Svs195195 }
38506429Svs195195 #endif
38516429Svs195195
38526429Svs195195 /*
38536429Svs195195 * restore_signals() turns off the signal
38546429Svs195195 * handlers used by restoring the original
38556429Svs195195 * values. If sigaction fails, the program
38566429Svs195195 * exits.
38576429Svs195195 */
38586429Svs195195 int
restore_signals()38596429Svs195195 restore_signals()
38606429Svs195195 {
38616429Svs195195 if (sigaction(SIGSEGV, &oldsegv, &newsegv)) {
38626429Svs195195 _exit(FPU_SYSCALL_FAIL);
38636429Svs195195 }
38646429Svs195195
38656429Svs195195 if (sigaction(SIGBUS, &oldbus, &newbus)) {
38666429Svs195195 _exit(FPU_SYSCALL_FAIL);
38676429Svs195195 }
38686429Svs195195
38696429Svs195195 if (sigaction(SIGILL, &oldill, &newill)) {
38706429Svs195195 _exit(FPU_SYSCALL_FAIL);
38716429Svs195195 }
38726429Svs195195
38736429Svs195195 if (sigaction(SIGFPE, &oldfpe, &newfpe)) {
38746429Svs195195 _exit(FPU_SYSCALL_FAIL);
38756429Svs195195 }
38766429Svs195195
38776429Svs195195 return (0);
38786429Svs195195
38796429Svs195195 }
38806429Svs195195
38816429Svs195195 /*
38826429Svs195195 * fpu_sysdiag(struct fps_test_ereport *report)
38836429Svs195195 * is the main caller of all fpu subtests. It
38846429Svs195195 * does the following tests: normal registers, fsr,
38856429Svs195195 * moving instructions, conversion instructions,
38866429Svs195195 * absolute values, compare, branching, arithmatic,
38876429Svs195195 * chain, datapath, and timing.
38886429Svs195195 * If an error is found, relevant data is stored
38896429Svs195195 * in report.
38906429Svs195195 */
38916429Svs195195 int
fpu_sysdiag(struct fps_test_ereport * report)38926429Svs195195 fpu_sysdiag(struct fps_test_ereport *report)
38936429Svs195195 {
38946429Svs195195
38956429Svs195195 int i;
38966429Svs195195
38976429Svs195195 #ifndef i86pc
38986429Svs195195
38996429Svs195195 /*
39006429Svs195195 * Initialize neg_val_sp[] and neg_val_dp[] with the -ve versions of
39016429Svs195195 * the values in val[]
39026429Svs195195 */
39036429Svs195195 for (i = 0; i < N_VALS; i++) {
39046429Svs195195 neg_val_sp[i] = val[i].floatsingle |
39056429Svs195195 ((uint32_t)1) << 31;
39066429Svs195195
39076429Svs195195 neg_val_dp[i] = val[i].floatdouble |
39086429Svs195195 ((uint64_t)1) << 63;
39096429Svs195195 }
39106429Svs195195
39116429Svs195195 /* Register Testing */
39126429Svs195195 if (registers_four(report)) {
39136429Svs195195 return (-1);
39146429Svs195195 }
39156429Svs195195
39166429Svs195195 if (trap_flag) {
39176429Svs195195 fail_trap(report, 7001);
39186429Svs195195 return (-1);
39196429Svs195195 }
39206429Svs195195
39216429Svs195195 if (registers_four_dp(report)) {
39226429Svs195195 return (-1);
39236429Svs195195 }
39246429Svs195195
39256429Svs195195 if (trap_flag) {
39266429Svs195195 fail_trap(report, 7002);
39276429Svs195195 }
39286429Svs195195
39296429Svs195195 if (registers_two(report)) {
39306429Svs195195 return (-1);
39316429Svs195195 }
39326429Svs195195
39336429Svs195195 if (trap_flag) {
39346429Svs195195 fail_trap(report, 7003);
39356429Svs195195 }
39366429Svs195195
39376429Svs195195 if (registers_two_dp(report)) {
39386429Svs195195 return (-1);
39396429Svs195195 }
39406429Svs195195
39416429Svs195195 if (trap_flag) {
39426429Svs195195 fail_trap(report, 7004);
39436429Svs195195 return (-1);
39446429Svs195195 }
39456429Svs195195
39466429Svs195195 if (registers_one(report)) {
39476429Svs195195 return (-1);
39486429Svs195195 }
39496429Svs195195
39506429Svs195195 if (trap_flag) {
39516429Svs195195 fail_trap(report, 7005);
39526429Svs195195 return (-1);
39536429Svs195195 }
39546429Svs195195
39556429Svs195195 if (registers_one_dp(report)) {
39566429Svs195195 return (-1);
39576429Svs195195 }
39586429Svs195195
39596429Svs195195 if (trap_flag) {
39606429Svs195195 fail_trap(report, 7006);
39616429Svs195195 return (-1);
39626429Svs195195 }
39636429Svs195195
39646429Svs195195 /* FSR testing */
39656429Svs195195 if (fsr_test(report)) {
39666429Svs195195 return (-1);
39676429Svs195195
39686429Svs195195 }
39696429Svs195195
39706429Svs195195 if (trap_flag) {
39716429Svs195195 fail_trap(report, 7007);
39726429Svs195195 return (-1);
39736429Svs195195 }
39746429Svs195195
39756429Svs195195 if (fmovs_ins(report)) {
39766429Svs195195 return (-1);
39776429Svs195195 }
39786429Svs195195
39796429Svs195195 if (trap_flag) {
39806429Svs195195 fail_trap(report, 7008);
39816429Svs195195 return (-1);
39826429Svs195195 }
39836429Svs195195
39846429Svs195195 /* Conversion routines */
39856429Svs195195 if (integer_to_float_sp(report)) {
39866429Svs195195 return (-1);
39876429Svs195195 }
39886429Svs195195
39896429Svs195195 if (trap_flag) {
39906429Svs195195 fail_trap(report, 7009);
39916429Svs195195 return (-1);
39926429Svs195195 }
39936429Svs195195
39946429Svs195195 if (integer_to_float_dp(report)) {
39956429Svs195195 return (-1);
39966429Svs195195 }
39976429Svs195195
39986429Svs195195 if (trap_flag) {
39996429Svs195195 fail_trap(report, 7010);
40006429Svs195195 return (-1);
40016429Svs195195 }
40026429Svs195195
40036429Svs195195 if (long_to_float_sp(report)) {
40046429Svs195195 return (-1);
40056429Svs195195 }
40066429Svs195195
40076429Svs195195 if (trap_flag) {
40086429Svs195195 fail_trap(report, 7011);
40096429Svs195195 return (-1);
40106429Svs195195 }
40116429Svs195195
40126429Svs195195 if (long_to_float_dp(report)) {
40136429Svs195195 return (-1);
40146429Svs195195 }
40156429Svs195195
40166429Svs195195 if (trap_flag) {
40176429Svs195195 fail_trap(report, 7012);
40186429Svs195195 return (-1);
40196429Svs195195 }
40206429Svs195195
40216429Svs195195 if (float_to_integer_sp(report)) {
40226429Svs195195 return (-1);
40236429Svs195195 }
40246429Svs195195
40256429Svs195195 if (trap_flag) {
40266429Svs195195 fail_trap(report, 7013);
40276429Svs195195 return (-1);
40286429Svs195195 }
40296429Svs195195
40306429Svs195195 if (float_to_integer_dp(report)) {
40316429Svs195195 return (-1);
40326429Svs195195 }
40336429Svs195195
40346429Svs195195 if (trap_flag) {
40356429Svs195195 fail_trap(report, 7014);
40366429Svs195195 return (-1);
40376429Svs195195 }
40386429Svs195195
40396429Svs195195 if (float_to_long_dp(report)) {
40406429Svs195195 return (-1);
40416429Svs195195 }
40426429Svs195195
40436429Svs195195 if (trap_flag) {
40446429Svs195195 fail_trap(report, 7015);
40456429Svs195195 return (-1);
40466429Svs195195 }
40476429Svs195195
40486429Svs195195 if (float_to_long_sp(report)) {
40496429Svs195195 return (-1);
40506429Svs195195 }
40516429Svs195195
40526429Svs195195 if (trap_flag) {
40536429Svs195195 fail_trap(report, 7016);
40546429Svs195195 return (-1);
40556429Svs195195 }
40566429Svs195195
40576429Svs195195 if (single_doub(report)) {
40586429Svs195195 return (-1);
40596429Svs195195 }
40606429Svs195195 if (trap_flag) {
40616429Svs195195 fail_trap(report, 7017);
40626429Svs195195 return (-1);
40636429Svs195195 }
40646429Svs195195 if (double_sing(report)) {
40656429Svs195195 return (-1);
40666429Svs195195 }
40676429Svs195195 if (trap_flag) {
40686429Svs195195 fail_trap(report, 7018);
40696429Svs195195 return (-1);
40706429Svs195195 }
40716429Svs195195 /* Absolute, -ve instructions */
40726429Svs195195 if (fabs_ins_sp(report)) {
40736429Svs195195 return (-1);
40746429Svs195195 }
40756429Svs195195 if (trap_flag) {
40766429Svs195195 fail_trap(report, 7019);
40776429Svs195195 return (-1);
40786429Svs195195 }
40796429Svs195195 if (fabs_ins_dp(report)) {
40806429Svs195195 return (-1);
40816429Svs195195 }
40826429Svs195195 if (trap_flag) {
40836429Svs195195 fail_trap(report, 7020);
40846429Svs195195 return (-1);
40856429Svs195195 }
40866429Svs195195 if (get_negative_value_pn_sp(report)) {
40876429Svs195195 return (-1);
40886429Svs195195 }
40896429Svs195195 if (trap_flag) {
40906429Svs195195 fail_trap(report, 7021);
40916429Svs195195 return (-1);
40926429Svs195195 }
40936429Svs195195 if (get_negative_value_pn_dp(report)) {
40946429Svs195195 return (-1);
40956429Svs195195 }
40966429Svs195195 if (trap_flag) {
40976429Svs195195 fail_trap(report, 7022);
40986429Svs195195 return (-1);
40996429Svs195195 }
41006429Svs195195 if (get_negative_value_np_sp(report)) {
41016429Svs195195 return (-1);
41026429Svs195195 }
41036429Svs195195 if (trap_flag) {
41046429Svs195195 fail_trap(report, 7023);
41056429Svs195195 return (-1);
41066429Svs195195 }
41076429Svs195195 if (get_negative_value_np_dp(report)) {
41086429Svs195195 return (-1);
41096429Svs195195 }
41106429Svs195195 if (trap_flag) {
41116429Svs195195 fail_trap(report, 7024);
41126429Svs195195 return (-1);
41136429Svs195195 }
41146429Svs195195 /* Compare and branch instructions */
41156429Svs195195 if (compare_sp(report)) {
41166429Svs195195 return (-1);
41176429Svs195195 }
41186429Svs195195 if (trap_flag) {
41196429Svs195195 fail_trap(report, 7025);
41206429Svs195195 return (-1);
41216429Svs195195 }
41226429Svs195195 if (compare_dp(report)) {
41236429Svs195195 return (-1);
41246429Svs195195 }
41256429Svs195195 if (trap_flag) {
41266429Svs195195 fail_trap(report, 7026);
41276429Svs195195 return (-1);
41286429Svs195195 }
41296429Svs195195 if (compare_sp_except(report)) {
41306429Svs195195 return (-1);
41316429Svs195195 }
41326429Svs195195 if (trap_flag) {
41336429Svs195195 fail_trap(report, 7027);
41346429Svs195195 return (-1);
41356429Svs195195 }
41366429Svs195195 if (compare_dp_except(report)) {
41376429Svs195195 return (-1);
41386429Svs195195 }
41396429Svs195195 if (trap_flag) {
41406429Svs195195 fail_trap(report, 7028);
41416429Svs195195 return (-1);
41426429Svs195195 }
41436429Svs195195 if (branching(report)) {
41446429Svs195195 return (-1);
41456429Svs195195
41466429Svs195195 }
41476429Svs195195 if (trap_flag) {
41486429Svs195195 fail_trap(report, 7029);
41496429Svs195195 return (-1);
41506429Svs195195 }
41516429Svs195195 if (no_branching(report)) {
41526429Svs195195 return (-1);
41536429Svs195195 }
41546429Svs195195 if (trap_flag) {
41556429Svs195195 fail_trap(report, 7030);
41566429Svs195195 return (-1);
41576429Svs195195 }
41586429Svs195195 /* Arithmetic instructions */
41596429Svs195195 if (addition_test_sp(report)) {
41606429Svs195195 return (-1);
41616429Svs195195 }
41626429Svs195195 if (trap_flag) {
41636429Svs195195 fail_trap(report, 7031);
41646429Svs195195 return (-1);
41656429Svs195195 }
41666429Svs195195 if (addition_test_dp(report)) {
41676429Svs195195 return (-1);
41686429Svs195195 }
41696429Svs195195 if (trap_flag) {
41706429Svs195195 fail_trap(report, 7032);
41716429Svs195195 return (-1);
41726429Svs195195 }
41736429Svs195195 if (subtraction_test_sp(report)) {
41746429Svs195195 return (-1);
41756429Svs195195 }
41766429Svs195195 if (trap_flag) {
41776429Svs195195 fail_trap(report, 7033);
41786429Svs195195 return (-1);
41796429Svs195195 }
41806429Svs195195 if (subtraction_test_dp(report)) {
41816429Svs195195 return (-1);
41826429Svs195195 }
41836429Svs195195 if (trap_flag) {
41846429Svs195195 fail_trap(report, 7034);
41856429Svs195195 return (-1);
41866429Svs195195 }
41876429Svs195195 if (multiplication_test_sp(report)) {
41886429Svs195195 return (-1);
41896429Svs195195 }
41906429Svs195195 if (trap_flag) {
41916429Svs195195 fail_trap(report, 7035);
41926429Svs195195 return (-1);
41936429Svs195195 }
41946429Svs195195 if (multiplication_test_dp(report)) {
41956429Svs195195 return (-1);
41966429Svs195195 }
41976429Svs195195 if (trap_flag) {
41986429Svs195195 fail_trap(report, 7036);
41996429Svs195195 return (-1);
42006429Svs195195 }
42016429Svs195195 if (squareroot_test_sp(report)) {
42026429Svs195195 return (-1);
42036429Svs195195 }
42046429Svs195195 if (trap_flag) {
42056429Svs195195 fail_trap(report, 7037);
42066429Svs195195 return (-1);
42076429Svs195195 }
42086429Svs195195 if (squareroot_test_dp(report)) {
42096429Svs195195 return (-1);
42106429Svs195195 }
42116429Svs195195 if (trap_flag) {
42126429Svs195195 fail_trap(report, 7038);
42136429Svs195195 return (-1);
42146429Svs195195 }
42156429Svs195195 if (division_test_sp(report)) {
42166429Svs195195 return (-1);
42176429Svs195195 }
42186429Svs195195 if (trap_flag) {
42196429Svs195195 fail_trap(report, 7039);
42206429Svs195195 return (-1);
42216429Svs195195 }
42226429Svs195195 if (division_test_dp(report)) {
42236429Svs195195 return (-1);
42246429Svs195195 }
42256429Svs195195 if (trap_flag) {
42266429Svs195195 fail_trap(report, 7040);
42276429Svs195195 return (-1);
42286429Svs195195 }
42296429Svs195195 /* chain, datapath, timing tests */
42306429Svs195195 if (chain_sp_test(report)) {
42316429Svs195195 return (-1);
42326429Svs195195 }
42336429Svs195195 if (trap_flag) {
42346429Svs195195 fail_trap(report, 7041);
42356429Svs195195 return (-1);
42366429Svs195195 }
42376429Svs195195 if (chain_dp_test(report)) {
42386429Svs195195 return (-1);
42396429Svs195195 }
42406429Svs195195 if (trap_flag) {
42416429Svs195195 fail_trap(report, 7042);
42426429Svs195195 return (-1);
42436429Svs195195 }
42446429Svs195195 if (data_path_sp(report)) {
42456429Svs195195 return (-1);
42466429Svs195195 }
42476429Svs195195 if (trap_flag) {
42486429Svs195195 fail_trap(report, 7043);
42496429Svs195195 return (-1);
42506429Svs195195 }
42516429Svs195195 if (data_path_dp(report)) {
42526429Svs195195 return (-1);
42536429Svs195195 }
42546429Svs195195 if (trap_flag) {
42556429Svs195195 fail_trap(report, 7044);
42566429Svs195195 return (-1);
42576429Svs195195 }
42586429Svs195195 if (timing_test(report)) {
42596429Svs195195 return (-1);
42606429Svs195195 }
42616429Svs195195 if (trap_flag) {
42626429Svs195195 fail_trap(report, 7045);
42636429Svs195195 return (-1);
42646429Svs195195 }
42656429Svs195195 if (check_conv(report)) {
42666429Svs195195 return (-1);
42676429Svs195195 }
42686429Svs195195 if (trap_flag) {
42696429Svs195195 fail_trap(report, 7046);
42706429Svs195195 return (-1);
42716429Svs195195 }
42726429Svs195195 #endif /* i86pc */
42736429Svs195195
42746429Svs195195 return (0);
42756429Svs195195 }
42766429Svs195195
42776429Svs195195 #define LLL 64
42786429Svs195195 #define REP_RXd "1104199269.000000"
42796429Svs195195 #define REP_RXc "1104199269,000000"
42806429Svs195195 #define REP_GCONd "4.5"
42816429Svs195195 #define REP_GCONc "4,5"
42826429Svs195195
42836429Svs195195 /*
42846429Svs195195 * check_conv(struct fps_test_ereport *report)
42856429Svs195195 * does a series of conversion testing.
42866429Svs195195 * If an error is found, relevant data is stored
42876429Svs195195 * in report.
42886429Svs195195 */
42896429Svs195195 static int
check_conv(struct fps_test_ereport * report)42906429Svs195195 check_conv(struct fps_test_ereport *report)
42916429Svs195195 {
42926429Svs195195 char dec_point;
42936429Svs195195 char err_data[MAX_INFO_SIZE];
42946429Svs195195 double gcon;
42956429Svs195195 char l_buf[LLL];
42966429Svs195195 char *pREP_RX;
42976429Svs195195 char *pREP_GCON;
42986429Svs195195 double rx;
42996429Svs195195 long double qgcon;
43006429Svs195195 struct lconv *lconv2;
43016429Svs195195 uint64_t observed;
43026429Svs195195 uint64_t expected;
43036429Svs195195
43046429Svs195195 (void) memset(l_buf, 0, LLL);
43056429Svs195195
43066429Svs195195 lconv2 = localeconv();
43076429Svs195195 if (NULL == lconv2)
43086429Svs195195 return (0);
43096429Svs195195 if (NULL == lconv2->decimal_point)
43106429Svs195195 return (0);
43116429Svs195195
43126429Svs195195 /* expect "." or ",". if not than return */
43136429Svs195195 if (1 == strlen(lconv2->decimal_point))
43146429Svs195195 dec_point = lconv2->decimal_point[0];
43156429Svs195195 else
43166429Svs195195 return (0);
43176429Svs195195
43186429Svs195195 if (',' == dec_point) {
43196429Svs195195 pREP_RX = REP_RXc;
43206429Svs195195 pREP_GCON = REP_GCONc;
43216429Svs195195 } else if ('.' == dec_point) {
43226429Svs195195 pREP_RX = REP_RXd;
43236429Svs195195 pREP_GCON = REP_GCONd;
43246429Svs195195 } else
43256429Svs195195 return (0);
43266429Svs195195
43276429Svs195195 rx = 1104199269;
43286429Svs195195
43296429Svs195195 (void) snprintf(l_buf, LLL - 1, "%f", rx);
43306429Svs195195 if (strncmp(l_buf, pREP_RX, strlen(pREP_RX)) != 0) {
43316429Svs195195 observed = (uint64_t)1;
43326429Svs195195 expected = (uint64_t)0;
4333*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
43346429Svs195195 "\nObserved: %s\nExpected: %s", l_buf, pREP_RX);
43356429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO, report,
43366429Svs195195 6326, &observed, &expected, 1, 1, err_data);
43376429Svs195195
43386429Svs195195 return (-1);
43396429Svs195195 }
43406429Svs195195
43416429Svs195195 gcon = 4.5;
43426429Svs195195 (void) memset(l_buf, 0, LLL);
4343*7186Skk158166 (void) gconvert(gcon, 15, 0, l_buf);
43446429Svs195195 if (strncmp(l_buf, pREP_GCON, strlen(pREP_GCON)) != 0) {
43456429Svs195195 observed = (uint64_t)1;
43466429Svs195195 expected = (uint64_t)0;
4347*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
43486429Svs195195 "\nObserved: %s\nExpected: %s", l_buf, pREP_GCON);
43496429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO, report,
43506429Svs195195 6327, &observed, &expected, 1, 1, err_data);
43516429Svs195195
43526429Svs195195 return (-2);
43536429Svs195195 }
43546429Svs195195
43556429Svs195195 qgcon = 4.5;
43566429Svs195195 (void) memset(l_buf, 0, LLL);
4357*7186Skk158166 (void) qgconvert(&qgcon, 15, 0, l_buf);
43586429Svs195195 if (strncmp(l_buf, pREP_GCON, strlen(pREP_GCON)) != 0) {
43596429Svs195195 observed = (uint64_t)1;
43606429Svs195195 expected = (uint64_t)0;
4361*7186Skk158166 (void) snprintf(err_data, sizeof (err_data),
43626429Svs195195 "\nObserved: %s\nExpected: %s", l_buf, pREP_GCON);
43636429Svs195195 setup_fps_test_struct(IS_EREPORT_INFO, report,
43646429Svs195195 6328, &observed, &expected, 1, 1, err_data);
43656429Svs195195
43666429Svs195195 return (-3);
43676429Svs195195 }
43686429Svs195195
43696429Svs195195 return (0);
43706429Svs195195 }
43716429Svs195195
43726429Svs195195 /*
43736429Svs195195 * fail_trap(struct fps_test_ereport *report, int flag_num)
43746429Svs195195 * creates the ereport data if a trap flag is set after a
43756429Svs195195 * successful test when it shouldn't be.
43766429Svs195195 */
43776429Svs195195 static void
fail_trap(struct fps_test_ereport * report,int flag_num)43786429Svs195195 fail_trap(struct fps_test_ereport *report, int flag_num)
43796429Svs195195 {
43806429Svs195195 uint64_t observed = 1;
43816429Svs195195 uint64_t expected = 0;
43826429Svs195195
43836429Svs195195 setup_fps_test_struct(NO_EREPORT_INFO, report,
43846429Svs195195 flag_num, &observed, &expected, 1, 1);
43856429Svs195195 }
4386