1 /* 2 * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/> 3 * (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com> 4 * 5 * This file is part of lsp-plugins 6 * Created on: 06 апр. 2018 г. 7 * 8 * lsp-plugins is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU Lesser General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * any later version. 12 * 13 * lsp-plugins is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public License 19 * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>. 20 */ 21 22 /* Copyright (C) 2007 Julien Pommier 23 24 This software is provided 'as-is', without any express or implied 25 warranty. In no event will the authors be held liable for any damages 26 arising from the use of this software. 27 28 Permission is granted to anyone to use this software for any purpose, 29 including commercial applications, and to alter it and redistribute it 30 freely, subject to the following restrictions: 31 32 1. The origin of this software must not be misrepresented; you must not 33 claim that you wrote the original software. If you use this software 34 in a product, an acknowledgment in the product documentation would be 35 appreciated but is not required. 36 2. Altered source versions must be plainly marked as such, and must not be 37 misrepresented as being the original software. 38 3. This notice may not be removed or altered from any source distribution. 39 40 (this is the zlib license) 41 */ 42 43 #ifndef DSP_ARCH_X86_SSE3_GRAPHICS_H_ 44 #define DSP_ARCH_X86_SSE3_GRAPHICS_H_ 45 46 #ifndef DSP_ARCH_X86_SSE3_IMPL 47 #error "This header should not be included directly" 48 #endif /* DSP_ARCH_X86_SSE3_IMPL */ 49 50 namespace sse3 51 { x64_axis_apply_log1(float * x,const float * v,float zero,float norm_x,size_t count)52 void x64_axis_apply_log1(float *x, const float *v, float zero, float norm_x, size_t count) 53 { 54 //--------------------------------------------------------------- 55 // Prepare constants 56 ARCH_X86_64_ASM 57 ( 58 __ASM_EMIT("movss %[zero], %%xmm0") 59 __ASM_EMIT("movss %[norm_x], %%xmm1") 60 __ASM_EMIT("shufps $0x00, %%xmm0, %%xmm0") // xmm0 == zero 61 __ASM_EMIT("shufps $0x00, %%xmm1, %%xmm1") // xmm1 == norm_x 62 63 __ASM_EMIT("sub $8, %[count]") 64 __ASM_EMIT("jb 2f") 65 __ASM_EMIT("movaps %%xmm0, %%xmm8") 66 __ASM_EMIT("movaps %%xmm1, %%xmm9") 67 __ASM_EMIT("movaps %%xmm2, %%xmm10") 68 69 // Do x8 blocks 70 __ASM_EMIT("1:") 71 __ASM_EMIT("movups 0x00(%[v]), %%xmm3") // xmm3 = v 72 __ASM_EMIT("movups 0x10(%[v]), %%xmm11") 73 __ASM_EMIT("andps 0x00 + %[ILOG], %%xmm3") // xmm3 = abs(v) 74 __ASM_EMIT("andps 0x00 + %[ILOG], %%xmm11") 75 __ASM_EMIT("add $0x20, %[v]") // v += 4 76 __ASM_EMIT("maxps 0x00 + %[FLOG], %%xmm3") // xmm3 = max(X_AMP, abs(v)), ignores denormalized values 77 __ASM_EMIT("maxps 0x00 + %[FLOG], %%xmm11") 78 __ASM_EMIT("mulps %%xmm0, %%xmm3") // xmm5 = max(X_AMP, abs(v)) * zero 79 __ASM_EMIT("mulps %%xmm8, %%xmm11") 80 // Step 2: parse float value 81 __ASM_EMIT("movdqa %%xmm3, %%xmm4") // xmm4 = v 82 __ASM_EMIT("movdqa %%xmm11, %%xmm12") 83 __ASM_EMIT("psrld $23, %%xmm4") // xmm4 = frac(v) 84 __ASM_EMIT("psrld $23, %%xmm12") 85 __ASM_EMIT("andps 0x10 + %[ILOG], %%xmm3") // xmm3 = mant(v) 86 __ASM_EMIT("andps 0x10 + %[ILOG], %%xmm11") 87 __ASM_EMIT("psubd 0x20 + %[ILOG], %%xmm4") // xmm4 = frac(v) - 127 88 __ASM_EMIT("psubd 0x20 + %[ILOG], %%xmm12") 89 __ASM_EMIT("orps 0x10 + %[FLOG], %%xmm3") // xmm3 = V = mant(v)+0.5 90 __ASM_EMIT("orps 0x10 + %[FLOG], %%xmm11") 91 __ASM_EMIT("cvtdq2ps %%xmm4, %%xmm4") // xmm4 = E = float(frac(v)-127) 92 __ASM_EMIT("cvtdq2ps %%xmm12, %%xmm12") 93 // Prepare logarithm approximation calculations 94 __ASM_EMIT("movaps %%xmm3, %%xmm5") // xmm5 = V 95 __ASM_EMIT("movaps %%xmm11, %%xmm13") 96 __ASM_EMIT("movaps %%xmm3, %%xmm6") // xmm6 = V 97 __ASM_EMIT("movaps %%xmm11, %%xmm14") 98 __ASM_EMIT("cmpltps 0x20 + %[FLOG], %%xmm5") // xmm5 = [ V < sqrt(1/2) ] 99 __ASM_EMIT("cmpltps 0x20 + %[FLOG], %%xmm13") 100 __ASM_EMIT("movaps 0x30 + %[FLOG], %%xmm7") // xmm7 = 1.0 101 __ASM_EMIT("movaps 0x30 + %[FLOG], %%xmm15") 102 __ASM_EMIT("andps %%xmm5, %%xmm6") // xmm6 = V * [ V < sqrt(1/2) ] 103 __ASM_EMIT("andps %%xmm13, %%xmm14") 104 __ASM_EMIT("addps %%xmm6, %%xmm3") // xmm6 = V + V * [ V < sqrt(1/2) ] 105 __ASM_EMIT("addps %%xmm14, %%xmm11") 106 __ASM_EMIT("andnps %%xmm7, %%xmm5") // xmm5 = 1.0 * [ V >= sqrt(1/2) ] 107 __ASM_EMIT("andnps %%xmm15, %%xmm13") 108 __ASM_EMIT("addps %%xmm5, %%xmm4") // xmm4 = E + 1.0 * [ V >= sqrt(1/2) ] = B 109 __ASM_EMIT("addps %%xmm13, %%xmm12") 110 __ASM_EMIT("subps %%xmm7, %%xmm3") // xmm3 = V + V * [ V < sqrt(1/2) ] - 1.0 = A 111 __ASM_EMIT("subps %%xmm15, %%xmm11") 112 // Calculate logarithmic values 113 __ASM_EMIT("movaps 0x40 + %[FLOG], %%xmm5") // xmm5 = L0 114 __ASM_EMIT("movaps 0x40 + %[FLOG], %%xmm13") 115 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = L0*A 116 __ASM_EMIT("mulps %%xmm11, %%xmm13") 117 __ASM_EMIT("addps 0x50 + %[FLOG], %%xmm5") // xmm5 = L1+L0*A 118 __ASM_EMIT("addps 0x50 + %[FLOG], %%xmm13") 119 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L1+L0*A) 120 __ASM_EMIT("mulps %%xmm11, %%xmm13") 121 __ASM_EMIT("addps 0x60 + %[FLOG], %%xmm5") // xmm5 = L2+A*(L1+L0*A) 122 __ASM_EMIT("addps 0x60 + %[FLOG], %%xmm13") 123 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L2+A*(L1+L0*A)) 124 __ASM_EMIT("mulps %%xmm11, %%xmm13") 125 __ASM_EMIT("addps 0x70 + %[FLOG], %%xmm5") // xmm5 = L3+A*L2+A*(L1+L0*A) 126 __ASM_EMIT("addps 0x70 + %[FLOG], %%xmm13") 127 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L3+A*L2+A*(L1+L0*A)) 128 __ASM_EMIT("mulps %%xmm11, %%xmm13") 129 __ASM_EMIT("addps 0x80 + %[FLOG], %%xmm5") // xmm5 = L4+A*(L3+A*L2+A*(L1+L0*A)) 130 __ASM_EMIT("addps 0x80 + %[FLOG], %%xmm13") 131 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L4+A*(L3+A*L2+A*(L1+L0*A))) 132 __ASM_EMIT("mulps %%xmm11, %%xmm13") 133 __ASM_EMIT("addps 0x90 + %[FLOG], %%xmm5") // xmm5 = L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))) 134 __ASM_EMIT("addps 0x90 + %[FLOG], %%xmm13") 135 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))) 136 __ASM_EMIT("mulps %%xmm11, %%xmm13") 137 __ASM_EMIT("addps 0xa0 + %[FLOG], %%xmm5") // xmm5 = L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))) 138 __ASM_EMIT("addps 0xa0 + %[FLOG], %%xmm13") 139 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))) 140 __ASM_EMIT("mulps %%xmm11, %%xmm13") 141 __ASM_EMIT("addps 0xb0 + %[FLOG], %%xmm5") // xmm5 = L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))) 142 __ASM_EMIT("addps 0xb0 + %[FLOG], %%xmm13") 143 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))))) 144 __ASM_EMIT("mulps %%xmm11, %%xmm13") 145 __ASM_EMIT("addps 0xc0 + %[FLOG], %%xmm5") // xmm5 = L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))))) 146 __ASM_EMIT("addps 0xc0 + %[FLOG], %%xmm13") 147 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) 148 __ASM_EMIT("mulps %%xmm11, %%xmm13") 149 __ASM_EMIT("addps 0xd0 + %[FLOG], %%xmm5") // xmm5 = A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9 150 __ASM_EMIT("addps 0xd0 + %[FLOG], %%xmm13") 151 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9) 152 __ASM_EMIT("mulps %%xmm11, %%xmm13") 153 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*A*(A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9) 154 __ASM_EMIT("mulps %%xmm11, %%xmm13") 155 __ASM_EMIT("mulps 0xe0 + %[FLOG], %%xmm4") // xmm4 = B*(LXE + LN2) 156 __ASM_EMIT("mulps 0xe0 + %[FLOG], %%xmm12") 157 __ASM_EMIT("addps %%xmm4, %%xmm5") // xmm5 = B*(LXE + LN2) + A*A*A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) 158 __ASM_EMIT("addps %%xmm12, %%xmm13") 159 __ASM_EMIT("addps %%xmm3, %%xmm5") // xmm5 = B*(LXE + LN2) + A*A*A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + A 160 __ASM_EMIT("addps %%xmm11, %%xmm13") 161 // Apply values to axes 162 __ASM_EMIT("movaps %%xmm5, %%xmm3") // xmm3 = log(abs(v*zero)), xmm5=log(abs(v*zero)) 163 __ASM_EMIT("movaps %%xmm13, %%xmm11") 164 __ASM_EMIT("movups 0x00(%[x]), %%xmm4") // xmm4 = x 165 __ASM_EMIT("movups 0x10(%[x]), %%xmm12") 166 __ASM_EMIT("mulps %%xmm1, %%xmm3") // xmm3 = log(abs(v*zero)) * norm_x 167 __ASM_EMIT("mulps %%xmm9, %%xmm11") 168 __ASM_EMIT("addps %%xmm3, %%xmm4") // xmm4 = x + log(abs(v*zero)) * norm_x 169 __ASM_EMIT("addps %%xmm11, %%xmm12") 170 __ASM_EMIT("movups %%xmm4, 0x00(%[x])") 171 __ASM_EMIT("movups %%xmm12, 0x10(%[x])") 172 __ASM_EMIT("add $0x20, %[x]") 173 __ASM_EMIT("sub $8, %[count]") 174 __ASM_EMIT("jae 1b") 175 176 __ASM_EMIT("2:") 177 __ASM_EMIT("add $4, %[count]") 178 __ASM_EMIT("jl 4f") 179 // Do x4 block 180 __ASM_EMIT("movups (%[v]), %%xmm3") // xmm3 = v 181 __ASM_EMIT("andps 0x00 + %[ILOG], %%xmm3") // xmm3 = abs(v) 182 __ASM_EMIT("add $0x10, %[v]") // v += 4 183 __ASM_EMIT("maxps 0x00 + %[FLOG], %%xmm3") // xmm3 = max(X_AMP, abs(v)), ignores denormalized values 184 __ASM_EMIT("mulps %%xmm0, %%xmm3") // xmm5 = max(X_AMP, abs(v)) * zero 185 // Step 2: parse float value 186 __ASM_EMIT("movdqa %%xmm3, %%xmm4") // xmm4 = v 187 __ASM_EMIT("psrld $23, %%xmm4") // xmm4 = frac(v) 188 __ASM_EMIT("andps 0x10 + %[ILOG], %%xmm3") // xmm3 = mant(v) 189 __ASM_EMIT("psubd 0x20 + %[ILOG], %%xmm4") // xmm4 = frac(v) - 127 190 __ASM_EMIT("orps 0x10 + %[FLOG], %%xmm3") // xmm3 = V = mant(v)+0.5 191 __ASM_EMIT("cvtdq2ps %%xmm4, %%xmm4") // xmm4 = E = float(frac(v)-127) 192 // Prepare logarithm approximation calculations 193 __ASM_EMIT("movaps %%xmm3, %%xmm5") // xmm5 = V 194 __ASM_EMIT("movaps %%xmm3, %%xmm6") // xmm6 = V 195 __ASM_EMIT("cmpltps 0x20 + %[FLOG], %%xmm5") // xmm5 = [ V < sqrt(1/2) ] 196 __ASM_EMIT("movaps 0x30 + %[FLOG], %%xmm7") // xmm7 = 1.0 197 __ASM_EMIT("andps %%xmm5, %%xmm6") // xmm6 = V * [ V < sqrt(1/2) ] 198 __ASM_EMIT("addps %%xmm6, %%xmm3") // xmm6 = V + V * [ V < sqrt(1/2) ] 199 __ASM_EMIT("andnps %%xmm7, %%xmm5") // xmm5 = 1.0 * [ V >= sqrt(1/2) ] 200 __ASM_EMIT("addps %%xmm5, %%xmm4") // xmm4 = E + 1.0 * [ V >= sqrt(1/2) ] = B 201 __ASM_EMIT("subps %%xmm7, %%xmm3") // xmm3 = V + V * [ V < sqrt(1/2) ] - 1.0 = A 202 // Calculate logarithmic values 203 __ASM_EMIT("movaps 0x40 + %[FLOG], %%xmm5") // xmm5 = L0 204 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = L0*A 205 __ASM_EMIT("addps 0x50 + %[FLOG], %%xmm5") // xmm5 = L1+L0*A 206 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L1+L0*A) 207 __ASM_EMIT("addps 0x60 + %[FLOG], %%xmm5") // xmm5 = L2+A*(L1+L0*A) 208 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L2+A*(L1+L0*A)) 209 __ASM_EMIT("addps 0x70 + %[FLOG], %%xmm5") // xmm5 = L3+A*L2+A*(L1+L0*A) 210 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L3+A*L2+A*(L1+L0*A)) 211 __ASM_EMIT("addps 0x80 + %[FLOG], %%xmm5") // xmm5 = L4+A*(L3+A*L2+A*(L1+L0*A)) 212 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L4+A*(L3+A*L2+A*(L1+L0*A))) 213 __ASM_EMIT("addps 0x90 + %[FLOG], %%xmm5") // xmm5 = L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))) 214 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))) 215 __ASM_EMIT("addps 0xa0 + %[FLOG], %%xmm5") // xmm5 = L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))) 216 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))) 217 __ASM_EMIT("addps 0xb0 + %[FLOG], %%xmm5") // xmm5 = L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))) 218 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))))) 219 __ASM_EMIT("addps 0xc0 + %[FLOG], %%xmm5") // xmm5 = L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))))) 220 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) 221 __ASM_EMIT("addps 0xd0 + %[FLOG], %%xmm5") // xmm5 = A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9 222 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9) 223 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*A*(A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9) 224 __ASM_EMIT("mulps 0xe0 + %[FLOG], %%xmm4") // xmm4 = B*(LXE + LN2) 225 __ASM_EMIT("addps %%xmm4, %%xmm5") // xmm5 = B*(LXE + LN2) + A*A*A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) 226 __ASM_EMIT("addps %%xmm3, %%xmm5") // xmm5 = B*(LXE + LN2) + A*A*A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + A 227 // Apply values to axes 228 __ASM_EMIT("movaps %%xmm5, %%xmm3") // xmm3 = log(abs(v*zero)), xmm5=log(abs(v*zero)) 229 __ASM_EMIT("movups (%[x]), %%xmm4") // xmm4 = x 230 __ASM_EMIT("mulps %%xmm1, %%xmm3") // xmm3 = log(abs(v*zero)) * norm_x 231 __ASM_EMIT("addps %%xmm3, %%xmm4") // xmm4 = x + log(abs(v*zero)) * norm_x 232 __ASM_EMIT("movups %%xmm4, (%[x])") 233 __ASM_EMIT("add $0x10, %[x]") 234 __ASM_EMIT("sub $4, %[count]") 235 236 __ASM_EMIT("4:") 237 __ASM_EMIT("add $3, %[count]") 238 __ASM_EMIT("jl 6f") 239 // Do x1 blocks 240 __ASM_EMIT("5:") 241 __ASM_EMIT("movss (%[v]), %%xmm3") // xmm3 = v 242 __ASM_EMIT("andps 0x00 + %[ILOG], %%xmm3") // xmm3 = abs(v) 243 __ASM_EMIT("add $0x04, %[v]") // v += 4 244 __ASM_EMIT("maxps 0x00 + %[FLOG], %%xmm3") // xmm3 = max(X_AMP, abs(v)), ignores denormalized values 245 __ASM_EMIT("mulps %%xmm0, %%xmm3") // xmm5 = max(X_AMP, abs(v)) * zero 246 // Step 2: parse float value 247 __ASM_EMIT("movdqa %%xmm3, %%xmm4") // xmm4 = v 248 __ASM_EMIT("psrld $23, %%xmm4") // xmm4 = frac(v) 249 __ASM_EMIT("andps 0x10 + %[ILOG], %%xmm3") // xmm3 = mant(v) 250 __ASM_EMIT("psubd 0x20 + %[ILOG], %%xmm4") // xmm4 = frac(v) - 127 251 __ASM_EMIT("orps 0x10 + %[FLOG], %%xmm3") // xmm3 = V = mant(v)+0.5 252 __ASM_EMIT("cvtdq2ps %%xmm4, %%xmm4") // xmm4 = E = float(frac(v)-127) 253 // Prepare logarithm approximation calculations 254 __ASM_EMIT("movaps %%xmm3, %%xmm5") // xmm5 = V 255 __ASM_EMIT("movaps %%xmm3, %%xmm6") // xmm6 = V 256 __ASM_EMIT("cmpltps 0x20 + %[FLOG], %%xmm5") // xmm5 = [ V < sqrt(1/2) ] 257 __ASM_EMIT("movaps 0x30 + %[FLOG], %%xmm7") // xmm7 = 1.0 258 __ASM_EMIT("andps %%xmm5, %%xmm6") // xmm6 = V * [ V < sqrt(1/2) ] 259 __ASM_EMIT("addps %%xmm6, %%xmm3") // xmm6 = V + V * [ V < sqrt(1/2) ] 260 __ASM_EMIT("andnps %%xmm7, %%xmm5") // xmm5 = 1.0 * [ V >= sqrt(1/2) ] 261 __ASM_EMIT("addps %%xmm5, %%xmm4") // xmm4 = E + 1.0 * [ V >= sqrt(1/2) ] = B 262 __ASM_EMIT("subps %%xmm7, %%xmm3") // xmm3 = V + V * [ V < sqrt(1/2) ] - 1.0 = A 263 // Calculate logarithmic values 264 __ASM_EMIT("movaps 0x40 + %[FLOG], %%xmm5") // xmm5 = L0 265 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = L0*A 266 __ASM_EMIT("addss 0x50 + %[FLOG], %%xmm5") // xmm5 = L1+L0*A 267 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(L1+L0*A) 268 __ASM_EMIT("addss 0x60 + %[FLOG], %%xmm5") // xmm5 = L2+A*(L1+L0*A) 269 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(L2+A*(L1+L0*A)) 270 __ASM_EMIT("addss 0x70 + %[FLOG], %%xmm5") // xmm5 = L3+A*L2+A*(L1+L0*A) 271 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(L3+A*L2+A*(L1+L0*A)) 272 __ASM_EMIT("addss 0x80 + %[FLOG], %%xmm5") // xmm5 = L4+A*(L3+A*L2+A*(L1+L0*A)) 273 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(L4+A*(L3+A*L2+A*(L1+L0*A))) 274 __ASM_EMIT("addss 0x90 + %[FLOG], %%xmm5") // xmm5 = L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))) 275 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))) 276 __ASM_EMIT("addss 0xa0 + %[FLOG], %%xmm5") // xmm5 = L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))) 277 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))) 278 __ASM_EMIT("addss 0xb0 + %[FLOG], %%xmm5") // xmm5 = L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))) 279 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))))) 280 __ASM_EMIT("addss 0xc0 + %[FLOG], %%xmm5") // xmm5 = L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))))) 281 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) 282 __ASM_EMIT("addss 0xd0 + %[FLOG], %%xmm5") // xmm5 = A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9 283 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9) 284 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*A*(A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9) 285 __ASM_EMIT("mulss 0xe0 + %[FLOG], %%xmm4") // xmm4 = B*(LXE + LN2) 286 __ASM_EMIT("addss %%xmm4, %%xmm5") // xmm5 = B*(LXE + LN2) + A*A*A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) 287 __ASM_EMIT("addss %%xmm3, %%xmm5") // xmm5 = B*(LXE + LN2) + A*A*A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + A 288 // Apply values to axes 289 __ASM_EMIT("movaps %%xmm5, %%xmm3") // xmm3 = log(abs(v*zero)), xmm5=log(abs(v*zero)) 290 __ASM_EMIT("movss (%[x]), %%xmm4") // xmm4 = x 291 __ASM_EMIT("mulps %%xmm1, %%xmm3") // xmm3 = log(abs(v*zero)) * norm_x 292 __ASM_EMIT("addps %%xmm3, %%xmm4") // xmm4 = x + log(abs(v*zero)) * norm_x 293 __ASM_EMIT("movss %%xmm4, (%[x])") 294 __ASM_EMIT("add $0x04, %[x]") 295 __ASM_EMIT("dec %[count]") 296 __ASM_EMIT("jge 5b") 297 298 __ASM_EMIT("6:") 299 : [v] "+r" (v), [x] "+r" (x) , 300 [count] "+r" (count) 301 : [zero] "m" (zero), [norm_x] "m" (norm_x), 302 [ILOG] "o" (LOG_IARGS), [FLOG] "o" (LOG_FARGS) 303 : 304 "%xmm0", "%xmm1", "%xmm2", "%xmm3", 305 "%xmm4", "%xmm5", "%xmm6", "%xmm7", 306 "%xmm8", "%xmm9", "%xmm10", "%xmm11", 307 "%xmm12", "%xmm13", "%xmm14", "%xmm15" 308 ); 309 } 310 x64_axis_apply_log2(float * x,float * y,const float * v,float zero,float norm_x,float norm_y,size_t count)311 void x64_axis_apply_log2(float *x, float *y, const float *v, float zero, float norm_x, float norm_y, size_t count) 312 { 313 //--------------------------------------------------------------- 314 // Prepare constants 315 ARCH_X86_64_ASM 316 ( 317 __ASM_EMIT("movss %[zero], %%xmm0") 318 __ASM_EMIT("movss %[norm_x], %%xmm1") 319 __ASM_EMIT("movss %[norm_y], %%xmm2") 320 __ASM_EMIT("shufps $0x00, %%xmm0, %%xmm0") // xmm0 == zero 321 __ASM_EMIT("shufps $0x00, %%xmm1, %%xmm1") // xmm1 == norm_x 322 __ASM_EMIT("shufps $0x00, %%xmm2, %%xmm2") // xmm2 == norm_y 323 324 __ASM_EMIT("sub $8, %[count]") 325 __ASM_EMIT("jb 2f") 326 __ASM_EMIT("movaps %%xmm0, %%xmm8") 327 __ASM_EMIT("movaps %%xmm1, %%xmm9") 328 __ASM_EMIT("movaps %%xmm2, %%xmm10") 329 330 // Do x8 blocks 331 __ASM_EMIT("1:") 332 __ASM_EMIT("movups 0x00(%[v]), %%xmm3") // xmm3 = v 333 __ASM_EMIT("movups 0x10(%[v]), %%xmm11") 334 __ASM_EMIT("andps 0x00 + %[ILOG], %%xmm3") // xmm3 = abs(v) 335 __ASM_EMIT("andps 0x00 + %[ILOG], %%xmm11") 336 __ASM_EMIT("add $0x20, %[v]") // v += 4 337 __ASM_EMIT("maxps 0x00 + %[FLOG], %%xmm3") // xmm3 = max(X_AMP, abs(v)), ignores denormalized values 338 __ASM_EMIT("maxps 0x00 + %[FLOG], %%xmm11") 339 __ASM_EMIT("mulps %%xmm0, %%xmm3") // xmm5 = max(X_AMP, abs(v)) * zero 340 __ASM_EMIT("mulps %%xmm8, %%xmm11") 341 // Step 2: parse float value 342 __ASM_EMIT("movdqa %%xmm3, %%xmm4") // xmm4 = v 343 __ASM_EMIT("movdqa %%xmm11, %%xmm12") 344 __ASM_EMIT("psrld $23, %%xmm4") // xmm4 = frac(v) 345 __ASM_EMIT("psrld $23, %%xmm12") 346 __ASM_EMIT("andps 0x10 + %[ILOG], %%xmm3") // xmm3 = mant(v) 347 __ASM_EMIT("andps 0x10 + %[ILOG], %%xmm11") 348 __ASM_EMIT("psubd 0x20 + %[ILOG], %%xmm4") // xmm4 = frac(v) - 127 349 __ASM_EMIT("psubd 0x20 + %[ILOG], %%xmm12") 350 __ASM_EMIT("orps 0x10 + %[FLOG], %%xmm3") // xmm3 = V = mant(v)+0.5 351 __ASM_EMIT("orps 0x10 + %[FLOG], %%xmm11") 352 __ASM_EMIT("cvtdq2ps %%xmm4, %%xmm4") // xmm4 = E = float(frac(v)-127) 353 __ASM_EMIT("cvtdq2ps %%xmm12, %%xmm12") 354 // Prepare logarithm approximation calculations 355 __ASM_EMIT("movaps %%xmm3, %%xmm5") // xmm5 = V 356 __ASM_EMIT("movaps %%xmm11, %%xmm13") 357 __ASM_EMIT("movaps %%xmm3, %%xmm6") // xmm6 = V 358 __ASM_EMIT("movaps %%xmm11, %%xmm14") 359 __ASM_EMIT("cmpltps 0x20 + %[FLOG], %%xmm5") // xmm5 = [ V < sqrt(1/2) ] 360 __ASM_EMIT("cmpltps 0x20 + %[FLOG], %%xmm13") 361 __ASM_EMIT("movaps 0x30 + %[FLOG], %%xmm7") // xmm7 = 1.0 362 __ASM_EMIT("movaps 0x30 + %[FLOG], %%xmm15") 363 __ASM_EMIT("andps %%xmm5, %%xmm6") // xmm6 = V * [ V < sqrt(1/2) ] 364 __ASM_EMIT("andps %%xmm13, %%xmm14") 365 __ASM_EMIT("addps %%xmm6, %%xmm3") // xmm6 = V + V * [ V < sqrt(1/2) ] 366 __ASM_EMIT("addps %%xmm14, %%xmm11") 367 __ASM_EMIT("andnps %%xmm7, %%xmm5") // xmm5 = 1.0 * [ V >= sqrt(1/2) ] 368 __ASM_EMIT("andnps %%xmm15, %%xmm13") 369 __ASM_EMIT("addps %%xmm5, %%xmm4") // xmm4 = E + 1.0 * [ V >= sqrt(1/2) ] = B 370 __ASM_EMIT("addps %%xmm13, %%xmm12") 371 __ASM_EMIT("subps %%xmm7, %%xmm3") // xmm3 = V + V * [ V < sqrt(1/2) ] - 1.0 = A 372 __ASM_EMIT("subps %%xmm15, %%xmm11") 373 // Calculate logarithmic values 374 __ASM_EMIT("movaps 0x40 + %[FLOG], %%xmm5") // xmm5 = L0 375 __ASM_EMIT("movaps 0x40 + %[FLOG], %%xmm13") 376 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = L0*A 377 __ASM_EMIT("mulps %%xmm11, %%xmm13") 378 __ASM_EMIT("addps 0x50 + %[FLOG], %%xmm5") // xmm5 = L1+L0*A 379 __ASM_EMIT("addps 0x50 + %[FLOG], %%xmm13") 380 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L1+L0*A) 381 __ASM_EMIT("mulps %%xmm11, %%xmm13") 382 __ASM_EMIT("addps 0x60 + %[FLOG], %%xmm5") // xmm5 = L2+A*(L1+L0*A) 383 __ASM_EMIT("addps 0x60 + %[FLOG], %%xmm13") 384 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L2+A*(L1+L0*A)) 385 __ASM_EMIT("mulps %%xmm11, %%xmm13") 386 __ASM_EMIT("addps 0x70 + %[FLOG], %%xmm5") // xmm5 = L3+A*L2+A*(L1+L0*A) 387 __ASM_EMIT("addps 0x70 + %[FLOG], %%xmm13") 388 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L3+A*L2+A*(L1+L0*A)) 389 __ASM_EMIT("mulps %%xmm11, %%xmm13") 390 __ASM_EMIT("addps 0x80 + %[FLOG], %%xmm5") // xmm5 = L4+A*(L3+A*L2+A*(L1+L0*A)) 391 __ASM_EMIT("addps 0x80 + %[FLOG], %%xmm13") 392 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L4+A*(L3+A*L2+A*(L1+L0*A))) 393 __ASM_EMIT("mulps %%xmm11, %%xmm13") 394 __ASM_EMIT("addps 0x90 + %[FLOG], %%xmm5") // xmm5 = L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))) 395 __ASM_EMIT("addps 0x90 + %[FLOG], %%xmm13") 396 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))) 397 __ASM_EMIT("mulps %%xmm11, %%xmm13") 398 __ASM_EMIT("addps 0xa0 + %[FLOG], %%xmm5") // xmm5 = L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))) 399 __ASM_EMIT("addps 0xa0 + %[FLOG], %%xmm13") 400 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))) 401 __ASM_EMIT("mulps %%xmm11, %%xmm13") 402 __ASM_EMIT("addps 0xb0 + %[FLOG], %%xmm5") // xmm5 = L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))) 403 __ASM_EMIT("addps 0xb0 + %[FLOG], %%xmm13") 404 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))))) 405 __ASM_EMIT("mulps %%xmm11, %%xmm13") 406 __ASM_EMIT("addps 0xc0 + %[FLOG], %%xmm5") // xmm5 = L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))))) 407 __ASM_EMIT("addps 0xc0 + %[FLOG], %%xmm13") 408 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) 409 __ASM_EMIT("mulps %%xmm11, %%xmm13") 410 __ASM_EMIT("addps 0xd0 + %[FLOG], %%xmm5") // xmm5 = A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9 411 __ASM_EMIT("addps 0xd0 + %[FLOG], %%xmm13") 412 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9) 413 __ASM_EMIT("mulps %%xmm11, %%xmm13") 414 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*A*(A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9) 415 __ASM_EMIT("mulps %%xmm11, %%xmm13") 416 __ASM_EMIT("mulps 0xe0 + %[FLOG], %%xmm4") // xmm4 = B*(LXE + LN2) 417 __ASM_EMIT("mulps 0xe0 + %[FLOG], %%xmm12") 418 __ASM_EMIT("addps %%xmm4, %%xmm5") // xmm5 = B*(LXE + LN2) + A*A*A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) 419 __ASM_EMIT("addps %%xmm12, %%xmm13") 420 __ASM_EMIT("addps %%xmm3, %%xmm5") // xmm5 = B*(LXE + LN2) + A*A*A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + A 421 __ASM_EMIT("addps %%xmm11, %%xmm13") 422 // Apply values to axes 423 __ASM_EMIT("movaps %%xmm5, %%xmm3") // xmm3 = log(abs(v*zero)), xmm5=log(abs(v*zero)) 424 __ASM_EMIT("movaps %%xmm13, %%xmm11") 425 __ASM_EMIT("movups 0x00(%[x]), %%xmm4") // xmm4 = x 426 __ASM_EMIT("movups 0x10(%[x]), %%xmm12") 427 __ASM_EMIT("movups 0x00(%[y]), %%xmm6") // xmm6 = y 428 __ASM_EMIT("movups 0x10(%[y]), %%xmm14") 429 __ASM_EMIT("mulps %%xmm1, %%xmm3") // xmm3 = log(abs(v*zero)) * norm_x 430 __ASM_EMIT("mulps %%xmm9, %%xmm11") 431 __ASM_EMIT("mulps %%xmm2, %%xmm5") // xmm5 = log(abs(v*zero)) * norm_y 432 __ASM_EMIT("mulps %%xmm10, %%xmm13") 433 __ASM_EMIT("addps %%xmm3, %%xmm4") // xmm4 = x + log(abs(v*zero)) * norm_x 434 __ASM_EMIT("addps %%xmm11, %%xmm12") 435 __ASM_EMIT("addps %%xmm5, %%xmm6") // xmm6 = y + log(abs(v*zero)) * norm_y 436 __ASM_EMIT("addps %%xmm13, %%xmm14") 437 __ASM_EMIT("movups %%xmm4, 0x00(%[x])") 438 __ASM_EMIT("movups %%xmm12, 0x10(%[x])") 439 __ASM_EMIT("movups %%xmm6, 0x00(%[y])") 440 __ASM_EMIT("movups %%xmm14, 0x10(%[y])") 441 __ASM_EMIT("add $0x20, %[x]") 442 __ASM_EMIT("add $0x20, %[y]") 443 __ASM_EMIT("sub $8, %[count]") 444 __ASM_EMIT("jae 1b") 445 446 __ASM_EMIT("2:") 447 __ASM_EMIT("add $4, %[count]") 448 __ASM_EMIT("jl 4f") 449 // Do x4 block 450 __ASM_EMIT("movups (%[v]), %%xmm3") // xmm3 = v 451 __ASM_EMIT("andps 0x00 + %[ILOG], %%xmm3") // xmm3 = abs(v) 452 __ASM_EMIT("add $0x10, %[v]") // v += 4 453 __ASM_EMIT("maxps 0x00 + %[FLOG], %%xmm3") // xmm3 = max(X_AMP, abs(v)), ignores denormalized values 454 __ASM_EMIT("mulps %%xmm0, %%xmm3") // xmm5 = max(X_AMP, abs(v)) * zero 455 // Step 2: parse float value 456 __ASM_EMIT("movdqa %%xmm3, %%xmm4") // xmm4 = v 457 __ASM_EMIT("psrld $23, %%xmm4") // xmm4 = frac(v) 458 __ASM_EMIT("andps 0x10 + %[ILOG], %%xmm3") // xmm3 = mant(v) 459 __ASM_EMIT("psubd 0x20 + %[ILOG], %%xmm4") // xmm4 = frac(v) - 127 460 __ASM_EMIT("orps 0x10 + %[FLOG], %%xmm3") // xmm3 = V = mant(v)+0.5 461 __ASM_EMIT("cvtdq2ps %%xmm4, %%xmm4") // xmm4 = E = float(frac(v)-127) 462 // Prepare logarithm approximation calculations 463 __ASM_EMIT("movaps %%xmm3, %%xmm5") // xmm5 = V 464 __ASM_EMIT("movaps %%xmm3, %%xmm6") // xmm6 = V 465 __ASM_EMIT("cmpltps 0x20 + %[FLOG], %%xmm5") // xmm5 = [ V < sqrt(1/2) ] 466 __ASM_EMIT("movaps 0x30 + %[FLOG], %%xmm7") // xmm7 = 1.0 467 __ASM_EMIT("andps %%xmm5, %%xmm6") // xmm6 = V * [ V < sqrt(1/2) ] 468 __ASM_EMIT("addps %%xmm6, %%xmm3") // xmm6 = V + V * [ V < sqrt(1/2) ] 469 __ASM_EMIT("andnps %%xmm7, %%xmm5") // xmm5 = 1.0 * [ V >= sqrt(1/2) ] 470 __ASM_EMIT("addps %%xmm5, %%xmm4") // xmm4 = E + 1.0 * [ V >= sqrt(1/2) ] = B 471 __ASM_EMIT("subps %%xmm7, %%xmm3") // xmm3 = V + V * [ V < sqrt(1/2) ] - 1.0 = A 472 // Calculate logarithmic values 473 __ASM_EMIT("movaps 0x40 + %[FLOG], %%xmm5") // xmm5 = L0 474 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = L0*A 475 __ASM_EMIT("addps 0x50 + %[FLOG], %%xmm5") // xmm5 = L1+L0*A 476 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L1+L0*A) 477 __ASM_EMIT("addps 0x60 + %[FLOG], %%xmm5") // xmm5 = L2+A*(L1+L0*A) 478 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L2+A*(L1+L0*A)) 479 __ASM_EMIT("addps 0x70 + %[FLOG], %%xmm5") // xmm5 = L3+A*L2+A*(L1+L0*A) 480 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L3+A*L2+A*(L1+L0*A)) 481 __ASM_EMIT("addps 0x80 + %[FLOG], %%xmm5") // xmm5 = L4+A*(L3+A*L2+A*(L1+L0*A)) 482 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L4+A*(L3+A*L2+A*(L1+L0*A))) 483 __ASM_EMIT("addps 0x90 + %[FLOG], %%xmm5") // xmm5 = L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))) 484 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))) 485 __ASM_EMIT("addps 0xa0 + %[FLOG], %%xmm5") // xmm5 = L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))) 486 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))) 487 __ASM_EMIT("addps 0xb0 + %[FLOG], %%xmm5") // xmm5 = L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))) 488 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))))) 489 __ASM_EMIT("addps 0xc0 + %[FLOG], %%xmm5") // xmm5 = L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))))) 490 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) 491 __ASM_EMIT("addps 0xd0 + %[FLOG], %%xmm5") // xmm5 = A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9 492 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*(A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9) 493 __ASM_EMIT("mulps %%xmm3, %%xmm5") // xmm5 = A*A*(A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9) 494 __ASM_EMIT("mulps 0xe0 + %[FLOG], %%xmm4") // xmm4 = B*(LXE + LN2) 495 __ASM_EMIT("addps %%xmm4, %%xmm5") // xmm5 = B*(LXE + LN2) + A*A*A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) 496 __ASM_EMIT("addps %%xmm3, %%xmm5") // xmm5 = B*(LXE + LN2) + A*A*A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + A 497 // Apply values to axes 498 __ASM_EMIT("movaps %%xmm5, %%xmm3") // xmm3 = log(abs(v*zero)), xmm5=log(abs(v*zero)) 499 __ASM_EMIT("movups (%[x]), %%xmm4") // xmm4 = x 500 __ASM_EMIT("movups (%[y]), %%xmm6") // xmm6 = y 501 __ASM_EMIT("mulps %%xmm1, %%xmm3") // xmm3 = log(abs(v*zero)) * norm_x 502 __ASM_EMIT("mulps %%xmm2, %%xmm5") // xmm5 = log(abs(v*zero)) * norm_y 503 __ASM_EMIT("addps %%xmm3, %%xmm4") // xmm4 = x + log(abs(v*zero)) * norm_x 504 __ASM_EMIT("addps %%xmm5, %%xmm6") // xmm6 = y + log(abs(v*zero)) * norm_y 505 __ASM_EMIT("movups %%xmm4, (%[x])") 506 __ASM_EMIT("movups %%xmm6, (%[y])") 507 __ASM_EMIT("add $0x10, %[x]") 508 __ASM_EMIT("add $0x10, %[y]") 509 __ASM_EMIT("sub $4, %[count]") 510 511 __ASM_EMIT("4:") 512 __ASM_EMIT("add $3, %[count]") 513 __ASM_EMIT("jl 6f") 514 // Do x1 blocks 515 __ASM_EMIT("5:") 516 __ASM_EMIT("movss (%[v]), %%xmm3") // xmm3 = v 517 __ASM_EMIT("andps 0x00 + %[ILOG], %%xmm3") // xmm3 = abs(v) 518 __ASM_EMIT("add $0x04, %[v]") // v += 4 519 __ASM_EMIT("maxps 0x00 + %[FLOG], %%xmm3") // xmm3 = max(X_AMP, abs(v)), ignores denormalized values 520 __ASM_EMIT("mulps %%xmm0, %%xmm3") // xmm5 = max(X_AMP, abs(v)) * zero 521 // Step 2: parse float value 522 __ASM_EMIT("movdqa %%xmm3, %%xmm4") // xmm4 = v 523 __ASM_EMIT("psrld $23, %%xmm4") // xmm4 = frac(v) 524 __ASM_EMIT("andps 0x10 + %[ILOG], %%xmm3") // xmm3 = mant(v) 525 __ASM_EMIT("psubd 0x20 + %[ILOG], %%xmm4") // xmm4 = frac(v) - 127 526 __ASM_EMIT("orps 0x10 + %[FLOG], %%xmm3") // xmm3 = V = mant(v)+0.5 527 __ASM_EMIT("cvtdq2ps %%xmm4, %%xmm4") // xmm4 = E = float(frac(v)-127) 528 // Prepare logarithm approximation calculations 529 __ASM_EMIT("movaps %%xmm3, %%xmm5") // xmm5 = V 530 __ASM_EMIT("movaps %%xmm3, %%xmm6") // xmm6 = V 531 __ASM_EMIT("cmpltps 0x20 + %[FLOG], %%xmm5") // xmm5 = [ V < sqrt(1/2) ] 532 __ASM_EMIT("movaps 0x30 + %[FLOG], %%xmm7") // xmm7 = 1.0 533 __ASM_EMIT("andps %%xmm5, %%xmm6") // xmm6 = V * [ V < sqrt(1/2) ] 534 __ASM_EMIT("addps %%xmm6, %%xmm3") // xmm6 = V + V * [ V < sqrt(1/2) ] 535 __ASM_EMIT("andnps %%xmm7, %%xmm5") // xmm5 = 1.0 * [ V >= sqrt(1/2) ] 536 __ASM_EMIT("addps %%xmm5, %%xmm4") // xmm4 = E + 1.0 * [ V >= sqrt(1/2) ] = B 537 __ASM_EMIT("subps %%xmm7, %%xmm3") // xmm3 = V + V * [ V < sqrt(1/2) ] - 1.0 = A 538 // Calculate logarithmic values 539 __ASM_EMIT("movaps 0x40 + %[FLOG], %%xmm5") // xmm5 = L0 540 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = L0*A 541 __ASM_EMIT("addss 0x50 + %[FLOG], %%xmm5") // xmm5 = L1+L0*A 542 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(L1+L0*A) 543 __ASM_EMIT("addss 0x60 + %[FLOG], %%xmm5") // xmm5 = L2+A*(L1+L0*A) 544 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(L2+A*(L1+L0*A)) 545 __ASM_EMIT("addss 0x70 + %[FLOG], %%xmm5") // xmm5 = L3+A*L2+A*(L1+L0*A) 546 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(L3+A*L2+A*(L1+L0*A)) 547 __ASM_EMIT("addss 0x80 + %[FLOG], %%xmm5") // xmm5 = L4+A*(L3+A*L2+A*(L1+L0*A)) 548 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(L4+A*(L3+A*L2+A*(L1+L0*A))) 549 __ASM_EMIT("addss 0x90 + %[FLOG], %%xmm5") // xmm5 = L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))) 550 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))) 551 __ASM_EMIT("addss 0xa0 + %[FLOG], %%xmm5") // xmm5 = L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))) 552 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))) 553 __ASM_EMIT("addss 0xb0 + %[FLOG], %%xmm5") // xmm5 = L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))) 554 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))))) 555 __ASM_EMIT("addss 0xc0 + %[FLOG], %%xmm5") // xmm5 = L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A)))))) 556 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) 557 __ASM_EMIT("addss 0xd0 + %[FLOG], %%xmm5") // xmm5 = A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9 558 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*(A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9) 559 __ASM_EMIT("mulss %%xmm3, %%xmm5") // xmm5 = A*A*(A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + L9) 560 __ASM_EMIT("mulss 0xe0 + %[FLOG], %%xmm4") // xmm4 = B*(LXE + LN2) 561 __ASM_EMIT("addss %%xmm4, %%xmm5") // xmm5 = B*(LXE + LN2) + A*A*A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) 562 __ASM_EMIT("addss %%xmm3, %%xmm5") // xmm5 = B*(LXE + LN2) + A*A*A*(L8+A*(L7+A*(L6+A*(L5+A*(L4+A*(L3+A*L2+A*(L1+L0*A))))))) + A 563 // Apply values to axes 564 __ASM_EMIT("movaps %%xmm5, %%xmm3") // xmm3 = log(abs(v*zero)), xmm5=log(abs(v*zero)) 565 __ASM_EMIT("movss (%[x]), %%xmm4") // xmm4 = x 566 __ASM_EMIT("movss (%[y]), %%xmm6") // xmm6 = y 567 __ASM_EMIT("mulps %%xmm1, %%xmm3") // xmm3 = log(abs(v*zero)) * norm_x 568 __ASM_EMIT("mulps %%xmm2, %%xmm5") // xmm5 = log(abs(v*zero)) * norm_y 569 __ASM_EMIT("addps %%xmm3, %%xmm4") // xmm4 = x + log(abs(v*zero)) * norm_x 570 __ASM_EMIT("addps %%xmm5, %%xmm6") // xmm6 = y + log(abs(v*zero)) * norm_y 571 __ASM_EMIT("movss %%xmm4, (%[x])") 572 __ASM_EMIT("movss %%xmm6, (%[y])") 573 __ASM_EMIT("add $0x04, %[x]") 574 __ASM_EMIT("add $0x04, %[y]") 575 __ASM_EMIT("dec %[count]") 576 __ASM_EMIT("jge 5b") 577 578 __ASM_EMIT("6:") 579 : [v] "+r" (v), [x] "+r" (x) , [y] "+r" (y), 580 [count] "+r" (count) 581 : [zero] "m" (zero), [norm_x] "m" (norm_x), [norm_y] "m" (norm_y), 582 [ILOG] "o" (LOG_IARGS), [FLOG] "o" (LOG_FARGS) 583 : 584 "%xmm0", "%xmm1", "%xmm2", "%xmm3", 585 "%xmm4", "%xmm5", "%xmm6", "%xmm7", 586 "%xmm8", "%xmm9", "%xmm10", "%xmm11", 587 "%xmm12", "%xmm13", "%xmm14", "%xmm15" 588 ); 589 } 590 x64_rgba32_to_bgra32(void * dst,const void * src,size_t count)591 void x64_rgba32_to_bgra32(void *dst, const void *src, size_t count) 592 { 593 IF_ARCH_X86_64(size_t off); 594 595 ARCH_X86_64_ASM 596 ( 597 __ASM_EMIT("movdqa %[MASK], %%xmm6") // xmm6 = 00 ff 00 ff 598 __ASM_EMIT("xor %[off], %[off]") // off = 0 599 __ASM_EMIT("movdqa %%xmm6, %%xmm7") // xmm7 = 00 ff 00 ff 600 __ASM_EMIT("pslld $8, %%xmm6") // xmm6 = ff 00 ff 00 601 602 // 16-element blocks 603 __ASM_EMIT("sub $16, %[count]") 604 __ASM_EMIT("jb 2f") 605 __ASM_EMIT("1:") 606 __ASM_EMIT("prefetcht0 0x40(%[src], %[off])") 607 __ASM_EMIT("prefetcht0 0x60(%[src], %[off])") 608 __ASM_EMIT("movdqu 0x00(%[src], %[off]), %%xmm0") // xmm0 = A1 R1 G1 B1 609 __ASM_EMIT("movdqu 0x10(%[src], %[off]), %%xmm1") 610 __ASM_EMIT("movdqu 0x20(%[src], %[off]), %%xmm2") 611 __ASM_EMIT("movdqu 0x30(%[src], %[off]), %%xmm3") 612 __ASM_EMIT("movdqa %%xmm0, %%xmm8") // xmm8 = A1 R1 G1 B1 613 __ASM_EMIT("movdqa %%xmm1, %%xmm10") 614 __ASM_EMIT("movdqa %%xmm2, %%xmm12") 615 __ASM_EMIT("movdqa %%xmm3, %%xmm14") 616 __ASM_EMIT("pand %%xmm7, %%xmm0") // xmm0 = 00 R1 00 B1 617 __ASM_EMIT("pand %%xmm7, %%xmm1") 618 __ASM_EMIT("pand %%xmm7, %%xmm2") 619 __ASM_EMIT("pand %%xmm7, %%xmm3") 620 __ASM_EMIT("pand %%xmm6, %%xmm8") // xmm8 = A1 00 G1 00 621 __ASM_EMIT("pand %%xmm6, %%xmm10") 622 __ASM_EMIT("pand %%xmm6, %%xmm12") 623 __ASM_EMIT("pand %%xmm6, %%xmm14") 624 __ASM_EMIT("movdqa %%xmm0, %%xmm9") // xmm9 = A1 00 G1 00 625 __ASM_EMIT("movdqa %%xmm1, %%xmm11") 626 __ASM_EMIT("movdqa %%xmm2, %%xmm13") 627 __ASM_EMIT("movdqa %%xmm3, %%xmm15") 628 __ASM_EMIT("pslld $16, %%xmm0") // xmm0 = 00 B1 00 00 629 __ASM_EMIT("pslld $16, %%xmm1") 630 __ASM_EMIT("pslld $16, %%xmm2") 631 __ASM_EMIT("pslld $16, %%xmm3") 632 __ASM_EMIT("psrld $16, %%xmm9") // xmm9 = 00 00 00 R1 633 __ASM_EMIT("psrld $16, %%xmm11") 634 __ASM_EMIT("psrld $16, %%xmm13") 635 __ASM_EMIT("psrld $16, %%xmm15") 636 __ASM_EMIT("orpd %%xmm8, %%xmm0") // xmm0 = A1 B1 G1 00 637 __ASM_EMIT("orpd %%xmm10, %%xmm1") 638 __ASM_EMIT("orpd %%xmm12, %%xmm2") 639 __ASM_EMIT("orpd %%xmm14, %%xmm3") 640 __ASM_EMIT("orpd %%xmm9, %%xmm0") // xmm0 = A1 B1 G1 R1 641 __ASM_EMIT("orpd %%xmm11, %%xmm1") 642 __ASM_EMIT("orpd %%xmm13, %%xmm2") 643 __ASM_EMIT("orpd %%xmm15, %%xmm3") 644 __ASM_EMIT("movdqu %%xmm0, 0x00(%[dst], %[off])") 645 __ASM_EMIT("movdqu %%xmm1, 0x10(%[dst], %[off])") 646 __ASM_EMIT("movdqu %%xmm2, 0x20(%[dst], %[off])") 647 __ASM_EMIT("movdqu %%xmm3, 0x30(%[dst], %[off])") 648 __ASM_EMIT("add $0x40, %[off]") 649 __ASM_EMIT("sub $16, %[count]") 650 __ASM_EMIT("jae 1b") 651 652 // 8-element blocks 653 __ASM_EMIT("2:") 654 __ASM_EMIT("add $8, %[count]") 655 __ASM_EMIT("jl 4f") 656 __ASM_EMIT("movdqu 0x00(%[src], %[off]), %%xmm0") // xmm0 = A1 R1 G1 B1 657 __ASM_EMIT("movdqu 0x10(%[src], %[off]), %%xmm1") 658 __ASM_EMIT("movdqa %%xmm0, %%xmm2") // xmm2 = A1 R1 G1 B1 659 __ASM_EMIT("movdqa %%xmm1, %%xmm3") 660 __ASM_EMIT("pand %%xmm7, %%xmm0") // xmm0 = 00 R1 00 B1 661 __ASM_EMIT("pand %%xmm6, %%xmm2") // xmm2 = A1 00 G1 00 662 __ASM_EMIT("pand %%xmm7, %%xmm1") 663 __ASM_EMIT("pand %%xmm6, %%xmm3") 664 __ASM_EMIT("movdqa %%xmm0, %%xmm4") // xmm4 = A1 00 G1 00 665 __ASM_EMIT("movdqa %%xmm1, %%xmm5") 666 __ASM_EMIT("pslld $16, %%xmm0") // xmm0 = 00 B1 00 00 667 __ASM_EMIT("pslld $16, %%xmm1") 668 __ASM_EMIT("psrld $16, %%xmm4") // xmm4 = 00 00 00 R1 669 __ASM_EMIT("psrld $16, %%xmm5") 670 __ASM_EMIT("orpd %%xmm2, %%xmm0") // xmm0 = A1 B1 G1 00 671 __ASM_EMIT("orpd %%xmm3, %%xmm1") 672 __ASM_EMIT("orpd %%xmm4, %%xmm0") // xmm0 = A1 B1 G1 R1 673 __ASM_EMIT("orpd %%xmm5, %%xmm1") 674 __ASM_EMIT("movdqu %%xmm0, 0x00(%[dst], %[off])") 675 __ASM_EMIT("movdqu %%xmm1, 0x10(%[dst], %[off])") 676 __ASM_EMIT("add $0x20, %[off]") 677 __ASM_EMIT("sub $8, %[count]") 678 679 // 4-element block 680 __ASM_EMIT("4:") 681 __ASM_EMIT("add $4, %[count]") 682 __ASM_EMIT("jl 6f") 683 __ASM_EMIT("movdqu 0x00(%[src], %[off]), %%xmm0") // xmm0 = A1 R1 G1 B1 684 __ASM_EMIT("movdqa %%xmm0, %%xmm2") // xmm2 = A1 R1 G1 B1 685 __ASM_EMIT("pand %%xmm7, %%xmm0") // xmm0 = 00 R1 00 B1 686 __ASM_EMIT("pand %%xmm6, %%xmm2") // xmm2 = A1 00 G1 00 687 __ASM_EMIT("movdqa %%xmm0, %%xmm4") // xmm4 = A1 00 G1 00 688 __ASM_EMIT("pslld $16, %%xmm0") // xmm0 = 00 B1 00 00 689 __ASM_EMIT("psrld $16, %%xmm4") // xmm4 = 00 00 00 R1 690 __ASM_EMIT("orpd %%xmm2, %%xmm0") // xmm0 = A1 B1 G1 00 691 __ASM_EMIT("orpd %%xmm4, %%xmm0") // xmm0 = A1 B1 G1 R1 692 __ASM_EMIT("movdqu %%xmm0, 0x00(%[dst], %[off])") 693 __ASM_EMIT("add $0x10, %[off]") 694 __ASM_EMIT("sub $4, %[count]") 695 696 // Tail 697 __ASM_EMIT("6:") 698 __ASM_EMIT("add $3, %[count]") 699 __ASM_EMIT("jl 8f") 700 __ASM_EMIT("7:") 701 __ASM_EMIT("movd 0x00(%[src], %[off]), %%xmm0") // xmm0 = AA RR GG BB 702 __ASM_EMIT("movdqa %%xmm0, %%xmm1") // xmm1 = AA RR GG BB 703 __ASM_EMIT("pand %%xmm7, %%xmm0") // xmm0 = 00 RR 00 BB 704 __ASM_EMIT("pand %%xmm6, %%xmm1") // xmm1 = AA 00 GG 00 705 __ASM_EMIT("movdqa %%xmm0, %%xmm2") // xmm2 = 00 RR 00 BB 706 __ASM_EMIT("pslld $16, %%xmm0") // xmm0 = 00 BB 00 00 707 __ASM_EMIT("psrld $16, %%xmm2") // xmm2 = 00 00 00 RR 708 __ASM_EMIT("orpd %%xmm1, %%xmm0") // xmm0 = AA 00 GG RR 709 __ASM_EMIT("orpd %%xmm2, %%xmm0") // xmm0 = AA BB GG RR 710 __ASM_EMIT("movd %%xmm0, 0x00(%[dst], %[off])") 711 __ASM_EMIT("add $4, %[off]") 712 __ASM_EMIT("dec %[count]") 713 __ASM_EMIT("jge 7b") 714 715 // End 716 __ASM_EMIT("8:") 717 718 : [dst] "+r"(dst), [src] "+r"(src), [count] "+r" (count), 719 [off] "=&r" (off) 720 : [MASK] "m" (X_CMASK) 721 : "cc", "memory", 722 "%xmm0", "%xmm1", "%xmm2", "%xmm3", 723 "%xmm4", "%xmm5", "%xmm6", "%xmm7", 724 "%xmm8", "%xmm9", "%xmm10", "%xmm11", 725 "%xmm12", "%xmm13", "%xmm14", "%xmm15" 726 ); 727 } 728 } 729 730 #endif /* DSP_ARCH_X86_SSE3_GRAPHICS_H_ */ 731