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 #ifdef __lint
30 #pragma error_messages(off, E_VALUE_TYPE)
31 #endif
32
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <fp.h>
36 #include <fps_ereport.h>
37
38 #define EXPECTED 1.9999999999999998E+00
39
40 static void fdivd(double *f22, double *f2, double *f12);
41 static void fmuld(double *x, double *y, double *z, double *z1);
42 static void fmulx(uint64_t *rs1, uint64_t *rs2, uint64_t *rd);
43 int fpu_fdivd(int rloop, struct fps_test_ereport *report);
44 int fpu_fmuld(int rloop, struct fps_test_ereport *report);
45 int fpu_fmulx(int rloop, struct fps_test_ereport *report);
46
47 #ifdef V9B
48
49 /* Lint doesn't recognize .il files where these are defined */
50 #ifdef __lint
51
52 unsigned long fcmpgt16(double in1, double in2);
53 unsigned long fcmpne16(double in1, double in2);
54 unsigned long setgsr(unsigned long);
55
56 #else
57
58 extern float fpackfix(double num);
59 extern unsigned long fcmpgt16(double in1, double in2);
60 extern unsigned long fcmpne16(double in1, double in2);
61 extern unsigned long setgsr(unsigned long);
62
63 #endif
64
65 int align_data(int loop,
66 struct fps_test_ereport *report);
67 int vis_test(struct fps_test_ereport *report);
68 static int align_error_create(char *err, uint32_t start, uint32_t offest,
69 int loop, uint32_t count);
70 static int do_aligndata(uchar_t *from, uint32_t *offset, size_t sz,
71 uchar_t *f0, uchar_t *f2, uint32_t bmask);
72 static int visgt16(struct fps_test_ereport *report);
73 static int visne16(struct fps_test_ereport *report);
74 static int vispackfix(struct fps_test_ereport *report);
75
76 #endif
77
78
79 /*
80 * fpu_fdivd(int rloop, int unit, struct fps_test_ereport *report)
81 * returns whether the correct value is calculated each time
82 * rloop times. If an error is found, the relevant data is stored
83 * in report. The test uses internally generated random double
84 * precision within a certain range to conduct the following test:
85 *
86 * (a * 2^1022) / ((a+e) * 2^1021)
87 *
88 * which is guaranteed to fill the resulting mantissa with all ones.
89 *
90 */
91 int
fpu_fdivd(int rloop,struct fps_test_ereport * report)92 fpu_fdivd(int rloop, struct fps_test_ereport *report)
93 {
94
95 char err_data[MAX_INFO_SIZE];
96 double expect_ans = EXPECTED;
97 double f12 = 0;
98 double f2;
99 double f22;
100 int loop = 0;
101 uint64_t expect;
102 uint64_t observe;
103
104 srand48(1L);
105
106 while (loop < rloop) {
107 loop++;
108
109 *(uint32_t *)& f22 = mrand48();
110 *(uint32_t *)& f22 &= 0x80069fff;
111 *(uint32_t *)& f22 |= 0x7fd69f00;
112
113 #ifdef __lint
114 (void) f22;
115 #endif
116
117 *((uint32_t *)& f22 + 1) = mrand48();
118 *((uint32_t *)& f22 + 1) |= 0x00000001;
119
120 *(uint64_t *)& f2 = *(uint64_t *)& f22 + 1;
121 *(uint32_t *)& f2 &= 0x800FFFFF;
122 *(uint32_t *)& f2 |= 0x7FC00000;
123 #ifdef __lint
124 (void) f2;
125 #endif
126
127 fdivd(&f22, &f2, &f12);
128
129 if (f12 != expect_ans) {
130 (void) snprintf(err_data, sizeof (err_data),
131 "\nExpected: %.16e,\nObserved: %.16e",
132 expect_ans, f12);
133 expect = *(uint64_t *)&expect_ans;
134 observe = *(uint64_t *)&f12;
135 setup_fps_test_struct(IS_EREPORT_INFO, report,
136 6340, &observe, &expect, 1, 1, err_data);
137
138 return (-1);
139 }
140 }
141
142 return (0);
143 }
144
145 /*
146 * fdivd(uint64_t *rs1, uint64_t *rs2, uint64_t *rd)
147 * performs the assembly level instructions for
148 * fpu_fdivd.
149 */
150 /* ARGSUSED */
151 static void
fdivd(double * f22,double * f2,double * f12)152 fdivd(double *f22, double *f2, double *f12)
153 {
154 asm("ldd [%i0], %f22");
155 asm("ldd [%i1], %f2");
156 asm("fdivd %f22, %f2, %f12");
157 asm("std %f12,[%i2]");
158 asm("membar #Sync");
159 }
160
161 /*
162 * fpu_fmuld(int rloop, int unit, struct fps_test_ereport *report)
163 * returns whether the correct value is calculated each time
164 * rloop times. If an error is found, the relevant data is stored
165 * in report. The goal is to check if (x * y) == (y * x). The
166 * data pattern is important, and the back-to-back fmuld's are
167 * important.
168 */
169 int
fpu_fmuld(int rloop,struct fps_test_ereport * report)170 fpu_fmuld(int rloop, struct fps_test_ereport *report)
171 {
172 char err_data[MAX_INFO_SIZE];
173 double x;
174 double y;
175 double z;
176 double z1;
177 int loop;
178 uint64_t expect;
179 uint64_t observe;
180 uint64_t *px;
181 uint64_t *py;
182
183 loop = 0;
184 px = (uint64_t *)& x;
185 py = (uint64_t *)& y;
186 *px = 0x2FEBD8507111CDE5UL; /* 4865027 */
187 *py = 0x2FE284A9A98EAA26UL;
188
189 #ifdef __lint
190 (void) x;
191 (void) y;
192 #endif
193
194 while (loop < rloop) {
195 loop++;
196 z = z1 = 0.0;
197
198 /*
199 * Data pattern and back-to-back fmuld() are
200 * important
201 */
202 fmuld(&x, &y, &z, &z1);
203
204 if (*(uint64_t *)&z != *(uint64_t *)&z1) {
205 (void) snprintf(err_data, sizeof (err_data),
206 "\nExpected: %.16e,\nObserved: %.16e",
207 *(uint64_t *)&z, *(uint64_t *)&z1);
208 expect = *(uint64_t *)&z;
209 observe = *(uint64_t *)&z1;
210 setup_fps_test_struct(IS_EREPORT_INFO, report,
211 6341, &observe, &expect, 1, 1, err_data);
212
213 return (-1);
214 }
215 }
216
217 return (0);
218 }
219
220 /*
221 * fmuld(double *x,double *y, double *z, double *z1)
222 * performs the assembly level instructions for
223 * fpu_fmuld.
224 */
225 /* ARGSUSED */
226 static void
fmuld(double * x,double * y,double * z,double * z1)227 fmuld(double *x, double *y, double *z, double *z1)
228 {
229 asm("ldd[%i0], %f0");
230 asm("ldd[%i1], %f4");
231 asm("fmuld%f0, %f4, %f2");
232 asm("fmuld%f4, %f0, %f6");
233 asm("std%f2, [%i2]");
234 asm("std%f6, [%i3]");
235 asm("membar #Sync");
236 }
237
238
239 /*
240 * fpu_fmulx(int rloop, int unit, struct fps_test_ereport *report)
241 * returns whether the correct value is calculated each time
242 * rloop times. If an error is found, the relevant data is stored
243 * in report. The goal is to check if (x * y) == (y * x) with
244 * 64-bit intgers.
245 */
246 int
fpu_fmulx(int rloop,struct fps_test_ereport * report)247 fpu_fmulx(int rloop, struct fps_test_ereport *report)
248 {
249 char err_data[MAX_INFO_SIZE];
250 int loop;
251 int loop_lim;
252 uint32_t *rs1;
253 uint32_t *rs2;
254 uint64_t expect;
255 uint64_t observe;
256 uint64_t v1;
257 uint64_t v2;
258 uint64_t vd1;
259 uint64_t vd2;
260 uint64_t *rd1;
261 uint64_t *rd2;
262
263 v1 = v2 = vd1 = vd2 = 0;
264 loop = 0;
265 loop_lim = rloop;
266
267 if (loop_lim < 10)
268 loop_lim = 10;
269
270 if (loop_lim > 100000)
271 loop_lim = 100000;
272
273 rs1 = (uint32_t *)& v1;
274 rs2 = (uint32_t *)& v2;
275 rd1 = &vd1;
276 rd2 = &vd2;
277
278 #ifdef __lint
279 (void) v1;
280 (void) v2;
281 #endif
282
283 srand(0l);
284 while (loop < loop_lim) {
285 loop++;
286
287 #ifndef __lint
288
289 *rs1 = mrand48();
290 *(rs1 + 1) = mrand48();
291 *rs2 = mrand48();
292 *(rs2 + 1) = mrand48();
293 #endif
294
295 /* LINTED */
296 fmulx((uint64_t *)rs1, (uint64_t *)rs2, rd1);
297
298 /* LINTED */
299 fmulx((uint64_t *)rs2, (uint64_t *)rs1, rd2);
300
301 if (*rd1 != *rd2) {
302 expect = (uint64_t)*rd1;
303 observe = (uint64_t)*rd2;
304 (void) snprintf(err_data, sizeof (err_data),
305 "\nExpected: %lld\nObserved: %lld", *rd1, *rd2);
306 setup_fps_test_struct(IS_EREPORT_INFO, report,
307 6356, &observe, &expect, 1, 1, err_data);
308
309 return (-1);
310 }
311 }
312
313 return (0);
314 }
315
316 /*
317 * fmulx(uint64_t *rs1, uint64_t *rs2, uint64_t *rd)
318 * performs the assembly level instructions for
319 * fpu_fmulx.
320 */
321 /* ARGSUSED */
322 static void
fmulx(uint64_t * rs1,uint64_t * rs2,uint64_t * rd)323 fmulx(uint64_t *rs1, uint64_t *rs2, uint64_t *rd)
324 {
325 asm("ldx [%i0], %l0");
326 asm("ldx [%i1], %l1");
327 asm("mulx %l0, %l1, %l2");
328 asm("stx %l2, [%i2]");
329 asm("membar #Sync");
330
331 }
332
333
334
335 #ifdef V9B
336
337 #pragma align 64 (f0)
338 #pragma align 8 (f2)
339
340 #define MEMSIZE 2048*3
341
342 static uchar_t f0[64];
343 static uchar_t f2[8];
344
345 static uint32_t bmask[] = {0x01234567, 0x12345678,
346 0x23456789, 0x3456789a,
347 0x456789ab, 0x56789abc,
348 0x6789abcd, 0x789abcde,
349 0x89abcdef, 0x9abcdef0,
350 0xabcdef01, 0xbcdef012,
351 0xcdef0123, 0xdef01234,
352 0xef012345, 0xf0123456,
353 0x55555555, 0xaaaaaaaa,
354 0x00000000, 0xffffffff};
355
356 #ifdef __lint
357
358 /*ARGSUSED*/
359 unsigned long
setgsr(unsigned long arg1)360 setgsr(unsigned long arg1)
361 {
362 return (0);
363 }
364
365 /*ARGSUSED*/
366 float
fpackfix(double arg1)367 fpackfix(double arg1)
368 {
369 return (0.0);
370 }
371
372 /*ARGSUSED*/
373 unsigned long
fcmpne16(double arg1,double arg2)374 fcmpne16(double arg1, double arg2)
375 {
376 return (0);
377 }
378
379 /*ARGSUSED*/
380 unsigned long
fcmpgt16(double arg1,double arg2)381 fcmpgt16(double arg1, double arg2)
382 {
383 return (0);
384 }
385
386 #endif /* LINT */
387
388 /*
389 * align_data(int loop, struct fps_test_ereport *report)
390 * returns whether a miscompare was found after running alignment tests
391 * loop amount of times. If an error is found, relevant data is stored
392 * in report. This test exercises the alignaddr and aligndata
393 * instructions with different byte alignments to ensure proper
394 * operation. These two instructions are used extensively by the kernel
395 * to move data size greater than 512 bytes. User level memcpy and
396 * memmove library also use these instructions for data size
397 * greater than 256 bytes.
398 */
399 int
align_data(int loop,struct fps_test_ereport * report)400 align_data(int loop, struct fps_test_ereport *report)
401 {
402 char err[MAX_INFO_SIZE];
403 int test_ret;
404 int nr_malloc;
405 size_t memsize;
406 struct timeval timeout;
407 uchar_t c;
408 uchar_t *pf0;
409 uchar_t *pf2;
410 uchar_t *src;
411 uint32_t cnt;
412 uint32_t i;
413 uint32_t offset;
414 uint32_t start;
415 uint64_t expect[2];
416 uint64_t observe[2];
417
418 timeout.tv_sec = 0;
419 timeout.tv_usec = 10000;
420 nr_malloc = 0;
421 err[0] = '\0';
422
423 /* Make sure memsize is 64 bytes aligned with minimum of 64 bytes */
424 memsize = MEMSIZE;
425 memsize = memsize / 64 * 64;
426
427 if (memsize < 64)
428 memsize = 64;
429
430 src = (uchar_t *)memalign(64, memsize + 64);
431
432 while (src == NULL && nr_malloc < 10) {
433 (void) select(1, NULL, NULL, NULL, &timeout);
434 nr_malloc++;
435 src = (uchar_t *)memalign(64, memsize + 64);
436 }
437
438 if (src == NULL)
439 _exit(FPU_SYSCALL_FAIL);
440
441 /* Initialize source array with sequential data */
442 c = 0;
443
444 for (i = 0; i < memsize + 64; i++)
445 *(src + i) = c++;
446
447 for (cnt = 0; cnt < loop; cnt++) {
448 for (start = 1; start < 64; start += 1) {
449 offset = 0;
450
451 test_ret = do_aligndata(src + start, &offset,
452 memsize, f0, f2, bmask[cnt % 20]);
453
454 /*
455 * Miscompare on the two aligndata
456 * instructions. Calculate offset to source
457 * array and get miscompare data
458 */
459
460 if (test_ret != 0) {
461 pf0 = f0 + offset % 64;
462 pf2 = f2;
463
464 for (i = 0; i < 8; i++) {
465 if (*(pf0 + i) != *(pf2 + i))
466 break;
467 }
468
469 (void) align_error_create(err, start,
470 offset + start + i, loop, cnt);
471 expect[0] =
472 (uint64_t)(*(uint8_t *)
473 (src + offset + start + i));
474 expect[1] = (uint64_t)0;
475 observe[0] = (uint64_t)(*(uint8_t *)(pf0 + i));
476 observe[1] = (uint64_t)(*(uint8_t *)(pf2 + i));
477 setup_fps_test_struct(
478 IS_EREPORT_INFO,
479 report, 6344, observe,
480 expect, 1, 2, err);
481
482 free(src);
483
484 return (-1);
485 }
486
487 /*
488 * No miscompare on the aligndata
489 * instructions. Check to see whether the
490 * last 64 bytes matches the input
491 */
492 if (test_ret == 0) {
493 pf2 = src + offset + start;
494
495 for (i = 0; i < 64; i++) {
496 if (f0[i] != *(pf2 + i)) {
497
498 (void) align_error_create(err,
499 start,
500 offset + start + i,
501 loop, cnt);
502 expect[0] =
503 (uint64_t)(*(uint8_t *)
504 (pf2 + i));
505 expect[1] = (uint64_t)0;
506 observe[0] = (uint64_t)f0[i];
507 observe[1] = (uint64_t)0;
508 setup_fps_test_struct(
509 IS_EREPORT_INFO,
510 report, 6343, observe,
511 expect, 1, 1, err);
512
513 free(src);
514 return (-1);
515 }
516 }
517 }
518 }
519 }
520
521 free(src);
522
523 return (0);
524 }
525
526 /*
527 * align_error_create(char *err, int start, int offset, int loop, int count)
528 * returns if a successful snprintf was performed when creating an align_data
529 * error message for align_data.
530 */
531 static int
align_error_create(char * err,uint32_t start,uint32_t offset,int loop,uint32_t count)532 align_error_create(char *err, uint32_t start,
533 uint32_t offset, int loop, uint32_t count)
534 {
535 if (err == NULL)
536 return (-1);
537
538 return snprintf(err, sizeof (err),
539 "Start = %2.2d offset = %2.2d loop = %d cnt = %d",
540 start, offset, loop, count);
541 }
542
543 /*
544 * do_aligndata(uchar_t *from, uint32_t *offset, size_t sz,
545 * uchar_t *f0, uchar_t *f2, uint32_t bmask) performs
546 * the assembly lvl routines for align_data.
547 */
548 /*ARGSUSED*/
549 static int
do_aligndata(uchar_t * from,uint32_t * offset,size_t sz,uchar_t * f0,uchar_t * f2,uint32_t bmask)550 do_aligndata(uchar_t *from, uint32_t *offset, size_t sz,
551 uchar_t *f0, uchar_t *f2, uint32_t bmask)
552 {
553 int ret = 1;
554
555 asm("bmask %i5,%g0,%g0");
556 /* produce GSR.offset and align %l0 to 8 bytes boundary */
557 asm("alignaddr %i0, %g0, %l0");
558 /* %i0 then used as error register, assume error */
559 asm("mov 1,%i0");
560 /* %l1 used as offset counter */
561 asm("mov -8,%l1");
562 asm("ldd [%l0], %f0");
563
564 asm("next_read:");
565
566 asm("ldd [%l0+8], %f2");
567 asm("ldd [%l0+0x10], %f4");
568 asm("faligndata %f0, %f2, %f32");
569 asm("faligndata %f0, %f2, %f48");
570 asm("fcmpd %fcc0,%f32,%f48");
571 asm("fblg,pn %fcc0,error");
572 /* %l1 contains offset value */
573 asm("add %l1,8,%l1");
574 /* 0 - 7 */
575
576 asm("ldd [%l0+0x18], %f6");
577 asm("faligndata %f2, %f4, %f34");
578 asm("faligndata %f2, %f4, %f48");
579 asm("fcmpd %fcc0,%f34,%f48");
580 asm("fblg,pn %fcc0,error");
581 /* %l1 contains offset value */
582 asm("add %l1,8,%l1");
583 /* 9 - 15 */
584
585 asm("ldd [%l0+0x20], %f8");
586 asm("faligndata %f4, %f6, %f36");
587 asm("faligndata %f4, %f6, %f48");
588 asm("fcmpd %fcc0,%f36,%f48");
589 asm("fblg,pn %fcc0,error");
590 /* %l1 contains offset value */
591 asm("add %l1,8,%l1");
592 /* 16 - 23 */
593
594 asm("ldd [%l0+0x28], %f10");
595 asm("faligndata %f6, %f8, %f38");
596 asm("faligndata %f6, %f8, %f48");
597 asm("fcmpd %fcc0,%f38,%f48");
598 asm("fblg,pn %fcc0,error");
599 /* contains offset value */
600 asm("add %l1,8,%l1");
601 /* 24 - 31 */
602
603 asm("ldd [%l0+0x28], %f10");
604 asm("faligndata %f8, %f10, %f40");
605 asm("faligndata %f8, %f10, %f48");
606 asm("fcmpd %fcc0,%f40,%f48");
607 asm("fblg,pn %fcc0,error");
608 /* %l1 contains offset value */
609 asm("add %l1,8,%l1");
610 /* 32 - 39 */
611
612 asm("ldd [%l0+0x30], %f12");
613 asm("faligndata %f10, %f12, %f42");
614 asm("faligndata %f10, %f12, %f48");
615 asm("fcmpd %fcc0,%f42,%f48");
616 asm("fblg,pn %fcc0,error");
617 /* %l1 contains offset value */
618 asm("add %l1,8,%l1");
619 /* 40 - 47 */
620
621 asm("ldd [%l0+0x38], %f14");
622 asm("faligndata %f12, %f14, %f44");
623 asm("faligndata %f12, %f14, %f48");
624 asm("fcmpd %fcc0,%f44,%f48");
625 asm("fblg,pn %fcc0,error");
626 /* %l1 contains offset value */
627 asm("add %l1,8,%l1");
628 /* 48 - 55 */
629
630 asm("ldd [%l0+0x40], %f0");
631 asm("faligndata %f14, %f0, %f46");
632 asm("faligndata %f14, %f0, %f48");
633 asm("fcmpd %fcc0,%f46,%f48");
634 asm("fblg,pn %fcc0,error");
635 /* %l1 contains offset value */
636 asm("add %l1,8,%l1");
637 /* 56 - 63 */
638
639 asm("subcc %i2,64,%i2");
640 asm("bg next_read");
641 asm("add %l0,64,%l0");
642
643 /* no miscompare error */
644 asm("mov 0,%i0");
645 ret = 0;
646 /* no error, move back to last 64 bytes boundary */
647 asm("sub %l1,56,%l1");
648
649 asm("error:");
650 asm("stda %f32,[%i3]0xf0");
651 asm("std %f48,[%i4]");
652 /* store offset value */
653 asm("st %l1,[%i1]");
654 asm("membar #Sync");
655
656 return (ret);
657 }
658
659 /*
660 * vis_test(struct fps_test_ereport *report)
661 * checks if various RISC operations are performed
662 * succesfully. If an error is found, relevant data
663 * is stored in report.
664 */
665 int
vis_test(struct fps_test_ereport * report)666 vis_test(struct fps_test_ereport *report)
667 {
668 int v1;
669 int v2;
670 int v3;
671
672 v1 = visgt16(report);
673 v2 = visne16(report);
674 v3 = vispackfix(report);
675
676 if ((0 != v1) || (0 != v2) || (0 != v3))
677 return (-1);
678
679 return (0);
680 }
681
682 /*
683 * visgt16(struct fps_test_ereport *report)
684 * does a greater-than compare instruction and returns if
685 * successful or not. If an error, relevant data is
686 * stored in report.
687 */
688 static int
visgt16(struct fps_test_ereport * report)689 visgt16(struct fps_test_ereport *report)
690 {
691 uint64_t expected;
692 uint64_t observed;
693 unsigned long a = 0x0000000000000001;
694 unsigned long b = 0x8000000008000008;
695 unsigned long c = fcmpgt16(*((double *)&a), *((double *)&b));
696
697 if (c == 0x8)
698 return (0);
699 else {
700 expected = (uint64_t)0x8;
701 observed = (*(uint64_t *)&c);
702 setup_fps_test_struct(NO_EREPORT_INFO, report,
703 6364, &observed, &expected, 1, 1);
704
705 return (-1);
706 }
707 }
708
709 /*
710 * visne16(struct fps_test_ereport *report)
711 * does a not-equal compare instruction and returns if
712 * successful or not. If an error, relevant data is
713 * stored in report.
714 */
715 static int
visne16(struct fps_test_ereport * report)716 visne16(struct fps_test_ereport *report)
717 {
718 uint64_t expected;
719 uint64_t observed;
720 unsigned long a = 0x0000000000000001;
721 unsigned long b = 0x0001000000001001;
722 unsigned long c = fcmpne16(*((double *)&a), *((double *)&b));
723
724 if (c == 0x9)
725 return (0);
726 else {
727 expected = (uint64_t)0x9;
728 observed = (*(uint64_t *)&c);
729 setup_fps_test_struct(NO_EREPORT_INFO, report,
730 6365, &observed, &expected, 1, 1);
731
732 return (-1);
733 }
734 }
735
736 /*
737 * vispackfix(struct fps_test_ereport *report)
738 * does four 16-bit pack conversions to a lower precsion
739 * format and returns if successful or not. If an error,
740 * relevant data is stored in report.
741 */
742 static int
vispackfix(struct fps_test_ereport * report)743 vispackfix(struct fps_test_ereport *report)
744 {
745 float b;
746 uint64_t expected;
747 uint64_t observed;
748 unsigned int c;
749 unsigned long a = 0x8008000008008008;
750 unsigned long gsr = 0;
751
752 (void) setgsr(gsr);
753
754 b = fpackfix(*((double *)&a));
755 c = *((unsigned int *)&b);
756
757 if (c == 0x80080800)
758 return (0);
759 else {
760 expected = (uint64_t)0x80080800;
761 observed = (uint64_t)c;
762 setup_fps_test_struct(NO_EREPORT_INFO, report,
763 6366, &observed, &expected, 1, 1);
764
765 return (-1);
766 }
767 }
768
769 #endif
770