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 2011 Nexenta Systems, Inc. All rights reserved. 24 */ 25 /* 26 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 30 #include <sys/isa_defs.h> 31 32 #ifdef _LITTLE_ENDIAN 33 #define HI(x) *(1+(int*)x) 34 #define LO(x) *(unsigned*)x 35 #else 36 #define HI(x) *(int*)x 37 #define LO(x) *(1+(unsigned*)x) 38 #endif 39 40 #ifdef __RESTRICT 41 #define restrict _Restrict 42 #else 43 #define restrict 44 #endif 45 46 extern const double __vlibm_TBL_sincos_hi[], __vlibm_TBL_sincos_lo[]; 47 extern int __vlibm_rem_pio2m( double *, double *, int, int, int ); 48 49 static const double 50 zero = 0.0, 51 one = 1.0, 52 two24 = 16777216.0, 53 pp1 = -1.666666666605760465276263943134982554676e-0001, 54 pp2 = 8.333261209690963126718376566146180944442e-0003, 55 p1 = -1.666666666666629669805215138920301589656e-0001, 56 p2 = 8.333333332390951295683993455280336376663e-0003, 57 p3 = -1.984126237997976692791551778230098403960e-0004, 58 p4 = 2.753403624854277237649987622848330351110e-0006, 59 qq1 = -4.999999999977710986407023955908711557870e-0001, 60 qq2 = 4.166654863857219350645055881018842089580e-0002, 61 q1 = -4.999999999999931701464060878888294524481e-0001, 62 q2 = 4.166666666394861917535640593963708222319e-0002, 63 q3 = -1.388888552656142867832756687736851681462e-0003, 64 q4 = 2.478519423681460796618128289454530524759e-0005; 65 66 void 67 __vlibm_vcos_bigf( int n, float * restrict x, int stridex, float * restrict y, 68 int stridey ) 69 { 70 for ( ; n--; x += stridex, y += stridey ) 71 { 72 double tx, tt[3], ty[2], t, w, z, a; 73 unsigned hx, xsb; 74 int e0, nx, j; 75 76 tx = *x; 77 hx = HI(&tx); 78 xsb = hx & 0x80000000; 79 hx &= ~0x80000000; 80 if ( hx <= 0x413921fb || hx >= 0x7ff00000 ) 81 continue; 82 e0 = ( hx >> 20 ) - 1046; 83 HI(&tx) = 0x41600000 | ( hx & 0xfffff ); 84 85 tt[0] = (double)( (int) tx ); 86 tx = ( tx - tt[0] ) * two24; 87 if ( tx != zero ) 88 { 89 nx = 2; 90 tt[1] = (double)( (int) tx ); 91 tt[2] = ( tx - tt[1] ) * two24; 92 if ( tt[2] != zero ) 93 nx = 3; 94 } 95 else 96 { 97 nx = 1; 98 tt[1] = tt[2] = zero; 99 } 100 nx = __vlibm_rem_pio2m( tt, ty, e0, nx, 2 ); 101 if ( xsb ) 102 { 103 nx = -nx; 104 ty[0] = -ty[0]; 105 ty[1] = -ty[1]; 106 } 107 nx = (nx + 1) & 3; /* Add 1 to turn sin into cos */ 108 109 /* now nx and ty[*] are the quadrant and reduced arg */ 110 xsb = ( nx & 2 ) << 30; 111 hx = HI(&ty[0]); 112 if ( nx & 1 ) 113 { 114 if ( hx & 0x80000000 ) 115 { 116 ty[0] = -ty[0]; 117 ty[1] = -ty[1]; 118 hx &= ~0x80000000; 119 } 120 if ( hx < 0x3fc40000 ) 121 { 122 z = ty[0] * ty[0]; 123 t = z * ( q1 + z * ( q2 + z * ( q3 + z * q4 ) ) ); 124 a = one + t; 125 } 126 else 127 { 128 j = ( hx + 0x4000 ) & 0x7fff8000; 129 HI(&t) = j; 130 LO(&t) = 0; 131 ty[0] = ( ty[0] - t ) + ty[1]; 132 z = ty[0] * ty[0]; 133 t = z * ( qq1 + z * qq2 ); 134 w = ty[0] * ( one + z * ( pp1 + z * pp2 ) ); 135 j = ( ( j - 0x3fc40000 ) >> 13 ) & ~3; 136 a = __vlibm_TBL_sincos_hi[j+1]; 137 t = __vlibm_TBL_sincos_lo[j+1] - ( __vlibm_TBL_sincos_hi[j] * w - a * t ); 138 a += t; 139 } 140 } 141 else 142 { 143 if ( hx & 0x80000000 ) 144 { 145 ty[0] = -ty[0]; 146 ty[1] = -ty[1]; 147 hx &= ~0x80000000; 148 xsb ^= 0x80000000; 149 } 150 if ( hx < 0x3fc90000 ) 151 { 152 z = ty[0] * ty[0]; 153 t = z * ( p1 + z * ( p2 + z * ( p3 + z * p4 ) ) ); 154 a = ty[0] + ( ty[1] + ty[0] * t ); 155 } 156 else 157 { 158 j = ( hx + 0x4000 ) & 0x7fff8000; 159 HI(&t) = j; 160 LO(&t) = 0; 161 ty[0] = ( ty[0] - t ) + ty[1]; 162 z = ty[0] * ty[0]; 163 t = z * ( qq1 + z * qq2 ); 164 w = ty[0] * ( one + z * ( pp1 + z * pp2 ) ); 165 j = ( ( j - 0x3fc40000 ) >> 13 ) & ~3; 166 a = __vlibm_TBL_sincos_hi[j]; 167 t = ( __vlibm_TBL_sincos_hi[j+1] * w + a * t ) + __vlibm_TBL_sincos_lo[j]; 168 a += t; 169 } 170 } 171 if ( xsb ) a = -a; 172 *y = a; 173 } 174 }