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