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: 21 нояб. 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 DSP_ARCH_ARM_NEON_D32_GRAPHICS_EFFECTS_H_ 23 #define DSP_ARCH_ARM_NEON_D32_GRAPHICS_EFFECTS_H_ 24 25 #ifndef DSP_ARCH_ARM_NEON_32_IMPL 26 #error "This header should not be included directly" 27 #endif /* DSP_ARCH_ARM_NEON_32_IMPL */ 28 29 namespace neon_d32 30 { 31 IF_ARCH_ARM 32 ( 33 static const float EFF_HSLA_HUE_XC[] __lsp_aligned16 = 34 { 35 1.0f, 1.0f, 1.0f, 1.0f 36 }; 37 ) 38 39 40 #define X8_TRANSPOSE \ 41 __ASM_EMIT("vtrn.32 q0, q1") \ 42 __ASM_EMIT("vtrn.32 q2, q3") \ 43 __ASM_EMIT("vtrn.32 q4, q5") \ 44 __ASM_EMIT("vtrn.32 q6, q7") \ 45 __ASM_EMIT("vswp d4, d1") \ 46 __ASM_EMIT("vswp d12, d9") \ 47 __ASM_EMIT("vswp d6, d3") \ 48 __ASM_EMIT("vswp d14, d11") 49 50 #define EFF_HSLA_HUE_CORE \ 51 /* q0 = v0 */ \ 52 /* q1 = v1 */ \ 53 /* q8 = h */ \ 54 /* q9 = s */ \ 55 /* q10 = l */ \ 56 /* q11 = a */ \ 57 /* q12 = T */ \ 58 /* q13 = KT */ \ 59 /* q14 = 0 */ \ 60 /* q15 = 1 */ \ 61 __ASM_EMIT("vmov q4, q1") /* q4 = v1 */ \ 62 __ASM_EMIT("vsub.f32 q2, q15, q0") /* q2 = 1 - v */ \ 63 __ASM_EMIT("vsub.f32 q6, q15, q4") \ 64 __ASM_EMIT("vcge.f32 q3, q14, q0") /* q3 = 0 > v */ \ 65 __ASM_EMIT("vcge.f32 q7, q14, q4") \ 66 __ASM_EMIT("vadd.f32 q0, q0, q15") /* q0 = v + 1 */ \ 67 __ASM_EMIT("vadd.f32 q4, q4, q15") \ 68 __ASM_EMIT("vbif q0, q2, q3") /* q0 = V = (v+1)&[0>v] | (1-v)&[0<=v] */ \ 69 __ASM_EMIT("vbif q4, q6, q7") \ 70 __ASM_EMIT("vsub.f32 q3, q0, q12") /* q3 = V - T */ \ 71 __ASM_EMIT("vsub.f32 q7, q4, q12") \ 72 __ASM_EMIT("vcge.f32 q1, q3, q14") /* q1 = [(V-T)>=0] */ \ 73 __ASM_EMIT("vcge.f32 q5, q7, q14") \ 74 __ASM_EMIT("vmul.f32 q3, q3, q13") /* q3 = (V-T)*KT */ \ 75 __ASM_EMIT("vmul.f32 q7, q7, q13") \ 76 __ASM_EMIT("vbit q0, q12, q1") /* q0 = EH = T&[(V-T)>=0] | V&[(V-T)<0] */ \ 77 __ASM_EMIT("vbit q4, q12, q5") \ 78 __ASM_EMIT("vand q3, q3, q1") /* q3 = A = ((V-T)*KT) & [(V-T)>=0] */ \ 79 __ASM_EMIT("vand q7, q7, q5") \ 80 __ASM_EMIT("vadd.f32 q0, q0, q8") /* q0 = H = h + T&[(V-T)>=0] | V&[(V-T)<0] */ \ 81 __ASM_EMIT("vadd.f32 q4, q4, q8") \ 82 __ASM_EMIT("vmov q1, q9") /* q1 = s */ \ 83 __ASM_EMIT("vmov q2, q10") /* q2 = l */ \ 84 __ASM_EMIT("vmov q5, q9") \ 85 __ASM_EMIT("vmov q6, q10") \ 86 /* Transpose back */ \ 87 X8_TRANSPOSE 88 89 /* 90 float t = 1.0f - eff->thresh; 91 float kt = 1.0f / eff->thresh; 92 93 value = v[i]; 94 value = (0 > value) ? 1.0f + value : 1.0f - value; 95 96 if ((value - t) >= 0) 97 { 98 hue = eff->h + t; 99 alpha = ((value - t) * kt); 100 } 101 else 102 { 103 hue = eff->h + value; 104 alpha = 0.0f; 105 } 106 107 dst[0] = (hue < 1.0f) ? hue : hue - 1.0f; 108 dst[1] = eff->s; 109 dst[2] = eff->l; 110 dst[3] = alpha; 111 */ 112 eff_hsla_hue(float * dst,const float * v,const dsp::hsla_hue_eff_t * eff,size_t count)113 void eff_hsla_hue(float *dst, const float *v, const dsp::hsla_hue_eff_t *eff, size_t count) 114 { 115 ARCH_ARM_ASM 116 ( 117 __ASM_EMIT("vld1.32 {q8}, [%[eff]]!") /* q8 = hsla */ 118 __ASM_EMIT("vldm %[XC], {q15}") /* q15 = 1 */ 119 __ASM_EMIT("vmov q9, q8") /* q9 = hsla */ 120 __ASM_EMIT("vld1.32 {d24[], d25[]}, [%[eff]]") /* q12 = t */ 121 __ASM_EMIT("vmov q10, q8") /* q10 = hsla */ 122 __ASM_EMIT("veor q14, q14") /* q14 = 0 */ 123 __ASM_EMIT("vmov q11, q8") /* q11 = hsla */ 124 __ASM_EMIT("vrecpe.f32 q0, q12") /* q0 = TD */ 125 __ASM_EMIT("vtrn.32 q8, q9") 126 __ASM_EMIT("vrecps.f32 q1, q0, q12") /* q1 = (2 - TD*T) */ 127 __ASM_EMIT("vtrn.32 q10, q11") 128 __ASM_EMIT("vmul.f32 q0, q1, q0") /* q0 = t' = TD * (2 - TD*T) */ 129 __ASM_EMIT("vswp d20, d17") 130 __ASM_EMIT("vrecps.f32 q1, q0, q12") /* q1 = (2 - TD*t') */ 131 __ASM_EMIT("vswp d22, d19") 132 __ASM_EMIT("vsub.f32 q12, q15, q12") /* q12 = T = 1 - t */ 133 __ASM_EMIT("vmul.f32 q13, q1, q0") /* q13 = KT = 1/t = t' * (2 - TD*t') */ 134 135 __ASM_EMIT("subs %[count], $8") 136 __ASM_EMIT("blo 2f") 137 138 //----------------------------------------------------------------- 139 // 8x blocks 140 __ASM_EMIT("1:") 141 142 __ASM_EMIT("vld1.32 {q0-q1}, [%[src]]!") /* q0 = v0, q1 = v1 */ 143 144 EFF_HSLA_HUE_CORE 145 146 __ASM_EMIT("subs %[count], $8") 147 __ASM_EMIT("vstm %[dst]!, {q0-q7}") 148 __ASM_EMIT("bhs 1b") 149 150 //----------------------------------------------------------------- 151 // 1x-8x block 152 __ASM_EMIT("2:") 153 __ASM_EMIT("adds %[count], $8") 154 __ASM_EMIT("bls 14f") 155 156 __ASM_EMIT("tst %[count], $4") 157 __ASM_EMIT("beq 4f") 158 __ASM_EMIT("vld1.32 {q0}, [%[src]]!") 159 __ASM_EMIT("4:") 160 __ASM_EMIT("tst %[count], $2") 161 __ASM_EMIT("beq 6f") 162 __ASM_EMIT("vld1.32 {d2}, [%[src]]!") 163 __ASM_EMIT("6:") 164 __ASM_EMIT("tst %[count], $1") 165 __ASM_EMIT("beq 8f") 166 __ASM_EMIT("vld1.32 d3[0], [%[src]]") 167 __ASM_EMIT("8:") 168 169 EFF_HSLA_HUE_CORE 170 171 __ASM_EMIT("tst %[count], $4") 172 __ASM_EMIT("beq 10f") 173 __ASM_EMIT("vstm %[dst]!, {q0-q3}") 174 __ASM_EMIT("10:") 175 __ASM_EMIT("tst %[count], $2") 176 __ASM_EMIT("beq 12f") 177 __ASM_EMIT("vstm %[dst]!, {q4-q5}") 178 __ASM_EMIT("12:") 179 __ASM_EMIT("tst %[count], $1") 180 __ASM_EMIT("beq 14f") 181 __ASM_EMIT("vstm %[dst], {q6}") 182 183 __ASM_EMIT("14:") 184 185 186 : [dst] "+r" (dst), [src] "+r" (v), [count] "+r" (count), 187 [eff] "+r" (eff) 188 : [XC] "r" (&EFF_HSLA_HUE_XC[0]) 189 : "cc", "memory", 190 "q0", "q1", "q2", "q3" , "q4", "q5", "q6", "q7", 191 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15" 192 ); 193 } 194 195 #undef EFF_HSLA_HUE_CORE 196 197 #define EFF_HSLA_SAT_CORE \ 198 /* q0 = v0 */ \ 199 /* q1 = v1 */ \ 200 /* q8 = h */ \ 201 /* q9 = s */ \ 202 /* q10 = l */ \ 203 /* q11 = a */ \ 204 /* q13 = 0 */ \ 205 /* q14 = T */ \ 206 /* q15 = KT */ \ 207 __ASM_EMIT("vabs.f32 q5, q1") /* q5 = V1 = abs(v1) */ \ 208 __ASM_EMIT("vabs.f32 q1, q0") /* q1 = V = abs(v) */ \ 209 __ASM_EMIT("vsub.f32 q3, q14, q1") /* q3 = T - V */ \ 210 __ASM_EMIT("vsub.f32 q7, q14, q5") \ 211 __ASM_EMIT("vcgt.f32 q2, q3, q13") /* q2 = [(T-V) > 0] */ \ 212 __ASM_EMIT("vcgt.f32 q6, q7, q13") \ 213 __ASM_EMIT("vmul.f32 q3, q3, q15") /* q3 = (T-V)*KT */ \ 214 __ASM_EMIT("vmul.f32 q7, q7, q15") \ 215 __ASM_EMIT("vbit q1, q14, q2") /* q1 = ES = V&[(T-V) <= 0] | T&[(T-V) > 0] */ \ 216 __ASM_EMIT("vbit q5, q14, q6") \ 217 __ASM_EMIT("vand q3, q3, q2") /* q3 = A = ((T-V)*KT) & [(T-V) > 0] */ \ 218 __ASM_EMIT("vand q7, q7, q6") \ 219 __ASM_EMIT("vmul.f32 q1, q1, q9") /* q1 = ES*s = S */ \ 220 __ASM_EMIT("vmul.f32 q5, q5, q9") \ 221 __ASM_EMIT("vmov q0, q8") \ 222 __ASM_EMIT("vmov q2, q10") \ 223 __ASM_EMIT("vmov q4, q8") \ 224 __ASM_EMIT("vmov q6, q10") \ 225 /* Transpose back */ \ 226 X8_TRANSPOSE 227 228 /* 229 kt = 1.0f / eff->thresh; 230 value = (value >= 0.0f) ? value : -value; 231 232 if ((eff->thresh - value) <= 0) 233 { 234 dst[1] = eff->s * value; 235 dst[3] = 0.0f; 236 } 237 else 238 { 239 dst[1] = eff->s * eff->thresh; 240 dst[3] = (eff->thresh - value) * kt; 241 } 242 243 dst[0] = eff->h; 244 dst[2] = eff->l; 245 */ 246 eff_hsla_sat(float * dst,const float * v,const dsp::hsla_sat_eff_t * eff,size_t count)247 void eff_hsla_sat(float *dst, const float *v, const dsp::hsla_sat_eff_t *eff, size_t count) 248 { 249 ARCH_ARM_ASM 250 ( 251 __ASM_EMIT("vld1.32 {q8}, [%[eff]]!") /* q8 = hsla */ 252 __ASM_EMIT("vld1.32 {d28[], d29[]}, [%[eff]]") /* q14 = T */ 253 __ASM_EMIT("vmov q9, q8") /* q9 = hsla */ 254 __ASM_EMIT("vrecpe.f32 q0, q14") /* q0 = TD */ 255 __ASM_EMIT("vtrn.32 q8, q9") 256 __ASM_EMIT("vrecps.f32 q1, q0, q14") /* q1 = (2 - TD*T) */ 257 __ASM_EMIT("vmov q10, q8") /* q10 = hsla */ 258 __ASM_EMIT("vmul.f32 q0, q1, q0") /* q0 = t' = TD * (2 - TD*T) */ 259 __ASM_EMIT("vmov q11, q9") /* q11 = hsla */ 260 __ASM_EMIT("vrecps.f32 q1, q0, q14") /* q1 = (2 - TD*t') */ 261 __ASM_EMIT("vswp d20, d17") 262 __ASM_EMIT("vmul.f32 q15, q1, q0") /* q15 = KT = 1/t = t' * (2 - TD*t') */ 263 __ASM_EMIT("vswp d22, d19") 264 __ASM_EMIT("veor q13, q13") /* q13 = 0 */ 265 266 __ASM_EMIT("subs %[count], $8") 267 __ASM_EMIT("blo 2f") 268 269 //----------------------------------------------------------------- 270 // 8x blocks 271 __ASM_EMIT("1:") 272 273 __ASM_EMIT("vld1.32 {q0-q1}, [%[src]]!") /* q0 = v0, q1 = v1 */ 274 275 EFF_HSLA_SAT_CORE 276 277 __ASM_EMIT("subs %[count], $8") 278 __ASM_EMIT("vstm %[dst]!, {q0-q7}") 279 __ASM_EMIT("bhs 1b") 280 281 //----------------------------------------------------------------- 282 // 1x-8x block 283 __ASM_EMIT("2:") 284 __ASM_EMIT("adds %[count], $8") 285 __ASM_EMIT("bls 14f") 286 287 __ASM_EMIT("tst %[count], $4") 288 __ASM_EMIT("beq 4f") 289 __ASM_EMIT("vld1.32 {q0}, [%[src]]!") 290 __ASM_EMIT("4:") 291 __ASM_EMIT("tst %[count], $2") 292 __ASM_EMIT("beq 6f") 293 __ASM_EMIT("vld1.32 {d2}, [%[src]]!") 294 __ASM_EMIT("6:") 295 __ASM_EMIT("tst %[count], $1") 296 __ASM_EMIT("beq 8f") 297 __ASM_EMIT("vld1.32 d3[0], [%[src]]") 298 __ASM_EMIT("8:") 299 300 EFF_HSLA_SAT_CORE 301 302 __ASM_EMIT("tst %[count], $4") 303 __ASM_EMIT("beq 10f") 304 __ASM_EMIT("vstm %[dst]!, {q0-q3}") 305 __ASM_EMIT("10:") 306 __ASM_EMIT("tst %[count], $2") 307 __ASM_EMIT("beq 12f") 308 __ASM_EMIT("vstm %[dst]!, {q4-q5}") 309 __ASM_EMIT("12:") 310 __ASM_EMIT("tst %[count], $1") 311 __ASM_EMIT("beq 14f") 312 __ASM_EMIT("vstm %[dst], {q6}") 313 314 __ASM_EMIT("14:") 315 316 317 : [dst] "+r" (dst), [src] "+r" (v), [count] "+r" (count), 318 [eff] "+r" (eff) 319 : 320 : "cc", "memory", 321 "q0", "q1", "q2", "q3" , "q4", "q5", "q6", "q7", 322 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15" 323 ); 324 } 325 326 #undef EFF_HSLA_SAT_CORE 327 328 329 #define EFF_HSLA_LIGHT_CORE \ 330 /* q0 = v0 */ \ 331 /* q1 = v1 */ \ 332 /* q8 = h */ \ 333 /* q9 = s */ \ 334 /* q10 = l */ \ 335 /* q11 = a */ \ 336 /* q13 = 0 */ \ 337 /* q14 = T */ \ 338 /* q15 = KT */ \ 339 __ASM_EMIT("vabs.f32 q5, q1") /* q5 = V1 = abs(v1) */ \ 340 __ASM_EMIT("vabs.f32 q1, q0") /* q1 = V = abs(v) */ \ 341 __ASM_EMIT("vsub.f32 q3, q14, q1") /* q3 = T - V */ \ 342 __ASM_EMIT("vsub.f32 q7, q14, q5") \ 343 __ASM_EMIT("vcgt.f32 q2, q3, q13") /* q2 = [(T-V) > 0] */ \ 344 __ASM_EMIT("vcgt.f32 q6, q7, q13") \ 345 __ASM_EMIT("vmul.f32 q3, q3, q15") /* q3 = (T-V)*KT */ \ 346 __ASM_EMIT("vmul.f32 q7, q7, q15") \ 347 __ASM_EMIT("vbit q1, q14, q2") /* q1 = EL = V&[(T-V) <= 0] | T&[(T-V) > 0] */ \ 348 __ASM_EMIT("vbit q5, q14, q6") \ 349 __ASM_EMIT("vand q3, q3, q2") /* q3 = A = ((T-V)*KT) & [(T-V) > 0] */ \ 350 __ASM_EMIT("vand q7, q7, q6") \ 351 __ASM_EMIT("vmul.f32 q2, q1, q10") /* q2 = EL*l = L */ \ 352 __ASM_EMIT("vmul.f32 q6, q5, q10") \ 353 __ASM_EMIT("vmov q0, q8") \ 354 __ASM_EMIT("vmov q1, q9") \ 355 __ASM_EMIT("vmov q4, q8") \ 356 __ASM_EMIT("vmov q5, q9") \ 357 /* Transpose back */ \ 358 X8_TRANSPOSE 359 360 /* 361 kt = 1.0f / eff->thresh; 362 value = (value >= 0.0f) ? value : -value; 363 364 if ((eff->thresh - value) <= 0) 365 { 366 dst[2] = eff->l * value; 367 dst[3] = 0.0f; 368 } 369 else 370 { 371 dst[2] = eff->l * eff->thresh; 372 dst[3] = (eff->thresh - value) * kt; 373 } 374 375 dst[0] = eff->h; 376 dst[1] = eff->s; 377 */ 378 eff_hsla_light(float * dst,const float * v,const dsp::hsla_light_eff_t * eff,size_t count)379 void eff_hsla_light(float *dst, const float *v, const dsp::hsla_light_eff_t *eff, size_t count) 380 { 381 ARCH_ARM_ASM 382 ( 383 __ASM_EMIT("vld1.32 {q8}, [%[eff]]!") /* q8 = hsla */ 384 __ASM_EMIT("vld1.32 {d28[], d29[]}, [%[eff]]") /* q14 = T */ 385 __ASM_EMIT("vmov q9, q8") /* q9 = hsla */ 386 __ASM_EMIT("vrecpe.f32 q0, q14") /* q0 = TD */ 387 __ASM_EMIT("vtrn.32 q8, q9") 388 __ASM_EMIT("vrecps.f32 q1, q0, q14") /* q1 = (2 - TD*T) */ 389 __ASM_EMIT("vmov q10, q8") /* q10 = hsla */ 390 __ASM_EMIT("vmul.f32 q0, q1, q0") /* q0 = t' = TD * (2 - TD*T) */ 391 __ASM_EMIT("vmov q11, q9") /* q11 = hsla */ 392 __ASM_EMIT("vrecps.f32 q1, q0, q14") /* q1 = (2 - TD*t') */ 393 __ASM_EMIT("vswp d20, d17") 394 __ASM_EMIT("vmul.f32 q15, q1, q0") /* q15 = KT = 1/t = t' * (2 - TD*t') */ 395 __ASM_EMIT("vswp d22, d19") 396 __ASM_EMIT("veor q13, q13") /* q13 = 0 */ 397 398 __ASM_EMIT("subs %[count], $8") 399 __ASM_EMIT("blo 2f") 400 401 //----------------------------------------------------------------- 402 // 8x blocks 403 __ASM_EMIT("1:") 404 405 __ASM_EMIT("vld1.32 {q0-q1}, [%[src]]!") /* q0 = v0, q1 = v1 */ 406 407 EFF_HSLA_LIGHT_CORE 408 409 __ASM_EMIT("subs %[count], $8") 410 __ASM_EMIT("vstm %[dst]!, {q0-q7}") 411 __ASM_EMIT("bhs 1b") 412 413 //----------------------------------------------------------------- 414 // 1x-8x block 415 __ASM_EMIT("2:") 416 __ASM_EMIT("adds %[count], $8") 417 __ASM_EMIT("bls 14f") 418 419 __ASM_EMIT("tst %[count], $4") 420 __ASM_EMIT("beq 4f") 421 __ASM_EMIT("vld1.32 {q0}, [%[src]]!") 422 __ASM_EMIT("4:") 423 __ASM_EMIT("tst %[count], $2") 424 __ASM_EMIT("beq 6f") 425 __ASM_EMIT("vld1.32 {d2}, [%[src]]!") 426 __ASM_EMIT("6:") 427 __ASM_EMIT("tst %[count], $1") 428 __ASM_EMIT("beq 8f") 429 __ASM_EMIT("vld1.32 d3[0], [%[src]]") 430 __ASM_EMIT("8:") 431 432 EFF_HSLA_LIGHT_CORE 433 434 __ASM_EMIT("tst %[count], $4") 435 __ASM_EMIT("beq 10f") 436 __ASM_EMIT("vstm %[dst]!, {q0-q3}") 437 __ASM_EMIT("10:") 438 __ASM_EMIT("tst %[count], $2") 439 __ASM_EMIT("beq 12f") 440 __ASM_EMIT("vstm %[dst]!, {q4-q5}") 441 __ASM_EMIT("12:") 442 __ASM_EMIT("tst %[count], $1") 443 __ASM_EMIT("beq 14f") 444 __ASM_EMIT("vstm %[dst], {q6}") 445 446 __ASM_EMIT("14:") 447 448 449 : [dst] "+r" (dst), [src] "+r" (v), [count] "+r" (count), 450 [eff] "+r" (eff) 451 : 452 : "cc", "memory", 453 "q0", "q1", "q2", "q3" , "q4", "q5", "q6", "q7", 454 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15" 455 ); 456 } 457 458 #undef EFF_HSLA_LIGHT_CORE 459 460 IF_ARCH_ARM 461 ( 462 static const float EFF_HSLA_ALPHA_XC[] __lsp_aligned16 = 463 { 464 1.0f, 1.0f, 1.0f, 1.0f 465 }; 466 ) 467 468 469 #define EFF_HSLA_ALPHA_CORE \ 470 /* q0 = v0 */ \ 471 /* q1 = v1 */ \ 472 /* q8 = h */ \ 473 /* q9 = s */ \ 474 /* q10 = l */ \ 475 /* q11 = a */ \ 476 /* q14 = 0 */ \ 477 /* q15 = 1 */ \ 478 __ASM_EMIT("vsub.f32 q2, q15, q0") /* q2 = 1 - v */ \ 479 __ASM_EMIT("vsub.f32 q6, q15, q1") \ 480 __ASM_EMIT("vcgt.f32 q4, q14, q0") /* q4 = 0 > v */ \ 481 __ASM_EMIT("vcgt.f32 q5, q14, q1") \ 482 __ASM_EMIT("vadd.f32 q3, q0, q15") /* q3 = v + 1 */ \ 483 __ASM_EMIT("vadd.f32 q7, q1, q15") \ 484 __ASM_EMIT("vbif q3, q2, q4") /* q0 = V = (v+1)&[0>v] | (1-v)&[0<=v] */ \ 485 __ASM_EMIT("vbif q7, q6, q5") \ 486 __ASM_EMIT("vmov q0, q8") \ 487 __ASM_EMIT("vmov q1, q9") \ 488 __ASM_EMIT("vmov q2, q10") \ 489 __ASM_EMIT("vmov q4, q8") \ 490 __ASM_EMIT("vmov q5, q9") \ 491 __ASM_EMIT("vmov q6, q10") \ 492 /* Transpose back */ \ 493 X8_TRANSPOSE 494 495 /* 496 value = v[i]; 497 value = (0.0f > value) ? 1.0f + value : 1.0f - value; 498 499 dst[0] = eff->h; 500 dst[1] = eff->s; 501 dst[2] = eff->l; 502 dst[3] = value; // Fill alpha channel 503 */ 504 eff_hsla_alpha(float * dst,const float * v,const dsp::hsla_alpha_eff_t * eff,size_t count)505 void eff_hsla_alpha(float *dst, const float *v, const dsp::hsla_alpha_eff_t *eff, size_t count) 506 { 507 ARCH_ARM_ASM 508 ( 509 __ASM_EMIT("vld1.32 {q8}, [%[eff]]") /* q8 = hsla */ 510 __ASM_EMIT("vldm %[XC], {q15}") /* q15 = 1 */ 511 __ASM_EMIT("vmov q9, q8") /* q9 = hsla */ 512 __ASM_EMIT("veor q14, q14") /* q14 = 0 */ 513 __ASM_EMIT("vtrn.32 q8, q9") 514 __ASM_EMIT("vmov q10, q8") 515 __ASM_EMIT("vmov q11, q9") 516 __ASM_EMIT("vswp d20, d17") 517 __ASM_EMIT("vswp d22, d19") 518 519 __ASM_EMIT("subs %[count], $8") 520 __ASM_EMIT("blo 2f") 521 522 //----------------------------------------------------------------- 523 // 8x blocks 524 __ASM_EMIT("1:") 525 526 __ASM_EMIT("vld1.32 {q0-q1}, [%[src]]!") /* q0 = v0, q1 = v1 */ 527 528 EFF_HSLA_ALPHA_CORE 529 530 __ASM_EMIT("subs %[count], $8") 531 __ASM_EMIT("vstm %[dst]!, {q0-q7}") 532 __ASM_EMIT("bhs 1b") 533 534 //----------------------------------------------------------------- 535 // 1x-8x block 536 __ASM_EMIT("2:") 537 __ASM_EMIT("adds %[count], $8") 538 __ASM_EMIT("bls 14f") 539 540 __ASM_EMIT("tst %[count], $4") 541 __ASM_EMIT("beq 4f") 542 __ASM_EMIT("vld1.32 {q0}, [%[src]]!") 543 __ASM_EMIT("4:") 544 __ASM_EMIT("tst %[count], $2") 545 __ASM_EMIT("beq 6f") 546 __ASM_EMIT("vld1.32 {d2}, [%[src]]!") 547 __ASM_EMIT("6:") 548 __ASM_EMIT("tst %[count], $1") 549 __ASM_EMIT("beq 8f") 550 __ASM_EMIT("vld1.32 d3[0], [%[src]]") 551 __ASM_EMIT("8:") 552 553 EFF_HSLA_ALPHA_CORE 554 555 __ASM_EMIT("tst %[count], $4") 556 __ASM_EMIT("beq 10f") 557 __ASM_EMIT("vstm %[dst]!, {q0-q3}") 558 __ASM_EMIT("10:") 559 __ASM_EMIT("tst %[count], $2") 560 __ASM_EMIT("beq 12f") 561 __ASM_EMIT("vstm %[dst]!, {q4-q5}") 562 __ASM_EMIT("12:") 563 __ASM_EMIT("tst %[count], $1") 564 __ASM_EMIT("beq 14f") 565 __ASM_EMIT("vstm %[dst], {q6}") 566 567 __ASM_EMIT("14:") 568 569 570 : [dst] "+r" (dst), [src] "+r" (v), [count] "+r" (count) 571 : [XC] "r" (&EFF_HSLA_ALPHA_XC[0]), [eff] "r" (eff) 572 : "cc", "memory", 573 "q0", "q1", "q2", "q3" , "q4", "q5", "q6", "q7", 574 "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15" 575 ); 576 } 577 578 #undef EFF_HSLA_ALPHA_CORE 579 580 #undef X8_TRANSPOSE 581 582 } 583 584 #endif /* DSP_ARCH_ARM_NEON_D32_GRAPHICS_EFFECTS_H_ */ 585