| @@ -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 | |
43 | static const double | | 43 | static const double |
44 | TWO52[2]={ | | 44 | TWO52[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 | |
49 | RESTYPE | | 58 | RESTYPE |
50 | LRINTNAME(double x) | | 59 | LRINTNAME(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); |