calculates 4 in ~1.72x speed of win libc implementation for 1, with same precision
| 266 | |
| 267 | // calculates 4 in ~1.72x speed of win libc implementation for 1, with same precision |
| 268 | VECTORCALL VECMATH_FINLINE vec4f v_atan(vec4f x) |
| 269 | { |
| 270 | vec4f signBit = v_and(x, V_CI_SIGN_MASK); |
| 271 | x = v_abs(x); |
| 272 | |
| 273 | vec4f mask1 = v_cmp_ge(x, v_splats(_ATAN_Q0)); |
| 274 | vec4f mask2 = v_andnot(mask1, v_cmp_ge(x, v_splats(_ATAN_Q1))); |
| 275 | vec4f mask3 = v_or(mask1, mask2); |
| 276 | |
| 277 | vec4f y = v_and(mask1, V_C_HALFPI); |
| 278 | y = v_or(y, v_and(mask2, V_C_PI_DIV_4)); |
| 279 | vec4f x1 = v_div(v_neg(V_C_ONE), x); |
| 280 | vec4f x2 = v_div(v_sub(x, V_C_ONE), v_add(x, V_C_ONE)); |
| 281 | x = v_andnot(mask3, x); |
| 282 | x = v_or(x, v_and(mask1, x1)); |
| 283 | x = v_or(x, v_and(mask2, x2)); |
| 284 | |
| 285 | vec4f z = v_mul(x, x); |
| 286 | vec4f tmp = v_madd(z, v_splats(_ATAN_P0), v_splats(_ATAN_P1)); |
| 287 | tmp = v_madd(tmp, z, v_splats(_ATAN_P2)); |
| 288 | tmp = v_madd(tmp, z, v_splats(_ATAN_P3)); |
| 289 | tmp = v_mul(tmp, z); |
| 290 | tmp = v_madd(tmp, x, x); |
| 291 | tmp = v_add(tmp, y); |
| 292 | |
| 293 | return v_xor(tmp, signBit); |
| 294 | } |
| 295 | |
| 296 | // approximate atan_est |error| is < 0.00045 |
| 297 | // calculates 4 in ~2.81x speed of win libc implementation for 1, with same precision |