1@/****************************************************************************** 2@ * 3@ * Copyright (C) 2015 The Android Open Source Project 4@ * 5@ * Licensed under the Apache License, Version 2.0 (the "License"); 6@ * you may not use this file except in compliance with the License. 7@ * You may obtain a copy of the License at: 8@ * 9@ * http://www.apache.org/licenses/LICENSE-2.0 10@ * 11@ * Unless required by applicable law or agreed to in writing, software 12@ * distributed under the License is distributed on an "AS IS" BASIS, 13@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14@ * See the License for the specific language governing permissions and 15@ * limitations under the License. 16@ * 17@ ***************************************************************************** 18@ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore 19@*/ 20@** 21@****************************************************************************** 22@* @file 23@* ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q.s 24@* 25@* @brief 26@* Contains function definitions for inter prediction interpolation. 27@* 28@* @author 29@* Mohit 30@* 31@* @par List of Functions: 32@* 33@* - ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q() 34@* 35@* @remarks 36@* None 37@* 38@******************************************************************************* 39@* 40 41@* All the functions here are replicated from ih264_inter_pred_filters.c 42@ 43 44@** 45@** 46@** 47@******************************************************************************* 48@* 49@* @brief 50@* This function implements a two stage cascaded six tap filter. It 51@* applies the six tap filter in the horizontal direction on the 52@* predictor values, followed by applying the same filter in the 53@* vertical direction on the output of the first stage. It then averages 54@* the output of the 1st stage and the output of the 2nd stage to obtain 55@* the quarter pel values. The six tap filtering operation is described 56@* in sec 8.4.2.2.1 titled "Luma sample interpolation process". 57@* 58@* @par Description: 59@* This function is called to obtain pixels lying at the following 60@* location (1/2,1/4) or (1/2,3/4). The function interpolates 61@* the predictors first in the horizontal direction and then in the 62@* vertical direction to output the (1/2,1/2). It then averages 63@* the output of the 2nd stage and (1/2,1/2) value to obtain (1/2,1/4) 64@* or (1/2,3/4) depending on the offset. 65@* 66@* @param[in] pu1_src 67@* UWORD8 pointer to the source 68@* 69@* @param[out] pu1_dst 70@* UWORD8 pointer to the destination 71@* 72@* @param[in] src_strd 73@* integer source stride 74@* 75@* @param[in] dst_strd 76@* integer destination stride 77@* 78@* @param[in] ht 79@* integer height of the array 80@* 81@* @param[in] wd 82@* integer width of the array 83@* 84@* @param[in] pu1_tmp: temporary buffer 85@* 86@* @param[in] dydx: x and y reference offset for qpel calculations 87@* 88@* @returns 89@* 90@* @remarks 91@* None 92@* 93@******************************************************************************* 94@*; 95 96@void ih264_inter_pred_luma_horz_hpel_vert_qpel(UWORD8 *pu1_src, 97@ UWORD8 *pu1_dst, 98@ WORD32 src_strd,, 99@ WORD32 dst_strd, 100@ WORD32 ht, 101@ WORD32 wd, 102@ UWORD8* pu1_tmp, 103@ UWORD32 dydx) 104 105@**************Variables Vs Registers***************************************** 106@ r0 => *pu1_src 107@ r1 => *pu1_dst 108@ r2 => src_strd 109@ r3 => dst_strd 110@ r4 => ht 111@ r5 => wd 112@ r7 => dydx 113@ r9 => *pu1_tmp 114 115.text 116.p2align 2 117 118 .global ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q 119 120ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q: 121 122 stmfd sp!, {r4-r12, r14} @ store register values to stack 123 vstmdb sp!, {d8-d15} @push neon registers to stack 124 ldr r4, [sp, #104] @ loads ht 125 sub r0, r0, r2, lsl #1 @ pu1_src-2*src_strd 126 sub r0, r0, #2 @ pu1_src-2 127 ldr r5, [sp, #108] @ loads wd 128 ldr r7, [sp, #116] @ loads dydx 129 lsr r7, r7, #3 @ dydx >> 2 followed by dydx & 0x3 and dydx>>1 to obtain the deciding bit 130 ldr r9, [sp, #112] @ pu1_tmp 131 add r7, r7, #2 132 mov r6, #48 133 mla r7, r7, r6, r9 134 135 subs r12, r5, #4 @if wd=4 branch to loop_4 136 beq loop_4_start 137 138 subs r12, r5, #8 @if wd=8 branch to loop_8 139 beq loop_8_start 140 141 @when wd=16 142 vmov.u16 q11, #20 @ Filter coeff 0x14 into Q11 143 vmov.u16 q12, #5 @ Filter coeff 0x5 into Q12 144 add r8, r0, #8 145 add r14, r1, #8 146 add r10, r9, #8 147 mov r12, r4 148 add r11, r7, #8 149 150loop_16_lowhalf_start: 151 vld1.32 {q0}, [r0], r2 @ row -2 load for horizontal filter 152 vext.8 d5, d0, d1, #5 153 vaddl.u8 q3, d0, d5 154 155 vext.8 d2, d0, d1, #2 156 vext.8 d3, d0, d1, #3 157 vaddl.u8 q4, d2, d3 158 vext.8 d4, d0, d1, #4 159 vmla.u16 q3, q4, q11 160 vext.8 d1, d0, d1, #1 161 vaddl.u8 q4, d1, d4 162 vld1.32 {q0}, [r0], r2 @ row -1 load for horizontal filter 163 vmls.u16 q3, q4, q12 164 vext.8 d5, d0, d1, #5 165 vaddl.u8 q4, d0, d5 166 vext.8 d2, d0, d1, #2 167 vext.8 d3, d0, d1, #3 168 vaddl.u8 q5, d2, d3 169 170 vst1.32 {q3}, [r9], r6 @ store temp buffer 0 171 172 vext.8 d4, d0, d1, #4 173 vmla.u16 q4, q5, q11 174 vext.8 d1, d0, d1, #1 175 vaddl.u8 q5, d1, d4 176 vld1.32 {q0}, [r0], r2 @ row 0 load for horizontal filter 177 vmls.u16 q4, q5, q12 178 vext.8 d5, d0, d1, #5 179 vaddl.u8 q5, d0, d5 180 vext.8 d2, d0, d1, #2 181 vext.8 d3, d0, d1, #3 182 vaddl.u8 q6, d2, d3 183 184 vst1.32 {q4}, [r9], r6 @ store temp buffer 1 185 186 vext.8 d4, d0, d1, #4 187 vmla.u16 q5, q6, q11 188 vext.8 d1, d0, d1, #1 189 vaddl.u8 q6, d1, d4 190 vld1.32 {q0}, [r0], r2 @ row 1 load for horizontal filter 191 vmls.u16 q5, q6, q12 192 vext.8 d5, d0, d1, #5 193 vaddl.u8 q6, d0, d5 194 vext.8 d2, d0, d1, #2 195 vext.8 d3, d0, d1, #3 196 vaddl.u8 q7, d2, d3 197 198 vst1.32 {q5}, [r9], r6 @ store temp buffer 2 199 200 vext.8 d4, d0, d1, #4 201 vmla.u16 q6, q7, q11 202 vext.8 d1, d0, d1, #1 203 vaddl.u8 q7, d1, d4 204 vld1.32 {q0}, [r0], r2 @ row 2 load for horizontal filter 205 vmls.u16 q6, q7, q12 206 vext.8 d5, d0, d1, #5 207 vaddl.u8 q7, d0, d5 208 vext.8 d2, d0, d1, #2 209 vext.8 d3, d0, d1, #3 210 vaddl.u8 q8, d2, d3 211 212 vst1.32 {q6}, [r9], r6 @ store temp buffer 3 213 214 vext.8 d4, d0, d1, #4 215 vmla.u16 q7, q8, q11 216 vext.8 d1, d0, d1, #1 217 vaddl.u8 q8, d1, d4 218 219 vmls.u16 q7, q8, q12 220loop_16_lowhalf: 221 222 vld1.32 {q0}, [r0], r2 @ row 3 load for horizontal filter 223 vext.8 d5, d0, d1, #5 224 vext.8 d2, d0, d1, #2 225 vext.8 d3, d0, d1, #3 226 vaddl.u8 q8, d0, d5 227 228 vst1.32 {q7}, [r9], r6 @ store temp buffer 4 229 vaddl.u8 q9, d2, d3 230 vext.8 d4, d0, d1, #4 231 vmla.u16 q8, q9, q11 232 vext.8 d1, d0, d1, #1 233 vadd.s16 q14, q4, q7 234 vaddl.u8 q9, d1, d4 235 vadd.s16 q15, q5, q6 236 vmls.u16 q8, q9, q12 237 vld1.32 {q0}, [r0], r2 @ row 4 load for hoorizontal filter 238 vext.8 d5, d0, d1, #5 239 vext.8 d2, d0, d1, #2 240 vext.8 d3, d0, d1, #3 241 vaddl.u8 q10, d0, d5 242 243 vst1.32 {q8}, [r9], r6 @ store temp buffer r5 244 245 vaddl.s16 q9, d6, d16 246 247 vld1.32 {q13}, [r7], r6 @ load from temp buffer 0 248 249 vaddl.s16 q3, d7, d17 250 251 vqrshrun.s16 d26, q13, #5 252 253 vmlal.s16 q9, d30, d22 254 vmlsl.s16 q9, d28, d24 255 vmlal.s16 q3, d31, d22 256 vmlsl.s16 q3, d29, d24 257 vaddl.u8 q1, d2, d3 258 vext.8 d4, d0, d1, #4 259 vmla.u16 q10, q1, q11 260 vqrshrun.s32 d18, q9, #10 261 vext.8 d1, d0, d1, #1 262 vqrshrun.s32 d19, q3, #10 263 vadd.s16 q14, q5, q8 264 vaddl.u8 q1, d1, d4 265 vadd.s16 q15, q6, q7 266 vmls.u16 q10, q1, q12 267 vqmovn.u16 d18, q9 268 vld1.32 {q0}, [r0], r2 @ row 5 load for horizontal filter 269 270 vrhadd.u8 d26, d18, d26 271 272 vext.8 d5, d0, d1, #5 273 vext.8 d2, d0, d1, #2 274 275 vst1.32 {q10}, [r9], r6 @ store temp buffer r6 276 277 vaddl.s16 q9, d8, d20 278 279 vaddl.s16 q3, d9, d21 280 281 vld1.32 {q4}, [r7], r6 @load from temp buffer 1 282 283 284 vst1.32 d26, [r1], r3 @ store row 0 285 286 vmlal.s16 q9, d30, d22 287 vmlsl.s16 q9, d28, d24 288 289 vqrshrun.s16 d28, q4, #5 290 291 vmlal.s16 q3, d31, d22 292 vmlsl.s16 q3, d29, d24 293 vext.8 d3, d0, d1, #3 294 vaddl.u8 q4, d0, d5 295 vaddl.u8 q1, d2, d3 296 vqrshrun.s32 d18, q9, #10 297 vext.8 d4, d0, d1, #4 298 vqrshrun.s32 d19, q3, #10 299 vmla.u16 q4, q1, q11 300 vext.8 d1, d0, d1, #1 301 vadd.s16 q13, q6, q10 302 vaddl.u8 q1, d1, d4 303 vqmovn.u16 d18, q9 304 vadd.s16 q15, q7, q8 305 vmls.u16 q4, q1, q12 306 vld1.32 {q0}, [r0], r2 @ row 6 load for horizontal filter 307 308 vrhadd.u8 d28, d28, d18 309 310 vext.8 d5, d0, d1, #5 311 vext.8 d2, d0, d1, #2 312 vext.8 d3, d0, d1, #3 313 314 vst1.32 d28, [r1], r3 @ store row 1 315 316 vaddl.u8 q14, d0, d5 317 318 vst1.32 {q4}, [r9], r6 @ store temp buffer r7 319 320 vaddl.s16 q9, d10, d8 321 vaddl.s16 q3, d11, d9 322 323 vld1.32 {q5}, [r7], r6 @ load from temp buffer 2 324 325 vmlal.s16 q9, d30, d22 326 vmlsl.s16 q9, d26, d24 327 vmlal.s16 q3, d31, d22 328 329 vqrshrun.s16 d26, q5, #5 330 331 vmlsl.s16 q3, d27, d24 332 vaddl.u8 q1, d2, d3 333 vext.8 d4, d0, d1, #4 334 vmla.u16 q14, q1, q11 335 vqrshrun.s32 d18, q9, #10 336 vext.8 d1, d0, d1, #1 337 vqrshrun.s32 d19, q3, #10 338 vadd.s16 q5, q7, q4 339 vaddl.u8 q1, d1, d4 340 vadd.s16 q15, q8, q10 341 vmls.u16 q14, q1, q12 342 vqmovn.u16 d27, q9 343 344 vaddl.s16 q9, d12, d28 345 vaddl.s16 q3, d13, d29 346 347 vrhadd.u8 d26, d26, d27 348 349 vmlal.s16 q9, d30, d22 350 vmlsl.s16 q9, d10, d24 351 vmlal.s16 q3, d31, d22 352 vmlsl.s16 q3, d11, d24 353 354 vst1.32 d26, [r1], r3 @ store row 2 355 356 vst1.32 {q14}, [r9] 357 358 359 vqrshrun.s32 d18, q9, #10 360 vmov q5, q10 361 vld1.32 {q15}, [r7], r6 @ load from temp buffer 3 362 363 vqrshrun.s32 d19, q3, #10 364 subs r4, r4, #4 365 366 vqrshrun.s16 d30, q15, #5 367 368 vqmovn.u16 d18, q9 369 vmov q6, q4 370 vmov q3, q7 371 vrhadd.u8 d30, d18, d30 372 vmov q4, q8 373 vmov q7, q14 374 vst1.32 d30, [r1], r3 @ store row 3 375 376 bgt loop_16_lowhalf @ looping if height =16 377 378 379loop_16_highhalf_start: 380 vld1.32 {q0}, [r8], r2 381 vext.8 d5, d0, d1, #5 382 vaddl.u8 q3, d0, d5 383 vext.8 d2, d0, d1, #2 384 vext.8 d3, d0, d1, #3 385 vaddl.u8 q4, d2, d3 386 vext.8 d4, d0, d1, #4 387 vmla.u16 q3, q4, q11 388 vext.8 d1, d0, d1, #1 389 vaddl.u8 q4, d1, d4 390 vld1.32 {q0}, [r8], r2 391 vmls.u16 q3, q4, q12 392 vext.8 d5, d0, d1, #5 393 vaddl.u8 q4, d0, d5 394 vext.8 d2, d0, d1, #2 395 vext.8 d3, d0, d1, #3 396 vaddl.u8 q5, d2, d3 397 398 vst1.32 {q3}, [r10], r6 399 400 vext.8 d4, d0, d1, #4 401 vmla.u16 q4, q5, q11 402 vext.8 d1, d0, d1, #1 403 vaddl.u8 q5, d1, d4 404 vld1.32 {q0}, [r8], r2 405 vmls.u16 q4, q5, q12 406 vext.8 d5, d0, d1, #5 407 vaddl.u8 q5, d0, d5 408 vext.8 d2, d0, d1, #2 409 vext.8 d3, d0, d1, #3 410 vaddl.u8 q6, d2, d3 411 412 vst1.32 {q4}, [r10], r6 413 414 vext.8 d4, d0, d1, #4 415 vmla.u16 q5, q6, q11 416 vext.8 d1, d0, d1, #1 417 vaddl.u8 q6, d1, d4 418 vld1.32 {q0}, [r8], r2 419 vmls.u16 q5, q6, q12 420 vext.8 d5, d0, d1, #5 421 vaddl.u8 q6, d0, d5 422 vext.8 d2, d0, d1, #2 423 vext.8 d3, d0, d1, #3 424 vaddl.u8 q7, d2, d3 425 426 vst1.32 {q5}, [r10], r6 427 428 vext.8 d4, d0, d1, #4 429 vmla.u16 q6, q7, q11 430 vext.8 d1, d0, d1, #1 431 vaddl.u8 q7, d1, d4 432 vld1.32 {q0}, [r8], r2 433 vmls.u16 q6, q7, q12 434 vext.8 d5, d0, d1, #5 435 vaddl.u8 q7, d0, d5 436 vext.8 d2, d0, d1, #2 437 vext.8 d3, d0, d1, #3 438 vaddl.u8 q8, d2, d3 439 440 vst1.32 {q6}, [r10], r6 441 442 vext.8 d4, d0, d1, #4 443 vmla.u16 q7, q8, q11 444 vext.8 d1, d0, d1, #1 445 vaddl.u8 q8, d1, d4 446 447 vmls.u16 q7, q8, q12 448 449loop_16_highhalf: 450 451 vld1.32 {q0}, [r8], r2 452 vext.8 d5, d0, d1, #5 453 vext.8 d2, d0, d1, #2 454 vext.8 d3, d0, d1, #3 455 vaddl.u8 q8, d0, d5 456 457 vst1.32 {q7}, [r10], r6 458 459 vaddl.u8 q9, d2, d3 460 vext.8 d4, d0, d1, #4 461 vmla.u16 q8, q9, q11 462 vext.8 d1, d0, d1, #1 463 vadd.s16 q14, q4, q7 464 vaddl.u8 q9, d1, d4 465 vadd.s16 q15, q5, q6 466 vmls.u16 q8, q9, q12 467 vld1.32 {q0}, [r8], r2 468 vext.8 d5, d0, d1, #5 469 vext.8 d2, d0, d1, #2 470 vext.8 d3, d0, d1, #3 471 vaddl.u8 q10, d0, d5 472 473 vst1.32 {q8}, [r10], r6 474 475 vaddl.s16 q9, d6, d16 476 477 vld1.32 {q13}, [r11], r6 478 479 vaddl.s16 q3, d7, d17 480 481 vqrshrun.s16 d26, q13, #5 482 483 vmlal.s16 q9, d30, d22 484 vmlsl.s16 q9, d28, d24 485 vmlal.s16 q3, d31, d22 486 vmlsl.s16 q3, d29, d24 487 vaddl.u8 q1, d2, d3 488 vext.8 d4, d0, d1, #4 489 vmla.u16 q10, q1, q11 490 vqrshrun.s32 d18, q9, #10 491 vext.8 d1, d0, d1, #1 492 vqrshrun.s32 d19, q3, #10 493 vadd.s16 q14, q5, q8 494 vaddl.u8 q1, d1, d4 495 vadd.s16 q15, q6, q7 496 vmls.u16 q10, q1, q12 497 vqmovn.u16 d18, q9 498 vld1.32 {q0}, [r8], r2 499 500 vrhadd.u8 d26, d18, d26 501 502 vext.8 d5, d0, d1, #5 503 vext.8 d2, d0, d1, #2 504 505 vst1.32 {q10}, [r10], r6 506 507 vaddl.s16 q9, d8, d20 508 vaddl.s16 q3, d9, d21 509 510 vld1.32 {q4}, [r11], r6 511 512 513 vst1.32 d26, [r14], r3 @store row 0 514 515 vmlal.s16 q9, d30, d22 516 vmlsl.s16 q9, d28, d24 517 518 vqrshrun.s16 d28, q4, #5 519 520 vmlal.s16 q3, d31, d22 521 vmlsl.s16 q3, d29, d24 522 vext.8 d3, d0, d1, #3 523 vaddl.u8 q4, d0, d5 524 vaddl.u8 q1, d2, d3 525 vqrshrun.s32 d18, q9, #10 526 vext.8 d4, d0, d1, #4 527 vqrshrun.s32 d19, q3, #10 528 vmla.u16 q4, q1, q11 529 vext.8 d1, d0, d1, #1 530 vadd.s16 q13, q6, q10 531 vaddl.u8 q1, d1, d4 532 vqmovn.u16 d18, q9 533 vadd.s16 q15, q7, q8 534 vmls.u16 q4, q1, q12 535 vld1.32 {q0}, [r8], r2 536 537 vrhadd.u8 d28, d28, d18 538 539 vext.8 d5, d0, d1, #5 540 vext.8 d2, d0, d1, #2 541 vext.8 d3, d0, d1, #3 542 543 vst1.32 d28, [r14], r3 @store row 1 544 545 vaddl.u8 q14, d0, d5 546 547 vst1.32 {q4}, [r10], r6 548 549 vaddl.s16 q9, d10, d8 550 vaddl.s16 q3, d11, d9 551 552 vld1.32 {q5}, [r11], r6 553 554 vmlal.s16 q9, d30, d22 555 vmlsl.s16 q9, d26, d24 556 vmlal.s16 q3, d31, d22 557 558 vqrshrun.s16 d26, q5, #5 559 560 vmlsl.s16 q3, d27, d24 561 vaddl.u8 q1, d2, d3 562 vext.8 d4, d0, d1, #4 563 vmla.u16 q14, q1, q11 564 vqrshrun.s32 d18, q9, #10 565 vext.8 d1, d0, d1, #1 566 vqrshrun.s32 d19, q3, #10 567 vadd.s16 q5, q7, q4 568 vaddl.u8 q1, d1, d4 569 vadd.s16 q15, q8, q10 570 vmls.u16 q14, q1, q12 571 vqmovn.u16 d27, q9 572 573 574 vaddl.s16 q9, d12, d28 575 vaddl.s16 q3, d13, d29 576 577 vrhadd.u8 d26, d26, d27 578 579 vmlal.s16 q9, d30, d22 580 vmlsl.s16 q9, d10, d24 581 vmlal.s16 q3, d31, d22 582 vmlsl.s16 q3, d11, d24 583 584 vst1.32 d26, [r14], r3 @ store row 2 585 586 vst1.32 {q14}, [r10] 587 588 vqrshrun.s32 d18, q9, #10 589 vmov q5, q10 590 vld1.32 {q15}, [r11], r6 591 592 vqrshrun.s32 d19, q3, #10 593 subs r12, r12, #4 594 595 vqrshrun.s16 d30, q15, #5 596 597 vqmovn.u16 d18, q9 598 vmov q6, q4 599 vmov q3, q7 600 vrhadd.u8 d30, d18, d30 601 vmov q4, q8 602 vmov q7, q14 603 vst1.32 d30, [r14], r3 @ store row 3 604 605 bgt loop_16_highhalf @ looping if height = 8 or 16 606 b end_func 607 608loop_8_start: 609 610 vmov.u16 q11, #20 @ Filter coeff 20 into Q11 611 vmov.u16 q12, #5 @ Filter coeff 5 into Q12 612 vld1.32 {q0}, [r0], r2 @ row -2 load for horizontal filter 613 vext.8 d5, d0, d1, #5 614 vaddl.u8 q3, d0, d5 615 616 vext.8 d2, d0, d1, #2 617 vext.8 d3, d0, d1, #3 618 vaddl.u8 q4, d2, d3 619 vext.8 d4, d0, d1, #4 620 vmla.u16 q3, q4, q11 621 vext.8 d1, d0, d1, #1 622 vaddl.u8 q4, d1, d4 623 vld1.32 {q0}, [r0], r2 @ row -1 load for horizontal filter 624 vmls.u16 q3, q4, q12 625 vext.8 d5, d0, d1, #5 626 vaddl.u8 q4, d0, d5 627 vext.8 d2, d0, d1, #2 628 vext.8 d3, d0, d1, #3 629 vaddl.u8 q5, d2, d3 630 631 vst1.32 {q3}, [r9], r6 @ store temp buffer 0 632 633 vext.8 d4, d0, d1, #4 634 vmla.u16 q4, q5, q11 635 vext.8 d1, d0, d1, #1 636 vaddl.u8 q5, d1, d4 637 vld1.32 {q0}, [r0], r2 @ row 0 load for horizontal filter 638 vmls.u16 q4, q5, q12 639 vext.8 d5, d0, d1, #5 640 vaddl.u8 q5, d0, d5 641 vext.8 d2, d0, d1, #2 642 vext.8 d3, d0, d1, #3 643 vaddl.u8 q6, d2, d3 644 645 vst1.32 {q4}, [r9], r6 @ store temp buffer 1 646 647 vext.8 d4, d0, d1, #4 648 vmla.u16 q5, q6, q11 649 vext.8 d1, d0, d1, #1 650 vaddl.u8 q6, d1, d4 651 vld1.32 {q0}, [r0], r2 @ row 1 load for horizontal filter 652 vmls.u16 q5, q6, q12 653 vext.8 d5, d0, d1, #5 654 vaddl.u8 q6, d0, d5 655 vext.8 d2, d0, d1, #2 656 vext.8 d3, d0, d1, #3 657 vaddl.u8 q7, d2, d3 658 659 vst1.32 {q5}, [r9], r6 @ store temp buffer 2 660 661 vext.8 d4, d0, d1, #4 662 vmla.u16 q6, q7, q11 663 vext.8 d1, d0, d1, #1 664 vaddl.u8 q7, d1, d4 665 vld1.32 {q0}, [r0], r2 @ row 2 load for horizontal filter 666 vmls.u16 q6, q7, q12 667 vext.8 d5, d0, d1, #5 668 vaddl.u8 q7, d0, d5 669 vext.8 d2, d0, d1, #2 670 vext.8 d3, d0, d1, #3 671 vaddl.u8 q8, d2, d3 672 673 vst1.32 {q6}, [r9], r6 @ store temp buffer 3 674 675 vext.8 d4, d0, d1, #4 676 vmla.u16 q7, q8, q11 677 vext.8 d1, d0, d1, #1 678 vaddl.u8 q8, d1, d4 679 680 vmls.u16 q7, q8, q12 681loop_8: 682 683 vld1.32 {q0}, [r0], r2 @ row 3 load for horizontal filter 684 vext.8 d5, d0, d1, #5 685 vext.8 d2, d0, d1, #2 686 vext.8 d3, d0, d1, #3 687 vaddl.u8 q8, d0, d5 688 689 vst1.32 {q7}, [r9], r6 @ store temp buffer 4 690 691 vaddl.u8 q9, d2, d3 692 vext.8 d4, d0, d1, #4 693 vmla.u16 q8, q9, q11 694 vext.8 d1, d0, d1, #1 695 vadd.s16 q14, q4, q7 696 vaddl.u8 q9, d1, d4 697 vadd.s16 q15, q5, q6 698 vmls.u16 q8, q9, q12 699 vld1.32 {q0}, [r0], r2 @ row 4 load for hoorizontal filter 700 vext.8 d5, d0, d1, #5 701 vext.8 d2, d0, d1, #2 702 vext.8 d3, d0, d1, #3 703 vaddl.u8 q10, d0, d5 704 705 vst1.32 {q8}, [r9], r6 @ store temp buffer r5 706 707 vaddl.s16 q9, d6, d16 708 709 vld1.32 {q13}, [r7], r6 @ load from temp buffer 0 710 711 vaddl.s16 q3, d7, d17 712 713 vqrshrun.s16 d26, q13, #5 714 715 vmlal.s16 q9, d30, d22 716 vmlsl.s16 q9, d28, d24 717 vmlal.s16 q3, d31, d22 718 vmlsl.s16 q3, d29, d24 719 vaddl.u8 q1, d2, d3 720 vext.8 d4, d0, d1, #4 721 vmla.u16 q10, q1, q11 722 vqrshrun.s32 d18, q9, #10 723 vext.8 d1, d0, d1, #1 724 vqrshrun.s32 d19, q3, #10 725 vadd.s16 q14, q5, q8 726 vaddl.u8 q1, d1, d4 727 vadd.s16 q15, q6, q7 728 vmls.u16 q10, q1, q12 729 vqmovn.u16 d18, q9 730 vld1.32 {q0}, [r0], r2 @ row 5 load for horizontal filter 731 732 vrhadd.u8 d26, d18, d26 733 734 vext.8 d5, d0, d1, #5 735 vext.8 d2, d0, d1, #2 736 737 vst1.32 {q10}, [r9], r6 @ store temp buffer r6 738 739 vaddl.s16 q9, d8, d20 740 741 vaddl.s16 q3, d9, d21 742 743 vld1.32 {q4}, [r7], r6 @load from temp buffer 1 744 745 746 vst1.32 d26, [r1], r3 @ store row 0 747 748 vmlal.s16 q9, d30, d22 749 vmlsl.s16 q9, d28, d24 750 751 vqrshrun.s16 d28, q4, #5 752 753 vmlal.s16 q3, d31, d22 754 vmlsl.s16 q3, d29, d24 755 vext.8 d3, d0, d1, #3 756 vaddl.u8 q4, d0, d5 757 vaddl.u8 q1, d2, d3 758 vqrshrun.s32 d18, q9, #10 759 vext.8 d4, d0, d1, #4 760 vqrshrun.s32 d19, q3, #10 761 vmla.u16 q4, q1, q11 762 vext.8 d1, d0, d1, #1 763 vadd.s16 q13, q6, q10 764 vaddl.u8 q1, d1, d4 765 vqmovn.u16 d18, q9 766 vadd.s16 q15, q7, q8 767 vmls.u16 q4, q1, q12 768 vld1.32 {q0}, [r0], r2 @ row 6 load for horizontal filter 769 770 vrhadd.u8 d28, d28, d18 771 772 vext.8 d5, d0, d1, #5 773 vext.8 d2, d0, d1, #2 774 vext.8 d3, d0, d1, #3 775 776 vst1.32 d28, [r1], r3 @ store row 1 777 778 vaddl.u8 q14, d0, d5 779 780 vst1.32 {q4}, [r9], r6 @ store temp buffer r7 781 782 vaddl.s16 q9, d10, d8 783 vaddl.s16 q3, d11, d9 784 785 vld1.32 {q5}, [r7], r6 @ load from temp buffer 2 786 787 vmlal.s16 q9, d30, d22 788 vmlsl.s16 q9, d26, d24 789 vmlal.s16 q3, d31, d22 790 791 vqrshrun.s16 d26, q5, #5 792 793 vmlsl.s16 q3, d27, d24 794 vaddl.u8 q1, d2, d3 795 vext.8 d4, d0, d1, #4 796 vmla.u16 q14, q1, q11 797 vqrshrun.s32 d18, q9, #10 798 vext.8 d1, d0, d1, #1 799 vqrshrun.s32 d19, q3, #10 800 vadd.s16 q5, q7, q4 801 vaddl.u8 q1, d1, d4 802 vadd.s16 q15, q8, q10 803 vmls.u16 q14, q1, q12 804 vqmovn.u16 d27, q9 805 806 vaddl.s16 q9, d12, d28 807 vaddl.s16 q3, d13, d29 808 809 vrhadd.u8 d26, d26, d27 810 811 vmlal.s16 q9, d30, d22 812 vmlsl.s16 q9, d10, d24 813 vmlal.s16 q3, d31, d22 814 vmlsl.s16 q3, d11, d24 815 816 vst1.32 d26, [r1], r3 @ store row 2 817 818 vst1.32 {q14}, [r9] 819 820 821 vqrshrun.s32 d18, q9, #10 822 vmov q5, q10 823 vld1.32 {q15}, [r7], r6 @ load from temp buffer 3 824 825 vqrshrun.s32 d19, q3, #10 826 subs r4, r4, #4 827 828 vqrshrun.s16 d30, q15, #5 829 830 vqmovn.u16 d18, q9 831 vmov q6, q4 832 vmov q3, q7 833 vrhadd.u8 d30, d18, d30 834 vmov q4, q8 835 vmov q7, q14 836 vst1.32 d30, [r1], r3 @ store row 3 837 838 bgt loop_8 @if height =8 or 16 loop 839 b end_func 840 841loop_4_start: 842 vmov.u16 d22, #20 @ Filter coeff 20 into D22 843 vmov.u16 d23, #5 @ Filter coeff 5 into D23 844 845 vld1.32 {q0}, [r0], r2 @row -2 load 846 vext.8 d5, d0, d1, #5 847 vaddl.u8 q3, d0, d5 848 vext.8 d2, d0, d1, #2 849 vext.8 d3, d0, d1, #3 850 vaddl.u8 q4, d2, d3 851 vext.8 d4, d0, d1, #4 852 vmla.u16 d6, d8, d22 853 vext.8 d1, d0, d1, #1 854 vaddl.u8 q4, d1, d4 855 vld1.32 {q0}, [r0], r2 @ row -1 load 856 vmls.u16 d6, d8, d23 857 vext.8 d5, d0, d1, #5 858 vaddl.u8 q4, d0, d5 859 vext.8 d2, d0, d1, #2 860 vext.8 d3, d0, d1, #3 861 vaddl.u8 q5, d2, d3 862 863 vst1.32 d6, [r9], r6 @ store temp buffer 0 864 865 vext.8 d4, d0, d1, #4 866 vmla.u16 d8, d10, d22 867 vext.8 d1, d0, d1, #1 868 vaddl.u8 q5, d1, d4 869 vld1.32 {q0}, [r0], r2 @ row 0 load 870 vmls.u16 d8, d10, d23 871 vext.8 d5, d0, d1, #5 872 vaddl.u8 q5, d0, d5 873 vext.8 d2, d0, d1, #2 874 vext.8 d3, d0, d1, #3 875 vaddl.u8 q6, d2, d3 876 877 vst1.32 d8, [r9], r6 @ store temp buffer 1 878 879 vext.8 d4, d0, d1, #4 880 vmla.u16 d10, d12, d22 881 vext.8 d1, d0, d1, #1 882 vaddl.u8 q6, d1, d4 883 vld1.32 {q0}, [r0], r2 @ row 1 load 884 vmls.u16 d10, d12, d23 885 vext.8 d5, d0, d1, #5 886 vaddl.u8 q6, d0, d5 887 vext.8 d2, d0, d1, #2 888 vext.8 d3, d0, d1, #3 889 vaddl.u8 q7, d2, d3 890 891 vst1.32 d10, [r9], r6 @ store temp buffer 2 892 893 vext.8 d4, d0, d1, #4 894 vmla.u16 d12, d14, d22 895 vext.8 d1, d0, d1, #1 896 vaddl.u8 q7, d1, d4 897 vld1.32 {q0}, [r0], r2 @ row 2 load 898 vmls.u16 d12, d14, d23 899 vext.8 d5, d0, d1, #5 900 vaddl.u8 q7, d0, d5 901 vext.8 d2, d0, d1, #2 902 vext.8 d3, d0, d1, #3 903 vaddl.u8 q8, d2, d3 904 vext.8 d4, d0, d1, #4 905 vmla.u16 d14, d16, d22 906 vext.8 d1, d0, d1, #1 907 vaddl.u8 q8, d1, d4 908 909 vst1.32 d12, [r9], r6 @ store temp buffer 3 910 911 vmls.u16 d14, d16, d23 912 913loop_4: 914 915 vld1.32 {q0}, [r0], r2 @ row 3 load 916 vext.8 d5, d0, d1, #5 917 vaddl.u8 q8, d0, d5 918 vext.8 d2, d0, d1, #2 919 vext.8 d3, d0, d1, #3 920 vaddl.u8 q9, d2, d3 921 vst1.32 d14, [r9], r6 @ store temp buffer 4 922 vext.8 d4, d0, d1, #4 923 vmla.u16 d16, d18, d22 924 vext.8 d1, d0, d1, #1 925 vaddl.u8 q9, d1, d4 926 vadd.s16 d2, d10, d12 927 vmls.u16 d16, d18, d23 928 vadd.s16 d3, d8, d14 929 vld1.32 {q9}, [r0], r2 @ row 4 load 930 vext.8 d25, d18, d19, #5 931 vaddl.u8 q13, d18, d25 932 vext.8 d20, d18, d19, #2 933 934 vst1.32 d16, [r9], r6 @ store temp buffer 5 935 936 vaddl.s16 q0, d6, d16 937 vmlal.s16 q0, d2, d22 938 vext.8 d21, d18, d19, #3 939 vaddl.u8 q14, d20, d21 940 vext.8 d24, d18, d19, #4 941 vmlsl.s16 q0, d3, d23 942 vmla.u16 d26, d28, d22 943 vext.8 d19, d18, d19, #1 944 vaddl.u8 q14, d19, d24 945 vadd.s16 d2, d12, d14 946 vmls.u16 d26, d28, d23 947 vqrshrun.s32 d0, q0, #0xa 948 vadd.s16 d3, d10, d16 949 vld1.32 {q9}, [r0], r2 @ row 5 load 950 vext.8 d25, d18, d19, #5 951 vqmovn.u16 d11, q0 952 vaddl.u8 q14, d18, d25 953 954 vst1.32 d26, [r9], r6 @ store temp buffer 6 955 956 @Q3 available here 957 vld1.32 d6, [r7], r6 @ load from temp buffer 0 958 vld1.32 d7, [r7], r6 @ load from temp buffer 1 959 vqrshrun.s16 d9, q3, #5 960 961 vext.8 d20, d18, d19, #2 962 963 vaddl.s16 q0, d8, d26 964 vmlal.s16 q0, d2, d22 965 vext.8 d21, d18, d19, #3 966 vaddl.u8 q3, d20, d21 967 vext.8 d24, d18, d19, #4 968 vmlsl.s16 q0, d3, d23 969 vmla.u16 d28, d6, d22 970 vext.8 d19, d18, d19, #1 971 vaddl.u8 q3, d19, d24 972 vadd.s16 d2, d14, d16 973 vmls.u16 d28, d6, d23 974 vqrshrun.s32 d0, q0, #0xa 975 vadd.s16 d3, d12, d26 976 vld1.32 {q9}, [r0], r2 @ row 6 load 977 vext.8 d25, d18, d19, #5 978 vqmovn.u16 d13, q0 979 980 vtrn.32 d11, d13 981 vaddl.s16 q0, d10, d28 982 vrhadd.u8 d9, d9, d11 983 984 vst1.32 d28, [r9], r6 @ store temp buffer 7 985 986 vmlal.s16 q0, d2, d22 987 vaddl.u8 q15, d18, d25 988 989 vst1.32 d9[0], [r1], r3 @ store row 0 990 991 vext.8 d20, d18, d19, #2 992 993 vst1.32 d9[1], [r1], r3 @ store row 1 994 995 vext.8 d21, d18, d19, #3 996 vmlsl.s16 q0, d3, d23 997 vaddl.u8 q4, d20, d21 998 vext.8 d24, d18, d19, #4 999 vmla.u16 d30, d8, d22 1000 vext.8 d19, d18, d19, #1 1001 vaddl.u8 q4, d19, d24 1002 vqrshrun.s32 d0, q0, #0xa 1003 vadd.s16 d2, d16, d26 1004 vmls.u16 d30, d8, d23 1005 vqmovn.u16 d4, q0 1006 1007 vadd.s16 d3, d14, d28 1008 1009 1010 vaddl.s16 q0, d12, d30 1011 1012 vst1.32 d30, [r9] 1013 1014 vmlal.s16 q0, d2, d22 1015 1016 vld1.32 d8, [r7], r6 @ load from temp buffer 2 1017 vld1.32 d9, [r7], r6 @ load from temp buffer 3 1018 vmlsl.s16 q0, d3, d23 1019 subs r4, r4, #4 1020 vqrshrun.s16 d10, q4, #5 1021 1022 vmov d12, d28 1023 1024 vqrshrun.s32 d0, q0, #0xa 1025 vmov d6, d14 1026 vmov d8, d16 1027 1028 vqmovn.u16 d5, q0 1029 1030 vtrn.32 d4, d5 1031 vrhadd.u8 d4, d4, d10 1032 vmov d10, d26 1033 vmov d14, d30 1034 1035 vst1.32 d4[0], [r1], r3 @ store row 2 1036 vst1.32 d4[1], [r1], r3 @ store row 3 1037 1038 bgt loop_4 1039 1040end_func: 1041 vldmia sp!, {d8-d15} @ Restore neon registers that were saved 1042 ldmfd sp!, {r4-r12, pc} @Restoring registers from stack 1043 1044 1045