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: 19 дек. 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 #ifndef INCLUDE_DSP_ARCH_X86_AVX2_GRAPHICS_EFFECTS_H_ 23 #define INCLUDE_DSP_ARCH_X86_AVX2_GRAPHICS_EFFECTS_H_ 24 25 #include <dsp/arch/x86/avx2/graphics/transpose.h> 26 27 #ifdef ARCH_X86_64 28 29 namespace avx2 30 { 31 IF_ARCH_X86( 32 static const float EFF_HSLA_HUE_XC[] __lsp_aligned32 = 33 { 34 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f 35 }; 36 ) 37 38 #define EFF_HSLA_HUE_CORE_X16 \ 39 /* ymm0 = v, ymm10 = h, ymm11 = s, ymm12 = l, ymm13 = 1, ymm14 = T, ymm15 = KT */ \ 40 __ASM_EMIT("vaddps %%ymm0, %%ymm13, %%ymm2") /* ymm2 = 1+v */ \ 41 __ASM_EMIT("vaddps %%ymm4, %%ymm13, %%ymm6") \ 42 __ASM_EMIT("vsubps %%ymm0, %%ymm13, %%ymm3") /* ymm3 = 1-v */ \ 43 __ASM_EMIT("vsubps %%ymm4, %%ymm13, %%ymm7") \ 44 __ASM_EMIT("vblendvps %%ymm0, %%ymm2, %%ymm3, %%ymm0") /* ymm0 = V = (v < 0) ? 1+v : 1-v */ \ 45 __ASM_EMIT("vblendvps %%ymm4, %%ymm6, %%ymm7, %%ymm4") \ 46 /* ymm0 = V, ymm1 = EH, ymm14 = T, ymm15 = KT */ \ 47 __ASM_EMIT("vsubps %%ymm14, %%ymm0, %%ymm3") /* ymm3 = V-T */ \ 48 __ASM_EMIT("vsubps %%ymm14, %%ymm4, %%ymm7") \ 49 __ASM_EMIT("vblendvps %%ymm3, %%ymm0, %%ymm14, %%ymm0") /* ymm0 = (V-T) < 0 ? V : T */ \ 50 __ASM_EMIT("vblendvps %%ymm7, %%ymm4, %%ymm14, %%ymm4") \ 51 __ASM_EMIT("vxorps %%ymm8, %%ymm8, %%ymm8") /* ymm8 = 0 */ \ 52 __ASM_EMIT("vaddps %%ymm10, %%ymm0, %%ymm0") /* ymm0 = NH = h + ((V-T) < 0 ? V : T) */ \ 53 __ASM_EMIT("vblendvps %%ymm3, %%ymm8, %%ymm3, %%ymm3") /* ymm3 = (V-T) < 0 ? 0 : V-T */ \ 54 __ASM_EMIT("vaddps %%ymm10, %%ymm4, %%ymm4") \ 55 __ASM_EMIT("vblendvps %%ymm7, %%ymm8, %%ymm7, %%ymm7") \ 56 __ASM_EMIT("vsubps %%ymm13, %%ymm0, %%ymm1") /* ymm1 = NH-1 */ \ 57 __ASM_EMIT("vmulps %%ymm15, %%ymm3, %%ymm3") /* ymm3 = A = KT * ((V-T) < 0 ? 0 : V-T) */ \ 58 __ASM_EMIT("vsubps %%ymm13, %%ymm4, %%ymm5") \ 59 __ASM_EMIT("vmulps %%ymm15, %%ymm7, %%ymm7") \ 60 __ASM_EMIT("vmovaps %%ymm12, %%ymm2") /* ymm2 = L */ \ 61 __ASM_EMIT("vmovaps %%ymm12, %%ymm6") \ 62 __ASM_EMIT("vblendvps %%ymm1, %%ymm0, %%ymm1, %%ymm0") /* ymm0 = H = ((NH-1)<0) ? NH : NH-1 */ \ 63 __ASM_EMIT("vblendvps %%ymm5, %%ymm4, %%ymm5, %%ymm4") \ 64 __ASM_EMIT("vmovaps %%ymm11, %%ymm1") /* ymm1 = S */ \ 65 __ASM_EMIT("vmovaps %%ymm11, %%ymm5") \ 66 MAT4_TRANSPOSE("%%ymm0", "%%ymm1", "%%ymm2", "%%ymm3", "%%ymm8", "%%ymm9") \ 67 MAT4_TRANSPOSE("%%ymm4", "%%ymm5", "%%ymm6", "%%ymm7", "%%ymm8", "%%ymm9") \ 68 MAT4X2_INTERLEAVE("0", "1", "2", "3", "8", "9") \ 69 MAT4X2_INTERLEAVE("4", "5", "6", "7", "8", "9") 70 71 #define EFF_HSLA_HUE_CORE_X8 \ 72 /* ymm0 = v, ymm10 = h, ymm11 = s, ymm12 = l, ymm13 = 1, ymm14 = T, ymm15 = KT */ \ 73 __ASM_EMIT("vaddps %%ymm0, %%ymm13, %%ymm2") /* ymm2 = 1+v */ \ 74 __ASM_EMIT("vsubps %%ymm0, %%ymm13, %%ymm3") /* ymm3 = 1-v */ \ 75 __ASM_EMIT("vblendvps %%ymm0, %%ymm2, %%ymm3, %%ymm0") /* ymm0 = V = (v < 0) ? 1+v : 1-v */ \ 76 /* ymm0 = V, ymm1 = EH, ymm14 = T, ymm15 = KT */ \ 77 __ASM_EMIT("vsubps %%ymm14, %%ymm0, %%ymm3") /* ymm3 = V-T */ \ 78 __ASM_EMIT("vblendvps %%ymm3, %%ymm0, %%ymm14, %%ymm0") /* ymm0 = (V-T) < 0 ? V : T */ \ 79 __ASM_EMIT("vxorps %%ymm8, %%ymm8, %%ymm8") /* ymm8 = 0 */ \ 80 __ASM_EMIT("vaddps %%ymm10, %%ymm0, %%ymm0") /* ymm0 = NH = h + ((V-T) < 0 ? V : T) */ \ 81 __ASM_EMIT("vblendvps %%ymm3, %%ymm8, %%ymm3, %%ymm3") /* ymm3 = (V-T) < 0 ? 0 : V-T */ \ 82 __ASM_EMIT("vsubps %%ymm13, %%ymm0, %%ymm1") /* ymm1 = NH-1 */ \ 83 __ASM_EMIT("vmulps %%ymm15, %%ymm3, %%ymm3") /* ymm3 = A = KT * ((V-T) < 0 ? 0 : V-T) */ \ 84 __ASM_EMIT("vmovaps %%ymm12, %%ymm2") /* ymm2 = L */ \ 85 __ASM_EMIT("vblendvps %%ymm1, %%ymm0, %%ymm1, %%ymm0") /* ymm0 = H = ((NH-1)<0) ? NH : NH-1 */ \ 86 __ASM_EMIT("vmovaps %%ymm11, %%ymm1") /* ymm1 = S */ \ 87 MAT4_TRANSPOSE("%%ymm0", "%%ymm1", "%%ymm2", "%%ymm3", "%%ymm8", "%%ymm9") \ 88 MAT4X2_INTERLEAVE("0", "1", "2", "3", "8", "9") 89 90 #define EFF_HSLA_HUE_CORE_X4 \ 91 /* xmm0 = v, xmm10 = h, xmm11 = s, xmm12 = l, xmm13 = 1, xmm14 = T, xmm15 = KT */ \ 92 __ASM_EMIT("vaddps %%xmm0, %%xmm13, %%xmm2") /* xmm2 = 1+v */ \ 93 __ASM_EMIT("vsubps %%xmm0, %%xmm13, %%xmm3") /* xmm3 = 1-v */ \ 94 __ASM_EMIT("vblendvps %%xmm0, %%xmm2, %%xmm3, %%xmm0") /* xmm0 = V = (v < 0) ? 1+v : 1-v */ \ 95 /* xmm0 = V, xmm1 = EH, xmm14 = T, xmm15 = KT */ \ 96 __ASM_EMIT("vsubps %%xmm14, %%xmm0, %%xmm3") /* xmm3 = V-T */ \ 97 __ASM_EMIT("vblendvps %%xmm3, %%xmm0, %%xmm14, %%xmm0") /* xmm0 = (V-T) < 0 ? V : T */ \ 98 __ASM_EMIT("vxorps %%xmm8, %%xmm8, %%xmm8") /* xmm8 = 0 */ \ 99 __ASM_EMIT("vaddps %%xmm10, %%xmm0, %%xmm0") /* xmm0 = NH = h + ((V-T) < 0 ? V : T) */ \ 100 __ASM_EMIT("vblendvps %%xmm3, %%xmm8, %%xmm3, %%xmm3") /* xmm3 = (V-T) < 0 ? 0 : V-T */ \ 101 __ASM_EMIT("vsubps %%xmm13, %%xmm0, %%xmm1") /* xmm1 = NH-1 */ \ 102 __ASM_EMIT("vmulps %%xmm15, %%xmm3, %%xmm3") /* xmm3 = A = KT * ((V-T) < 0 ? 0 : V-T) */ \ 103 __ASM_EMIT("vmovaps %%xmm12, %%xmm2") /* xmm2 = L */ \ 104 __ASM_EMIT("vblendvps %%xmm1, %%xmm0, %%xmm1, %%xmm0") /* xmm0 = H = ((NH-1)<0) ? NH : NH-1 */ \ 105 __ASM_EMIT("vmovaps %%xmm11, %%xmm1") /* xmm1 = S */ \ 106 MAT4_TRANSPOSE("%%xmm0", "%%xmm1", "%%xmm2", "%%xmm3", "%%xmm8", "%%xmm9") 107 108 /* 109 float value, hue, alpha; 110 float t = 1.0f - eff->thresh; 111 float kt = 1.0f / eff->thresh; 112 113 for (size_t i=0; i<count; ++i, dst += 4) 114 { 115 value = v[i]; 116 value = (value < 0) ? 1.0f + value : 1.0f - value; 117 118 if ((value - t) >= 0) 119 { 120 hue = eff->h + t; 121 alpha = ((value - t) * kt); 122 } 123 else 124 { 125 hue = eff->h + value; 126 alpha = 0.0f; 127 } 128 129 dst[0] = (hue < 1.0f) ? hue : hue - 1.0f; 130 dst[1] = eff->s; 131 dst[2] = eff->l; 132 dst[3] = alpha; 133 }*/ 134 x64_eff_hsla_hue(float * dst,const float * v,const dsp::hsla_hue_eff_t * eff,size_t count)135 void x64_eff_hsla_hue(float *dst, const float *v, const dsp::hsla_hue_eff_t *eff, size_t count) 136 { 137 ARCH_X86_ASM( 138 //----------------------------------------------------------------- 139 // Prepare 140 __ASM_EMIT("vbroadcastf128 0x00(%[eff]), %%ymm10") /* ymm10 = h s l a h s l a */ 141 __ASM_EMIT("vbroadcastss 0x10(%[eff]), %%ymm14") /* ymm14 = t */ 142 __ASM_EMIT("vmovaps 0x00 + %[XC], %%ymm13") /* ymm13 = 1 */ 143 __ASM_EMIT("vshufps $0xaa, %%ymm10, %%ymm10, %%ymm12") /* ymm12 = l */ 144 __ASM_EMIT("vdivps %%ymm14, %%ymm13, %%ymm15") /* ymm15 = KT = 1 / t */ 145 __ASM_EMIT("vshufps $0x55, %%ymm10, %%ymm10, %%ymm11") /* ymm12 = s */ 146 __ASM_EMIT("vsubps %%ymm14, %%ymm13, %%ymm14") /* ymm14 = T = 1 - t */ 147 __ASM_EMIT("vshufps $0x00, %%ymm10, %%ymm10, %%ymm10") /* ymm12 = h */ 148 149 //----------------------------------------------------------------- 150 // x16 blocks 151 __ASM_EMIT("sub $16, %[count]") 152 __ASM_EMIT("jb 2f") 153 __ASM_EMIT("1:") 154 __ASM_EMIT("vmovups 0x00(%[src]), %%ymm0") 155 __ASM_EMIT("vmovups 0x20(%[src]), %%ymm4") 156 EFF_HSLA_HUE_CORE_X16 157 __ASM_EMIT("vmovups %%ymm0, 0x000(%[dst])") 158 __ASM_EMIT("vmovups %%ymm1, 0x020(%[dst])") 159 __ASM_EMIT("vmovups %%ymm2, 0x040(%[dst])") 160 __ASM_EMIT("vmovups %%ymm3, 0x060(%[dst])") 161 __ASM_EMIT("vmovups %%ymm4, 0x080(%[dst])") 162 __ASM_EMIT("vmovups %%ymm5, 0x0a0(%[dst])") 163 __ASM_EMIT("vmovups %%ymm6, 0x0c0(%[dst])") 164 __ASM_EMIT("vmovups %%ymm7, 0x0e0(%[dst])") 165 __ASM_EMIT("add $0x40, %[src]") 166 __ASM_EMIT("add $0x100, %[dst]") 167 __ASM_EMIT("sub $16, %[count]") 168 __ASM_EMIT("jae 1b") 169 170 //----------------------------------------------------------------- 171 // x8 block 172 __ASM_EMIT("2:") 173 __ASM_EMIT("add $8, %[count]") 174 __ASM_EMIT("jl 4f") 175 __ASM_EMIT("vmovups 0x00(%[src]), %%ymm0") 176 EFF_HSLA_HUE_CORE_X8 177 __ASM_EMIT("vmovups %%ymm0, 0x000(%[dst])") 178 __ASM_EMIT("vmovups %%ymm1, 0x020(%[dst])") 179 __ASM_EMIT("vmovups %%ymm2, 0x040(%[dst])") 180 __ASM_EMIT("vmovups %%ymm3, 0x060(%[dst])") 181 __ASM_EMIT("sub $8, %[count]") 182 __ASM_EMIT("add $0x20, %[src]") 183 __ASM_EMIT("add $0x80, %[dst]") 184 185 //----------------------------------------------------------------- 186 // x4 block 187 __ASM_EMIT("4:") 188 __ASM_EMIT("add $4, %[count]") 189 __ASM_EMIT("jl 6f") 190 __ASM_EMIT("vmovups 0x00(%[src]), %%xmm0") 191 EFF_HSLA_HUE_CORE_X4 192 __ASM_EMIT("vmovups %%xmm0, 0x000(%[dst])") 193 __ASM_EMIT("vmovups %%xmm1, 0x010(%[dst])") 194 __ASM_EMIT("vmovups %%xmm2, 0x020(%[dst])") 195 __ASM_EMIT("vmovups %%xmm3, 0x030(%[dst])") 196 __ASM_EMIT("sub $4, %[count]") 197 __ASM_EMIT("add $0x10, %[src]") 198 __ASM_EMIT("add $0x40, %[dst]") 199 200 //----------------------------------------------------------------- 201 // x1-x3 block 202 __ASM_EMIT("6:") 203 __ASM_EMIT("add $4, %[count]") 204 __ASM_EMIT("jle 14f") 205 __ASM_EMIT("test $1, %[count]") 206 __ASM_EMIT("jz 8f") 207 __ASM_EMIT("vmovss 0x00(%[src]), %%xmm0") 208 __ASM_EMIT("add $0x04, %[src]") 209 __ASM_EMIT("8:") 210 __ASM_EMIT("test $2, %[count]") 211 __ASM_EMIT("jz 10f") 212 __ASM_EMIT("vmovhps 0x00(%[src]), %%xmm0, %%xmm0") 213 __ASM_EMIT("10:") 214 215 EFF_HSLA_HUE_CORE_X4 216 217 // Store last chunk 218 __ASM_EMIT("test $1, %[count]") 219 __ASM_EMIT("jz 12f") 220 __ASM_EMIT("vmovups %%xmm0, 0x00(%[dst])") 221 __ASM_EMIT("add $0x10, %[dst]") 222 __ASM_EMIT("12:") 223 __ASM_EMIT("test $2, %[count]") 224 __ASM_EMIT("jz 14f") 225 __ASM_EMIT("vmovups %%xmm2, 0x00(%[dst])") 226 __ASM_EMIT("vmovups %%xmm3, 0x10(%[dst])") 227 228 __ASM_EMIT("14:") 229 230 : [dst] "+r" (dst), [src] "+r" (v), [count] "+r" (count) 231 : [eff] "r" (eff), 232 [XC] "o" (EFF_HSLA_HUE_XC) 233 : "cc", "memory", 234 "%xmm0", "%xmm1", "%xmm2", "%xmm3", 235 "%xmm4", "%xmm5", "%xmm6", "%xmm7", 236 "%xmm8", "%xmm9", "%xmm10", "%xmm11", 237 "%xmm12", "%xmm13", "%xmm14", "%xmm15" 238 ); 239 } 240 241 static const float EFF_HSLA_ALPHA_XC[] __lsp_aligned32 = 242 { 243 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f 244 }; 245 246 #define EFF_HSLA_ALPHA_CORE_X16 \ 247 /* ymm0 = v, ymm12 = h, ymm13 = s, ymm14 = l, ymm15 = 1 */ \ 248 __ASM_EMIT("vaddps %%ymm0, %%ymm15, %%ymm2") /* ymm2 = 1+v */ \ 249 __ASM_EMIT("vaddps %%ymm4, %%ymm15, %%ymm6") \ 250 __ASM_EMIT("vsubps %%ymm0, %%ymm15, %%ymm3") /* ymm3 = 1-v */ \ 251 __ASM_EMIT("vsubps %%ymm4, %%ymm15, %%ymm7") \ 252 __ASM_EMIT("vblendvps %%ymm0, %%ymm2, %%ymm3, %%ymm3") /* ymm3 = (v<0) ? 1+v : 1-v */ \ 253 __ASM_EMIT("vblendvps %%ymm4, %%ymm6, %%ymm7, %%ymm7") \ 254 __ASM_EMIT("vmovaps %%ymm12, %%ymm0") /* ymm0 = H */ \ 255 __ASM_EMIT("vmovaps %%ymm13, %%ymm1") /* ymm1 = S */ \ 256 __ASM_EMIT("vmovaps %%ymm14, %%ymm2") /* ymm2 = L */ \ 257 __ASM_EMIT("vmovaps %%ymm12, %%ymm4") \ 258 __ASM_EMIT("vmovaps %%ymm13, %%ymm5") \ 259 __ASM_EMIT("vmovaps %%ymm14, %%ymm6") \ 260 MAT4_TRANSPOSE("%%ymm0", "%%ymm1", "%%ymm2", "%%ymm3", "%%ymm8", "%%ymm9") \ 261 MAT4_TRANSPOSE("%%ymm4", "%%ymm5", "%%ymm6", "%%ymm7", "%%ymm8", "%%ymm9") \ 262 MAT4X2_INTERLEAVE("0", "1", "2", "3", "8", "9") \ 263 MAT4X2_INTERLEAVE("4", "5", "6", "7", "8", "9") 264 265 266 #define EFF_HSLA_ALPHA_CORE_X8 \ 267 /* ymm0 = v, ymm12 = h, ymm13 = s, ymm14 = l, ymm15 = 1 */ \ 268 __ASM_EMIT("vaddps %%ymm0, %%ymm15, %%ymm2") /* ymm2 = 1+v */ \ 269 __ASM_EMIT("vsubps %%ymm0, %%ymm15, %%ymm3") /* ymm3 = 1-v */ \ 270 __ASM_EMIT("vblendvps %%ymm0, %%ymm2, %%ymm3, %%ymm3") /* ymm3 = (v<0) ? 1+v : 1-v */ \ 271 __ASM_EMIT("vmovaps %%ymm12, %%ymm0") /* ymm0 = H */ \ 272 __ASM_EMIT("vmovaps %%ymm13, %%ymm1") /* ymm1 = S */ \ 273 __ASM_EMIT("vmovaps %%ymm14, %%ymm2") /* ymm2 = L */ \ 274 MAT4_TRANSPOSE("%%ymm0", "%%ymm1", "%%ymm2", "%%ymm3", "%%ymm8", "%%ymm9") \ 275 MAT4X2_INTERLEAVE("0", "1", "2", "3", "8", "9") 276 277 #define EFF_HSLA_ALPHA_CORE_X4 \ 278 /* xmm0 = v, xmm12 = h, xmm13 = s, xmm14 = l, xmm15 = 1 */ \ 279 __ASM_EMIT("vaddps %%xmm0, %%xmm15, %%xmm2") /* xmm2 = 1+v */ \ 280 __ASM_EMIT("vsubps %%xmm0, %%xmm15, %%xmm3") /* xmm3 = 1-v */ \ 281 __ASM_EMIT("vblendvps %%xmm0, %%xmm2, %%xmm3, %%xmm3") /* xmm3 = (v<0) ? 1+v : 1-v */ \ 282 __ASM_EMIT("vmovaps %%xmm12, %%xmm0") /* xmm0 = H */ \ 283 __ASM_EMIT("vmovaps %%xmm13, %%xmm1") /* xmm1 = S */ \ 284 __ASM_EMIT("vmovaps %%xmm14, %%xmm2") /* xmm2 = L */ \ 285 MAT4_TRANSPOSE("%%xmm0", "%%xmm1", "%%xmm2", "%%xmm3", "%%xmm8", "%%xmm9") 286 287 /* 288 value = v[i]; 289 value = (value < 0) ? 1.0f + value : 1.0f - value; 290 291 dst[0] = eff->h; 292 dst[1] = eff->s; 293 dst[2] = eff->l; 294 dst[3] = value; // Fill alpha channel 295 */ x64_eff_hsla_alpha(float * dst,const float * v,const dsp::hsla_alpha_eff_t * eff,size_t count)296 void x64_eff_hsla_alpha(float *dst, const float *v, const dsp::hsla_alpha_eff_t *eff, size_t count) 297 { 298 ARCH_X86_ASM( 299 //----------------------------------------------------------------- 300 // Prepare 301 __ASM_EMIT("vbroadcastf128 0x00(%[eff]), %%ymm12") /* ymm12 = h s l a h s l a */ 302 __ASM_EMIT("vmovaps 0x00 + %[XC], %%ymm15") /* ymm15 = 1 */ 303 __ASM_EMIT("vshufps $0xaa, %%ymm12, %%ymm12, %%ymm14") /* ymm14 = l */ 304 __ASM_EMIT("vshufps $0x55, %%ymm12, %%ymm12, %%ymm13") /* ymm13 = s */ 305 __ASM_EMIT("vshufps $0x00, %%ymm12, %%ymm12, %%ymm12") /* ymm12 = h */ 306 307 //----------------------------------------------------------------- 308 // x16 blocks 309 __ASM_EMIT("sub $16, %[count]") 310 __ASM_EMIT("jb 2f") 311 __ASM_EMIT("1:") 312 __ASM_EMIT("vmovups 0x00(%[src]), %%ymm0") 313 __ASM_EMIT("vmovups 0x20(%[src]), %%ymm4") 314 EFF_HSLA_ALPHA_CORE_X16 315 __ASM_EMIT("vmovups %%ymm0, 0x000(%[dst])") 316 __ASM_EMIT("vmovups %%ymm1, 0x020(%[dst])") 317 __ASM_EMIT("vmovups %%ymm2, 0x040(%[dst])") 318 __ASM_EMIT("vmovups %%ymm3, 0x060(%[dst])") 319 __ASM_EMIT("vmovups %%ymm4, 0x080(%[dst])") 320 __ASM_EMIT("vmovups %%ymm5, 0x0a0(%[dst])") 321 __ASM_EMIT("vmovups %%ymm6, 0x0c0(%[dst])") 322 __ASM_EMIT("vmovups %%ymm7, 0x0e0(%[dst])") 323 __ASM_EMIT("add $0x40, %[src]") 324 __ASM_EMIT("add $0x100, %[dst]") 325 __ASM_EMIT("sub $16, %[count]") 326 __ASM_EMIT("jae 1b") 327 328 //----------------------------------------------------------------- 329 // x8 block 330 __ASM_EMIT("2:") 331 __ASM_EMIT("add $8, %[count]") 332 __ASM_EMIT("jl 4f") 333 __ASM_EMIT("vmovups 0x00(%[src]), %%ymm0") 334 EFF_HSLA_ALPHA_CORE_X8 335 __ASM_EMIT("vmovups %%ymm0, 0x000(%[dst])") 336 __ASM_EMIT("vmovups %%ymm1, 0x020(%[dst])") 337 __ASM_EMIT("vmovups %%ymm2, 0x040(%[dst])") 338 __ASM_EMIT("vmovups %%ymm3, 0x060(%[dst])") 339 __ASM_EMIT("sub $8, %[count]") 340 __ASM_EMIT("add $0x20, %[src]") 341 __ASM_EMIT("add $0x80, %[dst]") 342 343 //----------------------------------------------------------------- 344 // x4 block 345 __ASM_EMIT("4:") 346 __ASM_EMIT("add $4, %[count]") 347 __ASM_EMIT("jl 6f") 348 __ASM_EMIT("vmovups 0x00(%[src]), %%xmm0") 349 EFF_HSLA_ALPHA_CORE_X4 350 __ASM_EMIT("vmovups %%xmm0, 0x000(%[dst])") 351 __ASM_EMIT("vmovups %%xmm1, 0x010(%[dst])") 352 __ASM_EMIT("vmovups %%xmm2, 0x020(%[dst])") 353 __ASM_EMIT("vmovups %%xmm3, 0x030(%[dst])") 354 __ASM_EMIT("sub $4, %[count]") 355 __ASM_EMIT("add $0x10, %[src]") 356 __ASM_EMIT("add $0x40, %[dst]") 357 358 //----------------------------------------------------------------- 359 // x1-x3 block 360 __ASM_EMIT("6:") 361 __ASM_EMIT("add $4, %[count]") 362 __ASM_EMIT("jle 14f") 363 __ASM_EMIT("test $1, %[count]") 364 __ASM_EMIT("jz 8f") 365 __ASM_EMIT("vmovss 0x00(%[src]), %%xmm0") 366 __ASM_EMIT("add $0x04, %[src]") 367 __ASM_EMIT("8:") 368 __ASM_EMIT("test $2, %[count]") 369 __ASM_EMIT("jz 10f") 370 __ASM_EMIT("vmovhps 0x00(%[src]), %%xmm0, %%xmm0") 371 __ASM_EMIT("10:") 372 373 EFF_HSLA_ALPHA_CORE_X4 374 375 // Store last chunk 376 __ASM_EMIT("test $1, %[count]") 377 __ASM_EMIT("jz 12f") 378 __ASM_EMIT("vmovups %%xmm0, 0x00(%[dst])") 379 __ASM_EMIT("add $0x10, %[dst]") 380 __ASM_EMIT("12:") 381 __ASM_EMIT("test $2, %[count]") 382 __ASM_EMIT("jz 14f") 383 __ASM_EMIT("vmovups %%xmm2, 0x00(%[dst])") 384 __ASM_EMIT("vmovups %%xmm3, 0x10(%[dst])") 385 386 __ASM_EMIT("14:") 387 388 : [dst] "+r" (dst), [src] "+r" (v), [count] "+r" (count) 389 : [eff] "r" (eff), 390 [XC] "o" (EFF_HSLA_ALPHA_XC) 391 : "cc", "memory", 392 "%xmm0", "%xmm1", "%xmm2", "%xmm3", 393 "%xmm4", "%xmm5", "%xmm6", "%xmm7", 394 "%xmm8", "%xmm9", "%xmm10", "%xmm11", 395 "%xmm12", "%xmm13", "%xmm14", "%xmm15" 396 ); 397 } 398 399 static const uint32_t EFF_HSLA_SAT_XC[] __lsp_aligned32 = 400 { 401 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 402 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff 403 }; 404 405 #define EFF_HSLA_SAT_CORE_X16 \ 406 /* ymm0 = v, ymm10 = h, ymm11 = s, ymm12 = l, ymm13 = T, ymm14 = ABS, ymm15 = KT */ \ 407 __ASM_EMIT("vandps %%ymm14, %%ymm0, %%ymm0") /* ymm0 = V = abs(v) */ \ 408 __ASM_EMIT("vandps %%ymm14, %%ymm4, %%ymm4") \ 409 __ASM_EMIT("vxorps %%ymm8, %%ymm8, %%ymm8") /* ymm8 = 0 */ \ 410 __ASM_EMIT("vsubps %%ymm0, %%ymm13, %%ymm3") /* ymm3 = T-V */ \ 411 __ASM_EMIT("vsubps %%ymm4, %%ymm13, %%ymm7") \ 412 __ASM_EMIT("vblendvps %%ymm3, %%ymm0, %%ymm13, %%ymm1") /* ymm1 = ((T-V)<0) ? V : T */ \ 413 __ASM_EMIT("vblendvps %%ymm7, %%ymm4, %%ymm13, %%ymm5") \ 414 __ASM_EMIT("vblendvps %%ymm3, %%ymm8, %%ymm3, %%ymm3") /* ymm3 = ((T-V)<0) ? 0 : T-V */ \ 415 __ASM_EMIT("vblendvps %%ymm7, %%ymm8, %%ymm7, %%ymm7") \ 416 __ASM_EMIT("vmulps %%ymm11, %%ymm1, %%ymm1") /* ymm1 = S = s * (((T-V)<0) ? V : T) */ \ 417 __ASM_EMIT("vmulps %%ymm11, %%ymm5, %%ymm5") \ 418 __ASM_EMIT("vmulps %%ymm15, %%ymm3, %%ymm3") /* ymm3 = A = kt * (((T-V)<0) ? 0 : T-V) */ \ 419 __ASM_EMIT("vmulps %%ymm15, %%ymm7, %%ymm7") \ 420 __ASM_EMIT("vmovaps %%ymm10, %%ymm0") /* ymm0 = H */ \ 421 __ASM_EMIT("vmovaps %%ymm12, %%ymm2") /* ymm2 = L */ \ 422 __ASM_EMIT("vmovaps %%ymm10, %%ymm4") \ 423 __ASM_EMIT("vmovaps %%ymm12, %%ymm6") \ 424 MAT4_TRANSPOSE("%%ymm0", "%%ymm1", "%%ymm2", "%%ymm3", "%%ymm8", "%%ymm9") \ 425 MAT4_TRANSPOSE("%%ymm4", "%%ymm5", "%%ymm6", "%%ymm7", "%%ymm8", "%%ymm9") \ 426 MAT4X2_INTERLEAVE("0", "1", "2", "3", "8", "9") \ 427 MAT4X2_INTERLEAVE("4", "5", "6", "7", "8", "9") 428 429 #define EFF_HSLA_SAT_CORE_X8 \ 430 /* ymm0 = v, ymm10 = h, ymm11 = s, ymm12 = l, ymm13 = T, ymm14 = ABS, ymm15 = KT */ \ 431 __ASM_EMIT("vandps %%ymm14, %%ymm0, %%ymm0") /* ymm0 = V = abs(v) */ \ 432 __ASM_EMIT("vxorps %%ymm8, %%ymm8, %%ymm8") /* ymm8 = 0 */ \ 433 __ASM_EMIT("vsubps %%ymm0, %%ymm13, %%ymm3") /* ymm3 = T-V */ \ 434 __ASM_EMIT("vblendvps %%ymm3, %%ymm0, %%ymm13, %%ymm1") /* ymm1 = ((T-V)<0) ? V : T */ \ 435 __ASM_EMIT("vblendvps %%ymm3, %%ymm8, %%ymm3, %%ymm3") /* ymm3 = ((T-V)<0) ? 0 : T-V */ \ 436 __ASM_EMIT("vmulps %%ymm11, %%ymm1, %%ymm1") /* ymm1 = S = s * (((T-V)<0) ? V : T) */ \ 437 __ASM_EMIT("vmulps %%ymm15, %%ymm3, %%ymm3") /* ymm3 = A = kt * (((T-V)<0) ? 0 : T-V) */ \ 438 __ASM_EMIT("vmovaps %%ymm10, %%ymm0") /* ymm0 = H */ \ 439 __ASM_EMIT("vmovaps %%ymm12, %%ymm2") /* ymm2 = L */ \ 440 MAT4_TRANSPOSE("%%ymm0", "%%ymm1", "%%ymm2", "%%ymm3", "%%ymm8", "%%ymm9") \ 441 MAT4X2_INTERLEAVE("0", "1", "2", "3", "8", "9") 442 443 #define EFF_HSLA_SAT_CORE_X4 \ 444 /* xmm0 = v, xmm10 = h, xmm11 = s, xmm12 = l, xmm13 = T, xmm14 = ABS, xmm15 = KT */ \ 445 __ASM_EMIT("vandps %%xmm14, %%xmm0, %%xmm0") /* xmm0 = V = abs(v) */ \ 446 __ASM_EMIT("vxorps %%xmm8, %%xmm8, %%xmm8") /* xmm8 = 0 */ \ 447 __ASM_EMIT("vsubps %%xmm0, %%xmm13, %%xmm3") /* xmm3 = T-V */ \ 448 __ASM_EMIT("vblendvps %%xmm3, %%xmm0, %%xmm13, %%xmm1") /* xmm1 = ((T-V)<0) ? V : T */ \ 449 __ASM_EMIT("vblendvps %%xmm3, %%xmm8, %%xmm3, %%xmm3") /* xmm3 = ((T-V)<0) ? 0 : T-V */ \ 450 __ASM_EMIT("vmulps %%xmm11, %%xmm1, %%xmm1") /* xmm1 = S = s * (((T-V)<0) ? V : T) */ \ 451 __ASM_EMIT("vmulps %%xmm15, %%xmm3, %%xmm3") /* xmm3 = A = kt * (((T-V)<0) ? 0 : T-V) */ \ 452 __ASM_EMIT("vmovaps %%xmm10, %%xmm0") /* xmm0 = H */ \ 453 __ASM_EMIT("vmovaps %%xmm12, %%xmm2") /* xmm2 = L */ \ 454 MAT4_TRANSPOSE("%%xmm0", "%%xmm1", "%%xmm2", "%%xmm3", "%%xmm8", "%%xmm9") 455 456 /* 457 kt = 1.0f / eff->thresh; 458 value = (value >= 0.0f) ? value : -value; 459 460 if ((eff->thresh - value) < 0) 461 { 462 dst[1] = eff->s * value; 463 dst[3] = 0.0f; 464 } 465 else 466 { 467 dst[1] = eff->s * eff->thresh; 468 dst[3] = (eff->thresh - value) * kt; 469 } 470 471 dst[0] = eff->h; 472 dst[2] = eff->l; 473 */ 474 x64_eff_hsla_sat(float * dst,const float * v,const dsp::hsla_sat_eff_t * eff,size_t count)475 void x64_eff_hsla_sat(float *dst, const float *v, const dsp::hsla_sat_eff_t *eff, size_t count) 476 { 477 ARCH_X86_ASM( 478 //----------------------------------------------------------------- 479 // Prepare 480 __ASM_EMIT("vbroadcastf128 0x00(%[eff]), %%ymm10") /* ymm12 = h s l a h s l a */ 481 __ASM_EMIT("vmovaps 0x00 + %[XC], %%ymm15") /* ymm15 = 1 */ 482 __ASM_EMIT("vshufps $0xaa, %%ymm10, %%ymm10, %%ymm12") /* ymm12 = l */ 483 __ASM_EMIT("vmovaps 0x20 + %[XC], %%ymm14") /* ymm14 = ABS */ 484 __ASM_EMIT("vshufps $0x55, %%ymm10, %%ymm10, %%ymm11") /* ymm11 = s */ 485 __ASM_EMIT("vbroadcastss 0x10(%[eff]), %%ymm13") /* ymm13 = T */ 486 __ASM_EMIT("vshufps $0x00, %%ymm10, %%ymm10, %%ymm10") /* ymm10 = h */ 487 __ASM_EMIT("vdivps %%ymm13, %%ymm15, %%ymm15") /* ymm15 = KT = 1/T */ 488 489 //----------------------------------------------------------------- 490 // x16 blocks 491 __ASM_EMIT("sub $16, %[count]") 492 __ASM_EMIT("jb 2f") 493 __ASM_EMIT("1:") 494 __ASM_EMIT("vmovups 0x00(%[src]), %%ymm0") 495 __ASM_EMIT("vmovups 0x20(%[src]), %%ymm4") 496 EFF_HSLA_SAT_CORE_X16 497 __ASM_EMIT("vmovups %%ymm0, 0x000(%[dst])") 498 __ASM_EMIT("vmovups %%ymm1, 0x020(%[dst])") 499 __ASM_EMIT("vmovups %%ymm2, 0x040(%[dst])") 500 __ASM_EMIT("vmovups %%ymm3, 0x060(%[dst])") 501 __ASM_EMIT("vmovups %%ymm4, 0x080(%[dst])") 502 __ASM_EMIT("vmovups %%ymm5, 0x0a0(%[dst])") 503 __ASM_EMIT("vmovups %%ymm6, 0x0c0(%[dst])") 504 __ASM_EMIT("vmovups %%ymm7, 0x0e0(%[dst])") 505 __ASM_EMIT("add $0x40, %[src]") 506 __ASM_EMIT("add $0x100, %[dst]") 507 __ASM_EMIT("sub $16, %[count]") 508 __ASM_EMIT("jae 1b") 509 510 //----------------------------------------------------------------- 511 // x8 block 512 __ASM_EMIT("2:") 513 __ASM_EMIT("add $8, %[count]") 514 __ASM_EMIT("jl 4f") 515 __ASM_EMIT("vmovups 0x00(%[src]), %%ymm0") 516 EFF_HSLA_SAT_CORE_X8 517 __ASM_EMIT("vmovups %%ymm0, 0x000(%[dst])") 518 __ASM_EMIT("vmovups %%ymm1, 0x020(%[dst])") 519 __ASM_EMIT("vmovups %%ymm2, 0x040(%[dst])") 520 __ASM_EMIT("vmovups %%ymm3, 0x060(%[dst])") 521 __ASM_EMIT("sub $8, %[count]") 522 __ASM_EMIT("add $0x20, %[src]") 523 __ASM_EMIT("add $0x80, %[dst]") 524 525 //----------------------------------------------------------------- 526 // x4 block 527 __ASM_EMIT("4:") 528 __ASM_EMIT("add $4, %[count]") 529 __ASM_EMIT("jl 6f") 530 __ASM_EMIT("vmovups 0x00(%[src]), %%xmm0") 531 EFF_HSLA_SAT_CORE_X4 532 __ASM_EMIT("vmovups %%xmm0, 0x000(%[dst])") 533 __ASM_EMIT("vmovups %%xmm1, 0x010(%[dst])") 534 __ASM_EMIT("vmovups %%xmm2, 0x020(%[dst])") 535 __ASM_EMIT("vmovups %%xmm3, 0x030(%[dst])") 536 __ASM_EMIT("sub $4, %[count]") 537 __ASM_EMIT("add $0x10, %[src]") 538 __ASM_EMIT("add $0x40, %[dst]") 539 540 //----------------------------------------------------------------- 541 // x1-x3 block 542 __ASM_EMIT("6:") 543 __ASM_EMIT("add $4, %[count]") 544 __ASM_EMIT("jle 14f") 545 __ASM_EMIT("test $1, %[count]") 546 __ASM_EMIT("jz 8f") 547 __ASM_EMIT("vmovss 0x00(%[src]), %%xmm0") 548 __ASM_EMIT("add $0x04, %[src]") 549 __ASM_EMIT("8:") 550 __ASM_EMIT("test $2, %[count]") 551 __ASM_EMIT("jz 10f") 552 __ASM_EMIT("vmovhps 0x00(%[src]), %%xmm0, %%xmm0") 553 __ASM_EMIT("10:") 554 555 EFF_HSLA_SAT_CORE_X4 556 557 // Store last chunk 558 __ASM_EMIT("test $1, %[count]") 559 __ASM_EMIT("jz 12f") 560 __ASM_EMIT("vmovups %%xmm0, 0x00(%[dst])") 561 __ASM_EMIT("add $0x10, %[dst]") 562 __ASM_EMIT("12:") 563 __ASM_EMIT("test $2, %[count]") 564 __ASM_EMIT("jz 14f") 565 __ASM_EMIT("vmovups %%xmm2, 0x00(%[dst])") 566 __ASM_EMIT("vmovups %%xmm3, 0x10(%[dst])") 567 568 __ASM_EMIT("14:") 569 570 : [dst] "+r" (dst), [src] "+r" (v), [count] "+r" (count) 571 : [eff] "r" (eff), 572 [XC] "o" (EFF_HSLA_SAT_XC) 573 : "cc", "memory", 574 "%xmm0", "%xmm1", "%xmm2", "%xmm3", 575 "%xmm4", "%xmm5", "%xmm6", "%xmm7", 576 "%xmm8", "%xmm9", "%xmm10", "%xmm11", 577 "%xmm12", "%xmm13", "%xmm14", "%xmm15" 578 ); 579 } 580 581 static const uint32_t EFF_HSLA_LIGHT_XC[] __lsp_aligned32 = 582 { 583 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, 584 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff 585 }; 586 587 #define EFF_HSLA_LIGHT_CORE_X16 \ 588 /* ymm0 = v, ymm10 = h, ymm11 = s, ymm12 = l, ymm13 = T, ymm14 = ABS, ymm15 = KT */ \ 589 __ASM_EMIT("vandps %%ymm14, %%ymm0, %%ymm0") /* ymm0 = V = abs(v) */ \ 590 __ASM_EMIT("vandps %%ymm14, %%ymm4, %%ymm4") \ 591 __ASM_EMIT("vxorps %%ymm8, %%ymm8, %%ymm8") /* ymm8 = 0 */ \ 592 __ASM_EMIT("vsubps %%ymm0, %%ymm13, %%ymm3") /* ymm3 = T-V */ \ 593 __ASM_EMIT("vsubps %%ymm4, %%ymm13, %%ymm7") \ 594 __ASM_EMIT("vblendvps %%ymm3, %%ymm0, %%ymm13, %%ymm2") /* ymm2 = ((T-V)<0) ? V : T */ \ 595 __ASM_EMIT("vblendvps %%ymm7, %%ymm4, %%ymm13, %%ymm6") \ 596 __ASM_EMIT("vblendvps %%ymm3, %%ymm8, %%ymm3, %%ymm3") /* ymm3 = ((T-V)<0) ? 0 : T-V */ \ 597 __ASM_EMIT("vblendvps %%ymm7, %%ymm8, %%ymm7, %%ymm7") \ 598 __ASM_EMIT("vmulps %%ymm12, %%ymm2, %%ymm2") /* ymm2 = L = l * (((T-V)<0) ? V : T) */ \ 599 __ASM_EMIT("vmulps %%ymm12, %%ymm6, %%ymm6") \ 600 __ASM_EMIT("vmulps %%ymm15, %%ymm3, %%ymm3") /* ymm3 = A = kt * (((T-V)<0) ? 0 : T-V) */ \ 601 __ASM_EMIT("vmulps %%ymm15, %%ymm7, %%ymm7") \ 602 __ASM_EMIT("vmovaps %%ymm10, %%ymm0") /* ymm0 = H */ \ 603 __ASM_EMIT("vmovaps %%ymm10, %%ymm4") \ 604 __ASM_EMIT("vmovaps %%ymm11, %%ymm1") /* ymm1 = S */ \ 605 __ASM_EMIT("vmovaps %%ymm11, %%ymm5") \ 606 MAT4_TRANSPOSE("%%ymm0", "%%ymm1", "%%ymm2", "%%ymm3", "%%ymm8", "%%ymm9") \ 607 MAT4_TRANSPOSE("%%ymm4", "%%ymm5", "%%ymm6", "%%ymm7", "%%ymm8", "%%ymm9") \ 608 MAT4X2_INTERLEAVE("0", "1", "2", "3", "8", "9") \ 609 MAT4X2_INTERLEAVE("4", "5", "6", "7", "8", "9") 610 611 #define EFF_HSLA_LIGHT_CORE_X8 \ 612 /* ymm0 = v, ymm10 = h, ymm11 = s, ymm12 = l, ymm13 = T, ymm14 = ABS, ymm15 = KT */ \ 613 __ASM_EMIT("vandps %%ymm14, %%ymm0, %%ymm0") /* ymm0 = V = abs(v) */ \ 614 __ASM_EMIT("vxorps %%ymm8, %%ymm8, %%ymm8") /* ymm8 = 0 */ \ 615 __ASM_EMIT("vsubps %%ymm0, %%ymm13, %%ymm3") /* ymm3 = T-V */ \ 616 __ASM_EMIT("vblendvps %%ymm3, %%ymm0, %%ymm13, %%ymm2") /* ymm2 = ((T-V)<0) ? V : T */ \ 617 __ASM_EMIT("vblendvps %%ymm3, %%ymm8, %%ymm3, %%ymm3") /* ymm3 = ((T-V)<0) ? 0 : T-V */ \ 618 __ASM_EMIT("vmulps %%ymm12, %%ymm2, %%ymm2") /* ymm2 = L = l * (((T-V)<0) ? V : T) */ \ 619 __ASM_EMIT("vmulps %%ymm15, %%ymm3, %%ymm3") /* ymm3 = A = kt * (((T-V)<0) ? 0 : T-V) */ \ 620 __ASM_EMIT("vmovaps %%ymm10, %%ymm0") /* ymm0 = H */ \ 621 __ASM_EMIT("vmovaps %%ymm11, %%ymm1") /* ymm1 = S */ \ 622 MAT4_TRANSPOSE("%%ymm0", "%%ymm1", "%%ymm2", "%%ymm3", "%%ymm8", "%%ymm9") \ 623 MAT4X2_INTERLEAVE("0", "1", "2", "3", "8", "9") 624 625 #define EFF_HSLA_LIGHT_CORE_X4 \ 626 /* xmm0 = v, xmm10 = h, xmm11 = s, xmm12 = l, xmm13 = T, xmm14 = ABS, xmm15 = KT */ \ 627 __ASM_EMIT("vandps %%xmm14, %%xmm0, %%xmm0") /* xmm0 = V = abs(v) */ \ 628 __ASM_EMIT("vxorps %%xmm8, %%xmm8, %%xmm8") /* xmm8 = 0 */ \ 629 __ASM_EMIT("vsubps %%xmm0, %%xmm13, %%xmm3") /* xmm3 = T-V */ \ 630 __ASM_EMIT("vblendvps %%xmm3, %%xmm0, %%xmm13, %%xmm2") /* xmm2 = ((T-V)<0) ? V : T */ \ 631 __ASM_EMIT("vblendvps %%xmm3, %%xmm8, %%xmm3, %%xmm3") /* xmm3 = ((T-V)<0) ? 0 : T-V */ \ 632 __ASM_EMIT("vmulps %%xmm12, %%xmm2, %%xmm2") /* xmm2 = L = l * (((T-V)<0) ? V : T) */ \ 633 __ASM_EMIT("vmulps %%xmm15, %%xmm3, %%xmm3") /* xmm3 = A = kt * (((T-V)<0) ? 0 : T-V) */ \ 634 __ASM_EMIT("vmovaps %%xmm10, %%xmm0") /* xmm0 = H */ \ 635 __ASM_EMIT("vmovaps %%xmm11, %%xmm1") /* xmm1 = S */ \ 636 MAT4_TRANSPOSE("%%xmm0", "%%xmm1", "%%xmm2", "%%xmm3", "%%xmm8", "%%xmm9") 637 638 /* 639 value = (value >= 0.0f) ? value : -value; 640 641 if ((eff->thresh - value) < 0) 642 { 643 dst[2] = eff->l * value; 644 dst[3] = 0.0f; 645 } 646 else 647 { 648 dst[2] = eff->l * eff->thresh; 649 dst[3] = (eff->thresh - value) * kt; 650 } 651 652 dst[0] = eff->h; 653 dst[1] = eff->s; 654 */ 655 x64_eff_hsla_light(float * dst,const float * v,const dsp::hsla_light_eff_t * eff,size_t count)656 void x64_eff_hsla_light(float *dst, const float *v, const dsp::hsla_light_eff_t *eff, size_t count) 657 { 658 ARCH_X86_ASM( 659 //----------------------------------------------------------------- 660 // Prepare 661 __ASM_EMIT("vbroadcastf128 0x00(%[eff]), %%ymm10") /* ymm12 = h s l a h s l a */ 662 __ASM_EMIT("vmovaps 0x00 + %[XC], %%ymm15") /* ymm15 = 1 */ 663 __ASM_EMIT("vshufps $0xaa, %%ymm10, %%ymm10, %%ymm12") /* ymm12 = l */ 664 __ASM_EMIT("vmovaps 0x20 + %[XC], %%ymm14") /* ymm14 = ABS */ 665 __ASM_EMIT("vshufps $0x55, %%ymm10, %%ymm10, %%ymm11") /* ymm11 = s */ 666 __ASM_EMIT("vbroadcastss 0x10(%[eff]), %%ymm13") /* ymm13 = T */ 667 __ASM_EMIT("vshufps $0x00, %%ymm10, %%ymm10, %%ymm10") /* ymm10 = h */ 668 __ASM_EMIT("vdivps %%ymm13, %%ymm15, %%ymm15") /* ymm15 = KT = 1/T */ 669 670 //----------------------------------------------------------------- 671 // x16 blocks 672 __ASM_EMIT("sub $16, %[count]") 673 __ASM_EMIT("jb 2f") 674 __ASM_EMIT("1:") 675 __ASM_EMIT("vmovups 0x00(%[src]), %%ymm0") 676 __ASM_EMIT("vmovups 0x20(%[src]), %%ymm4") 677 EFF_HSLA_LIGHT_CORE_X16 678 __ASM_EMIT("vmovups %%ymm0, 0x000(%[dst])") 679 __ASM_EMIT("vmovups %%ymm1, 0x020(%[dst])") 680 __ASM_EMIT("vmovups %%ymm2, 0x040(%[dst])") 681 __ASM_EMIT("vmovups %%ymm3, 0x060(%[dst])") 682 __ASM_EMIT("vmovups %%ymm4, 0x080(%[dst])") 683 __ASM_EMIT("vmovups %%ymm5, 0x0a0(%[dst])") 684 __ASM_EMIT("vmovups %%ymm6, 0x0c0(%[dst])") 685 __ASM_EMIT("vmovups %%ymm7, 0x0e0(%[dst])") 686 __ASM_EMIT("add $0x40, %[src]") 687 __ASM_EMIT("add $0x100, %[dst]") 688 __ASM_EMIT("sub $16, %[count]") 689 __ASM_EMIT("jae 1b") 690 691 //----------------------------------------------------------------- 692 // x8 block 693 __ASM_EMIT("2:") 694 __ASM_EMIT("add $8, %[count]") 695 __ASM_EMIT("jl 4f") 696 __ASM_EMIT("vmovups 0x00(%[src]), %%ymm0") 697 EFF_HSLA_LIGHT_CORE_X8 698 __ASM_EMIT("vmovups %%ymm0, 0x000(%[dst])") 699 __ASM_EMIT("vmovups %%ymm1, 0x020(%[dst])") 700 __ASM_EMIT("vmovups %%ymm2, 0x040(%[dst])") 701 __ASM_EMIT("vmovups %%ymm3, 0x060(%[dst])") 702 __ASM_EMIT("sub $8, %[count]") 703 __ASM_EMIT("add $0x20, %[src]") 704 __ASM_EMIT("add $0x80, %[dst]") 705 706 //----------------------------------------------------------------- 707 // x4 block 708 __ASM_EMIT("4:") 709 __ASM_EMIT("add $4, %[count]") 710 __ASM_EMIT("jl 6f") 711 __ASM_EMIT("vmovups 0x00(%[src]), %%xmm0") 712 EFF_HSLA_LIGHT_CORE_X4 713 __ASM_EMIT("vmovups %%xmm0, 0x000(%[dst])") 714 __ASM_EMIT("vmovups %%xmm1, 0x010(%[dst])") 715 __ASM_EMIT("vmovups %%xmm2, 0x020(%[dst])") 716 __ASM_EMIT("vmovups %%xmm3, 0x030(%[dst])") 717 __ASM_EMIT("sub $4, %[count]") 718 __ASM_EMIT("add $0x10, %[src]") 719 __ASM_EMIT("add $0x40, %[dst]") 720 721 //----------------------------------------------------------------- 722 // x1-x3 block 723 __ASM_EMIT("6:") 724 __ASM_EMIT("add $4, %[count]") 725 __ASM_EMIT("jle 14f") 726 __ASM_EMIT("test $1, %[count]") 727 __ASM_EMIT("jz 8f") 728 __ASM_EMIT("vmovss 0x00(%[src]), %%xmm0") 729 __ASM_EMIT("add $0x04, %[src]") 730 __ASM_EMIT("8:") 731 __ASM_EMIT("test $2, %[count]") 732 __ASM_EMIT("jz 10f") 733 __ASM_EMIT("vmovhps 0x00(%[src]), %%xmm0, %%xmm0") 734 __ASM_EMIT("10:") 735 736 EFF_HSLA_LIGHT_CORE_X4 737 738 // Store last chunk 739 __ASM_EMIT("test $1, %[count]") 740 __ASM_EMIT("jz 12f") 741 __ASM_EMIT("vmovups %%xmm0, 0x00(%[dst])") 742 __ASM_EMIT("add $0x10, %[dst]") 743 __ASM_EMIT("12:") 744 __ASM_EMIT("test $2, %[count]") 745 __ASM_EMIT("jz 14f") 746 __ASM_EMIT("vmovups %%xmm2, 0x00(%[dst])") 747 __ASM_EMIT("vmovups %%xmm3, 0x10(%[dst])") 748 749 __ASM_EMIT("14:") 750 751 : [dst] "+r" (dst), [src] "+r" (v), [count] "+r" (count) 752 : [eff] "r" (eff), 753 [XC] "o" (EFF_HSLA_LIGHT_XC) 754 : "cc", "memory", 755 "%xmm0", "%xmm1", "%xmm2", "%xmm3", 756 "%xmm4", "%xmm5", "%xmm6", "%xmm7", 757 "%xmm8", "%xmm9", "%xmm10", "%xmm11", 758 "%xmm12", "%xmm13", "%xmm14", "%xmm15" 759 ); 760 } 761 } 762 763 #endif /* ARCH_X86_64 */ 764 765 #endif /* INCLUDE_DSP_ARCH_X86_AVX2_GRAPHICS_EFFECTS_H_ */ 766