1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <sys/types.h>
30 #include <sys/file.h>
31 #include <signal.h>
32 #include <ucontext.h>
33 #include <stdio.h>
34 #include <floatingpoint.h>
35 #include <locale.h>
36 #include <unistd.h>
37 #include <fp.h>
38 #include <externs.h>
39 #include <fps_ereport.h>
40
41 #define FPU_ID_MASK 0xCFF02FFF
42
43 extern int FPU_cpu;
44 static int check_conv();
45 uint_t trap_flag = 0x0;
46 unsigned long fsr_at_trap;
47
48 extern unsigned long long_float_d(unsigned long);
49 extern unsigned long float_long_d(unsigned long);
50 int fpu_sysdiag(struct fps_test_ereport *report);
51 int restore_signals();
52 static int addition_test_dp(struct fps_test_ereport *report);
53 static int addition_test_sp(struct fps_test_ereport *report);
54 static int branching(struct fps_test_ereport *report);
55 static int chain_dp_test(struct fps_test_ereport *report);
56 static int chain_sp_test(struct fps_test_ereport *report);
57 static int check_conv(struct fps_test_ereport *report);
58 static int compare_dp(struct fps_test_ereport *report);
59 static int compare_dp_except(struct fps_test_ereport *report);
60 static int compare_sp(struct fps_test_ereport *report);
61 static int compare_sp_except(struct fps_test_ereport *report);
62 static int data_path_dp(struct fps_test_ereport *report);
63 static int data_path_sp(struct fps_test_ereport *report);
64 static int division_test_dp(struct fps_test_ereport *report);
65 static int division_test_sp(struct fps_test_ereport *report);
66 static int double_sing(struct fps_test_ereport *report);
67 static int fabs_ins_dp(struct fps_test_ereport *report);
68 static int fabs_ins_sp(struct fps_test_ereport *report);
69 static int float_to_integer_dp(struct fps_test_ereport *report);
70 static int float_to_integer_sp(struct fps_test_ereport *report);
71 static int float_to_long_dp(struct fps_test_ereport *report);
72 static int float_to_long_sp(struct fps_test_ereport *report);
73 static int get_negative_value_pn_dp(struct fps_test_ereport *report);
74 static int get_negative_value_pn_sp(struct fps_test_ereport *report);
75 static int get_negative_value_np_dp(struct fps_test_ereport *report);
76 static int get_negative_value_np_sp(struct fps_test_ereport *report);
77 static int fmovs_ins(struct fps_test_ereport *report);
78 static int integer_to_float_dp(struct fps_test_ereport *report);
79 static int integer_to_float_sp(struct fps_test_ereport *report);
80 static int long_to_float_dp(struct fps_test_ereport *report);
81 static int long_to_float_sp(struct fps_test_ereport *report);
82 static int multiplication_test_dp(struct fps_test_ereport *report);
83 static int multiplication_test_sp(struct fps_test_ereport *report);
84 static int no_branching(struct fps_test_ereport *report);
85 static int registers_four(struct fps_test_ereport *report);
86 static int registers_four_dp(struct fps_test_ereport *report);
87 static int registers_one(struct fps_test_ereport *report);
88 static int registers_one_dp(struct fps_test_ereport *report);
89 static int registers_two(struct fps_test_ereport *report);
90 static int registers_two_dp(struct fps_test_ereport *report);
91 static int single_doub(struct fps_test_ereport *report);
92 static int squareroot_test_dp(struct fps_test_ereport *report);
93 static int squareroot_test_sp(struct fps_test_ereport *report);
94 static int subtraction_test_dp(struct fps_test_ereport *report);
95 static int subtraction_test_sp(struct fps_test_ereport *report);
96 static int timing_test(struct fps_test_ereport *report);
97 static void fail_trap(struct fps_test_ereport *report, int flag_num);
98
99 /* SIGFPE */
100 static void sigfpe_handler(int, siginfo_t *, ucontext_t *);
101 static struct sigaction oldfpe, newfpe;
102
103 /* SIGSEGV */
104 static void sigsegv_handler(int, siginfo_t *, ucontext_t *);
105 static struct sigaction oldsegv, newsegv;
106
107 /* SIGILL */
108 static void sigill_handler(int, siginfo_t *, ucontext_t *);
109 static struct sigaction oldill, newill;
110
111 /* SIGBUS */
112 static void sigbus_handler(int, siginfo_t *, ucontext_t *);
113 static struct sigaction oldbus, newbus;
114
115 static unsigned int pat[] = {
116 0x00000000,
117 0x55555555,
118 0xAAAAAAAA,
119 0xCCCCCCCC,
120 0x33333333,
121 0xFFFFFFFF,
122 0xA5A5A5A5,
123 0x3C3C3C3C,
124 0xF0F0F0F0,
125 0xEEEEEEEE,
126 0xDDDDDDDD,
127 0xBBBBBBBB,
128 0x77777777,
129 0x11111111,
130 0x22222222,
131 0x44444444,
132 0x88888888,
133 0x66666666,
134 0x99999999,
135 0x00FF00FF,
136 0xFF00FF00,
137 0xFFFF0000,
138 0x0000FFFF,
139
140 };
141
142 #define PAT_NUM (sizeof (pat)/sizeof (*pat))
143
144 /*
145 * Double precision patterns
146 */
147 static uint64_t pat_dp[] = {
148 0x0000000000000000UL,
149 0x5555555555555555UL,
150 0xAAAAAAAAAAAAAAAAUL,
151 0xCCCCCCCCCCCCCCCCUL,
152 0x3333333333333333UL,
153 0xFFFFFFFFFFFFFFFFUL,
154 0xA5A5A5A5A5A5A5A5UL,
155 0x3C3C3C3C3C3C3C3CUL,
156 0xF0F0F0F0F0F0F0F0UL,
157 0xEEEEEEEEEEEEEEEEUL,
158 0xDDDDDDDDDDDDDDDDUL,
159 0xBBBBBBBBBBBBBBBBUL,
160 0x7777777777777777UL,
161 0x1111111111111111UL,
162 0x2222222222222222UL,
163 0x4444444444444444UL,
164 0x8888888888888888UL,
165 0x6666666666666666UL,
166 0x9999999999999999UL,
167 0x00000000FFFFFFFFUL,
168 0xFFFFFFFF00000000UL,
169 0x0000FFFF0000FFFFUL,
170 0xFFFF0000FFFF0000UL
171 };
172
173 #define PAT_DP_NUM (sizeof (pat_dp)/sizeof (*pat_dp))
174
175 struct value {
176 unsigned long floatsingle;
177 uint64_t floatdouble;
178 uint64_t floatquad_u;
179 uint64_t floatquad_l;
180 };
181
182 #define N_VALS (sizeof (val)/sizeof (*val))
183
184 static struct value val[] = {
185 0, 0, 0, 0,
186 0x3F800000, 0x3FF0000000000000, 0x3FFF000000000000, 0,
187 0x40000000, 0x4000000000000000, 0x4000000000000000, 0,
188 0x40400000, 0x4008000000000000, 0x4000800000000000, 0,
189 0x40800000, 0x4010000000000000, 0x4001000000000000, 0,
190 0x40A00000, 0x4014000000000000, 0x4001400000000000, 0,
191 0x40C00000, 0x4018000000000000, 0x4001800000000000, 0,
192 0x40E00000, 0x401C000000000000, 0x4001C00000000000, 0,
193 0x41000000, 0x4020000000000000, 0x4002000000000000, 0,
194 0x41100000, 0x4022000000000000, 0x4002200000000000, 0,
195 0x41200000, 0x4024000000000000, 0x4002400000000000, 0,
196 0x41300000, 0x4026000000000000, 0x4002600000000000, 0,
197 0x41400000, 0x4028000000000000, 0x4002800000000000, 0,
198 0x41500000, 0x402A000000000000, 0x4002A00000000000, 0,
199 0x41600000, 0x402C000000000000, 0x4002C00000000000, 0,
200 0x41700000, 0x402E000000000000, 0x4002E00000000000, 0,
201 0x41800000, 0x4030000000000000, 0x4003000000000000, 0,
202 0x41880000, 0x4031000000000000, 0x4003100000000000, 0,
203 0x41900000, 0x4032000000000000, 0x4003200000000000, 0,
204 0x41980000, 0x4033000000000000, 0x4003300000000000, 0,
205 0x41a00000, 0x4034000000000000, 0x4003400000000000, 0,
206 0x41a80000, 0x4035000000000000, 0x4003500000000000, 0,
207 0x41b00000, 0x4036000000000000, 0x4003600000000000, 0,
208 0x41b80000, 0x4037000000000000, 0x4003700000000000, 0,
209 0x41c00000, 0x4038000000000000, 0x4003800000000000, 0,
210 0x41c80000, 0x4039000000000000, 0x4003900000000000, 0,
211 0x41d00000, 0x403a000000000000, 0x4003a00000000000, 0,
212 0x41d80000, 0x403b000000000000, 0x4003b00000000000, 0,
213 0x41e00000, 0x403c000000000000, 0x4003c00000000000, 0,
214 0x41e80000, 0x403d000000000000, 0x4003d00000000000, 0,
215 0x41f00000, 0x403e000000000000, 0x4003e00000000000, 0,
216 0x41f80000, 0x403f000000000000, 0x4003f00000000000, 0,
217 0x42000000, 0x4040000000000000, 0x4004000000000000, 0,
218 0x42040000, 0x4040800000000000, 0x4004080000000000, 0,
219 0x42080000, 0x4041000000000000, 0x4004100000000000, 0,
220 0x420c0000, 0x4041800000000000, 0x4004180000000000, 0,
221 0x42100000, 0x4042000000000000, 0x4004200000000000, 0,
222 0x42140000, 0x4042800000000000, 0x4004280000000000, 0,
223 0x42180000, 0x4043000000000000, 0x4004300000000000, 0,
224 0x421c0000, 0x4043800000000000, 0x4004380000000000, 0,
225 0x42200000, 0x4044000000000000, 0x4004400000000000, 0,
226 0x42240000, 0x4044800000000000, 0x4004480000000000, 0,
227 0x42280000, 0x4045000000000000, 0x4004500000000000, 0,
228 0x422c0000, 0x4045800000000000, 0x4004580000000000, 0,
229 0x42300000, 0x4046000000000000, 0x4004600000000000, 0,
230 0x42340000, 0x4046800000000000, 0x4004680000000000, 0,
231 0x42380000, 0x4047000000000000, 0x4004700000000000, 0,
232 0x423c0000, 0x4047800000000000, 0x4004780000000000, 0,
233 0x42400000, 0x4048000000000000, 0x4004800000000000, 0,
234 0x42440000, 0x4048800000000000, 0x4004880000000000, 0,
235 0x42480000, 0x4049000000000000, 0x4004900000000000, 0,
236 0x424c0000, 0x4049800000000000, 0x4004980000000000, 0,
237 0x42500000, 0x404a000000000000, 0x4004a00000000000, 0,
238 0x42540000, 0x404a800000000000, 0x4004a80000000000, 0,
239 0x42580000, 0x404b000000000000, 0x4004b00000000000, 0,
240 0x425c0000, 0x404b800000000000, 0x4004b80000000000, 0,
241 0x42600000, 0x404c000000000000, 0x4004c00000000000, 0,
242 0x42640000, 0x404c800000000000, 0x4004c80000000000, 0,
243 0x42680000, 0x404d000000000000, 0x4004d00000000000, 0,
244 0x426c0000, 0x404d800000000000, 0x4004d80000000000, 0,
245 0x42700000, 0x404e000000000000, 0x4004e00000000000, 0,
246 0x42740000, 0x404e800000000000, 0x4004e80000000000, 0,
247 0x42780000, 0x404f000000000000, 0x4004f00000000000, 0,
248 0x427c0000, 0x404f800000000000, 0x4004f80000000000, 0,
249 0x42800000, 0x4050000000000000, 0x4005000000000000, 0,
250 0x42820000, 0x4050400000000000, 0x4005040000000000, 0,
251 0x42840000, 0x4050800000000000, 0x4005080000000000, 0,
252 0x42860000, 0x4050c00000000000, 0x40050c0000000000, 0,
253 0x42880000, 0x4051000000000000, 0x4005100000000000, 0,
254 0x428a0000, 0x4051400000000000, 0x4005140000000000, 0,
255 0x428c0000, 0x4051800000000000, 0x4005180000000000, 0,
256 0x428e0000, 0x4051c00000000000, 0x40051c0000000000, 0,
257 0x42900000, 0x4052000000000000, 0x4005200000000000, 0,
258 0x42920000, 0x4052400000000000, 0x4005240000000000, 0,
259 0x42940000, 0x4052800000000000, 0x4005280000000000, 0,
260 0x42960000, 0x4052c00000000000, 0x40052c0000000000, 0,
261 0x42980000, 0x4053000000000000, 0x4005300000000000, 0,
262 0x429a0000, 0x4053400000000000, 0x4005340000000000, 0,
263 0x429c0000, 0x4053800000000000, 0x4005380000000000, 0,
264 0x429e0000, 0x4053c00000000000, 0x40053c0000000000, 0,
265 0x42a00000, 0x4054000000000000, 0x4005400000000000, 0,
266 0x42a20000, 0x4054400000000000, 0x4005440000000000, 0,
267 0x42a40000, 0x4054800000000000, 0x4005480000000000, 0,
268 0x42a60000, 0x4054c00000000000, 0x40054c0000000000, 0,
269 0x42a80000, 0x4055000000000000, 0x4005500000000000, 0,
270 0x42aa0000, 0x4055400000000000, 0x4005540000000000, 0,
271 0x42ac0000, 0x4055800000000000, 0x4005580000000000, 0,
272 0x42ae0000, 0x4055c00000000000, 0x40055c0000000000, 0,
273 0x42b00000, 0x4056000000000000, 0x4005600000000000, 0,
274 0x42b20000, 0x4056400000000000, 0x4005640000000000, 0,
275 0x42b40000, 0x4056800000000000, 0x4005680000000000, 0,
276 0x42b60000, 0x4056c00000000000, 0x40056c0000000000, 0,
277 0x42b80000, 0x4057000000000000, 0x4005700000000000, 0,
278 0x42ba0000, 0x4057400000000000, 0x4005740000000000, 0,
279 0x42bc0000, 0x4057800000000000, 0x4005780000000000, 0,
280 0x42be0000, 0x4057c00000000000, 0x40057c0000000000, 0,
281 0x42c00000, 0x4058000000000000, 0x4005800000000000, 0,
282 0x42c20000, 0x4058400000000000, 0x4005840000000000, 0,
283 0x42c40000, 0x4058800000000000, 0x4005880000000000, 0,
284 0x42c60000, 0x4058c00000000000, 0x40058c0000000000, 0,
285 0x42c80000, 0x4059000000000000, 0x4005900000000000, 0,
286 0x42ca0000, 0x4059400000000000, 0x4005940000000000, 0,
287 0x42cc0000, 0x4059800000000000, 0x4005980000000000, 0,
288 0x42ce0000, 0x4059c00000000000, 0x40059c0000000000, 0,
289 0x42d00000, 0x405a000000000000, 0x4005a00000000000, 0,
290 0x42d20000, 0x405a400000000000, 0x4005a40000000000, 0,
291 0x42d40000, 0x405a800000000000, 0x4005a80000000000, 0,
292 0x42d60000, 0x405ac00000000000, 0x4005ac0000000000, 0,
293 0x42d80000, 0x405b000000000000, 0x4005b00000000000, 0,
294 0x42da0000, 0x405b400000000000, 0x4005b40000000000, 0,
295 0x42dc0000, 0x405b800000000000, 0x4005b80000000000, 0,
296 0x42de0000, 0x405bc00000000000, 0x4005bc0000000000, 0,
297 0x42e00000, 0x405c000000000000, 0x4005c00000000000, 0,
298 0x42e20000, 0x405c400000000000, 0x4005c40000000000, 0,
299 0x42e40000, 0x405c800000000000, 0x4005c80000000000, 0,
300 0x42e60000, 0x405cc00000000000, 0x4005cc0000000000, 0,
301 0x42e80000, 0x405d000000000000, 0x4005d00000000000, 0,
302 0x42ea0000, 0x405d400000000000, 0x4005d40000000000, 0,
303 0x42ec0000, 0x405d800000000000, 0x4005d80000000000, 0,
304 0x42ee0000, 0x405dc00000000000, 0x4005dc0000000000, 0,
305 0x42f00000, 0x405e000000000000, 0x4005e00000000000, 0,
306 0x42f20000, 0x405e400000000000, 0x4005e40000000000, 0,
307 0x42f40000, 0x405e800000000000, 0x4005e80000000000, 0,
308 0x42f60000, 0x405ec00000000000, 0x4005ec0000000000, 0,
309 0x42f80000, 0x405f000000000000, 0x4005f00000000000, 0,
310 0x42fa0000, 0x405f400000000000, 0x4005f40000000000, 0,
311 0x42fc0000, 0x405f800000000000, 0x4005f80000000000, 0,
312 0x42fe0000, 0x405fc00000000000, 0x4005fc0000000000, 0,
313 0x43000000, 0x4060000000000000, 0x4006000000000000, 0,
314 0x43010000, 0x4060200000000000, 0x4006020000000000, 0,
315 0x43020000, 0x4060400000000000, 0x4006040000000000, 0,
316 0x43030000, 0x4060600000000000, 0x4006060000000000, 0,
317 0x43040000, 0x4060800000000000, 0x4006080000000000, 0,
318 0x43050000, 0x4060a00000000000, 0x40060a0000000000, 0,
319 0x43060000, 0x4060c00000000000, 0x40060c0000000000, 0,
320 0x43070000, 0x4060e00000000000, 0x40060e0000000000, 0,
321 0x43080000, 0x4061000000000000, 0x4006100000000000, 0,
322 0x43090000, 0x4061200000000000, 0x4006120000000000, 0,
323 0x430a0000, 0x4061400000000000, 0x4006140000000000, 0,
324 0x430b0000, 0x4061600000000000, 0x4006160000000000, 0,
325 0x430c0000, 0x4061800000000000, 0x4006180000000000, 0,
326 0x430d0000, 0x4061a00000000000, 0x40061a0000000000, 0,
327 0x430e0000, 0x4061c00000000000, 0x40061c0000000000, 0,
328 0x430f0000, 0x4061e00000000000, 0x40061e0000000000, 0,
329 0x43100000, 0x4062000000000000, 0x4006200000000000, 0,
330 0x43110000, 0x4062200000000000, 0x4006220000000000, 0,
331 0x43120000, 0x4062400000000000, 0x4006240000000000, 0,
332 0x43130000, 0x4062600000000000, 0x4006260000000000, 0,
333 0x43140000, 0x4062800000000000, 0x4006280000000000, 0,
334 0x43150000, 0x4062a00000000000, 0x40062a0000000000, 0,
335 0x43160000, 0x4062c00000000000, 0x40062c0000000000, 0,
336 0x43170000, 0x4062e00000000000, 0x40062e0000000000, 0,
337 0x43180000, 0x4063000000000000, 0x4006300000000000, 0,
338 0x43190000, 0x4063200000000000, 0x4006320000000000, 0,
339 0x431a0000, 0x4063400000000000, 0x4006340000000000, 0,
340 0x431b0000, 0x4063600000000000, 0x4006360000000000, 0,
341 0x431c0000, 0x4063800000000000, 0x4006380000000000, 0,
342 0x431d0000, 0x4063a00000000000, 0x40063a0000000000, 0,
343 0x431e0000, 0x4063c00000000000, 0x40063c0000000000, 0,
344 0x431f0000, 0x4063e00000000000, 0x40063e0000000000, 0,
345 0x43200000, 0x4064000000000000, 0x4006400000000000, 0,
346 0x43210000, 0x4064200000000000, 0x4006420000000000, 0,
347 0x43220000, 0x4064400000000000, 0x4006440000000000, 0,
348 0x43230000, 0x4064600000000000, 0x4006460000000000, 0,
349 0x43240000, 0x4064800000000000, 0x4006480000000000, 0,
350 0x43250000, 0x4064a00000000000, 0x40064a0000000000, 0,
351 0x43260000, 0x4064c00000000000, 0x40064c0000000000, 0,
352 0x43270000, 0x4064e00000000000, 0x40064e0000000000, 0,
353 0x43280000, 0x4065000000000000, 0x4006500000000000, 0,
354 0x43290000, 0x4065200000000000, 0x4006520000000000, 0,
355 0x432a0000, 0x4065400000000000, 0x4006540000000000, 0,
356 0x432b0000, 0x4065600000000000, 0x4006560000000000, 0,
357 0x432c0000, 0x4065800000000000, 0x4006580000000000, 0,
358 0x432d0000, 0x4065a00000000000, 0x40065a0000000000, 0,
359 0x432e0000, 0x4065c00000000000, 0x40065c0000000000, 0,
360 0x432f0000, 0x4065e00000000000, 0x40065e0000000000, 0,
361 0x43300000, 0x4066000000000000, 0x4006600000000000, 0,
362 0x43310000, 0x4066200000000000, 0x4006620000000000, 0,
363 0x43320000, 0x4066400000000000, 0x4006640000000000, 0,
364 0x43330000, 0x4066600000000000, 0x4006660000000000, 0,
365 0x43340000, 0x4066800000000000, 0x4006680000000000, 0,
366 0x43350000, 0x4066a00000000000, 0x40066a0000000000, 0,
367 0x43360000, 0x4066c00000000000, 0x40066c0000000000, 0,
368 0x43370000, 0x4066e00000000000, 0x40066e0000000000, 0,
369 0x43380000, 0x4067000000000000, 0x4006700000000000, 0,
370 0x43390000, 0x4067200000000000, 0x4006720000000000, 0,
371 0x433a0000, 0x4067400000000000, 0x4006740000000000, 0,
372 0x433b0000, 0x4067600000000000, 0x4006760000000000, 0,
373 0x433c0000, 0x4067800000000000, 0x4006780000000000, 0,
374 0x433d0000, 0x4067a00000000000, 0x40067a0000000000, 0,
375 0x433e0000, 0x4067c00000000000, 0x40067c0000000000, 0,
376 0x433f0000, 0x4067e00000000000, 0x40067e0000000000, 0,
377 0x43400000, 0x4068000000000000, 0x4006800000000000, 0,
378 0x43410000, 0x4068200000000000, 0x4006820000000000, 0,
379 0x43420000, 0x4068400000000000, 0x4006840000000000, 0,
380 0x43430000, 0x4068600000000000, 0x4006860000000000, 0,
381 0x43440000, 0x4068800000000000, 0x4006880000000000, 0,
382 0x43450000, 0x4068a00000000000, 0x40068a0000000000, 0,
383 0x43460000, 0x4068c00000000000, 0x40068c0000000000, 0,
384 0x43470000, 0x4068e00000000000, 0x40068e0000000000, 0,
385 0x43480000, 0x4069000000000000, 0x4006900000000000, 0,
386 0x43490000, 0x4069200000000000, 0x4006920000000000, 0,
387 0x434a0000, 0x4069400000000000, 0x4006940000000000, 0,
388 0x434b0000, 0x4069600000000000, 0x4006960000000000, 0,
389 0x434c0000, 0x4069800000000000, 0x4006980000000000, 0,
390 0x434d0000, 0x4069a00000000000, 0x40069a0000000000, 0,
391 0x434e0000, 0x4069c00000000000, 0x40069c0000000000, 0,
392 0x434f0000, 0x4069e00000000000, 0x40069e0000000000, 0,
393 0x43500000, 0x406a000000000000, 0x4006a00000000000, 0,
394 0x43510000, 0x406a200000000000, 0x4006a20000000000, 0,
395 0x43520000, 0x406a400000000000, 0x4006a40000000000, 0,
396 0x43530000, 0x406a600000000000, 0x4006a60000000000, 0,
397 0x43540000, 0x406a800000000000, 0x4006a80000000000, 0,
398 0x43550000, 0x406aa00000000000, 0x4006aa0000000000, 0,
399 0x43560000, 0x406ac00000000000, 0x4006ac0000000000, 0,
400 0x43570000, 0x406ae00000000000, 0x4006ae0000000000, 0,
401 0x43580000, 0x406b000000000000, 0x4006b00000000000, 0,
402 0x43590000, 0x406b200000000000, 0x4006b20000000000, 0,
403 0x435a0000, 0x406b400000000000, 0x4006b40000000000, 0,
404 0x435b0000, 0x406b600000000000, 0x4006b60000000000, 0,
405 0x435c0000, 0x406b800000000000, 0x4006b80000000000, 0,
406 0x435d0000, 0x406ba00000000000, 0x4006ba0000000000, 0,
407 0x435e0000, 0x406bc00000000000, 0x4006bc0000000000, 0,
408 0x435f0000, 0x406be00000000000, 0x4006be0000000000, 0,
409 0x43600000, 0x406c000000000000, 0x4006c00000000000, 0,
410 0x43610000, 0x406c200000000000, 0x4006c20000000000, 0,
411 0x43620000, 0x406c400000000000, 0x4006c40000000000, 0,
412 0x43630000, 0x406c600000000000, 0x4006c60000000000, 0,
413 0x43640000, 0x406c800000000000, 0x4006c80000000000, 0,
414 0x43650000, 0x406ca00000000000, 0x4006ca0000000000, 0,
415 0x43660000, 0x406cc00000000000, 0x4006cc0000000000, 0,
416 0x43670000, 0x406ce00000000000, 0x4006ce0000000000, 0,
417 0x43680000, 0x406d000000000000, 0x4006d00000000000, 0,
418 0x43690000, 0x406d200000000000, 0x4006d20000000000, 0,
419 0x436a0000, 0x406d400000000000, 0x4006d40000000000, 0,
420 0x436b0000, 0x406d600000000000, 0x4006d60000000000, 0,
421 0x436c0000, 0x406d800000000000, 0x4006d80000000000, 0,
422 0x436d0000, 0x406da00000000000, 0x4006da0000000000, 0,
423 0x436e0000, 0x406dc00000000000, 0x4006dc0000000000, 0,
424 0x436f0000, 0x406de00000000000, 0x4006de0000000000, 0,
425 0x43700000, 0x406e000000000000, 0x4006e00000000000, 0,
426 0x43710000, 0x406e200000000000, 0x4006e20000000000, 0,
427 0x43720000, 0x406e400000000000, 0x4006e40000000000, 0,
428 0x43730000, 0x406e600000000000, 0x4006e60000000000, 0,
429 0x43740000, 0x406e800000000000, 0x4006e80000000000, 0,
430 0x43750000, 0x406ea00000000000, 0x4006ea0000000000, 0,
431 0x43760000, 0x406ec00000000000, 0x4006ec0000000000, 0,
432 0x43770000, 0x406ee00000000000, 0x4006ee0000000000, 0,
433 0x43780000, 0x406f000000000000, 0x4006f00000000000, 0,
434 0x43790000, 0x406f200000000000, 0x4006f20000000000, 0,
435 0x437a0000, 0x406f400000000000, 0x4006f40000000000, 0,
436 0x437b0000, 0x406f600000000000, 0x4006f60000000000, 0,
437 0x437c0000, 0x406f800000000000, 0x4006f80000000000, 0,
438 0x437d0000, 0x406fa00000000000, 0x4006fa0000000000, 0,
439 0x437e0000, 0x406fc00000000000, 0x4006fc0000000000, 0,
440 0x437f0000, 0x406fe00000000000, 0x4006fe0000000000, 0,
441 };
442
443 /* -ve of the values in val[] above */
444 static unsigned long neg_val_sp[N_VALS];
445 static uint64_t neg_val_dp[N_VALS];
446
447 /*
448 * data_path_sp(struct fps_test_ereport *report)checks the data path
449 * between registers and memory, between memory and an floating
450 * registers, and between floating registers and the weitek chips.
451 * All the bits are covered including the sign bit. If an error is
452 * found, all relevant data is stored in report.
453 */
454 #ifndef i86pc
455 static int
data_path_sp(struct fps_test_ereport * report)456 data_path_sp(struct fps_test_ereport *report)
457 {
458 int i;
459 int j;
460 int k;
461 uint64_t expected;
462 uint64_t observed;
463 unsigned long prev_fsr;
464 unsigned long result;
465 unsigned long value;
466
467 prev_fsr = get_fsr();
468 init_regs(0);
469
470 for (i = 0; i < 2; i++) {
471 for (j = 1; j < 255; j++) {
472 for (k = 0; k < 23; k++) {
473 value = (i << 31) | (j << 23) | (1 << k);
474
475 if (result = datap_add(value)) {
476 observed = (uint64_t)result;
477 expected = (uint64_t)0;
478 setup_fps_test_struct(
479 NO_EREPORT_INFO,
480 report, 6217, &observed,
481 &expected, 1, 1);
482
483 return (-1);
484 }
485 if (result = datap_mult(value)) {
486 observed = (uint64_t)result;
487 expected = (uint64_t)0;
488 setup_fps_test_struct(
489 NO_EREPORT_INFO,
490 report, 6218, &observed,
491 &expected, 1, 1);
492
493 return (-1);
494 }
495 }
496 }
497 }
498
499 set_fsr(prev_fsr);
500
501 return (0);
502 }
503
504 /*
505 * data_path_dp(struct fps_test_ereport *report) performs the
506 * same function as data_path_sp except it's double precision
507 * instead of single. If an error is found, all relevant data
508 * is stored in report.
509 */
510 static int
data_path_dp(struct fps_test_ereport * report)511 data_path_dp(struct fps_test_ereport *report)
512 {
513 int i;
514 int j;
515 int k;
516 int l;
517 uint64_t observed[2];
518 uint64_t expected[2];
519 unsigned long prev_fsr;
520 unsigned long result_lsw = 0;
521 unsigned long result_msw = 0;
522 unsigned long value_lsw;
523 unsigned long value_msw;
524
525 prev_fsr = get_fsr();
526 init_regs(0);
527
528 for (i = 0; i < 2; i++) {
529 for (j = 1; j < 2047; j++) {
530 for (k = 0; k < 52; k++) {
531 value_lsw = (1 << k);
532
533 if (k > 32)
534 l = k - 32;
535 else
536 l = 32;
537
538 value_msw = (i << 31) | (j << 20) | (1 << l);
539
540 if (datap_add_dp(value_msw, value_lsw)) {
541 observed[0] = (uint64_t)result_msw;
542 observed[1] = (uint64_t)result_lsw;
543 expected[0] = (uint64_t)value_msw;
544 expected[1] = (uint64_t)value_lsw;
545 setup_fps_test_struct(
546 NO_EREPORT_INFO, report,
547 6219, observed, expected,
548 2, 2);
549
550 return (-1);
551 }
552
553 if (datap_mult_dp(value_msw, value_lsw)) {
554 observed[0] = (uint64_t)result_msw;
555 observed[1] = (uint64_t)result_lsw;
556 expected[0] = (uint64_t)value_msw;
557 expected[1] = (uint64_t)value_lsw;
558 setup_fps_test_struct(
559 NO_EREPORT_INFO, report,
560 6220, observed, expected,
561 2, 2);
562
563 return (-1);
564 }
565 }
566 }
567 }
568
569 set_fsr(prev_fsr);
570
571 return (0);
572 }
573
574 /*
575 * timing_test(struct fps_test_ereport *report) does 10 add
576 * operations continuously and 10 multiply operations
577 * continusously. If an error is found, relevant data is
578 * stored in report.
579 */
580 static int
timing_test(struct fps_test_ereport * report)581 timing_test(struct fps_test_ereport *report)
582 {
583 int i;
584 uint64_t expected;
585 uint64_t observed;
586 unsigned long result;
587 unsigned long prev_fsr;
588
589 prev_fsr = get_fsr();
590
591 for (i = 0; i < 1000; i++) {
592 init_regs(0);
593 if (result = timing_add_sp()) {
594 observed = (uint64_t)result;
595 expected = (uint64_t)0;
596 setup_fps_test_struct(NO_EREPORT_INFO,
597 report, 6221, &observed, &expected, 1, 1);
598
599 return (-1);
600 }
601
602 init_regs(0);
603
604 if (result = timing_mult_sp()) {
605 observed = (uint64_t)result;
606 expected = (uint64_t)0;
607 setup_fps_test_struct(NO_EREPORT_INFO,
608 report, 6222, &observed, &expected, 1, 1);
609
610 return (-1);
611 }
612
613 init_regs(0);
614
615 if (result = timing_add_dp()) {
616 observed = (uint64_t)result;
617 expected = (uint64_t)0;
618 setup_fps_test_struct(NO_EREPORT_INFO,
619 report, 6223, &observed, &expected, 1, 1);
620
621 return (-1);
622 }
623
624 init_regs(0);
625
626 if (result = timing_mult_dp()) {
627 observed = (uint64_t)result;
628 expected = (uint64_t)0;
629 setup_fps_test_struct(NO_EREPORT_INFO,
630 report, 6224, &observed, &expected, 1, 1);
631
632 return (-1);
633 }
634 }
635
636 set_fsr(prev_fsr);
637
638 return (0);
639 }
640
641 /*
642 * chain_sp_test(struct fps_test_ereport *report)
643 * performs a series of single precision chaining
644 * tests. If an error is found, relevant data is
645 * stored in report.
646 */
647 static int
chain_sp_test(struct fps_test_ereport * report)648 chain_sp_test(struct fps_test_ereport *report)
649 {
650 char err_data[MAX_INFO_SIZE];
651 int i;
652 uint64_t result;
653 uint64_t expected;
654 uint64_t observed;
655 unsigned long prev_fsr;
656
657 prev_fsr = get_fsr();
658 init_regs(0);
659 set_fsr(0);
660
661 for (i = 1; i < 60; i++) {
662 if ((result = chain_sp(i)) != (unsigned long) i) {
663 observed = (uint64_t)result;
664 expected = (uint64_t)i;
665 (void) snprintf(err_data, sizeof (err_data),
666 "\nExpected: %d\nObserved: %d", i, result);
667 setup_fps_test_struct(IS_EREPORT_INFO,
668 report, 6225, &observed, &expected, 1, 1,
669 err_data);
670
671 return (-1);
672 }
673 }
674
675 set_fsr(prev_fsr);
676
677 return (0);
678 }
679
680 /*
681 * chain_dp_test(struct fps_test_ereport *report)
682 * performs a series of double precision chaining
683 * tests. If an error is found, relevant data is
684 * stored in report.
685 */
686 static int
chain_dp_test(struct fps_test_ereport * report)687 chain_dp_test(struct fps_test_ereport *report)
688 {
689 char err_data[MAX_INFO_SIZE];
690 int i;
691 uint64_t result;
692 uint64_t expected;
693 uint64_t observed;
694 unsigned long prev_fsr;
695
696 prev_fsr = get_fsr();
697 init_regs(0);
698 set_fsr(0);
699
700 for (i = 1; i < 60; i++) {
701 if ((result = chain_dp(i)) != (unsigned long) i) {
702 observed = (uint64_t)result;
703 expected = (uint64_t)i;
704 (void) snprintf(err_data, sizeof (err_data),
705 "\nExpected: %d\nObserved: %d", i, result);
706 setup_fps_test_struct(IS_EREPORT_INFO,
707 report, 6226, &observed, &expected, 1, 1,
708 err_data);
709
710 return (-1);
711 }
712 }
713
714 set_fsr(prev_fsr);
715
716 return (0);
717 }
718
719 /*
720 * integer_to_float_sp(struct fps_test_ereport *report)
721 * does continuous integer to float, single precision
722 * conversions. If an error is found, relevant data is stored
723 * in report.
724 */
725 static int
integer_to_float_sp(struct fps_test_ereport * report)726 integer_to_float_sp(struct fps_test_ereport *report)
727 {
728 char err_data[MAX_INFO_SIZE];
729 int i;
730 uint64_t expected;
731 uint64_t observed;
732 unsigned long prev_fsr;
733 unsigned long result;
734
735 prev_fsr = get_fsr();
736 init_regs(0);
737
738 for (i = 0; i < N_VALS; i++) {
739 result = int_float_s(i);
740 if (result != val[i].floatsingle) {
741 observed = (uint64_t)result;
742 expected = (uint64_t)val[i].floatsingle;
743 (void) snprintf(err_data, sizeof (err_data),
744 "Val Entry[%d]\nExpected: %d"
745 "\nObserved: %d", i, val[i].floatsingle,
746 result);
747 setup_fps_test_struct(IS_EREPORT_INFO,
748 report, 6227, &observed, &expected, 1, 1,
749 err_data);
750
751 return (-1);
752 }
753 }
754
755 set_fsr(prev_fsr);
756
757 return (0);
758 }
759
760 /*
761 * integer_to_float_dp(struct fps_test_ereport *report)
762 * does continuous integer to float, double precision
763 * conversions. If an error is found, relevant data is stored
764 * in report.
765 */
766 static int
integer_to_float_dp(struct fps_test_ereport * report)767 integer_to_float_dp(struct fps_test_ereport *report)
768 {
769 char err_data[MAX_INFO_SIZE];
770 int i;
771 uint64_t expected;
772 uint64_t observed;
773 unsigned long prev_fsr;
774 unsigned long result;
775
776 prev_fsr = get_fsr();
777 init_regs(0);
778
779 for (i = 0; i < N_VALS; i++) {
780 result = int_float_d(i);
781 if (result != val[i].floatdouble) {
782 observed = (uint64_t)result;
783 expected = (uint64_t)val[i].floatdouble;
784 (void) snprintf(err_data, sizeof (err_data),
785 "Val Entry[%d]\nExpected: %lld"
786 "\nObserved: %lld", i, val[i].floatdouble,
787 result);
788 setup_fps_test_struct(IS_EREPORT_INFO,
789 report, 6228, &observed, &expected, 1, 1,
790 err_data);
791
792 return (-1);
793 }
794 }
795
796 set_fsr(prev_fsr);
797
798 return (0);
799 }
800
801 /*
802 * long_to_float_sp(struct fps_test_ereport *report)
803 * performs continuous, single precision, unsigned
804 * long to float conversions. If an error is found,
805 * relevant data is stored in report.
806 */
807 static int
long_to_float_sp(struct fps_test_ereport * report)808 long_to_float_sp(struct fps_test_ereport *report)
809 {
810 char err_data[MAX_INFO_SIZE];
811 uint64_t expected;
812 uint64_t observed;
813 unsigned long i;
814 unsigned long prev_fsr;
815 unsigned long result;
816
817 prev_fsr = get_fsr();
818 init_regs(0);
819
820 for (i = 0; i < N_VALS; i++) {
821 result = long_float_s(i);
822 if (result != val[i].floatsingle) {
823 observed = (uint64_t)result;
824 expected = (uint64_t)val[i].floatsingle;
825 (void) snprintf(err_data, sizeof (err_data),
826 "Val Entry[%d]\nExpected: %d"
827 "\nObserved: %d", i, val[i].floatdouble,
828 result);
829 setup_fps_test_struct(IS_EREPORT_INFO,
830 report, 6353, &observed, &expected, 1, 1,
831 err_data);
832
833 return (-1);
834 }
835 }
836
837 set_fsr(prev_fsr);
838
839 return (0);
840 }
841
842 /*
843 * long_to_float_dp(struct fps_test_ereport *report)
844 * performs continuous, double precision, unsigned
845 * long to float conversions. If an error is found,
846 * relevant data is stored in report.
847 */
848 static int
long_to_float_dp(struct fps_test_ereport * report)849 long_to_float_dp(struct fps_test_ereport *report)
850 {
851 char err_data[MAX_INFO_SIZE];
852 uint64_t expected;
853 uint64_t observed;
854 unsigned long i;
855 unsigned long prev_fsr;
856 unsigned long res1;
857
858 prev_fsr = get_fsr();
859 init_regs(0);
860
861 for (i = 0; i < N_VALS; i++) {
862 res1 = long_float_d(i);
863 if (res1 != val[i].floatdouble) {
864 observed = (uint64_t)res1;
865 expected = (uint64_t)val[i].floatdouble;
866 (void) snprintf(err_data, sizeof (err_data),
867 "Val Entry[%d]\nExpected: %lld"
868 "\nObserved: %lld", i, val[i].floatdouble,
869 res1);
870 setup_fps_test_struct(IS_EREPORT_INFO,
871 report, 6354, &observed, &expected, 1, 1,
872 err_data);
873
874 return (-1);
875 }
876 }
877
878 set_fsr(prev_fsr);
879
880 return (0);
881 }
882
883 /*
884 * float_to_integer_sp(struct fps_test_ereport *report)
885 * performs continuous, single precision float to
886 * integer conversions. If an error is found, relevant
887 * data is stored in report.
888 */
889 static int
float_to_integer_sp(struct fps_test_ereport * report)890 float_to_integer_sp(struct fps_test_ereport *report)
891 {
892 char err_data[MAX_INFO_SIZE];
893 uint64_t i;
894 unsigned long prev_fsr;
895 unsigned long result;
896 uint64_t observed;
897 uint64_t expected;
898
899 prev_fsr = get_fsr();
900
901 init_regs(0);
902
903 for (i = 0; i < N_VALS; i++) {
904 result = float_int_s(val[i].floatsingle);
905 if (result != i) {
906 observed = (uint64_t)result;
907 expected = (uint64_t)i;
908 (void) snprintf(err_data, sizeof (err_data),
909 "Val Entry[%d]\nExpected: %d"
910 "\nObserved: %d", i, i,
911 result);
912 setup_fps_test_struct(IS_EREPORT_INFO,
913 report, 6229, &observed, &expected, 1, 1,
914 err_data);
915
916 return (-1);
917 }
918 }
919
920 /*
921 * Value greater than highest representable value in int has to raise
922 * an invalid exception.
923 *
924 * Highest possible value in int (assume uint) is 2^32; Use 2^33 for a
925 * value greater.
926 */
927 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
928
929 /* Set trap flag to solicited */
930 trap_flag = trap_flag | TRAP_SOLICITED;
931
932 (void) float_int_s(0x50000000);
933
934 if (trap_flag) {
935 observed = (uint64_t)trap_flag;
936 expected = (uint64_t)0;
937 (void) snprintf(err_data, sizeof (err_data),
938 "fstoi max value exception not raised, "
939 "fp val=%lx, fsr=%lx",
940 0x50000000, fsr_at_trap);
941 setup_fps_test_struct(IS_EREPORT_INFO,
942 report, 5307, &observed, &expected, 1, 1,
943 err_data);
944
945 return (-1);
946 }
947
948 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
949 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
950 expected = (uint64_t)FSR_CEXC_NV;
951 (void) snprintf(err_data, sizeof (err_data),
952 "fstoi max value exception not raised, "
953 "fp val=%lx, fsr=%lx",
954 0x50000000, fsr_at_trap);
955 setup_fps_test_struct(IS_EREPORT_INFO,
956 report, 5308, &observed, &expected, 1, 1,
957 err_data);
958
959 return (-1);
960 }
961
962 /* NaNs should raise an exception when converted */
963 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
964 trap_flag = trap_flag | TRAP_SOLICITED;
965
966 (void) float_int_s(nan_sp);
967
968 if (trap_flag) {
969 observed = (uint64_t)trap_flag;
970 expected = (uint64_t)0;
971 (void) snprintf(err_data, sizeof (err_data),
972 "fstoi NaN exception not raised, "
973 "fp val=%lx, fsr=%lx",
974 nan_sp, fsr_at_trap);
975 setup_fps_test_struct(IS_EREPORT_INFO,
976 report, 5309, &observed, &expected, 1, 1,
977 err_data);
978
979 return (-1);
980 }
981
982 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
983 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
984 expected = (uint64_t)FSR_CEXC_NV;
985 (void) snprintf(err_data, sizeof (err_data),
986 "fstoi NaN exception not raised, "
987 "fp val=%lx, fsr=%lx",
988 nan_sp, fsr_at_trap);
989 setup_fps_test_struct(IS_EREPORT_INFO,
990 report, 5310, &observed, &expected, 1, 1,
991 err_data);
992
993 return (-1);
994 }
995
996 /* + infinity exceptions */
997 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
998 trap_flag = trap_flag | TRAP_SOLICITED;
999
1000 (void) float_int_s(PLUS_INF_SP);
1001
1002 if (trap_flag) {
1003 observed = (uint64_t)trap_flag;
1004 expected = (uint64_t)0;
1005 (void) snprintf(err_data, sizeof (err_data),
1006 "fstoi +infinity exception not raised, "
1007 "fp val=%lx, fsr=%lx",
1008 PLUS_INF_SP, fsr_at_trap);
1009 setup_fps_test_struct(IS_EREPORT_INFO,
1010 report, 5311, &observed, &expected, 1, 1,
1011 err_data);
1012
1013 return (-1);
1014 }
1015
1016 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
1017 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
1018 expected = (uint64_t)FSR_CEXC_NV;
1019 (void) snprintf(err_data, sizeof (err_data),
1020 "fstoi +infinity exception not raised, "
1021 "fp val=%lx, fsr=%lx",
1022 PLUS_INF_SP, fsr_at_trap);
1023 setup_fps_test_struct(IS_EREPORT_INFO,
1024 report, 5312, &observed, &expected, 1, 1,
1025 err_data);
1026
1027 return (-1);
1028 }
1029
1030 /* - infinity exceptions */
1031 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
1032 trap_flag = trap_flag | TRAP_SOLICITED;
1033
1034 (void) float_int_s(MINUS_INF_SP);
1035
1036 if (trap_flag) {
1037 observed = (uint64_t)trap_flag;
1038 expected = (uint64_t)0;
1039 (void) snprintf(err_data, sizeof (err_data),
1040 "fstoi -infinity exception not raised, "
1041 "fp val=%lx, fsr=%lx",
1042 MINUS_INF_SP, fsr_at_trap);
1043 setup_fps_test_struct(IS_EREPORT_INFO,
1044 report, 5313, &observed, &expected, 1, 1,
1045 err_data);
1046
1047 return (-1);
1048 }
1049
1050 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
1051 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
1052 expected = (uint64_t)FSR_CEXC_NV;
1053 (void) snprintf(err_data, sizeof (err_data),
1054 "fstoi -infinity exception not raised, "
1055 "fp val=%lx, fsr=%lx",
1056 MINUS_INF_SP, fsr_at_trap);
1057 setup_fps_test_struct(IS_EREPORT_INFO,
1058 report, 5314, &observed, &expected, 1, 1, err_data);
1059
1060 return (-1);
1061 }
1062
1063 /* Check for inexact exception raised because of fractions */
1064 set_fsr(prev_fsr | FSR_ENABLE_TEM_NX);
1065 trap_flag = trap_flag | TRAP_SOLICITED;
1066
1067 (void) float_int_s(pi_sp);
1068
1069 if (trap_flag) {
1070 observed = (uint64_t)trap_flag;
1071 expected = (uint64_t)0;
1072 (void) snprintf(err_data, sizeof (err_data),
1073 "fstoi inexact exception not raised, "
1074 "fp val=%lx, fsr=%lx",
1075 pi_sp, fsr_at_trap);
1076 setup_fps_test_struct(IS_EREPORT_INFO,
1077 report, 5315, &observed, &expected, 1, 1, err_data);
1078
1079 return (-1);
1080 }
1081
1082 if ((fsr_at_trap & FSR_CEXC_NX) != FSR_CEXC_NX) {
1083 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NX;
1084 expected = (uint64_t)FSR_CEXC_NX;
1085 (void) snprintf(err_data, sizeof (err_data),
1086 "fstoi inexact exception not raised, "
1087 "fp val=%lx, fsr=%lx",
1088 pi_sp, fsr_at_trap);
1089 setup_fps_test_struct(IS_EREPORT_INFO,
1090 report, 5316, &observed, &expected, 1, 1, err_data);
1091
1092 return (-1);
1093 }
1094
1095 set_fsr(prev_fsr);
1096 return (0);
1097 }
1098
1099 /*
1100 * float_to_integer_dp(struct fps_test_ereport *report)
1101 * performs continuous, double precision float to
1102 * integer conversions. If an error is found, relevant
1103 * data is stored in report.
1104 */
1105 static int
float_to_integer_dp(struct fps_test_ereport * report)1106 float_to_integer_dp(struct fps_test_ereport *report)
1107 {
1108 char err_data[MAX_INFO_SIZE];
1109 uint64_t i;
1110 uint64_t expected;
1111 uint64_t observed;
1112 unsigned long prev_fsr;
1113 unsigned long res1;
1114
1115 prev_fsr = get_fsr();
1116
1117 init_regs(0);
1118 for (i = 0; i < N_VALS; i++) {
1119 res1 = float_int_d(val[i].floatdouble);
1120
1121 if (res1 != i) {
1122 observed = (uint64_t)res1;
1123 expected = (uint64_t)i;
1124 (void) snprintf(err_data, sizeof (err_data),
1125 "Val Entry[%d]\nExpected: %d"
1126 "\nObserved: %d", i, i,
1127 res1);
1128 setup_fps_test_struct(IS_EREPORT_INFO,
1129 report, 6230, &observed, &expected, 1,
1130 1, err_data);
1131
1132 return (-1);
1133 }
1134 }
1135
1136 /*
1137 * Value greater than highest representable value in int has to raise
1138 * an invalid exception.
1139 *
1140 * Highest possible value in int (assume uint) is 2^32; Use 2^33 for a
1141 * value greater.
1142 */
1143 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
1144 trap_flag = trap_flag | TRAP_SOLICITED;
1145
1146 (void) float_int_d(0x4200000000000000);
1147
1148 if (trap_flag) {
1149 observed = (uint64_t)trap_flag;
1150 expected = (uint64_t)0;
1151 (void) snprintf(err_data, sizeof (err_data),
1152 "fdtoi max value exception not raised, "
1153 "fp val=%llx, fsr=%lx",
1154 0x4200000000000000, fsr_at_trap);
1155 setup_fps_test_struct(IS_EREPORT_INFO,
1156 report, 5317, &observed, &expected, 1,
1157 1, err_data);
1158
1159 return (-1);
1160 }
1161
1162 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
1163 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
1164 expected = (uint64_t)FSR_CEXC_NV;
1165 (void) snprintf(err_data, sizeof (err_data),
1166 "fdtoi max value exception not raised, "
1167 "fp val=%llx, fsr=%lx",
1168 0x4200000000000000, fsr_at_trap);
1169 setup_fps_test_struct(IS_EREPORT_INFO,
1170 report, 5318, &observed, &expected, 1,
1171 1, err_data);
1172
1173 return (-1);
1174 }
1175
1176 /* NaNs should raise an exception when converted */
1177 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
1178 trap_flag = trap_flag | TRAP_SOLICITED;
1179
1180 (void) float_int_d(nan_dp);
1181
1182 if (trap_flag) {
1183 observed = (uint64_t)trap_flag;
1184 expected = (uint64_t)0;
1185 (void) snprintf(err_data, sizeof (err_data),
1186 "fdtoi NaN exception not raised, "
1187 "fp val=%llx, fsr=%lx",
1188 nan_dp, fsr_at_trap);
1189 setup_fps_test_struct(IS_EREPORT_INFO,
1190 report, 5319, &observed, &expected, 1,
1191 1, err_data);
1192
1193 return (-1);
1194 }
1195
1196 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
1197 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
1198 expected = (uint64_t)FSR_CEXC_NV;
1199 (void) snprintf(err_data, sizeof (err_data),
1200 "fdtoi NaN exception not raised, "
1201 "fp val=%llx, fsr=%lx",
1202 nan_dp, fsr_at_trap);
1203 setup_fps_test_struct(IS_EREPORT_INFO,
1204 report, 5320, &observed, &expected, 1,
1205 1, err_data);
1206
1207 return (-1);
1208 }
1209
1210 /* + infinity exceptions */
1211 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
1212 trap_flag = trap_flag | TRAP_SOLICITED;
1213
1214 (void) float_int_d(PLUS_INF_DP);
1215
1216 if (trap_flag) {
1217 observed = (uint64_t)trap_flag;
1218 expected = (uint64_t)0;
1219 (void) snprintf(err_data, sizeof (err_data),
1220 "fdtoi +infinity exception not raised, "
1221 "fp val=%llx, fsr=%lx",
1222 PLUS_INF_DP, fsr_at_trap);
1223 setup_fps_test_struct(IS_EREPORT_INFO,
1224 report, 5321, &observed, &expected, 1,
1225 1, err_data);
1226
1227 return (-1);
1228 }
1229
1230 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
1231 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
1232 expected = (uint64_t)FSR_CEXC_NV;
1233 (void) snprintf(err_data, sizeof (err_data),
1234 "fdtoi +infinity exception not raised, "
1235 "fp val=%llx, fsr=%lx",
1236 PLUS_INF_DP, fsr_at_trap);
1237 setup_fps_test_struct(IS_EREPORT_INFO,
1238 report, 5322, &observed, &expected, 1,
1239 1, err_data);
1240
1241 return (-1);
1242 }
1243
1244 /* - infinity exceptions */
1245 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
1246 trap_flag = trap_flag | TRAP_SOLICITED;
1247
1248 (void) float_int_d(MINUS_INF_DP);
1249
1250 if (trap_flag) {
1251 observed = (uint64_t)trap_flag;
1252 expected = (uint64_t)0;
1253 (void) snprintf(err_data, sizeof (err_data),
1254 "fdtoi -infinity exception not raised, "
1255 "fp val=%llx, fsr=%lx",
1256 MINUS_INF_DP, fsr_at_trap);
1257 setup_fps_test_struct(IS_EREPORT_INFO,
1258 report, 5323, &observed, &expected, 1,
1259 1, err_data);
1260
1261 return (-1);
1262 }
1263
1264 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
1265 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
1266 expected = (uint64_t)FSR_CEXC_NV;
1267 (void) snprintf(err_data, sizeof (err_data),
1268 "fdtoi -infinity exception not raised, "
1269 "fp val=%llx, fsr=%lx",
1270 MINUS_INF_DP, fsr_at_trap);
1271 setup_fps_test_struct(IS_EREPORT_INFO,
1272 report, 5324, &observed, &expected, 1,
1273 1, err_data);
1274
1275 return (-1);
1276 }
1277
1278 /* Check for inexact exception raised because of fractions */
1279 set_fsr(prev_fsr | FSR_ENABLE_TEM_NX);
1280 trap_flag = trap_flag | TRAP_SOLICITED;
1281
1282 (void) float_int_d(pi_dp);
1283 if (trap_flag) {
1284 observed = (uint64_t)trap_flag;
1285 expected = (uint64_t)0;
1286 (void) snprintf(err_data, sizeof (err_data),
1287 "fdtoi inexact exception not raised, "
1288 "fp val=%llx, fsr=%lx",
1289 pi_dp, fsr_at_trap);
1290 setup_fps_test_struct(IS_EREPORT_INFO,
1291 report, 5325, &observed, &expected, 1,
1292 1, err_data);
1293
1294 return (-1);
1295 }
1296
1297 if ((fsr_at_trap & FSR_CEXC_NX) != FSR_CEXC_NX) {
1298 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NX;
1299 expected = (uint64_t)FSR_CEXC_NX;
1300 (void) snprintf(err_data, sizeof (err_data),
1301 "fdtoi inexact exception not raised, "
1302 "fp val=%llx, fsr=%lx",
1303 pi_dp, fsr_at_trap);
1304 setup_fps_test_struct(IS_EREPORT_INFO,
1305 report, 5326, &observed, &expected, 1,
1306 1, err_data);
1307
1308 return (-1);
1309 }
1310
1311 set_fsr(prev_fsr);
1312
1313 return (0);
1314 }
1315
1316 /*
1317 * float_to_long_sp(struct fps_test_ereport *report)
1318 * does continuous, single precision, float to long
1319 * conversions. If an error is found, relevant data
1320 * is stored in report.
1321 */
1322 static int
float_to_long_sp(struct fps_test_ereport * report)1323 float_to_long_sp(struct fps_test_ereport *report)
1324 {
1325 char err_data[MAX_INFO_SIZE];
1326 uint64_t i;
1327 uint64_t expected;
1328 uint64_t observed;
1329 unsigned long prev_fsr;
1330 unsigned long result;
1331
1332 prev_fsr = get_fsr();
1333
1334 init_regs(0);
1335
1336 for (i = 0; i < N_VALS; i++) {
1337 result = float_long_s(val[i].floatsingle);
1338
1339 if (result != i) {
1340 observed = (uint64_t)result;
1341 expected = (uint64_t)i;
1342 (void) snprintf(err_data, sizeof (err_data),
1343 "Val Entry[%d]\nExpected: %d"
1344 "\nObserved: %d", i, i,
1345 result);
1346 setup_fps_test_struct(IS_EREPORT_INFO,
1347 report, 6352, &observed, &expected, 1,
1348 1, err_data);
1349
1350 return (-1);
1351 }
1352 }
1353
1354 /*
1355 * Value greater than highest representable value in int has to raise
1356 * an invalid exception.
1357 *
1358 * Highest possible value in int (assume uint) is 2^64; Use 2^65 for a
1359 * value greater.
1360 */
1361
1362 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
1363 trap_flag = trap_flag | TRAP_SOLICITED;
1364
1365 (void) float_long_s(0x60000000);
1366
1367 if (trap_flag) {
1368 observed = (uint64_t)trap_flag;
1369 expected = (uint64_t)0;
1370 (void) snprintf(err_data, sizeof (err_data),
1371 "fstox max value exception not raised, "
1372 "fp val=%lx, fsr=%lx",
1373 0x60000000, fsr_at_trap);
1374 setup_fps_test_struct(IS_EREPORT_INFO,
1375 report, 5327, &observed, &expected, 1,
1376 1, err_data);
1377
1378 return (-1);
1379 }
1380
1381 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
1382 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
1383 expected = (uint64_t)FSR_CEXC_NV;
1384 (void) snprintf(err_data, sizeof (err_data),
1385 "fstox max value exception not raised, "
1386 "fp val=%lx, fsr=%lx",
1387 0x50000000, fsr_at_trap);
1388 setup_fps_test_struct(IS_EREPORT_INFO,
1389 report, 5328, &observed, &expected, 1,
1390 1, err_data);
1391
1392 return (-1);
1393 }
1394
1395 /* NaNs should raise an exception when converted */
1396 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
1397 trap_flag = trap_flag | TRAP_SOLICITED;
1398
1399 (void) float_long_s(nan_sp);
1400
1401 if (trap_flag) {
1402 observed = (uint64_t)trap_flag;
1403 expected = (uint64_t)0;
1404 (void) snprintf(err_data, sizeof (err_data),
1405 "fstox NaN exception not raised, "
1406 "fp val=%lx, fsr=%lx",
1407 nan_sp, fsr_at_trap);
1408 setup_fps_test_struct(IS_EREPORT_INFO,
1409 report, 5329, &observed, &expected, 1, 1,
1410 err_data);
1411
1412 return (-1);
1413 }
1414
1415 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
1416 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
1417 expected = (uint64_t)FSR_CEXC_NV;
1418 (void) snprintf(err_data, sizeof (err_data),
1419 "fstox NaN exception not raised, "
1420 "fp val=%lx, fsr=%lx",
1421 nan_sp, fsr_at_trap);
1422 setup_fps_test_struct(IS_EREPORT_INFO,
1423 report, 5330, &observed, &expected, 1, 1,
1424 err_data);
1425
1426 return (-1);
1427 }
1428
1429 /* + infinity exceptions */
1430 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
1431 trap_flag = trap_flag | TRAP_SOLICITED;
1432
1433 (void) float_long_s(PLUS_INF_SP);
1434
1435 if (trap_flag) {
1436 observed = (uint64_t)trap_flag;
1437 expected = (uint64_t)0;
1438 (void) snprintf(err_data, sizeof (err_data),
1439 "fstox +infinity exception not raised, "
1440 "fp val=%lx, fsr=%lx",
1441 PLUS_INF_SP, fsr_at_trap);
1442 setup_fps_test_struct(IS_EREPORT_INFO,
1443 report, 5331, &observed, &expected, 1,
1444 1, err_data);
1445
1446 return (-1);
1447 }
1448
1449 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
1450 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
1451 expected = (uint64_t)FSR_CEXC_NV;
1452 (void) snprintf(err_data, sizeof (err_data),
1453 "fstox +infinity exception not raised, "
1454 "fp val=%lx, fsr=%lx",
1455 PLUS_INF_SP, fsr_at_trap);
1456 setup_fps_test_struct(IS_EREPORT_INFO,
1457 report, 5332, &observed, &expected, 1,
1458 1, err_data);
1459
1460 return (-1);
1461 }
1462
1463 /* - infinity exceptions */
1464 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
1465 trap_flag = trap_flag | TRAP_SOLICITED;
1466
1467 (void) float_long_s(MINUS_INF_SP);
1468
1469 if (trap_flag) {
1470 observed = (uint64_t)trap_flag;
1471 expected = (uint64_t)0;
1472 (void) snprintf(err_data, sizeof (err_data),
1473 "fstox -infinity exception not raised, "
1474 "fp val=%lx, fsr=%lx",
1475 MINUS_INF_SP, fsr_at_trap);
1476 setup_fps_test_struct(IS_EREPORT_INFO,
1477 report, 5333, &observed, &expected, 1,
1478 1, err_data);
1479
1480 return (-1);
1481 }
1482
1483 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
1484 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
1485 expected = (uint64_t)FSR_CEXC_NV;
1486 (void) snprintf(err_data, sizeof (err_data),
1487 "fstox -infinity exception not raised, "
1488 "fp val=%lx, fsr=%lx",
1489 MINUS_INF_SP, fsr_at_trap);
1490 setup_fps_test_struct(IS_EREPORT_INFO,
1491 report, 5334, &observed, &expected, 1,
1492 1, err_data);
1493
1494 return (-1);
1495 }
1496
1497 /* Check for inexact exception raised because of fractions */
1498
1499 set_fsr(prev_fsr | FSR_ENABLE_TEM_NX);
1500 trap_flag = trap_flag | TRAP_SOLICITED;
1501
1502 (void) float_int_s(pi_sp);
1503
1504 if (trap_flag) {
1505 observed = (uint64_t)trap_flag;
1506 expected = (uint64_t)0;
1507 (void) snprintf(err_data, sizeof (err_data),
1508 "fstox inexact exception not raised, "
1509 "fp val=%lx, fsr=%lx",
1510 pi_sp, fsr_at_trap);
1511 setup_fps_test_struct(IS_EREPORT_INFO,
1512 report, 5335, &observed, &expected, 1,
1513 1, err_data);
1514
1515 return (-1);
1516 }
1517
1518 if ((fsr_at_trap & FSR_CEXC_NX) != FSR_CEXC_NX) {
1519 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NX;
1520 expected = (uint64_t)FSR_CEXC_NX;
1521 (void) snprintf(err_data, sizeof (err_data),
1522 "fstox inexact exception not raised, "
1523 "fp val=%lx, fsr=%lx",
1524 pi_sp, fsr_at_trap);
1525 setup_fps_test_struct(IS_EREPORT_INFO,
1526 report, 5336, &observed, &expected, 1,
1527 1, err_data);
1528
1529 return (-1);
1530 }
1531
1532 set_fsr(prev_fsr);
1533 return (0);
1534 }
1535
1536 /*
1537 * float_to_long_dp(struct fps_test_ereport *report)
1538 * does continuous, double precision, float to long
1539 * conversions. If an error is found, relevant data
1540 * is stored in report.
1541 */
1542 static int
float_to_long_dp(struct fps_test_ereport * report)1543 float_to_long_dp(struct fps_test_ereport *report)
1544 {
1545 char err_data[MAX_INFO_SIZE];
1546 uint64_t i;
1547 uint64_t expected;
1548 uint64_t observed;
1549 unsigned long prev_fsr;
1550 unsigned long res1;
1551
1552 prev_fsr = get_fsr();
1553
1554 init_regs(0);
1555
1556 for (i = 0; i < N_VALS; i++) {
1557 res1 = float_long_d(val[i].floatdouble);
1558
1559 if (res1 != i) {
1560 observed = (uint64_t)res1;
1561 expected = (uint64_t)i;
1562 (void) snprintf(err_data, sizeof (err_data),
1563 "Val Entry[%d]\nExpected: %d"
1564 "\nObserved: %d", i, i,
1565 res1);
1566 setup_fps_test_struct(IS_EREPORT_INFO,
1567 report, 6351, &observed, &expected, 1,
1568 1, err_data);
1569
1570 return (-1);
1571 }
1572 }
1573
1574 /*
1575 * Value greater than highest representable value in long has to
1576 * raise an invalid exception.
1577 *
1578 * Highest possible value in long (assume ulong) is 2^64; Use 2^65 for a
1579 * value greater.
1580 */
1581
1582 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
1583 trap_flag = trap_flag | TRAP_SOLICITED;
1584
1585 (void) float_long_d(0x4400000000000000);
1586
1587 if (trap_flag) {
1588 observed = (uint64_t)trap_flag;
1589 expected = (uint64_t)0;
1590 (void) snprintf(err_data, sizeof (err_data),
1591 "fdtox max value exception not raised, "
1592 "fp val=%lx, fsr=%lx",
1593 0x4400000000000000, fsr_at_trap);
1594 setup_fps_test_struct(IS_EREPORT_INFO,
1595 report, 5337, &observed, &expected, 1,
1596 1, err_data);
1597
1598 return (-1);
1599 }
1600
1601 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
1602 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
1603 expected = (uint64_t)FSR_CEXC_NV;
1604 (void) snprintf(err_data, sizeof (err_data),
1605 "fdtox max value exception not raised, "
1606 "fp val=%lx, fsr=%lx",
1607 0x4200000000000000, fsr_at_trap);
1608 setup_fps_test_struct(IS_EREPORT_INFO,
1609 report, 5338, &observed, &expected, 1,
1610 1, err_data);
1611
1612 return (-1);
1613 }
1614
1615 /* NaNs should raise an exception when converted */
1616 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
1617 trap_flag = trap_flag | TRAP_SOLICITED;
1618
1619 (void) float_long_d(nan_dp);
1620
1621 if (trap_flag) {
1622 observed = (uint64_t)trap_flag;
1623 expected = (uint64_t)0;
1624 (void) snprintf(err_data, sizeof (err_data),
1625 "fdtox NaN exception not raised, "
1626 "fp val=%lx, fsr=%lx",
1627 nan_dp, fsr_at_trap);
1628 setup_fps_test_struct(IS_EREPORT_INFO,
1629 report, 5339, &observed, &expected, 1,
1630 1, err_data);
1631
1632 return (-1);
1633 }
1634
1635 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
1636 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
1637 expected = (uint64_t)FSR_CEXC_NV;
1638 (void) snprintf(err_data, sizeof (err_data),
1639 "fdtox NaN exception not raised, "
1640 "fp val=%lx, fsr=%lx",
1641 nan_dp, fsr_at_trap);
1642 setup_fps_test_struct(IS_EREPORT_INFO,
1643 report, 5340, &observed, &expected, 1,
1644 1, err_data);
1645
1646 return (-1);
1647 }
1648
1649 /* + infinity exceptions */
1650 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
1651 trap_flag = trap_flag | TRAP_SOLICITED;
1652
1653 (void) float_long_d(PLUS_INF_DP);
1654
1655 if (trap_flag) {
1656 observed = (uint64_t)trap_flag;
1657 expected = (uint64_t)0;
1658 (void) snprintf(err_data, sizeof (err_data),
1659 "fdtox +infinity exception not raised, "
1660 "fp val=%lx, fsr=%lx",
1661 PLUS_INF_DP, fsr_at_trap);
1662 setup_fps_test_struct(IS_EREPORT_INFO,
1663 report, 5341, &observed, &expected, 1,
1664 1, err_data);
1665
1666 return (-1);
1667 }
1668
1669 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
1670 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
1671 expected = (uint64_t)FSR_CEXC_NV;
1672 (void) snprintf(err_data, sizeof (err_data),
1673 "fdtox +infinity exception not raised, "
1674 "fp val=%lx, fsr=%lx",
1675 PLUS_INF_DP, fsr_at_trap);
1676 setup_fps_test_struct(IS_EREPORT_INFO,
1677 report, 5342, &observed, &expected, 1,
1678 1, err_data);
1679
1680 return (-1);
1681 }
1682
1683 /* - infinity exceptions */
1684 set_fsr(prev_fsr | FSR_ENABLE_TEM_NV);
1685 trap_flag = trap_flag | TRAP_SOLICITED;
1686
1687 (void) float_long_d(MINUS_INF_DP);
1688
1689 if (trap_flag) {
1690 observed = (uint64_t)trap_flag;
1691 expected = (uint64_t)0;
1692 (void) snprintf(err_data, sizeof (err_data),
1693 "fdtox -infinity exception not raised, "
1694 "fp val=%lx, fsr=%lx",
1695 MINUS_INF_DP, fsr_at_trap);
1696 setup_fps_test_struct(IS_EREPORT_INFO,
1697 report, 5343, &observed, &expected, 1,
1698 1, err_data);
1699
1700 return (-1);
1701 }
1702
1703 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
1704 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
1705 expected = (uint64_t)FSR_CEXC_NV;
1706 (void) snprintf(err_data, sizeof (err_data),
1707 "fdtox -infinity exception not raised, "
1708 "fp val=%lx, fsr=%lx",
1709 MINUS_INF_DP, fsr_at_trap);
1710 setup_fps_test_struct(IS_EREPORT_INFO,
1711 report, 5344, &observed, &expected, 1,
1712 1, err_data);
1713
1714 return (-1);
1715 }
1716
1717 /* Check for inexact exception raised because of fractions */
1718
1719 set_fsr(prev_fsr | FSR_ENABLE_TEM_NX);
1720 trap_flag = trap_flag | TRAP_SOLICITED;
1721
1722 (void) float_long_d(pi_dp);
1723
1724 if (trap_flag) {
1725 observed = (uint64_t)trap_flag;
1726 expected = (uint64_t)0;
1727 (void) snprintf(err_data, sizeof (err_data),
1728 "fdtox inexact exception not raised, "
1729 "fp val=%lx, fsr=%lx",
1730 pi_dp, fsr_at_trap);
1731 setup_fps_test_struct(IS_EREPORT_INFO,
1732 report, 5345, &observed, &expected, 1,
1733 1, err_data);
1734
1735 return (-1);
1736 }
1737
1738 if ((fsr_at_trap & FSR_CEXC_NX) != FSR_CEXC_NX) {
1739 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NX;
1740 expected = (uint64_t)FSR_CEXC_NX;
1741 (void) snprintf(err_data, sizeof (err_data),
1742 "fdtox inexact exception not raised, "
1743 "fp val=%lx, fsr=%lx",
1744 pi_dp, fsr_at_trap);
1745 setup_fps_test_struct(IS_EREPORT_INFO,
1746 report, 5346, &observed, &expected, 1,
1747 1, err_data);
1748
1749 return (-1);
1750 }
1751
1752 set_fsr(prev_fsr);
1753
1754 return (0);
1755 }
1756
1757 /*
1758 * single_doub(struct fps_test_ereport *report)
1759 * does continues single to double conversion.
1760 * If an error is found, relevant data is stored
1761 * in report.
1762 */
1763 static int
single_doub(struct fps_test_ereport * report)1764 single_doub(struct fps_test_ereport *report)
1765 {
1766 char err_data[MAX_INFO_SIZE];
1767 int i;
1768 uint64_t expected;
1769 uint64_t observed;
1770 unsigned long prev_fsr;
1771 unsigned long result;
1772
1773
1774 prev_fsr = get_fsr();
1775
1776 init_regs(0);
1777
1778 for (i = 0; i < N_VALS; i++) {
1779 result = convert_sp_dp(val[i].floatsingle);
1780
1781 if (result != val[i].floatdouble) {
1782 observed = (uint64_t)result;
1783 expected = (uint64_t)val[i].floatdouble;
1784 (void) snprintf(err_data, sizeof (err_data),
1785 "Val Entry[%d]\nExpected: %lld"
1786 "\nObserved: %lld", i,
1787 val[i].floatdouble, result);
1788 setup_fps_test_struct(IS_EREPORT_INFO,
1789 report, 6231, &observed, &expected, 1,
1790 1, err_data);
1791
1792 return (-1);
1793 }
1794 }
1795
1796 set_fsr(prev_fsr);
1797
1798 return (0);
1799 }
1800
1801 /*
1802 * double_sing(struct fps_test_ereport *report)
1803 * does continues double to single conversion.
1804 * If an error is found, relevant data is stored
1805 * in report.
1806 */
1807 static int
double_sing(struct fps_test_ereport * report)1808 double_sing(struct fps_test_ereport *report)
1809 {
1810 char err_data[MAX_INFO_SIZE];
1811 int i;
1812 uint64_t expected;
1813 uint64_t observed;
1814 unsigned long result;
1815 unsigned long prev_fsr;
1816
1817 prev_fsr = get_fsr();
1818
1819 init_regs(0);
1820
1821 for (i = 0; i < N_VALS; i++) {
1822 result = convert_dp_sp(val[i].floatdouble);
1823
1824 if (result != val[i].floatsingle) {
1825 observed = (uint64_t)result;
1826 expected = (uint64_t)val[i].floatsingle;
1827 (void) snprintf(err_data, sizeof (err_data),
1828 "Val Entry[%d]\nExpected: %d"
1829 "\nObserved: %d", i,
1830 val[i].floatsingle, result);
1831 setup_fps_test_struct(IS_EREPORT_INFO,
1832 report, 6232, &observed, &expected, 1,
1833 1, err_data);
1834
1835 return (-1);
1836 }
1837 }
1838
1839 set_fsr(prev_fsr);
1840 return (0);
1841 }
1842
1843 /*
1844 * fmovs_ins(struct fps_test_ereport *report)
1845 * moves a value through the floating point
1846 * registers. If an error is found, relevant
1847 * data is stored
1848 * in report.
1849 */
1850 static int
fmovs_ins(struct fps_test_ereport * report)1851 fmovs_ins(struct fps_test_ereport *report)
1852 {
1853 char err_data[MAX_INFO_SIZE];
1854 uint64_t observed;
1855 uint64_t expected;
1856 unsigned long result;
1857 unsigned long prev_fsr;
1858
1859 prev_fsr = get_fsr();
1860
1861 init_regs(0);
1862
1863 if ((result = move_regs(0x3F800000)) != 0x3F800000) {
1864 observed = (uint64_t)result;
1865 expected = (uint64_t)0x3F800000;
1866 (void) snprintf(err_data, sizeof (err_data),
1867 "Wrote to f0, read from f31");
1868 setup_fps_test_struct(IS_EREPORT_INFO,
1869 report, 6233, &observed, &expected, 1,
1870 1, err_data);
1871
1872 return (-1);
1873 }
1874
1875 set_fsr(prev_fsr);
1876 return (0);
1877 }
1878
1879 /*
1880 * get_negative_value_pn_sp(struct fps_test_ereport *report)
1881 * converts single precision postive to negative values.
1882 * If an error is found, relevant data is stored
1883 * in report.
1884 */
1885 static int
get_negative_value_pn_sp(struct fps_test_ereport * report)1886 get_negative_value_pn_sp(struct fps_test_ereport *report)
1887 {
1888 char err_data[MAX_INFO_SIZE];
1889 int i;
1890 uint64_t observed;
1891 uint64_t expected;
1892 unsigned long prev_fsr;
1893 unsigned long result;
1894
1895 prev_fsr = get_fsr();
1896
1897 init_regs(0);
1898
1899 for (i = 0; i < N_VALS; i++) {
1900 result = negate_value_sp(val[i].floatsingle);
1901 if (result != neg_val_sp[i]) {
1902 observed = (uint64_t)result;
1903 expected = (uint64_t)neg_val_sp[i];
1904 (void) snprintf(err_data, sizeof (err_data),
1905 "Val Entry[%d]\nExpected: %d"
1906 "\nObserved: %d", i, neg_val_sp[i],
1907 result);
1908 setup_fps_test_struct(IS_EREPORT_INFO,
1909 report, 6234, &observed, &expected, 1,
1910 1, err_data);
1911
1912 return (-1);
1913 }
1914 }
1915
1916 set_fsr(prev_fsr);
1917 return (0);
1918 }
1919
1920 /*
1921 * get_negative_value_pn_dp(struct fps_test_ereport *report)
1922 * converts double precision postive to negative values.
1923 * If an error is found, relevant data is stored
1924 * in report.
1925 */
1926 static int
get_negative_value_pn_dp(struct fps_test_ereport * report)1927 get_negative_value_pn_dp(struct fps_test_ereport *report)
1928 {
1929 char err_data[MAX_INFO_SIZE];
1930 int i;
1931 uint64_t expected;
1932 uint64_t observed;
1933 uint64_t result;
1934
1935 init_regs_dp(0);
1936
1937 for (i = 0; i < N_VALS; i++) {
1938 result = negate_value_dp(val[i].floatdouble);
1939 if (result != neg_val_dp[i]) {
1940 observed = (uint64_t)result;
1941 expected = (uint64_t)neg_val_dp[i];
1942 (void) snprintf(err_data, sizeof (err_data),
1943 "Val Entry[%d]\nExpected: %lld"
1944 "\nObserved: %lld", i, neg_val_dp[i],
1945 result);
1946 setup_fps_test_struct(IS_EREPORT_INFO,
1947 report, 6362, &observed, &expected, 1,
1948 1, err_data);
1949
1950 return (-1);
1951 }
1952 }
1953
1954 return (0);
1955 }
1956
1957 /*
1958 * get_negative_value_np_sp(struct fps_test_ereport *report)
1959 * converts single precision negative to positive values.
1960 * If an error is found, relevant data is stored
1961 * in report.
1962 */
1963 static int
get_negative_value_np_sp(struct fps_test_ereport * report)1964 get_negative_value_np_sp(struct fps_test_ereport *report)
1965 {
1966 char err_data[MAX_INFO_SIZE];
1967 int i;
1968 uint64_t observed;
1969 uint64_t expected;
1970 unsigned long result;
1971 unsigned long prev_fsr;
1972
1973 prev_fsr = get_fsr();
1974
1975 init_regs(0);
1976
1977 for (i = 0; i < N_VALS; i++) {
1978 result = negate_value_sp(neg_val_sp[i]);
1979
1980 if (result != val[i].floatsingle) {
1981 observed = (uint64_t)result;
1982 expected = (uint64_t)val[i].floatsingle;
1983 (void) snprintf(err_data, sizeof (err_data),
1984 "Val Entry[%d]\nExpected: %d"
1985 "\nObserved: %d", i, val[i].floatsingle,
1986 result);
1987 setup_fps_test_struct(IS_EREPORT_INFO,
1988 report, 6235, &observed, &expected, 1,
1989 1, err_data);
1990
1991 return (-1);
1992 }
1993 }
1994
1995 set_fsr(prev_fsr);
1996 return (0);
1997 }
1998
1999 /*
2000 * get_negative_value_np_dp(struct fps_test_ereport *report)
2001 * converts double precision negative to positive values.
2002 * If an error is found, relevant data is stored
2003 * in report.
2004 */
2005 static int
get_negative_value_np_dp(struct fps_test_ereport * report)2006 get_negative_value_np_dp(struct fps_test_ereport *report)
2007 {
2008 char err_data[MAX_INFO_SIZE];
2009 int i;
2010 uint64_t expected;
2011 uint64_t observed;
2012 uint64_t result;
2013
2014 init_regs_dp(0);
2015
2016 for (i = 0; i < N_VALS; i++) {
2017 result = negate_value_dp(neg_val_dp[i]);
2018
2019 if (result != val[i].floatdouble) {
2020 observed = (uint64_t)result;
2021 expected = (uint64_t)val[i].floatdouble;
2022 (void) snprintf(err_data, sizeof (err_data),
2023 "Val Entry[%d]\nExpected: %lld"
2024 "\nObserved: %lld", i, val[i].floatdouble,
2025 result);
2026 setup_fps_test_struct(IS_EREPORT_INFO,
2027 report, 6363, &observed, &expected, 1,
2028 1, err_data);
2029
2030 return (-1);
2031 }
2032 }
2033
2034 return (0);
2035 }
2036
2037 /*
2038 * fabs_ins_sp(struct fps_test_ereport *report)
2039 * does single precision absolute value testing.
2040 * If an error is found, relevant data is stored
2041 * in report.
2042 */
2043 static int
fabs_ins_sp(struct fps_test_ereport * report)2044 fabs_ins_sp(struct fps_test_ereport *report)
2045 {
2046 char err_data[MAX_INFO_SIZE];
2047 int i;
2048 uint64_t expected;
2049 uint64_t observed;
2050 unsigned long result;
2051 unsigned long prev_fsr;
2052
2053 prev_fsr = get_fsr();
2054
2055 init_regs(0);
2056 for (i = 0; i < N_VALS; i++) {
2057 result = absolute_value_sp(neg_val_sp[i]);
2058 if (result != val[i].floatsingle) {
2059 observed = *(uint64_t *)&result;
2060 expected = *(uint64_t *)&(val[i].floatsingle);
2061 (void) snprintf(err_data, sizeof (err_data),
2062 "Val Entry[%d]\nExpected: %d"
2063 "\nObserved: %d", i, val[i].floatsingle,
2064 result);
2065 setup_fps_test_struct(IS_EREPORT_INFO,
2066 report, 6236, &observed, &expected, 1,
2067 1, err_data);
2068
2069 return (-1);
2070 }
2071 }
2072
2073 set_fsr(prev_fsr);
2074 return (0);
2075 }
2076
2077 /*
2078 * fabs_ins_dp(struct fps_test_ereport *report)
2079 * does double precision absolute value testing.
2080 * If an error is found, relevant data is stored
2081 * in report.
2082 */
2083 static int
fabs_ins_dp(struct fps_test_ereport * report)2084 fabs_ins_dp(struct fps_test_ereport *report)
2085 {
2086 char err_data[MAX_INFO_SIZE];
2087 int i;
2088 uint64_t expected;
2089 uint64_t observed;
2090 uint64_t result;
2091
2092 init_regs_dp(0);
2093
2094 for (i = 0; i < N_VALS; i++) {
2095 result = absolute_value_dp(neg_val_dp[i]);
2096
2097 if (result != val[i].floatdouble) {
2098 observed = (uint64_t)result;
2099 expected = (uint64_t)val[i].floatdouble;
2100 (void) snprintf(err_data, sizeof (err_data),
2101 "Val Entry[%d]\nExpected: %lld"
2102 "\nObserved: %lld", i, val[i].floatdouble,
2103 result);
2104 setup_fps_test_struct(IS_EREPORT_INFO,
2105 report, 6361, &observed, &expected, 1,
2106 1, err_data);
2107
2108 return (-1);
2109 }
2110 }
2111
2112 return (0);
2113 }
2114
2115 /*
2116 * addition_test_sp(struct fps_test_ereport *report)
2117 * tests single precision addition using floating
2118 * point registers (f4=f0+f2).
2119 * If an error is found, relevant data is stored
2120 * in report.
2121 */
2122 static int
addition_test_sp(struct fps_test_ereport * report)2123 addition_test_sp(struct fps_test_ereport *report)
2124 {
2125 char err_data[MAX_INFO_SIZE];
2126 int i;
2127 unsigned long result;
2128 unsigned long prev_fsr;
2129 uint64_t observed;
2130 uint64_t expected;
2131
2132 prev_fsr = get_fsr();
2133
2134 init_regs(0);
2135 for (i = 0; i < (N_VALS - 1); i++) {
2136 result = add_sp(val[i].floatsingle, val[1].floatsingle);
2137
2138 if (result != (val[i + 1].floatsingle)) {
2139
2140 observed = (uint64_t)result;
2141 expected = (uint64_t)val[i + 1].floatsingle;
2142 (void) snprintf(err_data, sizeof (err_data),
2143 "Val Entry[%d], reg f4=f0+f2"
2144 "\nExpected: %d\nObserved: %d",
2145 i, val[i + 1].floatsingle, result);
2146 setup_fps_test_struct(IS_EREPORT_INFO,
2147 report, 6237, &observed, &expected, 1,
2148 1, err_data);
2149
2150 return (-1);
2151 }
2152 }
2153
2154 set_fsr(prev_fsr);
2155 return (0);
2156 }
2157
2158 /*
2159 * addition_test_dp(struct fps_test_ereport *report)
2160 * tests double precision addition using floating
2161 * point registers (f4=f0+f2).
2162 * If an error is found, relevant data is stored
2163 * in report.
2164 */
2165 static int
addition_test_dp(struct fps_test_ereport * report)2166 addition_test_dp(struct fps_test_ereport *report)
2167 {
2168 char err_data[MAX_INFO_SIZE];
2169 int i;
2170 unsigned long result;
2171 unsigned long prev_fsr;
2172 uint64_t observed;
2173 uint64_t expected;
2174
2175 prev_fsr = get_fsr();
2176
2177 init_regs(0);
2178
2179 for (i = 0; i < (N_VALS - 1); i++) {
2180 result = add_dp(val[i].floatdouble, val[1].floatdouble);
2181
2182 if (result != (val[i + 1].floatdouble)) {
2183 observed = (uint64_t)result;
2184 expected = (uint64_t)val[i + 1].floatdouble;
2185 (void) snprintf(err_data, sizeof (err_data),
2186 "Val Entry[%d], reg f4=f0+f2"
2187 "\nExpected: %lld\nObserved: %lld",
2188 i, val[i + 1].floatdouble, result);
2189 setup_fps_test_struct(IS_EREPORT_INFO,
2190 report, 6238, &observed, &expected, 1,
2191 1, err_data);
2192
2193 return (-1);
2194 }
2195 }
2196
2197 set_fsr(prev_fsr);
2198 return (0);
2199 }
2200
2201 /*
2202 * subtraction_test_sp(struct fps_test_ereport *report)
2203 * tests single precision subtaction using floating
2204 * point registers (f4=f0-f2).
2205 * If an error is found, relevant data is stored
2206 * in report.
2207 */
2208 static int
subtraction_test_sp(struct fps_test_ereport * report)2209 subtraction_test_sp(struct fps_test_ereport *report)
2210 {
2211 char err_data[MAX_INFO_SIZE];
2212 int i;
2213 unsigned long result;
2214 unsigned long prev_fsr;
2215 uint64_t observed;
2216 uint64_t expected;
2217
2218 prev_fsr = get_fsr();
2219
2220 init_regs(0);
2221 for (i = 1; i < N_VALS; i++) {
2222 result = sub_sp(val[i].floatsingle, val[i - 1].floatsingle);
2223
2224 if (result != val[1].floatsingle) {
2225 observed = (uint64_t)result;
2226 expected = (uint64_t)val[1].floatsingle;
2227 (void) snprintf(err_data, sizeof (err_data),
2228 "Val Entry[%d], reg f4=f0-f2"
2229 "\nExpected: %d\nObserved: %d",
2230 i, val[1].floatsingle, result);
2231 setup_fps_test_struct(IS_EREPORT_INFO,
2232 report, 6239, &observed, &expected, 1,
2233 1, err_data);
2234
2235 return (-1);
2236 }
2237 }
2238
2239 set_fsr(prev_fsr);
2240 return (0);
2241 }
2242
2243 /*
2244 * subtraction_test_dp(struct fps_test_ereport *report)
2245 * tests double precision subtaction using floating
2246 * point registers (f4=f0-f2).
2247 * If an error is found, relevant data is stored
2248 * in report.
2249 */
2250 static int
subtraction_test_dp(struct fps_test_ereport * report)2251 subtraction_test_dp(struct fps_test_ereport *report)
2252 {
2253 char err_data[MAX_INFO_SIZE];
2254 int i;
2255 unsigned long result;
2256 unsigned long prev_fsr;
2257 uint64_t observed;
2258 uint64_t expected;
2259
2260 prev_fsr = get_fsr();
2261
2262 init_regs(0);
2263
2264 for (i = 1; i < N_VALS; i++) {
2265 result = sub_dp(val[i].floatdouble, val[i - 1].floatdouble);
2266
2267 if (result != val[1].floatdouble) {
2268 observed = (uint64_t)result;
2269 expected = (uint64_t)val[1].floatdouble;
2270 (void) snprintf(err_data, sizeof (err_data),
2271 "Val Entry[%d], reg f4=f0-f2"
2272 "\nExpected: %lld\nObserved: %lld",
2273 i, val[1].floatdouble, result);
2274 setup_fps_test_struct(IS_EREPORT_INFO,
2275 report, 6240, &observed, &expected, 1,
2276 1, err_data);
2277
2278 return (-1);
2279 }
2280 }
2281
2282 set_fsr(prev_fsr);
2283 return (0);
2284 }
2285
2286 /*
2287 * squareroot_test_sp(struct fps_test_ereport *report)
2288 * tests single precision squareroot.
2289 * If an error is found, relevant data is stored
2290 * in report.
2291 */
2292 static int
squareroot_test_sp(struct fps_test_ereport * report)2293 squareroot_test_sp(struct fps_test_ereport *report)
2294 {
2295 char err_data[MAX_INFO_SIZE];
2296 int i;
2297 uint64_t observed;
2298 uint64_t expected;
2299 unsigned long result, workvalue;
2300 unsigned long prev_fsr;
2301
2302 prev_fsr = get_fsr();
2303
2304 init_regs(0);
2305
2306 for (i = 1; i < N_VALS; i++) {
2307 workvalue = val[i].floatsingle;
2308 result = sqrt_sp(mult_sp(workvalue, workvalue));
2309 if (result != workvalue) {
2310 observed = (uint64_t)result;
2311 expected = (uint64_t)workvalue;
2312 (void) snprintf(err_data, sizeof (err_data),
2313 "\nExpected: %d\nObserved: %d", workvalue,
2314 result);
2315 setup_fps_test_struct(NO_EREPORT_INFO,
2316 report, 6241, &observed, &expected, 1, 1);
2317
2318 return (-1);
2319 }
2320 }
2321
2322 /* fsqrt(x), where x>0, should be positive */
2323 result = sqrt_sp(half_sp);
2324
2325 if (result & SIGN_FLAG_SP) {
2326 observed = (uint64_t)result & SIGN_FLAG_SP;
2327 expected = (uint64_t)0;
2328 setup_fps_test_struct(NO_EREPORT_INFO,
2329 report, 8241, &observed, &expected, 1, 1);
2330
2331 return (-1);
2332 }
2333
2334 /* fsqrt(-0)=-0. */
2335 result = sqrt_sp(MINUS_ZERO_SP);
2336
2337 if (!(result & MINUS_ZERO_SP)) {
2338 observed = (uint64_t)0;
2339 expected = (uint64_t)1;
2340 setup_fps_test_struct(NO_EREPORT_INFO,
2341 report, 8242, &observed, &expected, 1, 1);
2342
2343 return (-1);
2344 }
2345
2346 set_fsr(prev_fsr);
2347 return (0);
2348 }
2349
2350 /*
2351 * squareroot_test_dp(struct fps_test_ereport *report)
2352 * tests double precision squareroot.
2353 * If an error is found, relevant data is stored
2354 * in report.
2355 */
2356 static int
squareroot_test_dp(struct fps_test_ereport * report)2357 squareroot_test_dp(struct fps_test_ereport *report)
2358 {
2359 char err_data[MAX_INFO_SIZE];
2360 int i;
2361 uint64_t observed;
2362 uint64_t expected;
2363 unsigned long half_dp;
2364 unsigned long result;
2365 unsigned long workvalue;
2366 unsigned long prev_fsr;
2367
2368 prev_fsr = get_fsr();
2369
2370 init_regs(0);
2371
2372 for (i = 1; i < N_VALS; i++) {
2373 workvalue = val[i].floatdouble;
2374 result = sqrt_dp(mult_dp(workvalue, workvalue));
2375
2376 if (result != workvalue) {
2377 observed = (uint64_t)result;
2378 expected = (uint64_t)workvalue;
2379 (void) snprintf(err_data, sizeof (err_data),
2380 "\nExpected: %lld\nObserved: %lld", workvalue,
2381 result);
2382 setup_fps_test_struct(NO_EREPORT_INFO,
2383 report, 6242, &observed, &expected, 1, 1);
2384
2385 return (-1);
2386 }
2387 }
2388
2389 /* fsqrt(x), where x>0, should be positive */
2390 workvalue = half_msw;
2391 half_dp = workvalue << 32;
2392 half_dp = half_dp | half_lsw;
2393 result = sqrt_dp(half_dp);
2394
2395 if (result & SIGN_FLAG_DP) {
2396 observed = (uint64_t)result & SIGN_FLAG_DP;
2397 expected = (uint64_t)0;
2398 setup_fps_test_struct(NO_EREPORT_INFO,
2399 report, 8243, &observed, &expected, 1, 1);
2400
2401 return (-1);
2402 }
2403
2404 /* fsqrt(-0)=-0 */
2405 result = sqrt_dp(MINUS_ZERO_DP);
2406
2407 if (!(result & MINUS_ZERO_DP)) {
2408 observed = (uint64_t)0;
2409 expected = (uint64_t)1;
2410 setup_fps_test_struct(NO_EREPORT_INFO,
2411 report, 8244, &observed, &expected, 1, 1);
2412
2413 return (-1);
2414 }
2415
2416 set_fsr(prev_fsr);
2417 return (0);
2418 }
2419
2420 /*
2421 * division_test_sp(struct fps_test_ereport *report)
2422 * tests single precision division through registers.
2423 * (reg f4=f0/f2). If an error is found, relevant data
2424 * is stored in report.
2425 */
2426 static int
division_test_sp(struct fps_test_ereport * report)2427 division_test_sp(struct fps_test_ereport *report)
2428 {
2429 char err_data[MAX_INFO_SIZE];
2430 int i;
2431 unsigned long result;
2432 unsigned long prev_fsr;
2433 uint64_t observed;
2434 uint64_t expected;
2435
2436 prev_fsr = get_fsr();
2437
2438 init_regs(0);
2439 for (i = 1; i < N_VALS; i++) {
2440 result = div_sp(val[i].floatsingle, val[1].floatsingle);
2441
2442 if (result != val[i].floatsingle) {
2443 observed = (uint64_t)result;
2444 expected = (uint64_t)val[i].floatsingle;
2445 (void) snprintf(err_data, sizeof (err_data),
2446 "Val Entry[%d], reg f4=f0/f2"
2447 "\nExpected: %d\nObserved: %d",
2448 i, val[i].floatsingle, result);
2449 setup_fps_test_struct(IS_EREPORT_INFO,
2450 report, 6243, &observed, &expected, 1,
2451 1, err_data);
2452
2453 return (-1);
2454 }
2455 }
2456
2457 set_fsr(prev_fsr);
2458 return (0);
2459 }
2460
2461 /*
2462 * division_test_dp(struct fps_test_ereport *report)
2463 * tests double precision division through registers.
2464 * (reg f4=f0/f2). If an error is found, relevant data
2465 * is stored in report.
2466 */
2467 static int
division_test_dp(struct fps_test_ereport * report)2468 division_test_dp(struct fps_test_ereport *report)
2469 {
2470 char err_data[MAX_INFO_SIZE];
2471 int i;
2472 unsigned long result;
2473 unsigned long prev_fsr;
2474 uint64_t observed;
2475 uint64_t expected;
2476
2477 prev_fsr = get_fsr();
2478
2479 init_regs(0);
2480 for (i = 1; i < N_VALS; i++) {
2481 result = div_dp(val[i].floatdouble, val[1].floatdouble);
2482
2483 if (result != val[i].floatdouble) {
2484 observed = (uint64_t)result;
2485 expected = (uint64_t)val[i].floatdouble;
2486 (void) snprintf(err_data, sizeof (err_data),
2487 "Val Entry[%d], reg f4=f0/f2"
2488 "\nExpected: %lld\nObserved: %lld",
2489 i, val[i].floatdouble, result);
2490 setup_fps_test_struct(IS_EREPORT_INFO,
2491 report, 6244, &observed, &expected, 1, 1,
2492 err_data);
2493
2494 return (-1);
2495 }
2496 }
2497
2498 set_fsr(prev_fsr);
2499 return (0);
2500 }
2501
2502 /*
2503 * multiplication_test_sp(struct fps_test_ereport *report)
2504 * tests single precision multiplication through registers.
2505 * (reg f4=f0*f2). If an error is found, relevant data
2506 * is stored in report.
2507 */
2508 static int
multiplication_test_sp(struct fps_test_ereport * report)2509 multiplication_test_sp(struct fps_test_ereport *report)
2510 {
2511 char err_data[MAX_INFO_SIZE];
2512 int i;
2513 unsigned long result;
2514 unsigned long prev_fsr;
2515 uint64_t observed;
2516 uint64_t expected;
2517
2518 prev_fsr = get_fsr();
2519
2520 init_regs(0);
2521 for (i = 0; i < N_VALS; i++) {
2522 result = mult_sp(val[i].floatsingle, val[1].floatsingle);
2523
2524 if (result != val[i].floatsingle) {
2525 observed = (uint64_t)result;
2526 expected = (uint64_t)val[i].floatsingle;
2527 (void) snprintf(err_data, sizeof (err_data),
2528 "Val Entry[%d], reg f4=f0*f2"
2529 "\nExpected: %d\nObserved: %d",
2530 i, val[i].floatsingle, result);
2531 setup_fps_test_struct(IS_EREPORT_INFO, report,
2532 6245, &observed, &expected, 1, 1, err_data);
2533
2534 return (-1);
2535 }
2536 }
2537
2538 set_fsr(prev_fsr);
2539 return (0);
2540 }
2541
2542 /*
2543 * multiplication_test_dp(struct fps_test_ereport *report)
2544 * tests double precision multiplication through registers.
2545 * (reg f4=f0*f2). If an error is found, relevant data
2546 * is stored in report.
2547 */
2548 static int
multiplication_test_dp(struct fps_test_ereport * report)2549 multiplication_test_dp(struct fps_test_ereport *report)
2550 {
2551 char err_data[MAX_INFO_SIZE];
2552 int i;
2553 uint64_t observed;
2554 uint64_t expected;
2555 unsigned long result;
2556 unsigned long prev_fsr;
2557
2558 prev_fsr = get_fsr();
2559
2560 init_regs(0);
2561 for (i = 0; i < N_VALS; i++) {
2562 result = mult_dp(val[i].floatdouble, val[1].floatdouble);
2563
2564 if (result != val[i].floatdouble) {
2565 observed = (uint64_t)result;
2566 expected = (uint64_t)val[i].floatdouble;
2567 (void) snprintf(err_data, sizeof (err_data),
2568 "Val Entry[%d], reg f4=f0*f2"
2569 "\nExpected: %lld\nObserved: %lld",
2570 i, val[i].floatdouble, result);
2571 setup_fps_test_struct(IS_EREPORT_INFO,
2572 report, 6246, &observed, &expected, 1, 1,
2573 err_data);
2574
2575 return (-1);
2576 }
2577 }
2578
2579 set_fsr(prev_fsr);
2580 return (0);
2581 }
2582
2583 /*
2584 * compare_sp(struct fps_test_ereport *report)
2585 * performs single precision comparison tests.
2586 * If an error is found, relevant data is stored
2587 * in report.
2588 */
2589 static int
compare_sp(struct fps_test_ereport * report)2590 compare_sp(struct fps_test_ereport *report)
2591 {
2592 char err_data[MAX_INFO_SIZE];
2593 int i;
2594 uint64_t expected;
2595 uint64_t observed;
2596 unsigned long prev_fsr;
2597 unsigned long result = 0;
2598
2599 prev_fsr = get_fsr();
2600 set_fsr(prev_fsr & FSR_DISABLE_TEM);
2601 init_regs(0);
2602
2603 for (i = 0; i < (N_VALS - 1); i++) {
2604 #ifndef __lint
2605 result = fcmps_fcc(val[i].floatsingle, val[i].floatsingle, 0);
2606 #endif
2607
2608 if ((result & 0xc00) != 0) {
2609 observed = (uint64_t)result & 0xc00;
2610 expected = (uint64_t)0;
2611 (void) snprintf(err_data, sizeof (err_data),
2612 "f0= %d, f2= %d", i, i);
2613 setup_fps_test_struct(IS_EREPORT_INFO, report,
2614 6247, &observed, &expected, 1, 1, err_data);
2615
2616 return (-1);
2617 }
2618
2619 #ifndef __lint
2620 result = fcmps_fcc(val[i].floatsingle,
2621 val[i + 1].floatsingle, 0);
2622 #endif
2623 if ((result & 0xc00) != 0x400) {
2624 observed = (uint64_t)result & 0xc00;
2625 expected = (uint64_t)0x400;
2626 (void) snprintf(err_data, sizeof (err_data),
2627 "f0= %d, f2= %d", i, i+1);
2628 setup_fps_test_struct(IS_EREPORT_INFO, report,
2629 6248, &observed, &expected, 1, 1, err_data);
2630
2631 return (-1);
2632 }
2633
2634 #ifndef __lint
2635 result = fcmps_fcc(val[i + 1].floatsingle,
2636 val[i].floatsingle, 0);
2637 #endif
2638
2639 if ((result & 0xc00) != 0x800) {
2640 observed = (uint64_t)result & 0xc00;
2641 expected = (uint64_t)0x800;
2642 (void) snprintf(err_data, sizeof (err_data),
2643 "f0= %d, f2= %d", i+1, i);
2644 setup_fps_test_struct(IS_EREPORT_INFO, report,
2645 6249, &observed, &expected, 1, 1, err_data);
2646
2647 return (-1);
2648 }
2649
2650 set_fsr(prev_fsr & FSR_DISABLE_TEM);
2651 #ifndef __lint
2652 result = fcmps_fcc(val[i].floatsingle, 0x7f800400, 0);
2653 #endif
2654
2655 if ((result & 0xc00) != 0xc00) {
2656 observed = (uint64_t)result & 0xc00;
2657 expected = (uint64_t)0xc00;
2658 (void) snprintf(err_data, sizeof (err_data),
2659 "f0= %d, f2= NaN", i);
2660 setup_fps_test_struct(IS_EREPORT_INFO, report,
2661 6250, &observed, &expected, 1, 1, err_data);
2662
2663 return (-1);
2664 }
2665 }
2666
2667 /* Compare +/-zero and check if the comparision is okay */
2668
2669 result = fcmps_fcc(MINUS_ZERO_SP, PLUS_ZERO_SP, 0);
2670
2671 if (result & 0xc00) {
2672 observed = (uint64_t)result & 0xc00;
2673 expected = (uint64_t)0;
2674 (void) snprintf(err_data, sizeof (err_data),
2675 "f0= %d, f2= %d", +0, -0);
2676 setup_fps_test_struct(IS_EREPORT_INFO, report,
2677 8251, &observed, &expected, 1, 1, err_data);
2678
2679 return (-1);
2680 }
2681
2682 set_fsr(prev_fsr);
2683 return (0);
2684 }
2685
2686 /*
2687 * compare_dp(struct fps_test_ereport *report)
2688 * performs double precision comparison tests.
2689 * If an error is found, relevant data is stored
2690 * in report.
2691 */
2692 static int
compare_dp(struct fps_test_ereport * report)2693 compare_dp(struct fps_test_ereport *report)
2694 {
2695 char err_data[MAX_INFO_SIZE];
2696 int i;
2697 unsigned long result;
2698 unsigned long prev_fsr;
2699 uint64_t observed;
2700 uint64_t expected;
2701
2702 prev_fsr = get_fsr();
2703 set_fsr(prev_fsr & FSR_DISABLE_TEM);
2704
2705 init_regs(0);
2706
2707 for (i = 0; i < (N_VALS - 1); i++) {
2708 result = fcmpd_fcc(val[i].floatdouble, val[i].floatdouble, 0);
2709 if ((result & 0xc00) != 0) {
2710 observed = (uint64_t)result & 0xc00;
2711 expected = (uint64_t)0;
2712 (void) snprintf(err_data, sizeof (err_data),
2713 "f0= %d, f2= %d", i, i);
2714 setup_fps_test_struct(IS_EREPORT_INFO, report,
2715 6251, &observed, &expected, 1, 1, err_data);
2716
2717 return (-1);
2718 }
2719
2720 result = fcmpd_fcc(val[i].floatdouble,
2721 val[i + 1].floatdouble, 0);
2722
2723 if ((result & 0xc00) != 0x400) {
2724 observed = (uint64_t)result & 0xc00;
2725 expected = (uint64_t)0x400;
2726 (void) snprintf(err_data, sizeof (err_data),
2727 "f0= %d, f2= %d", i, i+1);
2728 setup_fps_test_struct(IS_EREPORT_INFO, report,
2729 6252, &observed, &expected, 1, 1, err_data);
2730
2731 return (-1);
2732 }
2733
2734 result = fcmpd_fcc(val[i + 1].floatdouble,
2735 val[i].floatdouble, 0);
2736
2737 if ((result & 0xc00) != 0x800) {
2738 observed = (uint64_t)result & 0xc00;
2739 expected = (uint64_t)0x800;
2740 (void) snprintf(err_data, sizeof (err_data),
2741 "f0= %d, f2= %d", i+1, i);
2742 setup_fps_test_struct(IS_EREPORT_INFO, report,
2743 6253, &observed, &expected, 1, 1, err_data);
2744
2745 return (-1);
2746 }
2747
2748 set_fsr(prev_fsr & FSR_DISABLE_TEM);
2749 result = fcmpd_fcc(val[i].floatdouble, 0x7ff0008000000000, 0);
2750
2751 if ((result & 0xc00) != 0xc00) {
2752 observed = (uint64_t)result & 0xc00;
2753 expected = (uint64_t)0xc00;
2754 (void) snprintf(err_data, sizeof (err_data),
2755 "f0= %d, f2=NaN", i);
2756 setup_fps_test_struct(IS_EREPORT_INFO, report,
2757 6254, &observed, &expected, 1, 1, err_data);
2758
2759 return (-1);
2760 }
2761 }
2762 /* Compare +/-zero and check if the comparision is okay */
2763
2764 result = fcmpd_fcc(MINUS_ZERO_DP, PLUS_ZERO_DP, 0);
2765
2766 if (result & 0xc00) {
2767 observed = (uint64_t)result & 0xc00;
2768 expected = (uint64_t)0;
2769 (void) snprintf(err_data, sizeof (err_data),
2770 "f0= %d, f2= %d", +0, -0);
2771 setup_fps_test_struct(IS_EREPORT_INFO, report,
2772 8252, &observed, &expected, 1, 1, err_data);
2773
2774 return (-1);
2775 }
2776
2777 set_fsr(prev_fsr);
2778 return (0);
2779 }
2780
2781 /*
2782 * branching(struct fps_test_ereport *report)
2783 * performs branch testing. If an error is found,
2784 * relevant data is stored in report.
2785 */
2786 static int
branching(struct fps_test_ereport * report)2787 branching(struct fps_test_ereport *report)
2788 {
2789 char err_data[MAX_INFO_SIZE];
2790 int i;
2791 unsigned long result;
2792 unsigned long prev_status;
2793 uint64_t observed;
2794 uint64_t expected;
2795
2796 prev_status = get_fsr();
2797 init_regs(0);
2798 result = get_fsr();
2799 result = result & 0xC0400000; /* set all exception bits to zero */
2800 set_fsr(result);
2801
2802 for (i = 0; i < 64; i++) {
2803 if (result = branches(0, val[i].floatsingle, 0x7f800400)) {
2804 observed = (uint64_t)result;
2805 expected = (uint64_t)0;
2806 setup_fps_test_struct(NO_EREPORT_INFO,
2807 report, 6255, &observed, &expected, 1, 1);
2808
2809 return (-1);
2810 }
2811
2812 if (result = branches(1, val[i + 1].floatsingle,
2813 val[i].floatsingle)) {
2814 observed = (uint64_t)result;
2815 expected = (uint64_t)0;
2816 (void) snprintf(err_data, sizeof (err_data),
2817 "reg f0= %d, f2= %d ", i+1, i);
2818 setup_fps_test_struct(IS_EREPORT_INFO,
2819 report, 6256, &observed, &expected, 1, 1,
2820 err_data);
2821
2822 return (-1);
2823 }
2824
2825 if (result = branches(2, val[i].floatsingle, 0x7f800400)) {
2826 observed = (uint64_t)result;
2827 expected = (uint64_t)0;
2828 setup_fps_test_struct(NO_EREPORT_INFO,
2829 report, 6257, &observed, &expected, 1, 1);
2830
2831 return (-1);
2832 }
2833
2834 if (result = branches(2, val[i + 1].floatsingle,
2835 val[i].floatsingle)) {
2836 observed = (uint64_t)result;
2837 expected = (uint64_t)0;
2838 (void) snprintf(err_data, sizeof (err_data),
2839 "reg f0= %d, f2= %d ", i+1, i);
2840 setup_fps_test_struct(IS_EREPORT_INFO,
2841 report, 6258, &observed, &expected, 1, 1,
2842 err_data);
2843
2844 return (-1);
2845 }
2846
2847 if (result = branches(3, val[i].floatsingle,
2848 val[i + 1].floatsingle)) {
2849 observed = (uint64_t)result;
2850 expected = (uint64_t)0;
2851 (void) snprintf(err_data, sizeof (err_data),
2852 "reg f0= %d and f2= %d ", i, i+1);
2853 setup_fps_test_struct(IS_EREPORT_INFO,
2854 report, 6259, &observed, &expected, 1, 1,
2855 err_data);
2856
2857 return (-1);
2858 }
2859
2860 if (result = branches(4, val[i].floatsingle, 0x7f800400)) {
2861 observed = (uint64_t)result;
2862 expected = (uint64_t)0;
2863 setup_fps_test_struct(NO_EREPORT_INFO,
2864 report, 6260, &observed, &expected, 1, 1);
2865
2866 return (-1);
2867 }
2868
2869 if (result = branches(4, val[i].floatsingle,
2870 val[i + 1].floatsingle)) {
2871 observed = (uint64_t)result;
2872 expected = (uint64_t)0;
2873 (void) snprintf(err_data, sizeof (err_data),
2874 "reg f0= %d, f2= %d ", i, i+1);
2875 setup_fps_test_struct(IS_EREPORT_INFO,
2876 report, 6261, &observed, &expected, 1, 1,
2877 err_data);
2878
2879 return (-1);
2880 }
2881
2882 if (result = branches(5, val[i].floatsingle,
2883 val[i + 1].floatsingle)) {
2884 observed = (uint64_t)result;
2885 expected = (uint64_t)0;
2886 (void) snprintf(err_data, sizeof (err_data),
2887 "reg f0= %d, f2= %d ", i, i+1);
2888 setup_fps_test_struct(IS_EREPORT_INFO,
2889 report, 6262, &observed, &expected, 1, 1,
2890 err_data);
2891
2892 return (-1);
2893 }
2894
2895 if (result = branches(5, val[i + 1].floatsingle,
2896 val[i].floatsingle)) {
2897 observed = (uint64_t)result;
2898 expected = (uint64_t)0;
2899 (void) snprintf(err_data, sizeof (err_data),
2900 "reg f0= %d, f2= %d ", i+1, i);
2901 setup_fps_test_struct(IS_EREPORT_INFO,
2902 report, 6263, &observed, &expected, 1, 1,
2903 err_data);
2904
2905 return (-1);
2906 }
2907
2908 if (result = branches(6, val[i].floatsingle,
2909 val[i + 1].floatsingle)) {
2910 observed = (uint64_t)result;
2911 expected = (uint64_t)0;
2912 (void) snprintf(err_data, sizeof (err_data),
2913 "reg f0= %d, f2= %d ", i, i+1);
2914 setup_fps_test_struct(IS_EREPORT_INFO,
2915 report, 6264, &observed, &expected, 1, 1,
2916 err_data);
2917
2918 return (-1);
2919 }
2920
2921 if (result = branches(7, val[i].floatsingle,
2922 val[i].floatsingle)) {
2923 observed = (uint64_t)result;
2924 expected = (uint64_t)0;
2925 (void) snprintf(err_data, sizeof (err_data),
2926 "reg f0= %d, f2= %d ", i, i);
2927 setup_fps_test_struct(IS_EREPORT_INFO,
2928 report, 6265, &observed, &expected, 1, 1,
2929 err_data);
2930
2931 return (-1);
2932 }
2933
2934 if (result = branches(8, val[i].floatsingle, 0x7f800400)) {
2935 observed = (uint64_t)result;
2936 expected = (uint64_t)0;
2937 setup_fps_test_struct(NO_EREPORT_INFO,
2938 report, 6266, &observed, &expected, 1, 1);
2939
2940 return (-1);
2941 }
2942
2943 if (result = branches(8, val[i].floatsingle,
2944 val[i].floatsingle)) {
2945 observed = (uint64_t)result;
2946 expected = (uint64_t)0;
2947 (void) snprintf(err_data, sizeof (err_data),
2948 "reg f0= %d, f2= %d ", i, i);
2949 setup_fps_test_struct(IS_EREPORT_INFO,
2950 report, 6267, &observed, &expected, 1, 1,
2951 err_data);
2952
2953 return (-1);
2954 }
2955 if (result = branches(9, val[i].floatsingle,
2956 val[i].floatsingle)) {
2957 observed = (uint64_t)result;
2958 expected = (uint64_t)0;
2959 (void) snprintf(err_data, sizeof (err_data),
2960 "reg f0= %d, f2= %d ", i, i);
2961 setup_fps_test_struct(IS_EREPORT_INFO,
2962 report, 6268, &observed, &expected, 1, 1,
2963 err_data);
2964
2965 return (-1);
2966 }
2967 if (result = branches(9, val[i + 1].floatsingle,
2968 val[i].floatsingle)) {
2969 observed = (uint64_t)result;
2970 expected = (uint64_t)0;
2971 (void) snprintf(err_data, sizeof (err_data),
2972 "reg f0= %d, f2= %d ", i+1, i);
2973 setup_fps_test_struct(IS_EREPORT_INFO,
2974 report, 6269, &observed, &expected, 1, 1,
2975 err_data);
2976
2977 return (-1);
2978 }
2979
2980 if (result = branches(10, val[i].floatsingle, 0x7f800400)) {
2981 observed = (uint64_t)result;
2982 expected = (uint64_t)0;
2983 setup_fps_test_struct(NO_EREPORT_INFO,
2984 report, 6270, &observed, &expected, 1, 1);
2985
2986 return (-1);
2987 }
2988
2989 if (result = branches(10, val[i].floatsingle,
2990 val[i].floatsingle)) {
2991 observed = (uint64_t)result;
2992 expected = (uint64_t)0;
2993 (void) snprintf(err_data, sizeof (err_data),
2994 "reg f0= %d, f2= %d", i, i);
2995 setup_fps_test_struct(IS_EREPORT_INFO,
2996 report, 6271, &observed, &expected, 1, 1,
2997 err_data);
2998
2999 return (-1);
3000 }
3001
3002 if (result = branches(10, val[i + 1].floatsingle,
3003 val[i].floatsingle)) {
3004 observed = (uint64_t)result;
3005 expected = (uint64_t)0;
3006 (void) snprintf(err_data, sizeof (err_data),
3007 "reg f0= %d, f2= %d", i+1, i);
3008 setup_fps_test_struct(IS_EREPORT_INFO,
3009 report, 6272, &observed, &expected, 1, 1,
3010 err_data);
3011
3012 return (-1);
3013 }
3014
3015 if (result = branches(11, val[i].floatsingle,
3016 val[i + 1].floatsingle)) {
3017 observed = (uint64_t)result;
3018 expected = (uint64_t)0;
3019 (void) snprintf(err_data, sizeof (err_data),
3020 "reg f0= %d, f2= %d", i, i+1);
3021 setup_fps_test_struct(IS_EREPORT_INFO,
3022 report, 6273, &observed, &expected, 1, 1,
3023 err_data);
3024
3025 return (-1);
3026 }
3027
3028 if (result = branches(11, val[i].floatsingle,
3029 val[i].floatsingle)) {
3030 observed = (uint64_t)result;
3031 expected = (uint64_t)0;
3032 (void) snprintf(err_data, sizeof (err_data),
3033 "reg f0= %d, f2= %d", i, i);
3034 setup_fps_test_struct(IS_EREPORT_INFO,
3035 report, 6274, &observed, &expected, 1, 1,
3036 err_data);
3037
3038 return (-1);
3039 }
3040
3041 if (result = branches(12, val[i].floatsingle, 0x7f800400)) {
3042 observed = (uint64_t)result;
3043 expected = (uint64_t)0;
3044 setup_fps_test_struct(NO_EREPORT_INFO,
3045 report, 6275, &observed, &expected, 1, 1);
3046
3047 return (-1);
3048 }
3049
3050 if (result = branches(12, val[i].floatsingle,
3051 val[i + 1].floatsingle)) {
3052 observed = (uint64_t)result;
3053 expected = (uint64_t)0;
3054 (void) snprintf(err_data, sizeof (err_data),
3055 "reg f0= %d, f2= %d", i, i+1);
3056 setup_fps_test_struct(IS_EREPORT_INFO,
3057 report, 6276, &observed, &expected, 1, 1,
3058 err_data);
3059
3060 return (-1);
3061 }
3062
3063 if (result = branches(12, val[i].floatsingle,
3064 val[i].floatsingle)) {
3065 observed = (uint64_t)result;
3066 expected = (uint64_t)0;
3067 (void) snprintf(err_data, sizeof (err_data),
3068 "reg f0= %d, f2= %d", i, i);
3069 setup_fps_test_struct(IS_EREPORT_INFO,
3070 report, 6277, &observed, &expected, 1, 1,
3071 err_data);
3072
3073 return (-1);
3074 }
3075
3076 if (result = branches(13, val[i].floatsingle,
3077 val[i + 1].floatsingle)) {
3078 observed = (uint64_t)result;
3079 expected = (uint64_t)0;
3080 (void) snprintf(err_data, sizeof (err_data),
3081 "reg f0= %d, f2= %d", i, i+1);
3082 setup_fps_test_struct(IS_EREPORT_INFO,
3083 report, 6278, &observed, &expected, 1, 1,
3084 err_data);
3085
3086 return (-1);
3087 }
3088
3089 if (result = branches(14, val[i].floatsingle,
3090 val[i + 1].floatsingle)) {
3091 observed = (uint64_t)result;
3092 expected = (uint64_t)0;
3093 (void) snprintf(err_data, sizeof (err_data),
3094 "reg f0= %d, f2= %d", i, i+1);
3095 setup_fps_test_struct(IS_EREPORT_INFO,
3096 report, 6279, &observed, &expected, 1, 1,
3097 err_data);
3098
3099 return (-1);
3100 }
3101
3102 if (result = branches(15, val[i].floatsingle,
3103 val[i + 1].floatsingle)) {
3104 observed = (uint64_t)result;
3105 expected = (uint64_t)0;
3106 (void) snprintf(err_data, sizeof (err_data),
3107 "reg f0= %d, f2= %d ", i, i+1);
3108 setup_fps_test_struct(IS_EREPORT_INFO,
3109 report, 6280, &observed, &expected, 1, 1,
3110 err_data);
3111
3112 return (-1);
3113 }
3114 }
3115
3116 set_fsr(prev_status);
3117 return (0);
3118
3119 }
3120
3121 /*
3122 * branching(struct fps_test_ereport *report)
3123 * performs negative branch testing. If an error is found,
3124 * relevant data is stored in report.
3125 */
3126 static int
no_branching(struct fps_test_ereport * report)3127 no_branching(struct fps_test_ereport *report)
3128 {
3129 char err_data[MAX_INFO_SIZE];
3130 int i;
3131 uint64_t observed;
3132 uint64_t expected;
3133 unsigned long result;
3134 unsigned long prev_status;
3135
3136 prev_status = get_fsr();
3137 init_regs(0);
3138 result = get_fsr();
3139 result = result & 0xC0400000; /* set all exception bits to zero */
3140 set_fsr(result);
3141
3142 for (i = 0; i < 64; i++) {
3143 if (!(branches(0, val[i].floatsingle,
3144 val[i].floatsingle))) {
3145 observed = (uint64_t)0;
3146 expected = (uint64_t)1;
3147 setup_fps_test_struct(NO_EREPORT_INFO,
3148 report, 6281, &observed, &expected, 1, 1);
3149
3150 return (-1);
3151 }
3152
3153 if (!(branches(1, val[i].floatsingle,
3154 val[i].floatsingle))) {
3155 observed = (uint64_t)0;
3156 expected = (uint64_t)1;
3157 (void) snprintf(err_data, sizeof (err_data),
3158 "reg f0= %d, f2= %d", i, i);
3159 setup_fps_test_struct(IS_EREPORT_INFO,
3160 report, 6282, &observed, &expected, 1, 1,
3161 err_data);
3162
3163 return (-1);
3164 }
3165
3166 if (!(branches(2, val[i].floatsingle,
3167 val[i].floatsingle))) {
3168 observed = (uint64_t)0;
3169 expected = (uint64_t)1;
3170 (void) snprintf(err_data, sizeof (err_data),
3171 "reg f0= %d, f2= %d", i, i);
3172 setup_fps_test_struct(IS_EREPORT_INFO,
3173 report, 6283, &observed, &expected, 1, 1,
3174 err_data);
3175
3176 return (-1);
3177 }
3178
3179 if (!(branches(3, val[i].floatsingle,
3180 val[i].floatsingle))) {
3181 observed = (uint64_t)0;
3182 expected = (uint64_t)1;
3183 (void) snprintf(err_data, sizeof (err_data),
3184 "reg f0= %d, f2= %d", i, i);
3185 setup_fps_test_struct(IS_EREPORT_INFO,
3186 report, 6284, &observed, &expected, 1, 1,
3187 err_data);
3188
3189 return (-1);
3190 }
3191
3192 if (!(branches(4, val[i].floatsingle,
3193 val[i].floatsingle))) {
3194 observed = (uint64_t)0;
3195 expected = (uint64_t)1;
3196 (void) snprintf(err_data, sizeof (err_data),
3197 "reg f0= %d, f2= %d", i, i);
3198 setup_fps_test_struct(IS_EREPORT_INFO,
3199 report, 6285, &observed, &expected, 1, 1,
3200 err_data);
3201
3202 return (-1);
3203 }
3204
3205 if (!(branches(5, val[i].floatsingle,
3206 val[i].floatsingle))) {
3207 observed = (uint64_t)0;
3208 expected = (uint64_t)1;
3209 (void) snprintf(err_data, sizeof (err_data),
3210 "reg f0= %d, f2= %d", i, i);
3211 setup_fps_test_struct(IS_EREPORT_INFO,
3212 report, 6286, &observed, &expected, 1, 1,
3213 err_data);
3214
3215 return (-1);
3216 }
3217
3218 if (!(branches(6, val[i].floatsingle,
3219 val[i].floatsingle))) {
3220 observed = (uint64_t)0;
3221 expected = (uint64_t)1;
3222 (void) snprintf(err_data, sizeof (err_data),
3223 "reg f0= %d, f2= %d", i, i);
3224 setup_fps_test_struct(IS_EREPORT_INFO,
3225 report, 6287, &observed, &expected, 1, 1,
3226 err_data);
3227
3228 return (-1);
3229 }
3230
3231 if (!(branches(7, val[i + 1].floatsingle,
3232 val[i].floatsingle))) {
3233 observed = (uint64_t)0;
3234 expected = (uint64_t)1;
3235 (void) snprintf(err_data, sizeof (err_data),
3236 "reg f0= %d, f2= %d", i+1, i);
3237 setup_fps_test_struct(IS_EREPORT_INFO,
3238 report, 6288, &observed, &expected, 1, 1,
3239 err_data);
3240
3241 return (-1);
3242 }
3243
3244 if (!(branches(8, val[i + 1].floatsingle,
3245 val[i].floatsingle))) {
3246 observed = (uint64_t)0;
3247 expected = (uint64_t)1;
3248 (void) snprintf(err_data, sizeof (err_data),
3249 "reg f0= %d, f2= %d", i+1, i);
3250 setup_fps_test_struct(IS_EREPORT_INFO,
3251 report, 6289, &observed, &expected, 1, 1,
3252 err_data);
3253
3254 return (-1);
3255 }
3256
3257 if (!(branches(9, val[i].floatsingle,
3258 val[i + 1].floatsingle))) {
3259 observed = (uint64_t)0;
3260 expected = (uint64_t)1;
3261 (void) snprintf(err_data, sizeof (err_data),
3262 "reg f0= %d, f2= %d", i, i+1);
3263 setup_fps_test_struct(IS_EREPORT_INFO,
3264 report, 6290, &observed, &expected, 1, 1,
3265 err_data);
3266
3267 return (-1);
3268 }
3269
3270 if (!(branches(10, val[i].floatsingle,
3271 val[i + 1].floatsingle))) {
3272 observed = (uint64_t)0;
3273 expected = (uint64_t)1;
3274 (void) snprintf(err_data, sizeof (err_data),
3275 "reg f0= %d, f2= %d", i, i+1);
3276 setup_fps_test_struct(IS_EREPORT_INFO,
3277 report, 6291, &observed, &expected, 1, 1,
3278 err_data);
3279
3280 return (-1);
3281 }
3282
3283 if (!(branches(11, val[i + 1].floatsingle,
3284 val[i].floatsingle))) {
3285 observed = (uint64_t)0;
3286 expected = (uint64_t)1;
3287 (void) snprintf(err_data, sizeof (err_data),
3288 "reg f0= %d, f2= %d", i+1, i);
3289 setup_fps_test_struct(IS_EREPORT_INFO,
3290 report, 6292, &observed, &expected, 1, 1,
3291 err_data);
3292
3293 return (-1);
3294 }
3295
3296 if (!(branches(12, val[i + 1].floatsingle,
3297 val[i].floatsingle))) {
3298 observed = (uint64_t)0;
3299 expected = (uint64_t)1;
3300 (void) snprintf(err_data, sizeof (err_data),
3301 "reg f0= %d, f2= %d", i+1, i);
3302 setup_fps_test_struct(IS_EREPORT_INFO,
3303 report, 6293, &observed, &expected, 1, 1,
3304 err_data);
3305
3306 return (-1);
3307 }
3308
3309 if (!(result = branches(13, val[i].floatsingle, 0x7f800400))) {
3310 observed = (uint64_t)0;
3311 expected = (uint64_t)1;
3312 setup_fps_test_struct(NO_EREPORT_INFO,
3313 report, 6294, &observed, &expected, 1, 1);
3314
3315 return (-1);
3316 }
3317
3318 }
3319
3320 set_fsr(prev_status);
3321
3322 return (0);
3323 }
3324
3325 /*
3326 * compare_sp_except(struct fps_test_ereport *report)
3327 * does single precision exception testing.
3328 * If an error is found, relevant data is stored
3329 * in report.
3330 */
3331 static int
compare_sp_except(struct fps_test_ereport * report)3332 compare_sp_except(struct fps_test_ereport *report)
3333 {
3334 char err_data[MAX_INFO_SIZE];
3335 int i;
3336 unsigned long result;
3337 unsigned long prev_status;
3338 uint64_t observed;
3339 uint64_t expected;
3340
3341 prev_status = get_fsr();
3342 init_regs(0);
3343 result = get_fsr();
3344 result = result | FSR_ENABLE_TEM_NV;
3345
3346 set_fsr(result);
3347
3348 for (i = 0; i < N_VALS; i++) {
3349
3350 trap_flag = trap_flag | TRAP_SOLICITED;
3351 result = cmp_s_ex(val[i].floatsingle, 0x7fbfffff);
3352 if (trap_flag) {
3353 observed = (uint64_t)trap_flag;
3354 expected = (uint64_t)0;
3355 (void) snprintf(err_data, sizeof (err_data),
3356 "fcmpxs exception did not occur, fsr=%lo",
3357 fsr_at_trap);
3358 setup_fps_test_struct(IS_EREPORT_INFO,
3359 report, 6295, &observed, &expected, 1, 1,
3360 err_data);
3361
3362 return (-1);
3363 }
3364 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
3365 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
3366 expected = (uint64_t)FSR_CEXC_NV;
3367 (void) snprintf(err_data, sizeof (err_data),
3368 "fcmpxs exception did not occur, fsr=%lo",
3369 fsr_at_trap);
3370 setup_fps_test_struct(IS_EREPORT_INFO,
3371 report, 6296, &observed, &expected, 1, 1,
3372 err_data);
3373
3374 return (-1);
3375 }
3376 }
3377
3378 set_fsr(prev_status);
3379 return (0);
3380 }
3381
3382 /*
3383 * compare_dp_except(struct fps_test_ereport *report)
3384 * does double precision exception testing.
3385 * If an error is found, relevant data is stored
3386 * in report.
3387 */
3388 static int
compare_dp_except(struct fps_test_ereport * report)3389 compare_dp_except(struct fps_test_ereport *report)
3390 {
3391 char err_data[MAX_INFO_SIZE];
3392 int i;
3393 unsigned long result;
3394 unsigned long prev_status;
3395 uint64_t observed;
3396 uint64_t expected;
3397
3398 prev_status = get_fsr();
3399 init_regs(0);
3400 result = get_fsr();
3401 result = result | FSR_ENABLE_TEM_NV;
3402 set_fsr(result);
3403
3404 for (i = 0; i < 199; i++) {
3405
3406 trap_flag = trap_flag | TRAP_SOLICITED;
3407 result = cmp_d_ex(val[i].floatdouble, 0x7ff0008000000000);
3408 if (trap_flag) {
3409 observed = (uint64_t)trap_flag;
3410 expected = (uint64_t)0;
3411 (void) snprintf(err_data, sizeof (err_data),
3412 "fcmpxd exception did not occur, fsr=%lo",
3413 fsr_at_trap);
3414 setup_fps_test_struct(IS_EREPORT_INFO,
3415 report, 6297, &observed, &expected, 1, 1,
3416 err_data);
3417
3418 return (-1);
3419 }
3420 if ((fsr_at_trap & FSR_CEXC_NV) != FSR_CEXC_NV) {
3421 observed = (uint64_t)fsr_at_trap & FSR_CEXC_NV;
3422 expected = (uint64_t)FSR_CEXC_NV;
3423 (void) snprintf(err_data, sizeof (err_data),
3424 "fcmpxd exception did not occur, fsr=%lo",
3425 fsr_at_trap);
3426 setup_fps_test_struct(IS_EREPORT_INFO,
3427 report, 6298, &observed, &expected, 1, 1,
3428 err_data);
3429
3430 return (-1);
3431 }
3432 }
3433
3434 set_fsr(prev_status);
3435 return (0);
3436 }
3437
3438 /*
3439 * Patterns used in the registers functions that are.
3440 * loaded into all registers.
3441 */
3442
3443 #define ALLZEROES_DP 0x0000000000000000UL
3444 #define ALLZEROES_SP 0x00000000U
3445 #define ALLONES_DP 0xFFFFFFFFFFFFFFFFUL
3446 #define ALLONES_SP 0xFFFFFFFFU
3447
3448 /*
3449 * registers_four(struct fps_test_ereport *report)
3450 * loads each nibble with 0xf on all the available FP
3451 * registers in single precision.
3452 * If an error is found, relevant data is stored
3453 * in report.
3454 */
3455 static int
registers_four(struct fps_test_ereport * report)3456 registers_four(struct fps_test_ereport *report)
3457 {
3458 char err_data[MAX_INFO_SIZE];
3459 int i;
3460 unsigned int result = 0;
3461 uint64_t observed;
3462 uint64_t expected;
3463
3464 #define ARB_VAL 4
3465
3466 for (i = 0; i < ARB_VAL; i++) {
3467 init_regs(ALLZEROES_SP);
3468 init_regs(ALLONES_SP);
3469 }
3470
3471 init_regs(ALLZEROES_SP);
3472 for (i = 0; i < 32; i++) {
3473 read_fpreg(&result, i);
3474 if (result != ALLZEROES_SP) {
3475 observed = (uint64_t)result;
3476 expected = (uint64_t)ALLZEROES_SP;
3477 (void) snprintf(err_data, sizeof (err_data),
3478 "Reg: %d\nExpected: %d\nObserved: %d",
3479 i, ALLZEROES_SP, result);
3480 setup_fps_test_struct(IS_EREPORT_INFO,
3481 report, 6345, &observed, &expected, 1, 1,
3482 err_data);
3483
3484 return (-1);
3485 }
3486 }
3487
3488 init_regs(ALLONES_SP);
3489
3490 for (i = 0; i < 32; i++) {
3491 read_fpreg(&result, i);
3492 if (result != ALLONES_SP) {
3493 observed = (uint64_t)result;
3494 expected = (uint64_t)ALLONES_SP;
3495 (void) snprintf(err_data, sizeof (err_data),
3496 "Reg: %d\nExpected: %d\nObserved: %d",
3497 i, ALLONES_SP, result);
3498 setup_fps_test_struct(IS_EREPORT_INFO,
3499 report, 8345, &observed, &expected, 1, 1,
3500 err_data);
3501
3502 return (-1);
3503 }
3504 }
3505
3506 return (0);
3507 }
3508
3509 /*
3510 * registers_four_dp(struct fps_test_ereport *report)
3511 * loads each nibble with 0xf on all the available FP
3512 * registers in double precision.
3513 * If an error is found, relevant data is stored
3514 * in report.
3515 */
3516 static int
registers_four_dp(struct fps_test_ereport * report)3517 registers_four_dp(struct fps_test_ereport *report)
3518 {
3519 char err_data[MAX_INFO_SIZE];
3520 int i;
3521 uint64_t expected;
3522 uint64_t observed;
3523 unsigned long result;
3524
3525 #define ARB_VAL 4
3526
3527 for (i = 0; i < ARB_VAL; i++) {
3528 init_regs_dp(ALLZEROES_DP);
3529 init_regs_dp(ALLONES_DP);
3530 }
3531
3532 init_regs_dp(16);
3533 read_fpreg_dp(&result, 2);
3534 init_regs_dp(ALLZEROES_DP);
3535 for (i = 0; i < 64; i = i + 2) {
3536 result = ALLONES_DP;
3537 read_fpreg_dp(&result, i);
3538 if (result != ALLZEROES_DP) {
3539 observed = (uint64_t)result;
3540 expected = (uint64_t)ALLZEROES_DP;
3541 (void) snprintf(err_data, sizeof (err_data),
3542 "Reg: %d\nExpected: %lld\nObserved: %lld",
3543 i, ALLZEROES_DP, result);
3544 setup_fps_test_struct(IS_EREPORT_INFO,
3545 report, 6346, &observed, &expected, 1, 1,
3546 err_data);
3547
3548 return (-1);
3549 }
3550 }
3551
3552 init_regs_dp(ALLONES_DP);
3553
3554 for (i = 30; i < 64; i = i + 2) {
3555 read_fpreg_dp(&result, i);
3556 if (result != ALLONES_DP) {
3557 observed = (uint64_t)result;
3558 expected = (uint64_t)ALLONES_DP;
3559 (void) snprintf(err_data, sizeof (err_data),
3560 "Reg: %d\nExpected: %lld\nObserved: %lld",
3561 i, ALLONES_DP, result);
3562 setup_fps_test_struct(IS_EREPORT_INFO,
3563 report, 8346, &observed, &expected, 1, 1,
3564 err_data);
3565
3566 return (-1);
3567 }
3568 }
3569
3570 return (0);
3571 }
3572
3573 /*
3574 * registers_two(struct fps_test_ereport *report)
3575 * tests single precision rotating ones through the
3576 * floating point registers. If an error is found,
3577 * relevant data is stored in report.
3578 */
3579 static int
registers_two(struct fps_test_ereport * report)3580 registers_two(struct fps_test_ereport *report)
3581 {
3582 char err_data[MAX_INFO_SIZE];
3583 int i;
3584 int j;
3585 uint64_t expected;
3586 uint64_t observed;
3587 unsigned int result;
3588 unsigned int value;
3589
3590 for (j = 0; j < 32; j++) {
3591 for (i = 0; i < 32; i++) {
3592 value = (1 << i);
3593 if ((result = register_test(j, value)) != value) {
3594 observed = (uint64_t)result;
3595 expected = (uint64_t)value;
3596 (void) snprintf(err_data, sizeof (err_data),
3597 "Reg: %d\nExpected: %d\nObserved: %d",
3598 j, value, result);
3599 setup_fps_test_struct(IS_EREPORT_INFO,
3600 report, 6301, &observed, &expected, 1,
3601 1, err_data);
3602
3603 return (-1);
3604 }
3605 }
3606 }
3607
3608 return (0);
3609 }
3610
3611 /*
3612 * registers_two_dp(struct fps_test_ereport *report)
3613 * tests double precision rotating ones through the
3614 * floating point registers. If an error is found,
3615 * relevant data is stored in report.
3616 */
3617 static int
registers_two_dp(struct fps_test_ereport * report)3618 registers_two_dp(struct fps_test_ereport *report)
3619 {
3620 char err_data[MAX_INFO_SIZE];
3621 int i;
3622 int j;
3623 uint64_t observed;
3624 uint64_t expected;
3625 unsigned long result;
3626 unsigned long value;
3627
3628 for (j = 0; j < 32; j = j + 2) {
3629 for (i = 0; i < 64; i++) {
3630 value = (1 << i);
3631 result = register_test_dp(j, value);
3632
3633 if (result != value) {
3634 observed = (*(uint64_t *)&result);
3635 expected = (*(uint64_t *)&value);
3636 (void) snprintf(err_data, sizeof (err_data),
3637 "Reg: %d\nExpected: %lld\nObserved: %lld",
3638 j, value, result);
3639 setup_fps_test_struct(IS_EREPORT_INFO,
3640 report, 5301, &observed, &expected, 1,
3641 1, err_data);
3642 return (-1);
3643 }
3644 }
3645 }
3646
3647 return (0);
3648 }
3649
3650 /*
3651 * registers_one(struct fps_test_ereport *report)
3652 * passes a single precision pattern through the
3653 * floating point registers. If an error is found,
3654 * relevant data is stored in report.
3655 */
3656 static int
registers_one(struct fps_test_ereport * report)3657 registers_one(struct fps_test_ereport *report)
3658 {
3659 char err_data[MAX_INFO_SIZE];
3660 int i;
3661 int j;
3662 unsigned int result;
3663
3664 uint64_t observed;
3665 uint64_t expected;
3666
3667 for (i = 0; i < 32; i++) {
3668 for (j = 0; j < PAT_NUM; j++) {
3669 result = register_test(i, pat[j]);
3670 if (result != pat[j]) {
3671 observed = (uint64_t)result;
3672 expected = (uint64_t)pat[j];
3673 (void) snprintf(err_data, sizeof (err_data),
3674 "Reg: %d\nExpected: %d\nObserved: %d",
3675 i, pat[j], result);
3676 setup_fps_test_struct(IS_EREPORT_INFO,
3677 report, 6302, &observed, &expected, 1,
3678 1, err_data);
3679
3680 return (-1);
3681 }
3682 }
3683 }
3684
3685 return (0);
3686 }
3687
3688 /*
3689 * registers_one_dp(struct fps_test_ereport *report)
3690 * passes a double precision pattern through the
3691 * floating point registers. If an error is found,
3692 * relevant data is stored in report.
3693 */
3694 static int
registers_one_dp(struct fps_test_ereport * report)3695 registers_one_dp(struct fps_test_ereport *report)
3696 {
3697 char err_data[MAX_INFO_SIZE];
3698 int i;
3699 int j;
3700 unsigned long result;
3701
3702 uint64_t observed;
3703 uint64_t expected;
3704
3705 for (i = 0; i < 64; i = i + 2) {
3706 for (j = 0; j < PAT_DP_NUM; j++) {
3707 result = register_test_dp(i, pat_dp[j]);
3708 if (result != pat_dp[j]) {
3709 observed = (uint64_t)result;
3710 expected = (uint64_t)pat[j];
3711 (void) snprintf(err_data, sizeof (err_data),
3712 "Reg: %d\nExpected: %lld"
3713 "\nObserved: %lld",
3714 i, pat[j], result);
3715 setup_fps_test_struct(IS_EREPORT_INFO,
3716 report, 5302, &observed, &expected, 1,
3717 1, err_data);
3718
3719 return (-1);
3720 }
3721 }
3722 }
3723
3724 return (0);
3725 }
3726
3727 /*
3728 * sigsegv_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
3729 * sets up the sigsegv signal handler. If reached during
3730 * non-negative testing, application exits.
3731 */
3732 /* ARGSUSED */
3733 static void
sigsegv_handler(int sig,siginfo_t * sip,ucontext_t * ucp)3734 sigsegv_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
3735 {
3736 ucp->uc_mcontext.fpregs.fpu_qcnt = 0;
3737
3738 fsr_at_trap = ucp->uc_mcontext.fpregs.fpu_fsr;
3739 if (trap_flag == (trap_flag | TRAP_SOLICITED)) {
3740 trap_flag = trap_flag & (~TRAP_SOLICITED);
3741 return;
3742 }
3743 trap_flag = trap_flag | TRAP_UNSOLICITED;
3744
3745 _exit(FPU_SIG_SEGV);
3746 }
3747
3748 /*
3749 * sigbus_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
3750 * sets up the sigbus signal handler. If reached during
3751 * non-negative testing, application exits.
3752 */
3753 /* ARGSUSED */
3754 static void
sigbus_handler(int sig,siginfo_t * sip,ucontext_t * ucp)3755 sigbus_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
3756 {
3757 ucp->uc_mcontext.fpregs.fpu_qcnt = 0;
3758
3759 fsr_at_trap = ucp->uc_mcontext.fpregs.fpu_fsr;
3760 if (trap_flag == (trap_flag | TRAP_SOLICITED)) {
3761 trap_flag = trap_flag & (~TRAP_SOLICITED);
3762 return;
3763 }
3764 trap_flag = trap_flag | TRAP_UNSOLICITED;
3765
3766 _exit(FPU_SIG_BUS);
3767
3768 }
3769
3770 /*
3771 * sigfpe_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
3772 * sets up the sigfpe signal handler. If reached during
3773 * non-negative testing, application exits.
3774 */
3775 /* ARGSUSED */
3776 static void
sigfpe_handler(int sig,siginfo_t * sip,ucontext_t * ucp)3777 sigfpe_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
3778 {
3779 ucp->uc_mcontext.fpregs.fpu_qcnt = 0;
3780
3781 fsr_at_trap = ucp->uc_mcontext.fpregs.fpu_fsr;
3782 if (trap_flag == (trap_flag | TRAP_SOLICITED)) {
3783 trap_flag = trap_flag & (~TRAP_SOLICITED);
3784 return;
3785 }
3786 trap_flag = trap_flag | TRAP_UNSOLICITED;
3787
3788 _exit(FPU_SIG_FPE);
3789 }
3790
3791 /*
3792 * sigill_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
3793 * sets up the sigill signal handler. If reached during
3794 * non-negative testing, application exits.
3795 */
3796 /* ARGSUSED */
3797 static void
sigill_handler(int sig,siginfo_t * sip,ucontext_t * ucp)3798 sigill_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
3799 {
3800 ucp->uc_mcontext.fpregs.fpu_qcnt = 0;
3801
3802 fsr_at_trap = ucp->uc_mcontext.fpregs.fpu_fsr;
3803 if (trap_flag == (trap_flag | TRAP_SOLICITED)) {
3804 trap_flag = trap_flag & (~TRAP_SOLICITED);
3805 return;
3806 }
3807 trap_flag = trap_flag | TRAP_UNSOLICITED;
3808
3809 _exit(FPU_SIG_ILL);
3810 }
3811
3812 /*
3813 * winitfp() sets the signal handlers used
3814 * for negative testing. If sigaction fails,
3815 * the program exits.
3816 */
3817 int
winitfp()3818 winitfp()
3819 {
3820 (void) sigemptyset(&newfpe.sa_mask);
3821 newfpe.sa_flags = SA_SIGINFO;
3822 newfpe.sa_handler = sigfpe_handler;
3823 if (sigaction(SIGFPE, &newfpe, &oldfpe)) {
3824 _exit(FPU_SYSCALL_FAIL);
3825 }
3826
3827 (void) sigemptyset(&newill.sa_mask);
3828 newill.sa_flags = SA_SIGINFO;
3829 newill.sa_handler = sigill_handler;
3830 if (sigaction(SIGILL, &newill, &oldill)) {
3831 _exit(FPU_SYSCALL_FAIL);
3832 }
3833
3834 (void) sigemptyset(&newbus.sa_mask);
3835 newbus.sa_flags = SA_SIGINFO;
3836 newbus.sa_handler = sigbus_handler;
3837 if (sigaction(SIGBUS, &newbus, &oldbus)) {
3838 _exit(FPU_SYSCALL_FAIL);
3839 }
3840
3841 (void) sigemptyset(&newsegv.sa_mask);
3842 newsegv.sa_flags = SA_SIGINFO;
3843 newsegv.sa_handler = sigsegv_handler;
3844 if (sigaction(SIGSEGV, &newsegv, &oldsegv)) {
3845 _exit(FPU_SYSCALL_FAIL);
3846 }
3847
3848 return (0);
3849 }
3850 #endif
3851
3852 /*
3853 * restore_signals() turns off the signal
3854 * handlers used by restoring the original
3855 * values. If sigaction fails, the program
3856 * exits.
3857 */
3858 int
restore_signals()3859 restore_signals()
3860 {
3861 if (sigaction(SIGSEGV, &oldsegv, &newsegv)) {
3862 _exit(FPU_SYSCALL_FAIL);
3863 }
3864
3865 if (sigaction(SIGBUS, &oldbus, &newbus)) {
3866 _exit(FPU_SYSCALL_FAIL);
3867 }
3868
3869 if (sigaction(SIGILL, &oldill, &newill)) {
3870 _exit(FPU_SYSCALL_FAIL);
3871 }
3872
3873 if (sigaction(SIGFPE, &oldfpe, &newfpe)) {
3874 _exit(FPU_SYSCALL_FAIL);
3875 }
3876
3877 return (0);
3878
3879 }
3880
3881 /*
3882 * fpu_sysdiag(struct fps_test_ereport *report)
3883 * is the main caller of all fpu subtests. It
3884 * does the following tests: normal registers, fsr,
3885 * moving instructions, conversion instructions,
3886 * absolute values, compare, branching, arithmatic,
3887 * chain, datapath, and timing.
3888 * If an error is found, relevant data is stored
3889 * in report.
3890 */
3891 int
fpu_sysdiag(struct fps_test_ereport * report)3892 fpu_sysdiag(struct fps_test_ereport *report)
3893 {
3894
3895 int i;
3896
3897 #ifndef i86pc
3898
3899 /*
3900 * Initialize neg_val_sp[] and neg_val_dp[] with the -ve versions of
3901 * the values in val[]
3902 */
3903 for (i = 0; i < N_VALS; i++) {
3904 neg_val_sp[i] = val[i].floatsingle |
3905 ((uint32_t)1) << 31;
3906
3907 neg_val_dp[i] = val[i].floatdouble |
3908 ((uint64_t)1) << 63;
3909 }
3910
3911 /* Register Testing */
3912 if (registers_four(report)) {
3913 return (-1);
3914 }
3915
3916 if (trap_flag) {
3917 fail_trap(report, 7001);
3918 return (-1);
3919 }
3920
3921 if (registers_four_dp(report)) {
3922 return (-1);
3923 }
3924
3925 if (trap_flag) {
3926 fail_trap(report, 7002);
3927 }
3928
3929 if (registers_two(report)) {
3930 return (-1);
3931 }
3932
3933 if (trap_flag) {
3934 fail_trap(report, 7003);
3935 }
3936
3937 if (registers_two_dp(report)) {
3938 return (-1);
3939 }
3940
3941 if (trap_flag) {
3942 fail_trap(report, 7004);
3943 return (-1);
3944 }
3945
3946 if (registers_one(report)) {
3947 return (-1);
3948 }
3949
3950 if (trap_flag) {
3951 fail_trap(report, 7005);
3952 return (-1);
3953 }
3954
3955 if (registers_one_dp(report)) {
3956 return (-1);
3957 }
3958
3959 if (trap_flag) {
3960 fail_trap(report, 7006);
3961 return (-1);
3962 }
3963
3964 /* FSR testing */
3965 if (fsr_test(report)) {
3966 return (-1);
3967
3968 }
3969
3970 if (trap_flag) {
3971 fail_trap(report, 7007);
3972 return (-1);
3973 }
3974
3975 if (fmovs_ins(report)) {
3976 return (-1);
3977 }
3978
3979 if (trap_flag) {
3980 fail_trap(report, 7008);
3981 return (-1);
3982 }
3983
3984 /* Conversion routines */
3985 if (integer_to_float_sp(report)) {
3986 return (-1);
3987 }
3988
3989 if (trap_flag) {
3990 fail_trap(report, 7009);
3991 return (-1);
3992 }
3993
3994 if (integer_to_float_dp(report)) {
3995 return (-1);
3996 }
3997
3998 if (trap_flag) {
3999 fail_trap(report, 7010);
4000 return (-1);
4001 }
4002
4003 if (long_to_float_sp(report)) {
4004 return (-1);
4005 }
4006
4007 if (trap_flag) {
4008 fail_trap(report, 7011);
4009 return (-1);
4010 }
4011
4012 if (long_to_float_dp(report)) {
4013 return (-1);
4014 }
4015
4016 if (trap_flag) {
4017 fail_trap(report, 7012);
4018 return (-1);
4019 }
4020
4021 if (float_to_integer_sp(report)) {
4022 return (-1);
4023 }
4024
4025 if (trap_flag) {
4026 fail_trap(report, 7013);
4027 return (-1);
4028 }
4029
4030 if (float_to_integer_dp(report)) {
4031 return (-1);
4032 }
4033
4034 if (trap_flag) {
4035 fail_trap(report, 7014);
4036 return (-1);
4037 }
4038
4039 if (float_to_long_dp(report)) {
4040 return (-1);
4041 }
4042
4043 if (trap_flag) {
4044 fail_trap(report, 7015);
4045 return (-1);
4046 }
4047
4048 if (float_to_long_sp(report)) {
4049 return (-1);
4050 }
4051
4052 if (trap_flag) {
4053 fail_trap(report, 7016);
4054 return (-1);
4055 }
4056
4057 if (single_doub(report)) {
4058 return (-1);
4059 }
4060 if (trap_flag) {
4061 fail_trap(report, 7017);
4062 return (-1);
4063 }
4064 if (double_sing(report)) {
4065 return (-1);
4066 }
4067 if (trap_flag) {
4068 fail_trap(report, 7018);
4069 return (-1);
4070 }
4071 /* Absolute, -ve instructions */
4072 if (fabs_ins_sp(report)) {
4073 return (-1);
4074 }
4075 if (trap_flag) {
4076 fail_trap(report, 7019);
4077 return (-1);
4078 }
4079 if (fabs_ins_dp(report)) {
4080 return (-1);
4081 }
4082 if (trap_flag) {
4083 fail_trap(report, 7020);
4084 return (-1);
4085 }
4086 if (get_negative_value_pn_sp(report)) {
4087 return (-1);
4088 }
4089 if (trap_flag) {
4090 fail_trap(report, 7021);
4091 return (-1);
4092 }
4093 if (get_negative_value_pn_dp(report)) {
4094 return (-1);
4095 }
4096 if (trap_flag) {
4097 fail_trap(report, 7022);
4098 return (-1);
4099 }
4100 if (get_negative_value_np_sp(report)) {
4101 return (-1);
4102 }
4103 if (trap_flag) {
4104 fail_trap(report, 7023);
4105 return (-1);
4106 }
4107 if (get_negative_value_np_dp(report)) {
4108 return (-1);
4109 }
4110 if (trap_flag) {
4111 fail_trap(report, 7024);
4112 return (-1);
4113 }
4114 /* Compare and branch instructions */
4115 if (compare_sp(report)) {
4116 return (-1);
4117 }
4118 if (trap_flag) {
4119 fail_trap(report, 7025);
4120 return (-1);
4121 }
4122 if (compare_dp(report)) {
4123 return (-1);
4124 }
4125 if (trap_flag) {
4126 fail_trap(report, 7026);
4127 return (-1);
4128 }
4129 if (compare_sp_except(report)) {
4130 return (-1);
4131 }
4132 if (trap_flag) {
4133 fail_trap(report, 7027);
4134 return (-1);
4135 }
4136 if (compare_dp_except(report)) {
4137 return (-1);
4138 }
4139 if (trap_flag) {
4140 fail_trap(report, 7028);
4141 return (-1);
4142 }
4143 if (branching(report)) {
4144 return (-1);
4145
4146 }
4147 if (trap_flag) {
4148 fail_trap(report, 7029);
4149 return (-1);
4150 }
4151 if (no_branching(report)) {
4152 return (-1);
4153 }
4154 if (trap_flag) {
4155 fail_trap(report, 7030);
4156 return (-1);
4157 }
4158 /* Arithmetic instructions */
4159 if (addition_test_sp(report)) {
4160 return (-1);
4161 }
4162 if (trap_flag) {
4163 fail_trap(report, 7031);
4164 return (-1);
4165 }
4166 if (addition_test_dp(report)) {
4167 return (-1);
4168 }
4169 if (trap_flag) {
4170 fail_trap(report, 7032);
4171 return (-1);
4172 }
4173 if (subtraction_test_sp(report)) {
4174 return (-1);
4175 }
4176 if (trap_flag) {
4177 fail_trap(report, 7033);
4178 return (-1);
4179 }
4180 if (subtraction_test_dp(report)) {
4181 return (-1);
4182 }
4183 if (trap_flag) {
4184 fail_trap(report, 7034);
4185 return (-1);
4186 }
4187 if (multiplication_test_sp(report)) {
4188 return (-1);
4189 }
4190 if (trap_flag) {
4191 fail_trap(report, 7035);
4192 return (-1);
4193 }
4194 if (multiplication_test_dp(report)) {
4195 return (-1);
4196 }
4197 if (trap_flag) {
4198 fail_trap(report, 7036);
4199 return (-1);
4200 }
4201 if (squareroot_test_sp(report)) {
4202 return (-1);
4203 }
4204 if (trap_flag) {
4205 fail_trap(report, 7037);
4206 return (-1);
4207 }
4208 if (squareroot_test_dp(report)) {
4209 return (-1);
4210 }
4211 if (trap_flag) {
4212 fail_trap(report, 7038);
4213 return (-1);
4214 }
4215 if (division_test_sp(report)) {
4216 return (-1);
4217 }
4218 if (trap_flag) {
4219 fail_trap(report, 7039);
4220 return (-1);
4221 }
4222 if (division_test_dp(report)) {
4223 return (-1);
4224 }
4225 if (trap_flag) {
4226 fail_trap(report, 7040);
4227 return (-1);
4228 }
4229 /* chain, datapath, timing tests */
4230 if (chain_sp_test(report)) {
4231 return (-1);
4232 }
4233 if (trap_flag) {
4234 fail_trap(report, 7041);
4235 return (-1);
4236 }
4237 if (chain_dp_test(report)) {
4238 return (-1);
4239 }
4240 if (trap_flag) {
4241 fail_trap(report, 7042);
4242 return (-1);
4243 }
4244 if (data_path_sp(report)) {
4245 return (-1);
4246 }
4247 if (trap_flag) {
4248 fail_trap(report, 7043);
4249 return (-1);
4250 }
4251 if (data_path_dp(report)) {
4252 return (-1);
4253 }
4254 if (trap_flag) {
4255 fail_trap(report, 7044);
4256 return (-1);
4257 }
4258 if (timing_test(report)) {
4259 return (-1);
4260 }
4261 if (trap_flag) {
4262 fail_trap(report, 7045);
4263 return (-1);
4264 }
4265 if (check_conv(report)) {
4266 return (-1);
4267 }
4268 if (trap_flag) {
4269 fail_trap(report, 7046);
4270 return (-1);
4271 }
4272 #endif /* i86pc */
4273
4274 return (0);
4275 }
4276
4277 #define LLL 64
4278 #define REP_RXd "1104199269.000000"
4279 #define REP_RXc "1104199269,000000"
4280 #define REP_GCONd "4.5"
4281 #define REP_GCONc "4,5"
4282
4283 /*
4284 * check_conv(struct fps_test_ereport *report)
4285 * does a series of conversion testing.
4286 * If an error is found, relevant data is stored
4287 * in report.
4288 */
4289 static int
check_conv(struct fps_test_ereport * report)4290 check_conv(struct fps_test_ereport *report)
4291 {
4292 char dec_point;
4293 char err_data[MAX_INFO_SIZE];
4294 double gcon;
4295 char l_buf[LLL];
4296 char *pREP_RX;
4297 char *pREP_GCON;
4298 double rx;
4299 long double qgcon;
4300 struct lconv *lconv2;
4301 uint64_t observed;
4302 uint64_t expected;
4303
4304 (void) memset(l_buf, 0, LLL);
4305
4306 lconv2 = localeconv();
4307 if (NULL == lconv2)
4308 return (0);
4309 if (NULL == lconv2->decimal_point)
4310 return (0);
4311
4312 /* expect "." or ",". if not than return */
4313 if (1 == strlen(lconv2->decimal_point))
4314 dec_point = lconv2->decimal_point[0];
4315 else
4316 return (0);
4317
4318 if (',' == dec_point) {
4319 pREP_RX = REP_RXc;
4320 pREP_GCON = REP_GCONc;
4321 } else if ('.' == dec_point) {
4322 pREP_RX = REP_RXd;
4323 pREP_GCON = REP_GCONd;
4324 } else
4325 return (0);
4326
4327 rx = 1104199269;
4328
4329 (void) snprintf(l_buf, LLL - 1, "%f", rx);
4330 if (strncmp(l_buf, pREP_RX, strlen(pREP_RX)) != 0) {
4331 observed = (uint64_t)1;
4332 expected = (uint64_t)0;
4333 (void) snprintf(err_data, sizeof (err_data),
4334 "\nObserved: %s\nExpected: %s", l_buf, pREP_RX);
4335 setup_fps_test_struct(IS_EREPORT_INFO, report,
4336 6326, &observed, &expected, 1, 1, err_data);
4337
4338 return (-1);
4339 }
4340
4341 gcon = 4.5;
4342 (void) memset(l_buf, 0, LLL);
4343 (void) gconvert(gcon, 15, 0, l_buf);
4344 if (strncmp(l_buf, pREP_GCON, strlen(pREP_GCON)) != 0) {
4345 observed = (uint64_t)1;
4346 expected = (uint64_t)0;
4347 (void) snprintf(err_data, sizeof (err_data),
4348 "\nObserved: %s\nExpected: %s", l_buf, pREP_GCON);
4349 setup_fps_test_struct(IS_EREPORT_INFO, report,
4350 6327, &observed, &expected, 1, 1, err_data);
4351
4352 return (-2);
4353 }
4354
4355 qgcon = 4.5;
4356 (void) memset(l_buf, 0, LLL);
4357 (void) qgconvert(&qgcon, 15, 0, l_buf);
4358 if (strncmp(l_buf, pREP_GCON, strlen(pREP_GCON)) != 0) {
4359 observed = (uint64_t)1;
4360 expected = (uint64_t)0;
4361 (void) snprintf(err_data, sizeof (err_data),
4362 "\nObserved: %s\nExpected: %s", l_buf, pREP_GCON);
4363 setup_fps_test_struct(IS_EREPORT_INFO, report,
4364 6328, &observed, &expected, 1, 1, err_data);
4365
4366 return (-3);
4367 }
4368
4369 return (0);
4370 }
4371
4372 /*
4373 * fail_trap(struct fps_test_ereport *report, int flag_num)
4374 * creates the ereport data if a trap flag is set after a
4375 * successful test when it shouldn't be.
4376 */
4377 static void
fail_trap(struct fps_test_ereport * report,int flag_num)4378 fail_trap(struct fps_test_ereport *report, int flag_num)
4379 {
4380 uint64_t observed = 1;
4381 uint64_t expected = 0;
4382
4383 setup_fps_test_struct(NO_EREPORT_INFO, report,
4384 flag_num, &observed, &expected, 1, 1);
4385 }
4386