Mon Feb 27 06:49:02 2017 UTC ()
the MI lrint() code assumes that rounding is done in at most double precision
but m68k (68881) uses extended precision by default, so put the FPU in
double-precision mode temporarily here.


(chs)
diff -r1.5 -r1.6 src/lib/libm/src/lrint.c

cvs diff -r1.5 -r1.6 src/lib/libm/src/Attic/lrint.c (expand / switch to unified diff)

--- src/lib/libm/src/Attic/lrint.c 2015/07/09 06:17:13 1.5
+++ src/lib/libm/src/Attic/lrint.c 2017/02/27 06:49:02 1.6
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: lrint.c,v 1.5 2015/07/09 06:17:13 nat Exp $ */ 1/* $NetBSD: lrint.c,v 1.6 2017/02/27 06:49:02 chs Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2004 4 * Copyright (c) 2004
5 * Matthias Drochner. All rights reserved. 5 * Matthias Drochner. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -36,50 +36,71 @@ @@ -36,50 +36,71 @@
36#define RESTYPE long int 36#define RESTYPE long int
37#define RESTYPE_MIN LONG_MIN 37#define RESTYPE_MIN LONG_MIN
38#define RESTYPE_MAX LONG_MAX 38#define RESTYPE_MAX LONG_MAX
39#endif 39#endif
40 40
41#define RESTYPE_BITS (sizeof(RESTYPE) * 8) 41#define RESTYPE_BITS (sizeof(RESTYPE) * 8)
42 42
43static const double 43static const double
44TWO52[2]={ 44TWO52[2]={
45 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ 45 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
46 -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ 46 -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
47}; 47};
48 48
 49#ifdef __HAVE_68881__
 50#include <m68k/fpreg.h>
 51
 52#define get_fpcr(__fpcr) \
 53 __asm__ __volatile__ ("fmove%.l %!,%0" : "=dm" (__fpcr))
 54#define set_fpcr(__fpcr) \
 55 __asm__ __volatile__ ("fmove%.l %0,%!" : : "dm" (__fpcr))
 56#endif
 57
49RESTYPE 58RESTYPE
50LRINTNAME(double x) 59LRINTNAME(double x)
51{ 60{
52 u_int32_t i0, i1; 61 u_int32_t i0, i1;
53 int e, s, shift; 62 int e, s, shift;
54 RESTYPE res; 63 RESTYPE res;
55 64
56 GET_HIGH_WORD(i0, x); 65 GET_HIGH_WORD(i0, x);
57 e = i0 >> 20; 66 e = i0 >> 20;
58 s = (uint32_t)e >> DBL_EXPBITS; 67 s = (uint32_t)e >> DBL_EXPBITS;
59 e = (e & 0x7ff) - DBL_EXP_BIAS; 68 e = (e & 0x7ff) - DBL_EXP_BIAS;
60 69
61 /* 1.0 x 2^-1 is the smallest number which can be rounded to 1 */ 70 /* 1.0 x 2^-1 is the smallest number which can be rounded to 1 */
62 if (e < -1) 71 if (e < -1)
63 return (0); 72 return (0);
64 /* 1.0 x 2^31 (or 2^63) is already too large */ 73 /* 1.0 x 2^31 (or 2^63) is already too large */
65 if (e >= (int)RESTYPE_BITS - 1) 74 if (e >= (int)RESTYPE_BITS - 1)
66 return (s ? RESTYPE_MIN : RESTYPE_MAX); /* ??? unspecified */ 75 return (s ? RESTYPE_MIN : RESTYPE_MAX); /* ??? unspecified */
67 76
68 /* >= 2^52 is already an exact integer */ 77 /* >= 2^52 is already an exact integer */
69 if (e < DBL_FRACBITS) { 78 if (e < DBL_FRACBITS) {
70 /* round, using current direction */ 79 /* round, using current direction */
 80#ifdef __HAVE_68881__
 81 int ofpcr, nfpcr;
 82
 83 /* For m68k hardfloat, use double-precision */
 84 get_fpcr(ofpcr);
 85 nfpcr = (ofpcr & ~FPCR_PREC) | FPCR_DBL;
 86 set_fpcr(nfpcr);
 87#endif
71 x += TWO52[s]; 88 x += TWO52[s];
72 x -= TWO52[s]; 89 x -= TWO52[s];
 90#ifdef __HAVE_68881__
 91 __asm__ __volatile__ ("/* dummy %0 */" : : "f" (x));
 92 set_fpcr(ofpcr);
 93#endif
73 } else 94 } else
74 return x; 95 return x;
75 96
76 EXTRACT_WORDS(i0, i1, x); 97 EXTRACT_WORDS(i0, i1, x);
77 e = ((i0 >> 20) & 0x7ff) - DBL_EXP_BIAS; 98 e = ((i0 >> 20) & 0x7ff) - DBL_EXP_BIAS;
78 i0 &= 0xfffff; 99 i0 &= 0xfffff;
79 i0 |= (1 << 20); 100 i0 |= (1 << 20);
80 101
81 shift = e - DBL_FRACBITS; 102 shift = e - DBL_FRACBITS;
82 if (shift >=0) 103 if (shift >=0)
83 res = (shift < 32 ? (RESTYPE)i1 << shift : 0); 104 res = (shift < 32 ? (RESTYPE)i1 << shift : 0);
84 else 105 else
85 res = (shift > -32 ? i1 >> -shift : 0); 106 res = (shift > -32 ? i1 >> -shift : 0);