ACL exp function impelement */
| 130 | } |
| 131 | /* ACL exp function impelement */ |
| 132 | inline float32x4_t vexpq_f32(float32x4_t x) |
| 133 | { |
| 134 | static const float32x4_t CONST_LN2 = vdupq_n_f32(0.6931471805f); // ln(2) |
| 135 | static const float32x4_t CONST_INV_LN2 = vdupq_n_f32(1.4426950408f); // 1/ln(2) |
| 136 | static const float32x4_t CONST_0 = vdupq_n_f32(0.f); |
| 137 | static const int32x4_t CONST_NEGATIVE_126 = vdupq_n_s32(-126); |
| 138 | |
| 139 | // Perform range reduction [-log(2),log(2)] |
| 140 | int32x4_t m = vcvtq_s32_f32(vmulq_f32(x, CONST_INV_LN2)); |
| 141 | float32x4_t val = vmlsq_f32(x, vcvtq_f32_s32(m), CONST_LN2); |
| 142 | |
| 143 | // Polynomial Approximation |
| 144 | float32x4_t poly = vtaylor_polyq_f32(val, exp_tab); |
| 145 | |
| 146 | // Reconstruct |
| 147 | poly = vreinterpretq_f32_s32(vqaddq_s32(vreinterpretq_s32_f32(poly), vqshlq_n_s32(m, 23))); |
| 148 | poly = vbslq_f32(vcltq_s32(m, CONST_NEGATIVE_126), CONST_0, poly); |
| 149 | |
| 150 | return poly; |
| 151 | } |
| 152 | /* |
| 153 | exp(x) = lim(1+x/n)^n // n=10 |
| 154 | */ |
no test coverage detected