Math from this web page: http://developer.download.nvidia.com/cg/sin.html This is ~2x slower than sin_est() or cos_est(), and less accurate, but I'm keeping it here for comparison purposes to help validate/sanity check sin_est() and cos_est().
| 284 | // Math from this web page: http://developer.download.nvidia.com/cg/sin.html |
| 285 | // This is ~2x slower than sin_est() or cos_est(), and less accurate, but I'm keeping it here for comparison purposes to help validate/sanity check sin_est() and cos_est(). |
| 286 | inline vfloat spmd_kernel::sincos_est_a(vfloat a, bool sin_flag) |
| 287 | { |
| 288 | const float c0_x = 0.0f, c0_y = 0.5f, c0_z = 1.0f; |
| 289 | const float c1_x = 0.25f, c1_y = -9.0f, c1_z = 0.75f, c1_w = 0.159154943091f; |
| 290 | const float c2_x = 24.9808039603f, c2_y = -24.9808039603f, c2_z = -60.1458091736f, c2_w = 60.1458091736f; |
| 291 | const float c3_x = 85.4537887573f, c3_y = -85.4537887573f, c3_z = -64.9393539429f, c3_w = 64.9393539429f; |
| 292 | const float c4_x = 19.7392082214f, c4_y = -19.7392082214f, c4_z = -1.0f, c4_w = 1.0f; |
| 293 | |
| 294 | vfloat r0_x, r0_y, r0_z, r1_x, r1_y, r1_z, r2_x, r2_y, r2_z; |
| 295 | |
| 296 | store_all(r1_x, sin_flag ? vfms(c1_w, a, c1_x) : c1_w * a); |
| 297 | |
| 298 | store_all(r1_y, frac(r1_x)); |
| 299 | |
| 300 | store_all(r2_x, (vfloat)(r1_y < c1_x)); |
| 301 | |
| 302 | store_all(r2_y, (vfloat)(r1_y >= c1_y)); |
| 303 | store_all(r2_z, (vfloat)(r1_y >= c1_z)); |
| 304 | |
| 305 | store_all(r2_y, vfma(r2_x, c4_z, vfma(r2_y, c4_w, r2_z * c4_z))); |
| 306 | |
| 307 | store_all(r0_x, c0_x - r1_y); |
| 308 | store_all(r0_y, c0_y - r1_y); |
| 309 | store_all(r0_z, c0_z - r1_y); |
| 310 | |
| 311 | store_all(r0_x, r0_x * r0_x); |
| 312 | store_all(r0_y, r0_y * r0_y); |
| 313 | store_all(r0_z, r0_z * r0_z); |
| 314 | |
| 315 | store_all(r1_x, vfma(c2_x, r0_x, c2_z)); |
| 316 | store_all(r1_y, vfma(c2_y, r0_y, c2_w)); |
| 317 | store_all(r1_z, vfma(c2_x, r0_z, c2_z)); |
| 318 | |
| 319 | store_all(r1_x, vfma(r1_x, r0_x, c3_x)); |
| 320 | store_all(r1_y, vfma(r1_y, r0_y, c3_y)); |
| 321 | store_all(r1_z, vfma(r1_z, r0_z, c3_x)); |
| 322 | |
| 323 | store_all(r1_x, vfma(r1_x, r0_x, c3_z)); |
| 324 | store_all(r1_y, vfma(r1_y, r0_y, c3_w)); |
| 325 | store_all(r1_z, vfma(r1_z, r0_z, c3_z)); |
| 326 | |
| 327 | store_all(r1_x, vfma(r1_x, r0_x, c4_x)); |
| 328 | store_all(r1_y, vfma(r1_y, r0_y, c4_y)); |
| 329 | store_all(r1_z, vfma(r1_z, r0_z, c4_x)); |
| 330 | |
| 331 | store_all(r1_x, vfma(r1_x, r0_x, c4_z)); |
| 332 | store_all(r1_y, vfma(r1_y, r0_y, c4_w)); |
| 333 | store_all(r1_z, vfma(r1_z, r0_z, c4_z)); |
| 334 | |
| 335 | store_all(r0_x, vfnma(r1_x, r2_x, vfnma(r1_y, r2_y, r1_z * -r2_z))); |
| 336 | |
| 337 | return r0_x; |
| 338 | } |
| 339 | |
| 340 | // positive values only |
| 341 | CPPSPMD_FORCE_INLINE vfloat spmd_kernel::recip_est1(const vfloat& q) |