1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #include "textflag.h" 6 7 // Various constants 8 DATA sincosxnan<>+0(SB)/8, $0x7ff8000000000000 9 GLOBL sincosxnan<>+0(SB), RODATA, $8 10 DATA sincosxlim<>+0(SB)/8, $0x432921fb54442d19 11 GLOBL sincosxlim<>+0(SB), RODATA, $8 12 DATA sincosxadd<>+0(SB)/8, $0xc338000000000000 13 GLOBL sincosxadd<>+0(SB), RODATA, $8 14 DATA sincosxpi2l<>+0(SB)/8, $0.108285667392191389e-31 15 GLOBL sincosxpi2l<>+0(SB), RODATA, $8 16 DATA sincosxpi2m<>+0(SB)/8, $0.612323399573676480e-16 17 GLOBL sincosxpi2m<>+0(SB), RODATA, $8 18 DATA sincosxpi2h<>+0(SB)/8, $0.157079632679489656e+01 19 GLOBL sincosxpi2h<>+0(SB), RODATA, $8 20 DATA sincosrpi2<>+0(SB)/8, $0.636619772367581341e+00 21 GLOBL sincosrpi2<>+0(SB), RODATA, $8 22 23 // Minimax polynomial approximations 24 DATA sincosc0<>+0(SB)/8, $0.100000000000000000E+01 25 GLOBL sincosc0<>+0(SB), RODATA, $8 26 DATA sincosc1<>+0(SB)/8, $-.499999999999999833E+00 27 GLOBL sincosc1<>+0(SB), RODATA, $8 28 DATA sincosc2<>+0(SB)/8, $0.416666666666625843E-01 29 GLOBL sincosc2<>+0(SB), RODATA, $8 30 DATA sincosc3<>+0(SB)/8, $-.138888888885498984E-02 31 GLOBL sincosc3<>+0(SB), RODATA, $8 32 DATA sincosc4<>+0(SB)/8, $0.248015871681607202E-04 33 GLOBL sincosc4<>+0(SB), RODATA, $8 34 DATA sincosc5<>+0(SB)/8, $-.275572911309937875E-06 35 GLOBL sincosc5<>+0(SB), RODATA, $8 36 DATA sincosc6<>+0(SB)/8, $0.208735047247632818E-08 37 GLOBL sincosc6<>+0(SB), RODATA, $8 38 DATA sincosc7<>+0(SB)/8, $-.112753632738365317E-10 39 GLOBL sincosc7<>+0(SB), RODATA, $8 40 DATA sincoss0<>+0(SB)/8, $0.100000000000000000E+01 41 GLOBL sincoss0<>+0(SB), RODATA, $8 42 DATA sincoss1<>+0(SB)/8, $-.166666666666666657E+00 43 GLOBL sincoss1<>+0(SB), RODATA, $8 44 DATA sincoss2<>+0(SB)/8, $0.833333333333309209E-02 45 GLOBL sincoss2<>+0(SB), RODATA, $8 46 DATA sincoss3<>+0(SB)/8, $-.198412698410701448E-03 47 GLOBL sincoss3<>+0(SB), RODATA, $8 48 DATA sincoss4<>+0(SB)/8, $0.275573191453906794E-05 49 GLOBL sincoss4<>+0(SB), RODATA, $8 50 DATA sincoss5<>+0(SB)/8, $-.250520918387633290E-07 51 GLOBL sincoss5<>+0(SB), RODATA, $8 52 DATA sincoss6<>+0(SB)/8, $0.160571285514715856E-09 53 GLOBL sincoss6<>+0(SB), RODATA, $8 54 DATA sincoss7<>+0(SB)/8, $-.753213484933210972E-12 55 GLOBL sincoss7<>+0(SB), RODATA, $8 56 57 // Sin returns the sine of the radian argument x. 58 // 59 // Special cases are: 60 // Sin(0) = 0 61 // Sin(Inf) = NaN 62 // Sin(NaN) = NaN 63 // The algorithm used is minimax polynomial approximation. 64 // with coefficients determined with a Remez exchange algorithm. 65 66 TEXT sinAsm(SB),NOSPLIT,$0-16 67 FMOVD x+0(FP), F0 68 //special case Sin(0) = 0 69 FMOVD $(0.0), F1 70 FCMPU F0, F1 71 BEQ sinIsZero 72 WORD $0xB3120000 //ltdbr %f0,%f0 73 BLTU L17 74 FMOVD F0, F5 75 L2: 76 MOVD $sincoss7<>+0(SB), R1 77 FMOVD 0(R1), F4 78 MOVD $sincoss6<>+0(SB), R1 79 FMOVD 0(R1), F1 80 MOVD $sincoss5<>+0(SB), R1 81 VLEG $0, 0(R1), V18 82 MOVD $sincoss4<>+0(SB), R1 83 FMOVD 0(R1), F6 84 MOVD $sincoss2<>+0(SB), R1 85 VLEG $0, 0(R1), V16 86 MOVD $sincoss3<>+0(SB), R1 87 FMOVD 0(R1), F7 88 MOVD $sincoss1<>+0(SB), R1 89 FMOVD 0(R1), F3 90 MOVD $sincoss0<>+0(SB), R1 91 FMOVD 0(R1), F2 92 WFCHDBS V2, V5, V2 93 BEQ L18 94 MOVD $sincosrpi2<>+0(SB), R1 95 FMOVD 0(R1), F3 96 MOVD $sincosxadd<>+0(SB), R1 97 FMOVD 0(R1), F2 98 WFMSDB V0, V3, V2, V3 99 FMOVD 0(R1), F6 100 FADD F3, F6 101 MOVD $sincosxpi2h<>+0(SB), R1 102 FMOVD 0(R1), F2 103 FMSUB F2, F6, F0, F0 104 MOVD $sincosxpi2m<>+0(SB), R1 105 FMOVD 0(R1), F4 106 FMADD F4, F6, F0, F0 107 MOVD $sincosxpi2l<>+0(SB), R1 108 WFMDB V0, V0, V1 109 FMOVD 0(R1), F7 110 WFMDB V1, V1, V2 111 WORD $0xB3CD0013 //lgdr %r1,%f3 112 MOVD $sincosxlim<>+0(SB), R2 113 WORD $0xA7110001 //tmll %r1,1 114 BEQ L6 115 FMOVD 0(R2), F0 116 WFCHDBS V0, V5, V0 117 BNE L14 118 MOVD $sincosc7<>+0(SB), R2 119 FMOVD 0(R2), F0 120 MOVD $sincosc6<>+0(SB), R2 121 FMOVD 0(R2), F4 122 MOVD $sincosc5<>+0(SB), R2 123 WFMADB V1, V0, V4, V0 124 FMOVD 0(R2), F6 125 MOVD $sincosc4<>+0(SB), R2 126 WFMADB V1, V0, V6, V0 127 FMOVD 0(R2), F4 128 MOVD $sincosc2<>+0(SB), R2 129 FMOVD 0(R2), F6 130 WFMADB V2, V4, V6, V4 131 MOVD $sincosc3<>+0(SB), R2 132 FMOVD 0(R2), F3 133 MOVD $sincosc1<>+0(SB), R2 134 WFMADB V2, V0, V3, V0 135 FMOVD 0(R2), F6 136 WFMADB V1, V4, V6, V4 137 WORD $0xA7110002 //tmll %r1,2 138 WFMADB V2, V0, V4, V0 139 MOVD $sincosc0<>+0(SB), R1 140 FMOVD 0(R1), F2 141 WFMADB V1, V0, V2, V0 142 BNE L15 143 FMOVD F0, ret+8(FP) 144 RET 145 146 L6: 147 FMOVD 0(R2), F4 148 WFCHDBS V4, V5, V4 149 BNE L14 150 MOVD $sincoss7<>+0(SB), R2 151 FMOVD 0(R2), F4 152 MOVD $sincoss6<>+0(SB), R2 153 FMOVD 0(R2), F3 154 MOVD $sincoss5<>+0(SB), R2 155 WFMADB V1, V4, V3, V4 156 WFMADB V6, V7, V0, V6 157 FMOVD 0(R2), F0 158 MOVD $sincoss4<>+0(SB), R2 159 FMADD F4, F1, F0, F0 160 FMOVD 0(R2), F3 161 MOVD $sincoss2<>+0(SB), R2 162 FMOVD 0(R2), F4 163 MOVD $sincoss3<>+0(SB), R2 164 WFMADB V2, V3, V4, V3 165 FMOVD 0(R2), F4 166 MOVD $sincoss1<>+0(SB), R2 167 WFMADB V2, V0, V4, V0 168 FMOVD 0(R2), F4 169 WFMADB V1, V3, V4, V3 170 FNEG F6, F4 171 WFMADB V2, V0, V3, V2 172 WFMDB V4, V1, V0 173 WORD $0xA7110002 //tmll %r1,2 174 WFMSDB V0, V2, V6, V0 175 BNE L15 176 FMOVD F0, ret+8(FP) 177 RET 178 179 L14: 180 MOVD $sincosxnan<>+0(SB), R1 181 FMOVD 0(R1), F0 182 FMOVD F0, ret+8(FP) 183 RET 184 185 L18: 186 WFMDB V0, V0, V2 187 WFMADB V2, V4, V1, V4 188 WFMDB V2, V2, V1 189 WFMADB V2, V4, V18, V4 190 WFMADB V1, V6, V16, V6 191 WFMADB V1, V4, V7, V4 192 WFMADB V2, V6, V3, V6 193 FMUL F0, F2 194 WFMADB V1, V4, V6, V4 195 FMADD F4, F2, F0, F0 196 FMOVD F0, ret+8(FP) 197 RET 198 199 L17: 200 FNEG F0, F5 201 BR L2 202 L15: 203 FNEG F0, F0 204 FMOVD F0, ret+8(FP) 205 RET 206 207 208 sinIsZero: 209 FMOVD F0, ret+8(FP) 210 RET 211 212 // Cos returns the cosine of the radian argument. 213 // 214 // Special cases are: 215 // Cos(Inf) = NaN 216 // Cos(NaN) = NaN 217 // The algorithm used is minimax polynomial approximation. 218 // with coefficients determined with a Remez exchange algorithm. 219 220 TEXT cosAsm(SB),NOSPLIT,$0-16 221 FMOVD x+0(FP), F0 222 WORD $0xB3120000 //ltdbr %f0,%f0 223 BLTU L35 224 FMOVD F0, F1 225 L21: 226 MOVD $sincosc7<>+0(SB), R1 227 FMOVD 0(R1), F4 228 MOVD $sincosc6<>+0(SB), R1 229 VLEG $0, 0(R1), V20 230 MOVD $sincosc5<>+0(SB), R1 231 VLEG $0, 0(R1), V18 232 MOVD $sincosc4<>+0(SB), R1 233 FMOVD 0(R1), F6 234 MOVD $sincosc2<>+0(SB), R1 235 VLEG $0, 0(R1), V16 236 MOVD $sincosc3<>+0(SB), R1 237 FMOVD 0(R1), F7 238 MOVD $sincosc1<>+0(SB), R1 239 FMOVD 0(R1), F5 240 MOVD $sincosrpi2<>+0(SB), R1 241 FMOVD 0(R1), F2 242 MOVD $sincosxadd<>+0(SB), R1 243 FMOVD 0(R1), F3 244 MOVD $sincoss0<>+0(SB), R1 245 WFMSDB V0, V2, V3, V2 246 FMOVD 0(R1), F3 247 WFCHDBS V3, V1, V3 248 WORD $0xB3CD0012 //lgdr %r1,%f2 249 BEQ L36 250 MOVD $sincosxadd<>+0(SB), R2 251 FMOVD 0(R2), F4 252 FADD F2, F4 253 MOVD $sincosxpi2h<>+0(SB), R2 254 FMOVD 0(R2), F2 255 WFMSDB V4, V2, V0, V2 256 MOVD $sincosxpi2m<>+0(SB), R2 257 FMOVD 0(R2), F0 258 WFMADB V4, V0, V2, V0 259 MOVD $sincosxpi2l<>+0(SB), R2 260 WFMDB V0, V0, V2 261 FMOVD 0(R2), F5 262 WFMDB V2, V2, V6 263 MOVD $sincosxlim<>+0(SB), R2 264 WORD $0xA7110001 //tmll %r1,1 265 BNE L25 266 FMOVD 0(R2), F0 267 WFCHDBS V0, V1, V0 268 BNE L33 269 MOVD $sincosc7<>+0(SB), R2 270 FMOVD 0(R2), F0 271 MOVD $sincosc6<>+0(SB), R2 272 FMOVD 0(R2), F4 273 MOVD $sincosc5<>+0(SB), R2 274 WFMADB V2, V0, V4, V0 275 FMOVD 0(R2), F1 276 MOVD $sincosc4<>+0(SB), R2 277 WFMADB V2, V0, V1, V0 278 FMOVD 0(R2), F4 279 MOVD $sincosc2<>+0(SB), R2 280 FMOVD 0(R2), F1 281 WFMADB V6, V4, V1, V4 282 MOVD $sincosc3<>+0(SB), R2 283 FMOVD 0(R2), F3 284 MOVD $sincosc1<>+0(SB), R2 285 WFMADB V6, V0, V3, V0 286 FMOVD 0(R2), F1 287 WFMADB V2, V4, V1, V4 288 WORD $0xA7110002 //tmll %r1,2 289 WFMADB V6, V0, V4, V0 290 MOVD $sincosc0<>+0(SB), R1 291 FMOVD 0(R1), F4 292 WFMADB V2, V0, V4, V0 293 BNE L34 294 FMOVD F0, ret+8(FP) 295 RET 296 297 L25: 298 FMOVD 0(R2), F3 299 WFCHDBS V3, V1, V1 300 BNE L33 301 MOVD $sincoss7<>+0(SB), R2 302 FMOVD 0(R2), F1 303 MOVD $sincoss6<>+0(SB), R2 304 FMOVD 0(R2), F3 305 MOVD $sincoss5<>+0(SB), R2 306 WFMADB V2, V1, V3, V1 307 FMOVD 0(R2), F3 308 MOVD $sincoss4<>+0(SB), R2 309 WFMADB V2, V1, V3, V1 310 FMOVD 0(R2), F3 311 MOVD $sincoss2<>+0(SB), R2 312 FMOVD 0(R2), F7 313 WFMADB V6, V3, V7, V3 314 MOVD $sincoss3<>+0(SB), R2 315 FMADD F5, F4, F0, F0 316 FMOVD 0(R2), F4 317 MOVD $sincoss1<>+0(SB), R2 318 FMADD F1, F6, F4, F4 319 FMOVD 0(R2), F1 320 FMADD F3, F2, F1, F1 321 FMUL F0, F2 322 WFMADB V6, V4, V1, V6 323 WORD $0xA7110002 //tmll %r1,2 324 FMADD F6, F2, F0, F0 325 BNE L34 326 FMOVD F0, ret+8(FP) 327 RET 328 329 L33: 330 MOVD $sincosxnan<>+0(SB), R1 331 FMOVD 0(R1), F0 332 FMOVD F0, ret+8(FP) 333 RET 334 335 L36: 336 FMUL F0, F0 337 MOVD $sincosc0<>+0(SB), R1 338 WFMDB V0, V0, V1 339 WFMADB V0, V4, V20, V4 340 WFMADB V1, V6, V16, V6 341 WFMADB V0, V4, V18, V4 342 WFMADB V0, V6, V5, V6 343 WFMADB V1, V4, V7, V4 344 FMOVD 0(R1), F2 345 WFMADB V1, V4, V6, V4 346 WFMADB V0, V4, V2, V0 347 FMOVD F0, ret+8(FP) 348 RET 349 350 L35: 351 FNEG F0, F1 352 BR L21 353 L34: 354 FNEG F0, F0 355 FMOVD F0, ret+8(FP) 356 RET 357