1 @/***************************************************************************** 2 @* 3 @* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore 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 @/** 19 @ ******************************************************************************* 20 @ * @file 21 @ * ihevc_itrans_recon_8x8_neon.s 22 @ * 23 @ * @brief 24 @ * contains function definitions for single stage inverse transform 25 @ * 26 @ * @author 27 @ * anand s 28 @ * 29 @ * @par list of functions: 30 @ * - ihevc_itrans_recon_16x16() 31 @ * 32 @ * @remarks 33 @ * none 34 @ * 35 @ ******************************************************************************* 36 @*/ 37 38 @/** 39 @ ******************************************************************************* 40 @ * 41 @ * @brief 42 @ * this function performs inverse transform and reconstruction for 8x8 43 @ * input block 44 @ * 45 @ * @par description: 46 @ * performs inverse transform and adds the prediction data and clips output 47 @ * to 8 bit 48 @ * 49 @ * @param[in] pi2_src 50 @ * input 16x16 coefficients 51 @ * 52 @ * @param[in] pi2_tmp 53 @ * temporary 16x16 buffer for storing inverse 54 @ * 55 @ * transform 56 @ * 1st stage output 57 @ * 58 @ * @param[in] pu1_pred 59 @ * prediction 16x16 block 60 @ * 61 @ * @param[out] pu1_dst 62 @ * output 8x8 block 63 @ * 64 @ * @param[in] src_strd 65 @ * input stride 66 @ * 67 @ * @param[in] pred_strd 68 @ * prediction stride 69 @ * 70 @ * @param[in] dst_strd 71 @ * output stride 72 @ * 73 @ * @param[in] shift 74 @ * output shift 75 @ * 76 @ * @param[in] r12 77 @ * zero columns in pi2_src 78 @ * 79 @ * @returns void 80 @ * 81 @ * @remarks 82 @ * none 83 @ * 84 @ ******************************************************************************* 85 @ */ 86 87 @void ihevc_itrans_recon_16x16(word16 *pi2_src, 88 @ word16 *pi2_tmp, 89 @ uword8 *pu1_pred, 90 @ uword8 *pu1_dst, 91 @ word32 src_strd, 92 @ word32 pred_strd, 93 @ word32 dst_strd, 94 @ word32 r12 95 @ word32 r11 ) 96 97 @**************variables vs registers************************* 98 @ r0 => *pi2_src 99 @ r1 => *pi2_tmp 100 @ r2 => *pu1_pred 101 @ r3 => *pu1_dst 102 @ src_strd 103 @ pred_strd 104 @ dst_strd 105 @ r12 106 @ r11 107 108 .equ src_stride_offset, 104 109 .equ pred_stride_offset, 108 110 .equ out_stride_offset, 112 111 .equ zero_cols_offset, 116 112 .equ zero_rows_offset, 120 113 114 .text 115 .align 4 116 117 118 119 120 121 122 .set shift_stage1_idct , 7 123 .set shift_stage2_idct , 12 124 @#define zero_cols r12 125 @#define zero_rows r11 126 .globl ihevc_itrans_recon_16x16_a9q 127 128 .extern g_ai2_ihevc_trans_16_transpose 129 130 g_ai2_ihevc_trans_16_transpose_addr: 131 .long g_ai2_ihevc_trans_16_transpose - ulbl1 - 8 132 133 .type ihevc_itrans_recon_16x16_a9q, %function 134 135 ihevc_itrans_recon_16x16_a9q: 136 137 stmfd sp!,{r4-r12,lr} 138 vpush {d8 - d15} 139 ldr r6,[sp,#src_stride_offset] @ src stride 140 ldr r12,[sp,#zero_cols_offset] 141 ldr r11,[sp,#zero_rows_offset] 142 143 144 145 ldr r14,g_ai2_ihevc_trans_16_transpose_addr 146 ulbl1: 147 add r14,r14,pc 148 vld1.16 {d0,d1,d2,d3},[r14] @//d0,d1 are used for storing the constant data 149 movw r7,#0xffff 150 and r12,r12,r7 151 and r11,r11,r7 152 mov r6,r6,lsl #1 @ x sizeof(word16) 153 add r9,r0,r6, lsl #1 @ 2 rows 154 155 add r10,r6,r6, lsl #1 @ 3 rows 156 add r5,r6,r6,lsl #2 157 movw r7,#0xfff0 158 159 cmp r12,r7 160 bge zero_12cols_decision 161 162 cmp r12,#0xff00 163 bge zero_8cols_decision 164 165 166 167 168 mov r14,#4 169 cmp r11,r7 170 rsbge r10,r6,#0 171 172 cmp r11,#0xff00 173 movge r8,r5 174 rsbge r8,r8,#0 175 movlt r8,r10 176 add r5,r5,r6,lsl #3 177 rsb r5,r5,#0 178 179 b first_stage_top_four_bottom_four 180 181 zero_12cols_decision: 182 mov r14,#1 183 cmp r11,#0xff00 184 movge r8,r5 185 movlt r8,r10 186 add r5,r5,r6,lsl #3 187 rsb r5,r5,#0 188 189 b first_stage_top_four_bottom_four 190 191 zero_8cols_decision: 192 mov r14,#2 193 mov r8,r5 194 rsb r8,r8,#0 195 cmp r11,#0xff00 196 movlt r8,r10 197 add r5,r5,r6,lsl #3 198 rsb r5,r5,#0 199 cmp r11,r7 200 rsbge r10,r6,#0 201 202 203 b first_stage_top_four_bottom_four 204 205 206 @d0[0]= 64 d2[0]=64 207 @d0[1]= 90 d2[1]=57 208 @d0[2]= 89 d2[2]=50 209 @d0[3]= 87 d2[3]=43 210 @d1[0]= 83 d3[0]=36 211 @d1[1]= 80 d3[1]=25 212 @d1[2]= 75 d3[2]=18 213 @d1[3]= 70 d3[3]=9 214 215 216 217 first_stage: 218 add r0,r0,#8 219 add r9,r9,#8 220 221 first_stage_top_four_bottom_four: 222 223 vld1.16 d10,[r0],r6 224 vld1.16 d11,[r9],r6 225 vld1.16 d6,[r0],r10 226 vld1.16 d7,[r9],r10 227 cmp r11,r7 228 bge skip_load4rows 229 230 vld1.16 d4,[r0],r6 231 vld1.16 d5,[r9],r6 232 vld1.16 d8,[r0],r8 233 vld1.16 d9,[r9],r8 234 235 @ registers used: q0,q1,q3,q5,q2,q4 236 237 @ d10 =r0 238 @d6= r1 239 @d11=r2 240 @d7=r3 241 242 skip_load4rows: 243 vmull.s16 q12,d6,d0[1] @// y1 * cos1(part of b0) 244 vmull.s16 q13,d6,d0[3] @// y1 * cos3(part of b1) 245 vmull.s16 q14,d6,d1[1] @// y1 * sin3(part of b2) 246 vmull.s16 q15,d6,d1[3] @// y1 * sin1(part of b3) 247 248 vmlal.s16 q12,d7,d0[3] @// y1 * cos1 + y3 * cos3(part of b0) 249 vmlal.s16 q13,d7,d2[1] @// y1 * cos3 - y3 * sin1(part of b1) 250 vmlal.s16 q14,d7,d3[3] @// y1 * sin3 - y3 * cos1(part of b2) 251 vmlsl.s16 q15,d7,d2[3] @// y1 * sin1 - y3 * sin3(part of b3) 252 253 254 255 256 257 258 vmull.s16 q6,d10,d0[0] 259 vmlal.s16 q6,d11,d0[2] 260 vmull.s16 q7,d10,d0[0] 261 vmlal.s16 q7,d11,d1[2] 262 vmull.s16 q8,d10,d0[0] 263 vmlal.s16 q8,d11,d2[2] 264 vmull.s16 q9,d10,d0[0] 265 vmlal.s16 q9,d11,d3[2] 266 267 bge skip_last12rows_kernel1 268 269 270 vmlal.s16 q12,d8,d1[1] 271 vmlal.s16 q13,d8,d3[3] 272 vmlsl.s16 q14,d8,d1[3] 273 vmlsl.s16 q15,d8,d0[3] 274 275 276 vmlal.s16 q12,d9,d1[3] 277 vmlsl.s16 q13,d9,d2[3] 278 vmlsl.s16 q14,d9,d0[3] 279 vmlal.s16 q15,d9,d3[3] 280 281 282 283 284 285 vmlal.s16 q6,d4,d1[0] 286 vmlal.s16 q6,d5,d1[2] 287 vmlal.s16 q7,d4,d3[0] 288 vmlsl.s16 q7,d5,d3[2] 289 vmlsl.s16 q8,d4,d3[0] 290 vmlsl.s16 q8,d5,d0[2] 291 vmlsl.s16 q9,d4,d1[0] 292 vmlsl.s16 q9,d5,d2[2] 293 294 @d0[0]= 64 d2[0]=64 295 @d0[1]= 90 d2[1]=57 296 @d0[2]= 89 d2[2]=50 297 @d0[3]= 87 d2[3]=43 298 @d1[0]= 83 d3[0]=36 299 @d1[1]= 80 d3[1]=25 300 @d1[2]= 75 d3[2]=18 301 @d1[3]= 70 d3[3]=9 302 cmp r11,#0xff00 303 bge skip_last12rows_kernel1 304 305 306 vld1.16 d10,[r0],r6 307 vld1.16 d11,[r9],r6 308 vld1.16 d6,[r0],r10 309 vld1.16 d7,[r9],r10 310 vld1.16 d4,[r0],r6 311 vld1.16 d5,[r9],r6 312 vld1.16 d8,[r0],r5 313 vld1.16 d9,[r9],r5 314 315 316 317 318 vmlal.s16 q12,d6,d2[1] @// y1 * cos1(part of b0) 319 vmlsl.s16 q13,d6,d1[1] @// y1 * cos3(part of b1) 320 vmlsl.s16 q14,d6,d3[1] @// y1 * sin3(part of b2) 321 vmlal.s16 q15,d6,d0[1] @// y1 * sin1(part of b3) 322 323 vmlal.s16 q12,d7,d2[3] @// y1 * cos1 + y3 * cos3(part of b0) 324 vmlsl.s16 q13,d7,d0[1] @// y1 * cos3 - y3 * sin1(part of b1) 325 vmlal.s16 q14,d7,d2[1] @// y1 * sin3 - y3 * cos1(part of b2) 326 vmlal.s16 q15,d7,d3[1] @// y1 * sin1 - y3 * sin3(part of b3) 327 328 329 330 vmlal.s16 q12,d8,d3[1] 331 vmlsl.s16 q13,d8,d1[3] 332 vmlal.s16 q14,d8,d0[1] 333 vmlsl.s16 q15,d8,d1[1] 334 335 336 vmlal.s16 q12,d9,d3[3] 337 vmlsl.s16 q13,d9,d3[1] 338 vmlal.s16 q14,d9,d2[3] 339 vmlsl.s16 q15,d9,d2[1] 340 341 342 343 344 345 vmlal.s16 q6,d10,d0[0] 346 vmlal.s16 q6,d11,d2[2] 347 vmlal.s16 q6,d4,d3[0] 348 vmlal.s16 q6,d5,d3[2] 349 350 351 352 353 vmlsl.s16 q7,d10,d0[0] 354 vmlsl.s16 q7,d11,d0[2] 355 vmlsl.s16 q7,d4,d1[0] 356 vmlsl.s16 q7,d5,d2[2] 357 358 359 vmlsl.s16 q8,d10,d0[0] 360 vmlal.s16 q8,d11,d3[2] 361 vmlal.s16 q8,d4,d1[0] 362 vmlal.s16 q8,d5,d1[2] 363 364 365 vmlal.s16 q9,d10,d0[0] 366 vmlal.s16 q9,d11,d1[2] 367 vmlsl.s16 q9,d4,d3[0] 368 vmlsl.s16 q9,d5,d0[2] 369 370 skip_last12rows_kernel1: 371 vadd.s32 q10,q6,q12 372 vsub.s32 q11,q6,q12 373 374 vadd.s32 q6,q7,q13 375 vsub.s32 q12,q7,q13 376 377 vadd.s32 q7,q8,q14 378 vsub.s32 q13,q8,q14 379 380 381 vadd.s32 q8,q9,q15 382 vsub.s32 q14,q9,q15 383 384 385 386 387 388 389 390 vqrshrn.s32 d30,q10,#shift_stage1_idct @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct) 391 vqrshrn.s32 d19,q11,#shift_stage1_idct @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct) 392 vqrshrn.s32 d31,q7,#shift_stage1_idct @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct) 393 vqrshrn.s32 d18,q13,#shift_stage1_idct @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct) 394 vqrshrn.s32 d12,q6,#shift_stage1_idct @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct) 395 vqrshrn.s32 d15,q12,#shift_stage1_idct @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct) 396 vqrshrn.s32 d13,q8,#shift_stage1_idct @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct) 397 vqrshrn.s32 d14,q14,#shift_stage1_idct @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct) 398 399 vst1.16 {d30,d31},[r1]! 400 vst1.16 {d18,d19},[r1]! 401 sub r1,r1,#32 402 403 bge skip_stage1_kernel_load 404 405 first_stage_middle_eight: 406 407 408 409 vld1.16 d10,[r0],r6 410 vld1.16 d11,[r9],r6 411 vld1.16 d6,[r0],r10 412 vld1.16 d7,[r9],r10 413 vld1.16 d4,[r0],r6 414 vld1.16 d5,[r9],r6 415 vld1.16 d8,[r0],r8 416 vld1.16 d9,[r9],r8 417 418 419 skip_stage1_kernel_load: 420 vmull.s16 q12,d6,d2[1] @// y1 * cos1(part of b0) 421 vmull.s16 q13,d6,d2[3] @// y1 * cos3(part of b1) 422 vmull.s16 q14,d6,d3[1] @// y1 * sin3(part of b2) 423 vmull.s16 q15,d6,d3[3] @// y1 * sin1(part of b3) 424 425 vmlsl.s16 q12,d7,d1[1] @// y1 * cos1 + y3 * cos3(part of b0) 426 vmlsl.s16 q13,d7,d0[1] @// y1 * cos3 - y3 * sin1(part of b1) 427 vmlsl.s16 q14,d7,d1[3] @// y1 * sin3 - y3 * cos1(part of b2) 428 vmlsl.s16 q15,d7,d3[1] @// y1 * sin1 - y3 * sin3(part of b3) 429 430 431 432 433 434 435 vmull.s16 q11,d10,d0[0] 436 vmlsl.s16 q11,d11,d3[2] 437 vmull.s16 q10,d10,d0[0] 438 vmlsl.s16 q10,d11,d2[2] 439 vmull.s16 q8,d10,d0[0] 440 vmlsl.s16 q8,d11,d1[2] 441 vmull.s16 q9,d10,d0[0] 442 vmlsl.s16 q9,d11,d0[2] 443 444 445 cmp r11,r7 446 bge skip_last12rows_kernel2 447 448 vmlsl.s16 q12,d8,d3[1] 449 vmlal.s16 q13,d8,d2[1] 450 vmlal.s16 q14,d8,d0[1] 451 vmlal.s16 q15,d8,d2[3] 452 453 454 vmlal.s16 q12,d9,d0[1] 455 vmlal.s16 q13,d9,d3[1] 456 vmlsl.s16 q14,d9,d1[1] 457 vmlsl.s16 q15,d9,d2[1] 458 459 460 461 vmlsl.s16 q11,d4,d1[0] 462 vmlal.s16 q11,d5,d2[2] 463 vmlsl.s16 q10,d4,d3[0] 464 vmlal.s16 q10,d5,d0[2] 465 vmlal.s16 q8,d4,d3[0] 466 vmlal.s16 q8,d5,d3[2] 467 vmlal.s16 q9,d4,d1[0] 468 vmlsl.s16 q9,d5,d1[2] 469 470 @d0[0]= 64 d2[0]=64 471 @d0[1]= 90 d2[1]=57 472 @d0[2]= 89 d2[2]=50 473 @d0[3]= 87 d2[3]=43 474 @d1[0]= 83 d3[0]=36 475 @d1[1]= 80 d3[1]=25 476 @d1[2]= 75 d3[2]=18 477 @d1[3]= 70 d3[3]=9 478 cmp r11,#0xff00 479 bge skip_last12rows_kernel2 480 481 vld1.16 d10,[r0],r6 482 vld1.16 d11,[r9],r6 483 vld1.16 d6,[r0],r10 484 vld1.16 d7,[r9],r10 485 vld1.16 d4,[r0],r6 486 vld1.16 d5,[r9],r6 487 vld1.16 d8,[r0],r5 488 vld1.16 d9,[r9],r5 489 490 491 vmlsl.s16 q12,d6,d3[3] @// y1 * cos1(part of b0) 492 vmlsl.s16 q13,d6,d0[3] @// y1 * cos3(part of b1) 493 vmlal.s16 q14,d6,d2[3] @// y1 * sin3(part of b2) 494 vmlal.s16 q15,d6,d1[3] @// y1 * sin1(part of b3) 495 496 vmlsl.s16 q12,d7,d0[3] @// y1 * cos1 + y3 * cos3(part of b0) 497 vmlal.s16 q13,d7,d1[3] @// y1 * cos3 - y3 * sin1(part of b1) 498 vmlal.s16 q14,d7,d3[3] @// y1 * sin3 - y3 * cos1(part of b2) 499 vmlsl.s16 q15,d7,d1[1] @// y1 * sin1 - y3 * sin3(part of b3) 500 501 502 vmlal.s16 q12,d8,d2[3] 503 vmlal.s16 q13,d8,d3[3] 504 vmlsl.s16 q14,d8,d2[1] 505 vmlal.s16 q15,d8,d0[3] 506 507 508 vmlal.s16 q12,d9,d1[3] 509 vmlsl.s16 q13,d9,d1[1] 510 vmlal.s16 q14,d9,d0[3] 511 vmlsl.s16 q15,d9,d0[1] 512 513 514 515 516 vmlal.s16 q11,d10,d0[0] 517 vmlsl.s16 q11,d11,d1[2] 518 vmlsl.s16 q11,d4,d3[0] 519 vmlal.s16 q11,d5,d0[2] 520 521 522 523 vmlsl.s16 q10,d10,d0[0] 524 vmlsl.s16 q10,d11,d3[2] 525 vmlal.s16 q10,d4,d1[0] 526 vmlsl.s16 q10,d5,d1[2] 527 528 529 vmlsl.s16 q8,d10,d0[0] 530 vmlal.s16 q8,d11,d0[2] 531 vmlsl.s16 q8,d4,d1[0] 532 vmlal.s16 q8,d5,d2[2] 533 534 535 536 vmlal.s16 q9,d10,d0[0] 537 vmlsl.s16 q9,d11,d2[2] 538 vmlal.s16 q9,d4,d3[0] 539 vmlsl.s16 q9,d5,d3[2] 540 541 skip_last12rows_kernel2: 542 543 vadd.s32 q2,q11,q12 544 vsub.s32 q11,q11,q12 545 546 vadd.s32 q3,q10,q13 547 vsub.s32 q12,q10,q13 548 549 vadd.s32 q5,q8,q14 550 vsub.s32 q13,q8,q14 551 552 553 vadd.s32 q8,q9,q15 554 vsub.s32 q14,q9,q15 555 556 557 vqrshrn.s32 d18,q2,#shift_stage1_idct @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct) 558 vqrshrn.s32 d31,q11,#shift_stage1_idct @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct) 559 vqrshrn.s32 d19,q5,#shift_stage1_idct @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct) 560 vqrshrn.s32 d30,q13,#shift_stage1_idct @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct) 561 vqrshrn.s32 d20,q3,#shift_stage1_idct @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct) 562 vqrshrn.s32 d23,q12,#shift_stage1_idct @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct) 563 vqrshrn.s32 d21,q8,#shift_stage1_idct @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct) 564 vqrshrn.s32 d22,q14,#shift_stage1_idct @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct) 565 566 567 @ registers used: {q2,q4,q6,q7}, {q9,q15,q10,q11} 568 569 570 571 572 573 574 vld1.16 {d4,d5},[r1]! 575 vld1.16 {d8,d9},[r1]! 576 sub r1,r1,#32 577 578 @d4=r0 579 @d12=r1 580 @d5=r2 581 @d13=r3 582 583 @d18=r4 584 @d20=r5 585 @d19=r6 586 @d21=r7 587 588 @d22=r8 589 @d30=r9 590 @d23=r10 591 @d31=r11 592 593 @d14=r12 594 @d8=r13 595 @d15=r14 596 @d9=r15 597 598 599 vtrn.16 q2,q6 600 vtrn.16 q9,q10 601 vtrn.16 q11,q15 602 vtrn.16 q7,q4 603 604 605 606 vtrn.32 d4,d5 607 vtrn.32 d12,d13 608 609 vtrn.32 d18,d19 610 vtrn.32 d20,d21 611 612 vtrn.32 d22,d23 613 vtrn.32 d30,d31 614 615 vtrn.32 d14,d15 616 vtrn.32 d8,d9 617 618 619 @ d4 =r0 1- 4 values 620 @ d5 =r2 1- 4 values 621 @ d12=r1 1- 4 values 622 @ d13=r3 1- 4 values 623 624 @ d18 =r0 5- 8 values 625 @ d19 =r2 5- 8 values 626 @ d20=r1 5- 8 values 627 @ d21=r3 5- 8 values 628 629 @ d22 =r0 9- 12 values 630 @ d23 =r2 9- 12 values 631 @ d30=r1 9- 12 values 632 @ d31=r3 9- 12 values 633 634 @ d14 =r0 13-16 values 635 @ d15 =r2 13- 16 values 636 @ d8=r1 13- 16 values 637 @ d9=r3 13- 16 values 638 639 640 vst1.16 {q2},[r1]! 641 vst1.16 {q6},[r1]! 642 643 vst1.16 {q9},[r1]! 644 vst1.16 {q10},[r1]! 645 vst1.16 {q11},[r1]! 646 vst1.16 {q15},[r1]! 647 vst1.16 {q7},[r1]! 648 vst1.16 {q4},[r1]! 649 650 651 subs r14,r14,#1 652 bne first_stage 653 654 655 656 657 658 659 660 661 662 663 mov r6,r7 664 665 ldr r8,[sp,#pred_stride_offset] @ prediction stride 666 ldr r7,[sp,#out_stride_offset] @ destination stride 667 668 mov r10,#16 669 670 cmp r12,r6 671 subge r1,r1,#128 672 bge label1 673 674 cmp r12,#0xff00 675 subge r1,r1,#256 676 bge label_2 677 678 sub r1,r1,#512 679 rsb r10,r10,#0 680 681 label_2: 682 add r9,r1,#128 683 add r11,r9,#128 684 add r0,r11,#128 685 686 687 688 label1: 689 @ mov r6,r1 690 691 692 mov r14,#4 693 add r4,r2,r8, lsl #1 @ r4 = r2 + pred_strd * 2 => r4 points to 3rd row of pred data 694 add r5,r8,r8, lsl #1 @ 695 @ add r0,r3,r7, lsl #1 @ r0 points to 3rd row of dest data 696 @ add r10,r7,r7, lsl #1 @ 697 698 699 700 701 second_stage: 702 vld1.16 {d10,d11},[r1]! 703 vld1.16 {d6,d7},[r1],r10 704 cmp r12,r6 705 bge second_stage_process 706 vld1.16 {d4,d5},[r9]! 707 vld1.16 {d8,d9},[r9],r10 708 709 second_stage_process: 710 711 712 vmull.s16 q12,d6,d0[1] @// y1 * cos1(part of b0) 713 vmull.s16 q13,d6,d0[3] @// y1 * cos3(part of b1) 714 vmull.s16 q14,d6,d1[1] @// y1 * sin3(part of b2) 715 vmull.s16 q15,d6,d1[3] @// y1 * sin1(part of b3) 716 717 vmlal.s16 q12,d7,d0[3] @// y1 * cos1 + y3 * cos3(part of b0) 718 vmlal.s16 q13,d7,d2[1] @// y1 * cos3 - y3 * sin1(part of b1) 719 vmlal.s16 q14,d7,d3[3] @// y1 * sin3 - y3 * cos1(part of b2) 720 vmlsl.s16 q15,d7,d2[3] @// y1 * sin1 - y3 * sin3(part of b3) 721 722 723 vmull.s16 q6,d10,d0[0] 724 vmlal.s16 q6,d11,d0[2] 725 vmull.s16 q7,d10,d0[0] 726 vmlal.s16 q7,d11,d1[2] 727 vmull.s16 q8,d10,d0[0] 728 vmlal.s16 q8,d11,d2[2] 729 vmull.s16 q9,d10,d0[0] 730 vmlal.s16 q9,d11,d3[2] 731 732 bge skip_last8rows_stage2_kernel1 733 734 vmlal.s16 q12,d8,d1[1] 735 vmlal.s16 q13,d8,d3[3] 736 vmlsl.s16 q14,d8,d1[3] 737 vmlsl.s16 q15,d8,d0[3] 738 739 740 vmlal.s16 q12,d9,d1[3] 741 vmlsl.s16 q13,d9,d2[3] 742 vmlsl.s16 q14,d9,d0[3] 743 vmlal.s16 q15,d9,d3[3] 744 745 746 vmlal.s16 q6,d4,d1[0] 747 vmlal.s16 q6,d5,d1[2] 748 vmlal.s16 q7,d4,d3[0] 749 vmlsl.s16 q7,d5,d3[2] 750 vmlsl.s16 q8,d4,d3[0] 751 vmlsl.s16 q8,d5,d0[2] 752 vmlsl.s16 q9,d4,d1[0] 753 vmlsl.s16 q9,d5,d2[2] 754 755 cmp r12,#0xff00 756 bge skip_last8rows_stage2_kernel1 757 758 759 vld1.16 {d10,d11},[r11]! 760 vld1.16 {d6,d7},[r11],r10 761 vld1.16 {d4,d5},[r0]! 762 vld1.16 {d8,d9},[r0],r10 763 764 765 766 767 768 vmlal.s16 q12,d6,d2[1] @// y1 * cos1(part of b0) 769 vmlsl.s16 q13,d6,d1[1] @// y1 * cos3(part of b1) 770 vmlsl.s16 q14,d6,d3[1] @// y1 * sin3(part of b2) 771 vmlal.s16 q15,d6,d0[1] @// y1 * sin1(part of b3) 772 773 vmlal.s16 q12,d7,d2[3] @// y1 * cos1 + y3 * cos3(part of b0) 774 vmlsl.s16 q13,d7,d0[1] @// y1 * cos3 - y3 * sin1(part of b1) 775 vmlal.s16 q14,d7,d2[1] @// y1 * sin3 - y3 * cos1(part of b2) 776 vmlal.s16 q15,d7,d3[1] @// y1 * sin1 - y3 * sin3(part of b3) 777 778 779 780 vmlal.s16 q12,d8,d3[1] 781 vmlsl.s16 q13,d8,d1[3] 782 vmlal.s16 q14,d8,d0[1] 783 vmlsl.s16 q15,d8,d1[1] 784 785 786 vmlal.s16 q12,d9,d3[3] 787 vmlsl.s16 q13,d9,d3[1] 788 vmlal.s16 q14,d9,d2[3] 789 vmlsl.s16 q15,d9,d2[1] 790 791 792 793 794 795 vmlal.s16 q6,d10,d0[0] 796 vmlal.s16 q6,d11,d2[2] 797 vmlal.s16 q6,d4,d3[0] 798 vmlal.s16 q6,d5,d3[2] 799 800 801 802 803 vmlsl.s16 q7,d10,d0[0] 804 vmlsl.s16 q7,d11,d0[2] 805 vmlsl.s16 q7,d4,d1[0] 806 vmlsl.s16 q7,d5,d2[2] 807 808 809 vmlsl.s16 q8,d10,d0[0] 810 vmlal.s16 q8,d11,d3[2] 811 vmlal.s16 q8,d4,d1[0] 812 vmlal.s16 q8,d5,d1[2] 813 814 815 vmlal.s16 q9,d10,d0[0] 816 vmlal.s16 q9,d11,d1[2] 817 vmlsl.s16 q9,d4,d3[0] 818 vmlsl.s16 q9,d5,d0[2] 819 820 821 822 823 824 825 skip_last8rows_stage2_kernel1: 826 827 828 829 vadd.s32 q10,q6,q12 830 vsub.s32 q11,q6,q12 831 832 vadd.s32 q6,q7,q13 833 vsub.s32 q12,q7,q13 834 835 vadd.s32 q7,q8,q14 836 vsub.s32 q13,q8,q14 837 838 839 vadd.s32 q8,q9,q15 840 vsub.s32 q14,q9,q15 841 842 843 844 845 846 847 848 vqrshrn.s32 d30,q10,#shift_stage2_idct @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct) 849 vqrshrn.s32 d19,q11,#shift_stage2_idct @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct) 850 vqrshrn.s32 d31,q7,#shift_stage2_idct @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct) 851 vqrshrn.s32 d18,q13,#shift_stage2_idct @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct) 852 vqrshrn.s32 d12,q6,#shift_stage2_idct @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct) 853 vqrshrn.s32 d15,q12,#shift_stage2_idct @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct) 854 vqrshrn.s32 d13,q8,#shift_stage2_idct @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct) 855 vqrshrn.s32 d14,q14,#shift_stage2_idct @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct) 856 857 bge skip_stage2_kernel_load 858 859 @q2,q4,q6,q7 is used 860 vld1.16 {d10,d11},[r1]! 861 vld1.16 {d6,d7},[r1]! 862 vld1.16 {d4,d5},[r9]! 863 vld1.16 {d8,d9},[r9]! 864 skip_stage2_kernel_load: 865 sub r1,r1,#32 866 vst1.16 {d30,d31},[r1]! 867 vst1.16 {d18,d19},[r1]! 868 sub r1,r1,#32 869 870 vmull.s16 q12,d6,d2[1] @// y1 * cos1(part of b0) 871 vmull.s16 q13,d6,d2[3] @// y1 * cos3(part of b1) 872 vmull.s16 q14,d6,d3[1] @// y1 * sin3(part of b2) 873 vmull.s16 q15,d6,d3[3] @// y1 * sin1(part of b3) 874 875 vmlsl.s16 q12,d7,d1[1] @// y1 * cos1 + y3 * cos3(part of b0) 876 vmlsl.s16 q13,d7,d0[1] @// y1 * cos3 - y3 * sin1(part of b1) 877 vmlsl.s16 q14,d7,d1[3] @// y1 * sin3 - y3 * cos1(part of b2) 878 vmlsl.s16 q15,d7,d3[1] @// y1 * sin1 - y3 * sin3(part of b3) 879 880 881 vmull.s16 q11,d10,d0[0] 882 vmlsl.s16 q11,d11,d3[2] 883 vmull.s16 q10,d10,d0[0] 884 vmlsl.s16 q10,d11,d2[2] 885 vmull.s16 q8,d10,d0[0] 886 vmlsl.s16 q8,d11,d1[2] 887 vmull.s16 q9,d10,d0[0] 888 vmlsl.s16 q9,d11,d0[2] 889 890 891 892 cmp r12,r6 893 bge skip_last8rows_stage2_kernel2 894 895 896 vmlsl.s16 q12,d8,d3[1] 897 vmlal.s16 q13,d8,d2[1] 898 vmlal.s16 q14,d8,d0[1] 899 vmlal.s16 q15,d8,d2[3] 900 901 902 vmlal.s16 q12,d9,d0[1] 903 vmlal.s16 q13,d9,d3[1] 904 vmlsl.s16 q14,d9,d1[1] 905 vmlsl.s16 q15,d9,d2[1] 906 907 908 909 vmlsl.s16 q11,d4,d1[0] 910 vmlal.s16 q11,d5,d2[2] 911 vmlsl.s16 q10,d4,d3[0] 912 vmlal.s16 q10,d5,d0[2] 913 vmlal.s16 q8,d4,d3[0] 914 vmlal.s16 q8,d5,d3[2] 915 vmlal.s16 q9,d4,d1[0] 916 vmlsl.s16 q9,d5,d1[2] 917 cmp r12,#0xff00 918 bge skip_last8rows_stage2_kernel2 919 920 vld1.16 {d10,d11},[r11]! 921 vld1.16 {d6,d7},[r11]! 922 vld1.16 {d4,d5},[r0]! 923 vld1.16 {d8,d9},[r0]! 924 925 vmlsl.s16 q12,d6,d3[3] @// y1 * cos1(part of b0) 926 vmlsl.s16 q13,d6,d0[3] @// y1 * cos3(part of b1) 927 vmlal.s16 q14,d6,d2[3] @// y1 * sin3(part of b2) 928 vmlal.s16 q15,d6,d1[3] @// y1 * sin1(part of b3) 929 930 vmlsl.s16 q12,d7,d0[3] @// y1 * cos1 + y3 * cos3(part of b0) 931 vmlal.s16 q13,d7,d1[3] @// y1 * cos3 - y3 * sin1(part of b1) 932 vmlal.s16 q14,d7,d3[3] @// y1 * sin3 - y3 * cos1(part of b2) 933 vmlsl.s16 q15,d7,d1[1] @// y1 * sin1 - y3 * sin3(part of b3) 934 935 936 vmlal.s16 q12,d8,d2[3] 937 vmlal.s16 q13,d8,d3[3] 938 vmlsl.s16 q14,d8,d2[1] 939 vmlal.s16 q15,d8,d0[3] 940 941 942 vmlal.s16 q12,d9,d1[3] 943 vmlsl.s16 q13,d9,d1[1] 944 vmlal.s16 q14,d9,d0[3] 945 vmlsl.s16 q15,d9,d0[1] 946 947 948 949 950 vmlal.s16 q11,d10,d0[0] 951 vmlsl.s16 q11,d11,d1[2] 952 vmlsl.s16 q11,d4,d3[0] 953 vmlal.s16 q11,d5,d0[2] 954 955 956 957 vmlsl.s16 q10,d10,d0[0] 958 vmlsl.s16 q10,d11,d3[2] 959 vmlal.s16 q10,d4,d1[0] 960 vmlsl.s16 q10,d5,d1[2] 961 962 963 vmlsl.s16 q8,d10,d0[0] 964 vmlal.s16 q8,d11,d0[2] 965 vmlsl.s16 q8,d4,d1[0] 966 vmlal.s16 q8,d5,d2[2] 967 968 969 970 vmlal.s16 q9,d10,d0[0] 971 vmlsl.s16 q9,d11,d2[2] 972 vmlal.s16 q9,d4,d3[0] 973 vmlsl.s16 q9,d5,d3[2] 974 975 976 skip_last8rows_stage2_kernel2: 977 978 979 980 vadd.s32 q2,q11,q12 981 vsub.s32 q11,q11,q12 982 983 vadd.s32 q3,q10,q13 984 vsub.s32 q12,q10,q13 985 986 vadd.s32 q5,q8,q14 987 vsub.s32 q13,q8,q14 988 989 990 vadd.s32 q8,q9,q15 991 vsub.s32 q14,q9,q15 992 993 994 vqrshrn.s32 d18,q2,#shift_stage2_idct @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct) 995 vqrshrn.s32 d31,q11,#shift_stage2_idct @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct) 996 vqrshrn.s32 d19,q5,#shift_stage2_idct @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct) 997 vqrshrn.s32 d30,q13,#shift_stage2_idct @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct) 998 vqrshrn.s32 d20,q3,#shift_stage2_idct @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct) 999 vqrshrn.s32 d23,q12,#shift_stage2_idct @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct) 1000 vqrshrn.s32 d21,q8,#shift_stage2_idct @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct) 1001 vqrshrn.s32 d22,q14,#shift_stage2_idct @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct) 1002 1003 vld1.16 {d4,d5},[r1]! 1004 vld1.16 {d8,d9},[r1]! 1005 1006 1007 1008 @ registers used: {q2,q4,q6,q7}, {q9,q15,q10,q11} 1009 1010 @d4=r0 1011 @d12=r1 1012 @d5=r2 1013 @d13=r3 1014 1015 @d18=r4 1016 @d20=r5 1017 @d19=r6 1018 @d21=r7 1019 1020 @d22=r8 1021 @d30=r9 1022 @d23=r10 1023 @d31=r11 1024 1025 @d14=r12 1026 @d8=r13 1027 @d15=r14 1028 @d9=r15 1029 1030 1031 vtrn.16 q2,q6 1032 vtrn.16 q9,q10 1033 vtrn.16 q11,q15 1034 vtrn.16 q7,q4 1035 1036 1037 1038 vtrn.32 d4,d5 1039 vtrn.32 d12,d13 1040 1041 vtrn.32 d18,d19 1042 vtrn.32 d20,d21 1043 1044 vtrn.32 d22,d23 1045 vtrn.32 d30,d31 1046 1047 vtrn.32 d14,d15 1048 vtrn.32 d8,d9 1049 1050 @ d4 =r0 1- 4 values 1051 @ d5 =r2 1- 4 values 1052 @ d12=r1 1- 4 values 1053 @ d13=r3 1- 4 values 1054 1055 @ d18 =r0 5- 8 values 1056 @ d19 =r2 5- 8 values 1057 @ d20=r1 5- 8 values 1058 @ d21=r3 5- 8 values 1059 1060 @ d22 =r0 9- 12 values 1061 @ d23 =r2 9- 12 values 1062 @ d30=r1 9- 12 values 1063 @ d31=r3 9- 12 values 1064 1065 @ d14 =r0 13-16 values 1066 @ d15 =r2 13- 16 values 1067 @ d8=r1 13- 16 values 1068 @ d9=r3 13- 16 values 1069 1070 1071 vswp d5,d18 1072 vswp d23,d14 1073 vswp d13,d20 1074 vswp d31,d8 1075 1076 @ q2: r0 1-8 values 1077 @ q11: r0 9-16 values 1078 @ q9 : r2 1-8 values 1079 @ q7 : r2 9-16 values 1080 @ q6 : r1 1- 8 values 1081 @ q10: r3 1-8 values 1082 @ q15: r1 9-16 values 1083 @ q4: r3 9-16 values 1084 1085 1086 @ registers free: q8,q14,q12,q13 1087 1088 1089 vld1.8 {d16,d17},[r2],r8 1090 vld1.8 {d28,d29},[r2],r5 1091 vld1.8 {d24,d25},[r4],r8 1092 vld1.8 {d26,d27},[r4],r5 1093 1094 1095 1096 1097 vaddw.u8 q2,q2,d16 1098 vaddw.u8 q11,q11,d17 1099 vaddw.u8 q6,q6,d28 1100 vaddw.u8 q15,q15,d29 1101 vaddw.u8 q9,q9,d24 1102 vaddw.u8 q7,q7,d25 1103 vaddw.u8 q10,q10,d26 1104 vaddw.u8 q4,q4,d27 1105 1106 1107 vqmovun.s16 d16,q2 1108 vqmovun.s16 d17,q11 1109 vqmovun.s16 d28,q6 1110 vqmovun.s16 d29,q15 1111 vqmovun.s16 d24,q9 1112 vqmovun.s16 d25,q7 1113 vqmovun.s16 d26,q10 1114 vqmovun.s16 d27,q4 1115 1116 1117 1118 vst1.8 {d16,d17},[r3],r7 1119 vst1.8 {d28,d29},[r3],r7 1120 vst1.8 {d24,d25},[r3],r7 1121 vst1.8 {d26,d27},[r3],r7 1122 1123 subs r14,r14,#1 1124 1125 1126 1127 bne second_stage 1128 1129 1130 vpop {d8 - d15} 1131 ldmfd sp!,{r4-r12,pc} 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143