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