1 ; 2 ; Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3 ; 4 ; Use of this source code is governed by a BSD-style license 5 ; that can be found in the LICENSE file in the root of the source 6 ; tree. An additional intellectual property rights grant can be found 7 ; in the file PATENTS. All contributing project authors may 8 ; be found in the AUTHORS file in the root of the source tree. 9 ; 10 11 12 EXPORT |vp8_sixtap_predict8x4_neon| 13 ARM 14 REQUIRE8 15 PRESERVE8 16 17 AREA ||.text||, CODE, READONLY, ALIGN=2 18 ; r0 unsigned char *src_ptr, 19 ; r1 int src_pixels_per_line, 20 ; r2 int xoffset, 21 ; r3 int yoffset, 22 ; r4 unsigned char *dst_ptr, 23 ; stack(r5) int dst_pitch 24 25 |vp8_sixtap_predict8x4_neon| PROC 26 push {r4-r5, lr} 27 28 ldr r12, _filter8_coeff_ 29 ldr r4, [sp, #12] ;load parameters from stack 30 ldr r5, [sp, #16] ;load parameters from stack 31 32 cmp r2, #0 ;skip first_pass filter if xoffset=0 33 beq secondpass_filter8x4_only 34 35 add r2, r12, r2, lsl #5 ;calculate filter location 36 37 cmp r3, #0 ;skip second_pass filter if yoffset=0 38 39 vld1.s32 {q14, q15}, [r2] ;load first_pass filter 40 41 beq firstpass_filter8x4_only 42 43 sub sp, sp, #32 ;reserve space on stack for temporary storage 44 vabs.s32 q12, q14 45 vabs.s32 q13, q15 46 47 sub r0, r0, #2 ;move srcptr back to (line-2) and (column-2) 48 mov lr, sp 49 sub r0, r0, r1, lsl #1 50 51 vdup.8 d0, d24[0] ;first_pass filter (d0-d5) 52 vdup.8 d1, d24[4] 53 vdup.8 d2, d25[0] 54 55 ;First pass: output_height lines x output_width columns (9x8) 56 vld1.u8 {q3}, [r0], r1 ;load src data 57 vdup.8 d3, d25[4] 58 vld1.u8 {q4}, [r0], r1 59 vdup.8 d4, d26[0] 60 vld1.u8 {q5}, [r0], r1 61 vdup.8 d5, d26[4] 62 vld1.u8 {q6}, [r0], r1 63 64 pld [r0] 65 pld [r0, r1] 66 pld [r0, r1, lsl #1] 67 68 vmull.u8 q7, d6, d0 ;(src_ptr[-2] * vp8_filter[0]) 69 vmull.u8 q8, d8, d0 70 vmull.u8 q9, d10, d0 71 vmull.u8 q10, d12, d0 72 73 vext.8 d28, d6, d7, #1 ;construct src_ptr[-1] 74 vext.8 d29, d8, d9, #1 75 vext.8 d30, d10, d11, #1 76 vext.8 d31, d12, d13, #1 77 78 vmlsl.u8 q7, d28, d1 ;-(src_ptr[-1] * vp8_filter[1]) 79 vmlsl.u8 q8, d29, d1 80 vmlsl.u8 q9, d30, d1 81 vmlsl.u8 q10, d31, d1 82 83 vext.8 d28, d6, d7, #4 ;construct src_ptr[2] 84 vext.8 d29, d8, d9, #4 85 vext.8 d30, d10, d11, #4 86 vext.8 d31, d12, d13, #4 87 88 vmlsl.u8 q7, d28, d4 ;-(src_ptr[2] * vp8_filter[4]) 89 vmlsl.u8 q8, d29, d4 90 vmlsl.u8 q9, d30, d4 91 vmlsl.u8 q10, d31, d4 92 93 vext.8 d28, d6, d7, #2 ;construct src_ptr[0] 94 vext.8 d29, d8, d9, #2 95 vext.8 d30, d10, d11, #2 96 vext.8 d31, d12, d13, #2 97 98 vmlal.u8 q7, d28, d2 ;(src_ptr[0] * vp8_filter[2]) 99 vmlal.u8 q8, d29, d2 100 vmlal.u8 q9, d30, d2 101 vmlal.u8 q10, d31, d2 102 103 vext.8 d28, d6, d7, #5 ;construct src_ptr[3] 104 vext.8 d29, d8, d9, #5 105 vext.8 d30, d10, d11, #5 106 vext.8 d31, d12, d13, #5 107 108 vmlal.u8 q7, d28, d5 ;(src_ptr[3] * vp8_filter[5]) 109 vmlal.u8 q8, d29, d5 110 vmlal.u8 q9, d30, d5 111 vmlal.u8 q10, d31, d5 112 113 vext.8 d28, d6, d7, #3 ;construct src_ptr[1] 114 vext.8 d29, d8, d9, #3 115 vext.8 d30, d10, d11, #3 116 vext.8 d31, d12, d13, #3 117 118 vmull.u8 q3, d28, d3 ;(src_ptr[1] * vp8_filter[3]) 119 vmull.u8 q4, d29, d3 120 vmull.u8 q5, d30, d3 121 vmull.u8 q6, d31, d3 122 123 vqadd.s16 q7, q3 ;sum of all (src_data*filter_parameters) 124 vqadd.s16 q8, q4 125 vqadd.s16 q9, q5 126 vqadd.s16 q10, q6 127 128 vld1.u8 {q3}, [r0], r1 ;load src data 129 130 vqrshrun.s16 d22, q7, #7 ;shift/round/saturate to u8 131 vqrshrun.s16 d23, q8, #7 132 vqrshrun.s16 d24, q9, #7 133 vqrshrun.s16 d25, q10, #7 134 135 vld1.u8 {q4}, [r0], r1 136 vst1.u8 {d22}, [lr]! ;store result 137 vld1.u8 {q5}, [r0], r1 138 vst1.u8 {d23}, [lr]! 139 vld1.u8 {q6}, [r0], r1 140 vst1.u8 {d24}, [lr]! 141 vld1.u8 {q7}, [r0], r1 142 vst1.u8 {d25}, [lr]! 143 144 ;first_pass filtering on the rest 5-line data 145 vmull.u8 q8, d6, d0 ;(src_ptr[-2] * vp8_filter[0]) 146 vmull.u8 q9, d8, d0 147 vmull.u8 q10, d10, d0 148 vmull.u8 q11, d12, d0 149 vmull.u8 q12, d14, d0 150 151 vext.8 d27, d6, d7, #1 ;construct src_ptr[-1] 152 vext.8 d28, d8, d9, #1 153 vext.8 d29, d10, d11, #1 154 vext.8 d30, d12, d13, #1 155 vext.8 d31, d14, d15, #1 156 157 vmlsl.u8 q8, d27, d1 ;-(src_ptr[-1] * vp8_filter[1]) 158 vmlsl.u8 q9, d28, d1 159 vmlsl.u8 q10, d29, d1 160 vmlsl.u8 q11, d30, d1 161 vmlsl.u8 q12, d31, d1 162 163 vext.8 d27, d6, d7, #4 ;construct src_ptr[2] 164 vext.8 d28, d8, d9, #4 165 vext.8 d29, d10, d11, #4 166 vext.8 d30, d12, d13, #4 167 vext.8 d31, d14, d15, #4 168 169 vmlsl.u8 q8, d27, d4 ;-(src_ptr[2] * vp8_filter[4]) 170 vmlsl.u8 q9, d28, d4 171 vmlsl.u8 q10, d29, d4 172 vmlsl.u8 q11, d30, d4 173 vmlsl.u8 q12, d31, d4 174 175 vext.8 d27, d6, d7, #2 ;construct src_ptr[0] 176 vext.8 d28, d8, d9, #2 177 vext.8 d29, d10, d11, #2 178 vext.8 d30, d12, d13, #2 179 vext.8 d31, d14, d15, #2 180 181 vmlal.u8 q8, d27, d2 ;(src_ptr[0] * vp8_filter[2]) 182 vmlal.u8 q9, d28, d2 183 vmlal.u8 q10, d29, d2 184 vmlal.u8 q11, d30, d2 185 vmlal.u8 q12, d31, d2 186 187 vext.8 d27, d6, d7, #5 ;construct src_ptr[3] 188 vext.8 d28, d8, d9, #5 189 vext.8 d29, d10, d11, #5 190 vext.8 d30, d12, d13, #5 191 vext.8 d31, d14, d15, #5 192 193 vmlal.u8 q8, d27, d5 ;(src_ptr[3] * vp8_filter[5]) 194 vmlal.u8 q9, d28, d5 195 vmlal.u8 q10, d29, d5 196 vmlal.u8 q11, d30, d5 197 vmlal.u8 q12, d31, d5 198 199 vext.8 d27, d6, d7, #3 ;construct src_ptr[1] 200 vext.8 d28, d8, d9, #3 201 vext.8 d29, d10, d11, #3 202 vext.8 d30, d12, d13, #3 203 vext.8 d31, d14, d15, #3 204 205 vmull.u8 q3, d27, d3 ;(src_ptr[1] * vp8_filter[3]) 206 vmull.u8 q4, d28, d3 207 vmull.u8 q5, d29, d3 208 vmull.u8 q6, d30, d3 209 vmull.u8 q7, d31, d3 210 211 vqadd.s16 q8, q3 ;sum of all (src_data*filter_parameters) 212 vqadd.s16 q9, q4 213 vqadd.s16 q10, q5 214 vqadd.s16 q11, q6 215 vqadd.s16 q12, q7 216 217 vqrshrun.s16 d26, q8, #7 ;shift/round/saturate to u8 218 vqrshrun.s16 d27, q9, #7 219 vqrshrun.s16 d28, q10, #7 220 vqrshrun.s16 d29, q11, #7 ;load intermediate data from stack 221 vqrshrun.s16 d30, q12, #7 222 223 ;Second pass: 8x4 224 ;secondpass_filter 225 add r3, r12, r3, lsl #5 226 sub lr, lr, #32 227 228 vld1.s32 {q5, q6}, [r3] ;load second_pass filter 229 vld1.u8 {q11}, [lr]! 230 231 vabs.s32 q7, q5 232 vabs.s32 q8, q6 233 234 vld1.u8 {q12}, [lr]! 235 236 vdup.8 d0, d14[0] ;second_pass filter parameters (d0-d5) 237 vdup.8 d1, d14[4] 238 vdup.8 d2, d15[0] 239 vdup.8 d3, d15[4] 240 vdup.8 d4, d16[0] 241 vdup.8 d5, d16[4] 242 243 vmull.u8 q3, d22, d0 ;(src_ptr[-2] * vp8_filter[0]) 244 vmull.u8 q4, d23, d0 245 vmull.u8 q5, d24, d0 246 vmull.u8 q6, d25, d0 247 248 vmlsl.u8 q3, d23, d1 ;-(src_ptr[-1] * vp8_filter[1]) 249 vmlsl.u8 q4, d24, d1 250 vmlsl.u8 q5, d25, d1 251 vmlsl.u8 q6, d26, d1 252 253 vmlsl.u8 q3, d26, d4 ;-(src_ptr[2] * vp8_filter[4]) 254 vmlsl.u8 q4, d27, d4 255 vmlsl.u8 q5, d28, d4 256 vmlsl.u8 q6, d29, d4 257 258 vmlal.u8 q3, d24, d2 ;(src_ptr[0] * vp8_filter[2]) 259 vmlal.u8 q4, d25, d2 260 vmlal.u8 q5, d26, d2 261 vmlal.u8 q6, d27, d2 262 263 vmlal.u8 q3, d27, d5 ;(src_ptr[3] * vp8_filter[5]) 264 vmlal.u8 q4, d28, d5 265 vmlal.u8 q5, d29, d5 266 vmlal.u8 q6, d30, d5 267 268 vmull.u8 q7, d25, d3 ;(src_ptr[1] * vp8_filter[3]) 269 vmull.u8 q8, d26, d3 270 vmull.u8 q9, d27, d3 271 vmull.u8 q10, d28, d3 272 273 vqadd.s16 q7, q3 ;sum of all (src_data*filter_parameters) 274 vqadd.s16 q8, q4 275 vqadd.s16 q9, q5 276 vqadd.s16 q10, q6 277 278 vqrshrun.s16 d6, q7, #7 ;shift/round/saturate to u8 279 vqrshrun.s16 d7, q8, #7 280 vqrshrun.s16 d8, q9, #7 281 vqrshrun.s16 d9, q10, #7 282 283 vst1.u8 {d6}, [r4], r5 ;store result 284 vst1.u8 {d7}, [r4], r5 285 vst1.u8 {d8}, [r4], r5 286 vst1.u8 {d9}, [r4], r5 287 288 add sp, sp, #32 289 pop {r4-r5,pc} 290 291 ;-------------------- 292 firstpass_filter8x4_only 293 vabs.s32 q12, q14 294 vabs.s32 q13, q15 295 296 sub r0, r0, #2 ;move srcptr back to (line-2) and (column-2) 297 vld1.u8 {q3}, [r0], r1 ;load src data 298 299 vdup.8 d0, d24[0] ;first_pass filter (d0-d5) 300 vld1.u8 {q4}, [r0], r1 301 vdup.8 d1, d24[4] 302 vld1.u8 {q5}, [r0], r1 303 vdup.8 d2, d25[0] 304 vld1.u8 {q6}, [r0], r1 305 vdup.8 d3, d25[4] 306 vdup.8 d4, d26[0] 307 vdup.8 d5, d26[4] 308 309 ;First pass: output_height lines x output_width columns (4x8) 310 pld [r0] 311 pld [r0, r1] 312 pld [r0, r1, lsl #1] 313 314 vmull.u8 q7, d6, d0 ;(src_ptr[-2] * vp8_filter[0]) 315 vmull.u8 q8, d8, d0 316 vmull.u8 q9, d10, d0 317 vmull.u8 q10, d12, d0 318 319 vext.8 d28, d6, d7, #1 ;construct src_ptr[-1] 320 vext.8 d29, d8, d9, #1 321 vext.8 d30, d10, d11, #1 322 vext.8 d31, d12, d13, #1 323 324 vmlsl.u8 q7, d28, d1 ;-(src_ptr[-1] * vp8_filter[1]) 325 vmlsl.u8 q8, d29, d1 326 vmlsl.u8 q9, d30, d1 327 vmlsl.u8 q10, d31, d1 328 329 vext.8 d28, d6, d7, #4 ;construct src_ptr[2] 330 vext.8 d29, d8, d9, #4 331 vext.8 d30, d10, d11, #4 332 vext.8 d31, d12, d13, #4 333 334 vmlsl.u8 q7, d28, d4 ;-(src_ptr[2] * vp8_filter[4]) 335 vmlsl.u8 q8, d29, d4 336 vmlsl.u8 q9, d30, d4 337 vmlsl.u8 q10, d31, d4 338 339 vext.8 d28, d6, d7, #2 ;construct src_ptr[0] 340 vext.8 d29, d8, d9, #2 341 vext.8 d30, d10, d11, #2 342 vext.8 d31, d12, d13, #2 343 344 vmlal.u8 q7, d28, d2 ;(src_ptr[0] * vp8_filter[2]) 345 vmlal.u8 q8, d29, d2 346 vmlal.u8 q9, d30, d2 347 vmlal.u8 q10, d31, d2 348 349 vext.8 d28, d6, d7, #5 ;construct src_ptr[3] 350 vext.8 d29, d8, d9, #5 351 vext.8 d30, d10, d11, #5 352 vext.8 d31, d12, d13, #5 353 354 vmlal.u8 q7, d28, d5 ;(src_ptr[3] * vp8_filter[5]) 355 vmlal.u8 q8, d29, d5 356 vmlal.u8 q9, d30, d5 357 vmlal.u8 q10, d31, d5 358 359 vext.8 d28, d6, d7, #3 ;construct src_ptr[1] 360 vext.8 d29, d8, d9, #3 361 vext.8 d30, d10, d11, #3 362 vext.8 d31, d12, d13, #3 363 364 vmull.u8 q3, d28, d3 ;(src_ptr[1] * vp8_filter[3]) 365 vmull.u8 q4, d29, d3 366 vmull.u8 q5, d30, d3 367 vmull.u8 q6, d31, d3 368 369 vqadd.s16 q7, q3 ;sum of all (src_data*filter_parameters) 370 vqadd.s16 q8, q4 371 vqadd.s16 q9, q5 372 vqadd.s16 q10, q6 373 374 vqrshrun.s16 d22, q7, #7 ;shift/round/saturate to u8 375 vqrshrun.s16 d23, q8, #7 376 vqrshrun.s16 d24, q9, #7 377 vqrshrun.s16 d25, q10, #7 378 379 vst1.u8 {d22}, [r4], r5 ;store result 380 vst1.u8 {d23}, [r4], r5 381 vst1.u8 {d24}, [r4], r5 382 vst1.u8 {d25}, [r4], r5 383 384 pop {r4-r5,pc} 385 386 ;--------------------- 387 secondpass_filter8x4_only 388 ;Second pass: 8x4 389 add r3, r12, r3, lsl #5 390 sub r0, r0, r1, lsl #1 391 vld1.s32 {q5, q6}, [r3] ;load second_pass filter 392 vabs.s32 q7, q5 393 vabs.s32 q8, q6 394 395 vld1.u8 {d22}, [r0], r1 396 vld1.u8 {d23}, [r0], r1 397 vld1.u8 {d24}, [r0], r1 398 vdup.8 d0, d14[0] ;second_pass filter parameters (d0-d5) 399 vld1.u8 {d25}, [r0], r1 400 vdup.8 d1, d14[4] 401 vld1.u8 {d26}, [r0], r1 402 vdup.8 d2, d15[0] 403 vld1.u8 {d27}, [r0], r1 404 vdup.8 d3, d15[4] 405 vld1.u8 {d28}, [r0], r1 406 vdup.8 d4, d16[0] 407 vld1.u8 {d29}, [r0], r1 408 vdup.8 d5, d16[4] 409 vld1.u8 {d30}, [r0], r1 410 411 vmull.u8 q3, d22, d0 ;(src_ptr[-2] * vp8_filter[0]) 412 vmull.u8 q4, d23, d0 413 vmull.u8 q5, d24, d0 414 vmull.u8 q6, d25, d0 415 416 vmlsl.u8 q3, d23, d1 ;-(src_ptr[-1] * vp8_filter[1]) 417 vmlsl.u8 q4, d24, d1 418 vmlsl.u8 q5, d25, d1 419 vmlsl.u8 q6, d26, d1 420 421 vmlsl.u8 q3, d26, d4 ;-(src_ptr[2] * vp8_filter[4]) 422 vmlsl.u8 q4, d27, d4 423 vmlsl.u8 q5, d28, d4 424 vmlsl.u8 q6, d29, d4 425 426 vmlal.u8 q3, d24, d2 ;(src_ptr[0] * vp8_filter[2]) 427 vmlal.u8 q4, d25, d2 428 vmlal.u8 q5, d26, d2 429 vmlal.u8 q6, d27, d2 430 431 vmlal.u8 q3, d27, d5 ;(src_ptr[3] * vp8_filter[5]) 432 vmlal.u8 q4, d28, d5 433 vmlal.u8 q5, d29, d5 434 vmlal.u8 q6, d30, d5 435 436 vmull.u8 q7, d25, d3 ;(src_ptr[1] * vp8_filter[3]) 437 vmull.u8 q8, d26, d3 438 vmull.u8 q9, d27, d3 439 vmull.u8 q10, d28, d3 440 441 vqadd.s16 q7, q3 ;sum of all (src_data*filter_parameters) 442 vqadd.s16 q8, q4 443 vqadd.s16 q9, q5 444 vqadd.s16 q10, q6 445 446 vqrshrun.s16 d6, q7, #7 ;shift/round/saturate to u8 447 vqrshrun.s16 d7, q8, #7 448 vqrshrun.s16 d8, q9, #7 449 vqrshrun.s16 d9, q10, #7 450 451 vst1.u8 {d6}, [r4], r5 ;store result 452 vst1.u8 {d7}, [r4], r5 453 vst1.u8 {d8}, [r4], r5 454 vst1.u8 {d9}, [r4], r5 455 456 pop {r4-r5,pc} 457 458 ENDP 459 460 ;----------------- 461 462 _filter8_coeff_ 463 DCD filter8_coeff 464 filter8_coeff 465 DCD 0, 0, 128, 0, 0, 0, 0, 0 466 DCD 0, -6, 123, 12, -1, 0, 0, 0 467 DCD 2, -11, 108, 36, -8, 1, 0, 0 468 DCD 0, -9, 93, 50, -6, 0, 0, 0 469 DCD 3, -16, 77, 77, -16, 3, 0, 0 470 DCD 0, -6, 50, 93, -9, 0, 0, 0 471 DCD 1, -8, 36, 108, -11, 2, 0, 0 472 DCD 0, -1, 12, 123, -6, 0, 0, 0 473 474 END 475