1 /* Function log10f vectorized with AVX2.
2 Copyright (C) 2021-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 https://www.gnu.org/licenses/. */
20 * ALGORITHM DESCRIPTION:
22 * Get short reciprocal approximation Rcp ~ 1/mantissa(x)
24 * log10(x) = k*log10(2.0) - log10(Rcp) + poly_approximation(R)
25 * log10(Rcp) is tabulated
30 /* Offsets for data table __svml_slog10_data_internal
37 #define iOffExpoMask 160
44 .section .text.avx2, "ax", @progbits
45 ENTRY(_ZGVdN8v_log10f_avx2)
47 cfi_def_cfa_offset(16)
54 /* reduction: compute r, n */
55 vmovups iBrkValue+__svml_slog10_data_internal(%rip), %ymm4
56 vmovups sPoly+__svml_slog10_data_internal(%rip), %ymm15
57 vmovups sPoly+64+__svml_slog10_data_internal(%rip), %ymm9
58 vmovups sPoly+128+__svml_slog10_data_internal(%rip), %ymm10
59 vmovups sPoly+192+__svml_slog10_data_internal(%rip), %ymm12
60 vpsubd %ymm4, %ymm0, %ymm1
61 vcmplt_oqps MinNorm+__svml_slog10_data_internal(%rip), %ymm0, %ymm5
62 vcmpnle_uqps MaxNorm+__svml_slog10_data_internal(%rip), %ymm0, %ymm6
63 vpand iOffExpoMask+__svml_slog10_data_internal(%rip), %ymm1, %ymm3
64 vpsrad $23, %ymm1, %ymm2
65 vpaddd %ymm4, %ymm3, %ymm8
66 vcvtdq2ps %ymm2, %ymm1
67 vsubps One+__svml_slog10_data_internal(%rip), %ymm8, %ymm13
68 vmulps L2L+__svml_slog10_data_internal(%rip), %ymm1, %ymm14
69 vfmadd213ps sPoly+32+__svml_slog10_data_internal(%rip), %ymm13, %ymm15
70 vfmadd213ps sPoly+96+__svml_slog10_data_internal(%rip), %ymm13, %ymm9
71 vmulps %ymm13, %ymm13, %ymm11
72 vfmadd213ps sPoly+160+__svml_slog10_data_internal(%rip), %ymm13, %ymm10
73 vfmadd213ps sPoly+224+__svml_slog10_data_internal(%rip), %ymm13, %ymm12
74 vfmadd213ps %ymm9, %ymm11, %ymm15
75 vfmadd213ps %ymm10, %ymm11, %ymm15
76 vfmadd213ps %ymm12, %ymm11, %ymm15
77 vfmadd213ps sPoly+256+__svml_slog10_data_internal(%rip), %ymm13, %ymm15
78 vfmadd213ps %ymm14, %ymm13, %ymm15
79 vorps %ymm6, %ymm5, %ymm7
81 /* combine and get argument value range mask */
83 vfmadd132ps L2H+__svml_slog10_data_internal(%rip), %ymm15, %ymm1
86 /* Go to special inputs processing branch */
87 jne L(SPECIAL_VALUES_BRANCH)
88 # LOE rbx r12 r13 r14 r15 edx ymm0 ymm1
91 * and exit the function
108 L(SPECIAL_VALUES_BRANCH):
109 vmovups %ymm0, 32(%rsp)
110 vmovups %ymm1, 64(%rsp)
111 # LOE rbx r12 r13 r14 r15 edx ymm1
114 # LOE rbx r12 r13 r14 r15 eax edx
118 /* DW_CFA_expression: r12 (r12) (DW_OP_lit8; DW_OP_minus; DW_OP_const4s: -32; DW_OP_and; DW_OP_const4s: -80; DW_OP_plus) */
119 .cfi_escape 0x10, 0x0c, 0x0e, 0x38, 0x1c, 0x0d, 0xe0, 0xff, 0xff, 0xff, 0x1a, 0x0d, 0xb0, 0xff, 0xff, 0xff, 0x22
122 /* DW_CFA_expression: r13 (r13) (DW_OP_lit8; DW_OP_minus; DW_OP_const4s: -32; DW_OP_and; DW_OP_const4s: -88; DW_OP_plus) */
123 .cfi_escape 0x10, 0x0d, 0x0e, 0x38, 0x1c, 0x0d, 0xe0, 0xff, 0xff, 0xff, 0x1a, 0x0d, 0xa8, 0xff, 0xff, 0xff, 0x22
126 /* DW_CFA_expression: r14 (r14) (DW_OP_lit8; DW_OP_minus; DW_OP_const4s: -32; DW_OP_and; DW_OP_const4s: -96; DW_OP_plus) */
127 .cfi_escape 0x10, 0x0e, 0x0e, 0x38, 0x1c, 0x0d, 0xe0, 0xff, 0xff, 0xff, 0x1a, 0x0d, 0xa0, 0xff, 0xff, 0xff, 0x22
128 # LOE rbx r15 r12d r13d
137 /* Call scalar math function */
138 jc L(SCALAR_MATH_CALL)
139 # LOE rbx r15 r12d r13d
145 L(SPECIAL_VALUES_LOOP):
149 /* Check bits in range mask */
150 jl L(RANGEMASK_CHECK)
151 # LOE rbx r15 r12d r13d
159 vmovups 64(%rsp), %ymm1
163 /* DW_CFA_expression: r12 (r12) (DW_OP_lit8; DW_OP_minus; DW_OP_const4s: -32; DW_OP_and; DW_OP_const4s: -80; DW_OP_plus) */
164 .cfi_escape 0x10, 0x0c, 0x0e, 0x38, 0x1c, 0x0d, 0xe0, 0xff, 0xff, 0xff, 0x1a, 0x0d, 0xb0, 0xff, 0xff, 0xff, 0x22
165 /* DW_CFA_expression: r13 (r13) (DW_OP_lit8; DW_OP_minus; DW_OP_const4s: -32; DW_OP_and; DW_OP_const4s: -88; DW_OP_plus) */
166 .cfi_escape 0x10, 0x0d, 0x0e, 0x38, 0x1c, 0x0d, 0xe0, 0xff, 0xff, 0xff, 0x1a, 0x0d, 0xa8, 0xff, 0xff, 0xff, 0x22
167 /* DW_CFA_expression: r14 (r14) (DW_OP_lit8; DW_OP_minus; DW_OP_const4s: -32; DW_OP_and; DW_OP_const4s: -96; DW_OP_plus) */
168 .cfi_escape 0x10, 0x0e, 0x0e, 0x38, 0x1c, 0x0d, 0xe0, 0xff, 0xff, 0xff, 0x1a, 0x0d, 0xa0, 0xff, 0xff, 0xff, 0x22
169 # LOE rbx r12 r13 r14 r15 ymm1
171 /* Scalar math fucntion call
172 * to process special input
177 movss 32(%rsp, %r14, 4), %xmm0
179 # LOE rbx r14 r15 r12d r13d xmm0
181 movss %xmm0, 64(%rsp, %r14, 4)
183 /* Process special inputs in loop */
184 jmp L(SPECIAL_VALUES_LOOP)
185 # LOE rbx r15 r12d r13d
186 END(_ZGVdN8v_log10f_avx2)
188 .section .rodata, "a"
191 #ifdef __svml_slog10_data_internal_typedef
192 typedef unsigned int VUINT32;
194 __declspec(align(32)) VUINT32 MinNorm[8][1];
195 __declspec(align(32)) VUINT32 MaxNorm[8][1];
196 __declspec(align(32)) VUINT32 L2H[8][1];
197 __declspec(align(32)) VUINT32 L2L[8][1];
198 __declspec(align(32)) VUINT32 iBrkValue[8][1];
199 __declspec(align(32)) VUINT32 iOffExpoMask[8][1];
200 __declspec(align(32)) VUINT32 One[8][1];
201 __declspec(align(32)) VUINT32 sPoly[9][8][1];
202 __declspec(align(32)) VUINT32 L2[8][1];
203 } __svml_slog10_data_internal;
205 __svml_slog10_data_internal:
207 .long 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000
210 .long 0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff, 0x7f7fffff
213 .long 0x3e9a2100, 0x3e9a2100, 0x3e9a2100, 0x3e9a2100, 0x3e9a2100, 0x3e9a2100, 0x3e9a2100, 0x3e9a2100
216 .long 0xb64AF600, 0xb64AF600, 0xb64AF600, 0xb64AF600, 0xb64AF600, 0xb64AF600, 0xb64AF600, 0xb64AF600
217 /* iBrkValue = SP 2/3 */
219 .long 0x3f2aaaab, 0x3f2aaaab, 0x3f2aaaab, 0x3f2aaaab, 0x3f2aaaab, 0x3f2aaaab, 0x3f2aaaab, 0x3f2aaaab
220 /* iOffExpoMask = SP significand mask */
222 .long 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff
225 .long 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000
228 .long 0x3d8063B4, 0x3d8063B4, 0x3d8063B4, 0x3d8063B4, 0x3d8063B4, 0x3d8063B4, 0x3d8063B4, 0x3d8063B4 /* coeff9 */
229 .long 0xbd890073, 0xbd890073, 0xbd890073, 0xbd890073, 0xbd890073, 0xbd890073, 0xbd890073, 0xbd890073 /* coeff8 */
230 .long 0x3d775317, 0x3d775317, 0x3d775317, 0x3d775317, 0x3d775317, 0x3d775317, 0x3d775317, 0x3d775317 /* coeff7 */
231 .long 0xbd91FB27, 0xbd91FB27, 0xbd91FB27, 0xbd91FB27, 0xbd91FB27, 0xbd91FB27, 0xbd91FB27, 0xbd91FB27 /* coeff6 */
232 .long 0x3dB20B96, 0x3dB20B96, 0x3dB20B96, 0x3dB20B96, 0x3dB20B96, 0x3dB20B96, 0x3dB20B96, 0x3dB20B96 /* coeff5 */
233 .long 0xbdDE6E20, 0xbdDE6E20, 0xbdDE6E20, 0xbdDE6E20, 0xbdDE6E20, 0xbdDE6E20, 0xbdDE6E20, 0xbdDE6E20 /* coeff4 */
234 .long 0x3e143CE5, 0x3e143CE5, 0x3e143CE5, 0x3e143CE5, 0x3e143CE5, 0x3e143CE5, 0x3e143CE5, 0x3e143CE5 /* coeff3 */
235 .long 0xbe5E5BC5, 0xbe5E5BC5, 0xbe5E5BC5, 0xbe5E5BC5, 0xbe5E5BC5, 0xbe5E5BC5, 0xbe5E5BC5, 0xbe5E5BC5 /* coeff2 */
236 .long 0x3eDE5BD9, 0x3eDE5BD9, 0x3eDE5BD9, 0x3eDE5BD9, 0x3eDE5BD9, 0x3eDE5BD9, 0x3eDE5BD9, 0x3eDE5BD9 /* coeff1 */
239 .long 0x3e9a209b, 0x3e9a209b, 0x3e9a209b, 0x3e9a209b, 0x3e9a209b, 0x3e9a209b, 0x3e9a209b, 0x3e9a209b
241 .type __svml_slog10_data_internal, @object
242 .size __svml_slog10_data_internal, .-__svml_slog10_data_internal