You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1143 lines
26 KiB

@/*****************************************************************************
@*
@* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
@*
@* Licensed under the Apache License, Version 2.0 (the "License");
@* you may not use this file except in compliance with the License.
@* You may obtain a copy of the License at:
@*
@* http://www.apache.org/licenses/LICENSE-2.0
@*
@* Unless required by applicable law or agreed to in writing, software
@* distributed under the License is distributed on an "AS IS" BASIS,
@* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@* See the License for the specific language governing permissions and
@* limitations under the License.
@*
@*****************************************************************************/
@/**
@ *******************************************************************************
@ * @file
@ * ihevc_itrans_recon_8x8_neon.s
@ *
@ * @brief
@ * contains function definitions for single stage inverse transform
@ *
@ * @author
@ * anand s
@ *
@ * @par list of functions:
@ * - ihevc_itrans_recon_16x16()
@ *
@ * @remarks
@ * none
@ *
@ *******************************************************************************
@*/
@/**
@ *******************************************************************************
@ *
@ * @brief
@ * this function performs inverse transform and reconstruction for 8x8
@ * input block
@ *
@ * @par description:
@ * performs inverse transform and adds the prediction data and clips output
@ * to 8 bit
@ *
@ * @param[in] pi2_src
@ * input 16x16 coefficients
@ *
@ * @param[in] pi2_tmp
@ * temporary 16x16 buffer for storing inverse
@ *
@ * transform
@ * 1st stage output
@ *
@ * @param[in] pu1_pred
@ * prediction 16x16 block
@ *
@ * @param[out] pu1_dst
@ * output 8x8 block
@ *
@ * @param[in] src_strd
@ * input stride
@ *
@ * @param[in] pred_strd
@ * prediction stride
@ *
@ * @param[in] dst_strd
@ * output stride
@ *
@ * @param[in] shift
@ * output shift
@ *
@ * @param[in] r12
@ * zero columns in pi2_src
@ *
@ * @returns void
@ *
@ * @remarks
@ * none
@ *
@ *******************************************************************************
@ */
@void ihevc_itrans_recon_16x16(word16 *pi2_src,
@ word16 *pi2_tmp,
@ uword8 *pu1_pred,
@ uword8 *pu1_dst,
@ word32 src_strd,
@ word32 pred_strd,
@ word32 dst_strd,
@ word32 r12
@ word32 r11 )
@**************variables vs registers*************************
@ r0 => *pi2_src
@ r1 => *pi2_tmp
@ r2 => *pu1_pred
@ r3 => *pu1_dst
@ src_strd
@ pred_strd
@ dst_strd
@ r12
@ r11
.equ src_stride_offset, 104
.equ pred_stride_offset, 108
.equ out_stride_offset, 112
.equ zero_cols_offset, 116
.equ zero_rows_offset, 120
.text
.align 4
.set shift_stage1_idct , 7
.set shift_stage2_idct , 12
@#define zero_cols r12
@#define zero_rows r11
.globl ihevc_itrans_recon_16x16_a9q
.extern g_ai2_ihevc_trans_16_transpose
g_ai2_ihevc_trans_16_transpose_addr:
.long g_ai2_ihevc_trans_16_transpose - ulbl1 - 8
.type ihevc_itrans_recon_16x16_a9q, %function
ihevc_itrans_recon_16x16_a9q:
stmfd sp!,{r4-r12,lr}
vpush {d8 - d15}
ldr r6,[sp,#src_stride_offset] @ src stride
ldr r12,[sp,#zero_cols_offset]
ldr r11,[sp,#zero_rows_offset]
ldr r14,g_ai2_ihevc_trans_16_transpose_addr
ulbl1:
add r14,r14,pc
vld1.16 {d0,d1,d2,d3},[r14] @//d0,d1 are used for storing the constant data
movw r7,#0xffff
and r12,r12,r7
and r11,r11,r7
mov r6,r6,lsl #1 @ x sizeof(word16)
add r9,r0,r6, lsl #1 @ 2 rows
add r10,r6,r6, lsl #1 @ 3 rows
add r5,r6,r6,lsl #2
movw r7,#0xfff0
cmp r12,r7
bge zero_12cols_decision
cmp r12,#0xff00
bge zero_8cols_decision
mov r14,#4
cmp r11,r7
rsbge r10,r6,#0
cmp r11,#0xff00
movge r8,r5
rsbge r8,r8,#0
movlt r8,r10
add r5,r5,r6,lsl #3
rsb r5,r5,#0
b first_stage_top_four_bottom_four
zero_12cols_decision:
mov r14,#1
cmp r11,#0xff00
movge r8,r5
movlt r8,r10
add r5,r5,r6,lsl #3
rsb r5,r5,#0
b first_stage_top_four_bottom_four
zero_8cols_decision:
mov r14,#2
mov r8,r5
rsb r8,r8,#0
cmp r11,#0xff00
movlt r8,r10
add r5,r5,r6,lsl #3
rsb r5,r5,#0
cmp r11,r7
rsbge r10,r6,#0
b first_stage_top_four_bottom_four
@d0[0]= 64 d2[0]=64
@d0[1]= 90 d2[1]=57
@d0[2]= 89 d2[2]=50
@d0[3]= 87 d2[3]=43
@d1[0]= 83 d3[0]=36
@d1[1]= 80 d3[1]=25
@d1[2]= 75 d3[2]=18
@d1[3]= 70 d3[3]=9
first_stage:
add r0,r0,#8
add r9,r9,#8
first_stage_top_four_bottom_four:
vld1.16 d10,[r0],r6
vld1.16 d11,[r9],r6
vld1.16 d6,[r0],r10
vld1.16 d7,[r9],r10
cmp r11,r7
bge skip_load4rows
vld1.16 d4,[r0],r6
vld1.16 d5,[r9],r6
vld1.16 d8,[r0],r8
vld1.16 d9,[r9],r8
@ registers used: q0,q1,q3,q5,q2,q4
@ d10 =r0
@d6= r1
@d11=r2
@d7=r3
skip_load4rows:
vmull.s16 q12,d6,d0[1] @// y1 * cos1(part of b0)
vmull.s16 q13,d6,d0[3] @// y1 * cos3(part of b1)
vmull.s16 q14,d6,d1[1] @// y1 * sin3(part of b2)
vmull.s16 q15,d6,d1[3] @// y1 * sin1(part of b3)
vmlal.s16 q12,d7,d0[3] @// y1 * cos1 + y3 * cos3(part of b0)
vmlal.s16 q13,d7,d2[1] @// y1 * cos3 - y3 * sin1(part of b1)
vmlal.s16 q14,d7,d3[3] @// y1 * sin3 - y3 * cos1(part of b2)
vmlsl.s16 q15,d7,d2[3] @// y1 * sin1 - y3 * sin3(part of b3)
vmull.s16 q6,d10,d0[0]
vmlal.s16 q6,d11,d0[2]
vmull.s16 q7,d10,d0[0]
vmlal.s16 q7,d11,d1[2]
vmull.s16 q8,d10,d0[0]
vmlal.s16 q8,d11,d2[2]
vmull.s16 q9,d10,d0[0]
vmlal.s16 q9,d11,d3[2]
bge skip_last12rows_kernel1
vmlal.s16 q12,d8,d1[1]
vmlal.s16 q13,d8,d3[3]
vmlsl.s16 q14,d8,d1[3]
vmlsl.s16 q15,d8,d0[3]
vmlal.s16 q12,d9,d1[3]
vmlsl.s16 q13,d9,d2[3]
vmlsl.s16 q14,d9,d0[3]
vmlal.s16 q15,d9,d3[3]
vmlal.s16 q6,d4,d1[0]
vmlal.s16 q6,d5,d1[2]
vmlal.s16 q7,d4,d3[0]
vmlsl.s16 q7,d5,d3[2]
vmlsl.s16 q8,d4,d3[0]
vmlsl.s16 q8,d5,d0[2]
vmlsl.s16 q9,d4,d1[0]
vmlsl.s16 q9,d5,d2[2]
@d0[0]= 64 d2[0]=64
@d0[1]= 90 d2[1]=57
@d0[2]= 89 d2[2]=50
@d0[3]= 87 d2[3]=43
@d1[0]= 83 d3[0]=36
@d1[1]= 80 d3[1]=25
@d1[2]= 75 d3[2]=18
@d1[3]= 70 d3[3]=9
cmp r11,#0xff00
bge skip_last12rows_kernel1
vld1.16 d10,[r0],r6
vld1.16 d11,[r9],r6
vld1.16 d6,[r0],r10
vld1.16 d7,[r9],r10
vld1.16 d4,[r0],r6
vld1.16 d5,[r9],r6
vld1.16 d8,[r0],r5
vld1.16 d9,[r9],r5
vmlal.s16 q12,d6,d2[1] @// y1 * cos1(part of b0)
vmlsl.s16 q13,d6,d1[1] @// y1 * cos3(part of b1)
vmlsl.s16 q14,d6,d3[1] @// y1 * sin3(part of b2)
vmlal.s16 q15,d6,d0[1] @// y1 * sin1(part of b3)
vmlal.s16 q12,d7,d2[3] @// y1 * cos1 + y3 * cos3(part of b0)
vmlsl.s16 q13,d7,d0[1] @// y1 * cos3 - y3 * sin1(part of b1)
vmlal.s16 q14,d7,d2[1] @// y1 * sin3 - y3 * cos1(part of b2)
vmlal.s16 q15,d7,d3[1] @// y1 * sin1 - y3 * sin3(part of b3)
vmlal.s16 q12,d8,d3[1]
vmlsl.s16 q13,d8,d1[3]
vmlal.s16 q14,d8,d0[1]
vmlsl.s16 q15,d8,d1[1]
vmlal.s16 q12,d9,d3[3]
vmlsl.s16 q13,d9,d3[1]
vmlal.s16 q14,d9,d2[3]
vmlsl.s16 q15,d9,d2[1]
vmlal.s16 q6,d10,d0[0]
vmlal.s16 q6,d11,d2[2]
vmlal.s16 q6,d4,d3[0]
vmlal.s16 q6,d5,d3[2]
vmlsl.s16 q7,d10,d0[0]
vmlsl.s16 q7,d11,d0[2]
vmlsl.s16 q7,d4,d1[0]
vmlsl.s16 q7,d5,d2[2]
vmlsl.s16 q8,d10,d0[0]
vmlal.s16 q8,d11,d3[2]
vmlal.s16 q8,d4,d1[0]
vmlal.s16 q8,d5,d1[2]
vmlal.s16 q9,d10,d0[0]
vmlal.s16 q9,d11,d1[2]
vmlsl.s16 q9,d4,d3[0]
vmlsl.s16 q9,d5,d0[2]
skip_last12rows_kernel1:
vadd.s32 q10,q6,q12
vsub.s32 q11,q6,q12
vadd.s32 q6,q7,q13
vsub.s32 q12,q7,q13
vadd.s32 q7,q8,q14
vsub.s32 q13,q8,q14
vadd.s32 q8,q9,q15
vsub.s32 q14,q9,q15
vqrshrn.s32 d30,q10,#shift_stage1_idct @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d19,q11,#shift_stage1_idct @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d31,q7,#shift_stage1_idct @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d18,q13,#shift_stage1_idct @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d12,q6,#shift_stage1_idct @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d15,q12,#shift_stage1_idct @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d13,q8,#shift_stage1_idct @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d14,q14,#shift_stage1_idct @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct)
vst1.16 {d30,d31},[r1]!
vst1.16 {d18,d19},[r1]!
sub r1,r1,#32
bge skip_stage1_kernel_load
first_stage_middle_eight:
vld1.16 d10,[r0],r6
vld1.16 d11,[r9],r6
vld1.16 d6,[r0],r10
vld1.16 d7,[r9],r10
vld1.16 d4,[r0],r6
vld1.16 d5,[r9],r6
vld1.16 d8,[r0],r8
vld1.16 d9,[r9],r8
skip_stage1_kernel_load:
vmull.s16 q12,d6,d2[1] @// y1 * cos1(part of b0)
vmull.s16 q13,d6,d2[3] @// y1 * cos3(part of b1)
vmull.s16 q14,d6,d3[1] @// y1 * sin3(part of b2)
vmull.s16 q15,d6,d3[3] @// y1 * sin1(part of b3)
vmlsl.s16 q12,d7,d1[1] @// y1 * cos1 + y3 * cos3(part of b0)
vmlsl.s16 q13,d7,d0[1] @// y1 * cos3 - y3 * sin1(part of b1)
vmlsl.s16 q14,d7,d1[3] @// y1 * sin3 - y3 * cos1(part of b2)
vmlsl.s16 q15,d7,d3[1] @// y1 * sin1 - y3 * sin3(part of b3)
vmull.s16 q11,d10,d0[0]
vmlsl.s16 q11,d11,d3[2]
vmull.s16 q10,d10,d0[0]
vmlsl.s16 q10,d11,d2[2]
vmull.s16 q8,d10,d0[0]
vmlsl.s16 q8,d11,d1[2]
vmull.s16 q9,d10,d0[0]
vmlsl.s16 q9,d11,d0[2]
cmp r11,r7
bge skip_last12rows_kernel2
vmlsl.s16 q12,d8,d3[1]
vmlal.s16 q13,d8,d2[1]
vmlal.s16 q14,d8,d0[1]
vmlal.s16 q15,d8,d2[3]
vmlal.s16 q12,d9,d0[1]
vmlal.s16 q13,d9,d3[1]
vmlsl.s16 q14,d9,d1[1]
vmlsl.s16 q15,d9,d2[1]
vmlsl.s16 q11,d4,d1[0]
vmlal.s16 q11,d5,d2[2]
vmlsl.s16 q10,d4,d3[0]
vmlal.s16 q10,d5,d0[2]
vmlal.s16 q8,d4,d3[0]
vmlal.s16 q8,d5,d3[2]
vmlal.s16 q9,d4,d1[0]
vmlsl.s16 q9,d5,d1[2]
@d0[0]= 64 d2[0]=64
@d0[1]= 90 d2[1]=57
@d0[2]= 89 d2[2]=50
@d0[3]= 87 d2[3]=43
@d1[0]= 83 d3[0]=36
@d1[1]= 80 d3[1]=25
@d1[2]= 75 d3[2]=18
@d1[3]= 70 d3[3]=9
cmp r11,#0xff00
bge skip_last12rows_kernel2
vld1.16 d10,[r0],r6
vld1.16 d11,[r9],r6
vld1.16 d6,[r0],r10
vld1.16 d7,[r9],r10
vld1.16 d4,[r0],r6
vld1.16 d5,[r9],r6
vld1.16 d8,[r0],r5
vld1.16 d9,[r9],r5
vmlsl.s16 q12,d6,d3[3] @// y1 * cos1(part of b0)
vmlsl.s16 q13,d6,d0[3] @// y1 * cos3(part of b1)
vmlal.s16 q14,d6,d2[3] @// y1 * sin3(part of b2)
vmlal.s16 q15,d6,d1[3] @// y1 * sin1(part of b3)
vmlsl.s16 q12,d7,d0[3] @// y1 * cos1 + y3 * cos3(part of b0)
vmlal.s16 q13,d7,d1[3] @// y1 * cos3 - y3 * sin1(part of b1)
vmlal.s16 q14,d7,d3[3] @// y1 * sin3 - y3 * cos1(part of b2)
vmlsl.s16 q15,d7,d1[1] @// y1 * sin1 - y3 * sin3(part of b3)
vmlal.s16 q12,d8,d2[3]
vmlal.s16 q13,d8,d3[3]
vmlsl.s16 q14,d8,d2[1]
vmlal.s16 q15,d8,d0[3]
vmlal.s16 q12,d9,d1[3]
vmlsl.s16 q13,d9,d1[1]
vmlal.s16 q14,d9,d0[3]
vmlsl.s16 q15,d9,d0[1]
vmlal.s16 q11,d10,d0[0]
vmlsl.s16 q11,d11,d1[2]
vmlsl.s16 q11,d4,d3[0]
vmlal.s16 q11,d5,d0[2]
vmlsl.s16 q10,d10,d0[0]
vmlsl.s16 q10,d11,d3[2]
vmlal.s16 q10,d4,d1[0]
vmlsl.s16 q10,d5,d1[2]
vmlsl.s16 q8,d10,d0[0]
vmlal.s16 q8,d11,d0[2]
vmlsl.s16 q8,d4,d1[0]
vmlal.s16 q8,d5,d2[2]
vmlal.s16 q9,d10,d0[0]
vmlsl.s16 q9,d11,d2[2]
vmlal.s16 q9,d4,d3[0]
vmlsl.s16 q9,d5,d3[2]
skip_last12rows_kernel2:
vadd.s32 q2,q11,q12
vsub.s32 q11,q11,q12
vadd.s32 q3,q10,q13
vsub.s32 q12,q10,q13
vadd.s32 q5,q8,q14
vsub.s32 q13,q8,q14
vadd.s32 q8,q9,q15
vsub.s32 q14,q9,q15
vqrshrn.s32 d18,q2,#shift_stage1_idct @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d31,q11,#shift_stage1_idct @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d19,q5,#shift_stage1_idct @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d30,q13,#shift_stage1_idct @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d20,q3,#shift_stage1_idct @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d23,q12,#shift_stage1_idct @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d21,q8,#shift_stage1_idct @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d22,q14,#shift_stage1_idct @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct)
@ registers used: {q2,q4,q6,q7}, {q9,q15,q10,q11}
vld1.16 {d4,d5},[r1]!
vld1.16 {d8,d9},[r1]!
sub r1,r1,#32
@d4=r0
@d12=r1
@d5=r2
@d13=r3
@d18=r4
@d20=r5
@d19=r6
@d21=r7
@d22=r8
@d30=r9
@d23=r10
@d31=r11
@d14=r12
@d8=r13
@d15=r14
@d9=r15
vtrn.16 q2,q6
vtrn.16 q9,q10
vtrn.16 q11,q15
vtrn.16 q7,q4
vtrn.32 d4,d5
vtrn.32 d12,d13
vtrn.32 d18,d19
vtrn.32 d20,d21
vtrn.32 d22,d23
vtrn.32 d30,d31
vtrn.32 d14,d15
vtrn.32 d8,d9
@ d4 =r0 1- 4 values
@ d5 =r2 1- 4 values
@ d12=r1 1- 4 values
@ d13=r3 1- 4 values
@ d18 =r0 5- 8 values
@ d19 =r2 5- 8 values
@ d20=r1 5- 8 values
@ d21=r3 5- 8 values
@ d22 =r0 9- 12 values
@ d23 =r2 9- 12 values
@ d30=r1 9- 12 values
@ d31=r3 9- 12 values
@ d14 =r0 13-16 values
@ d15 =r2 13- 16 values
@ d8=r1 13- 16 values
@ d9=r3 13- 16 values
vst1.16 {q2},[r1]!
vst1.16 {q6},[r1]!
vst1.16 {q9},[r1]!
vst1.16 {q10},[r1]!
vst1.16 {q11},[r1]!
vst1.16 {q15},[r1]!
vst1.16 {q7},[r1]!
vst1.16 {q4},[r1]!
subs r14,r14,#1
bne first_stage
mov r6,r7
ldr r8,[sp,#pred_stride_offset] @ prediction stride
ldr r7,[sp,#out_stride_offset] @ destination stride
mov r10,#16
cmp r12,r6
subge r1,r1,#128
bge label1
cmp r12,#0xff00
subge r1,r1,#256
bge label_2
sub r1,r1,#512
rsb r10,r10,#0
label_2:
add r9,r1,#128
add r11,r9,#128
add r0,r11,#128
label1:
@ mov r6,r1
mov r14,#4
add r4,r2,r8, lsl #1 @ r4 = r2 + pred_strd * 2 => r4 points to 3rd row of pred data
add r5,r8,r8, lsl #1 @
@ add r0,r3,r7, lsl #1 @ r0 points to 3rd row of dest data
@ add r10,r7,r7, lsl #1 @
second_stage:
vld1.16 {d10,d11},[r1]!
vld1.16 {d6,d7},[r1],r10
cmp r12,r6
bge second_stage_process
vld1.16 {d4,d5},[r9]!
vld1.16 {d8,d9},[r9],r10
second_stage_process:
vmull.s16 q12,d6,d0[1] @// y1 * cos1(part of b0)
vmull.s16 q13,d6,d0[3] @// y1 * cos3(part of b1)
vmull.s16 q14,d6,d1[1] @// y1 * sin3(part of b2)
vmull.s16 q15,d6,d1[3] @// y1 * sin1(part of b3)
vmlal.s16 q12,d7,d0[3] @// y1 * cos1 + y3 * cos3(part of b0)
vmlal.s16 q13,d7,d2[1] @// y1 * cos3 - y3 * sin1(part of b1)
vmlal.s16 q14,d7,d3[3] @// y1 * sin3 - y3 * cos1(part of b2)
vmlsl.s16 q15,d7,d2[3] @// y1 * sin1 - y3 * sin3(part of b3)
vmull.s16 q6,d10,d0[0]
vmlal.s16 q6,d11,d0[2]
vmull.s16 q7,d10,d0[0]
vmlal.s16 q7,d11,d1[2]
vmull.s16 q8,d10,d0[0]
vmlal.s16 q8,d11,d2[2]
vmull.s16 q9,d10,d0[0]
vmlal.s16 q9,d11,d3[2]
bge skip_last8rows_stage2_kernel1
vmlal.s16 q12,d8,d1[1]
vmlal.s16 q13,d8,d3[3]
vmlsl.s16 q14,d8,d1[3]
vmlsl.s16 q15,d8,d0[3]
vmlal.s16 q12,d9,d1[3]
vmlsl.s16 q13,d9,d2[3]
vmlsl.s16 q14,d9,d0[3]
vmlal.s16 q15,d9,d3[3]
vmlal.s16 q6,d4,d1[0]
vmlal.s16 q6,d5,d1[2]
vmlal.s16 q7,d4,d3[0]
vmlsl.s16 q7,d5,d3[2]
vmlsl.s16 q8,d4,d3[0]
vmlsl.s16 q8,d5,d0[2]
vmlsl.s16 q9,d4,d1[0]
vmlsl.s16 q9,d5,d2[2]
cmp r12,#0xff00
bge skip_last8rows_stage2_kernel1
vld1.16 {d10,d11},[r11]!
vld1.16 {d6,d7},[r11],r10
vld1.16 {d4,d5},[r0]!
vld1.16 {d8,d9},[r0],r10
vmlal.s16 q12,d6,d2[1] @// y1 * cos1(part of b0)
vmlsl.s16 q13,d6,d1[1] @// y1 * cos3(part of b1)
vmlsl.s16 q14,d6,d3[1] @// y1 * sin3(part of b2)
vmlal.s16 q15,d6,d0[1] @// y1 * sin1(part of b3)
vmlal.s16 q12,d7,d2[3] @// y1 * cos1 + y3 * cos3(part of b0)
vmlsl.s16 q13,d7,d0[1] @// y1 * cos3 - y3 * sin1(part of b1)
vmlal.s16 q14,d7,d2[1] @// y1 * sin3 - y3 * cos1(part of b2)
vmlal.s16 q15,d7,d3[1] @// y1 * sin1 - y3 * sin3(part of b3)
vmlal.s16 q12,d8,d3[1]
vmlsl.s16 q13,d8,d1[3]
vmlal.s16 q14,d8,d0[1]
vmlsl.s16 q15,d8,d1[1]
vmlal.s16 q12,d9,d3[3]
vmlsl.s16 q13,d9,d3[1]
vmlal.s16 q14,d9,d2[3]
vmlsl.s16 q15,d9,d2[1]
vmlal.s16 q6,d10,d0[0]
vmlal.s16 q6,d11,d2[2]
vmlal.s16 q6,d4,d3[0]
vmlal.s16 q6,d5,d3[2]
vmlsl.s16 q7,d10,d0[0]
vmlsl.s16 q7,d11,d0[2]
vmlsl.s16 q7,d4,d1[0]
vmlsl.s16 q7,d5,d2[2]
vmlsl.s16 q8,d10,d0[0]
vmlal.s16 q8,d11,d3[2]
vmlal.s16 q8,d4,d1[0]
vmlal.s16 q8,d5,d1[2]
vmlal.s16 q9,d10,d0[0]
vmlal.s16 q9,d11,d1[2]
vmlsl.s16 q9,d4,d3[0]
vmlsl.s16 q9,d5,d0[2]
skip_last8rows_stage2_kernel1:
vadd.s32 q10,q6,q12
vsub.s32 q11,q6,q12
vadd.s32 q6,q7,q13
vsub.s32 q12,q7,q13
vadd.s32 q7,q8,q14
vsub.s32 q13,q8,q14
vadd.s32 q8,q9,q15
vsub.s32 q14,q9,q15
vqrshrn.s32 d30,q10,#shift_stage2_idct @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d19,q11,#shift_stage2_idct @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d31,q7,#shift_stage2_idct @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d18,q13,#shift_stage2_idct @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d12,q6,#shift_stage2_idct @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d15,q12,#shift_stage2_idct @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d13,q8,#shift_stage2_idct @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d14,q14,#shift_stage2_idct @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct)
bge skip_stage2_kernel_load
@q2,q4,q6,q7 is used
vld1.16 {d10,d11},[r1]!
vld1.16 {d6,d7},[r1]!
vld1.16 {d4,d5},[r9]!
vld1.16 {d8,d9},[r9]!
skip_stage2_kernel_load:
sub r1,r1,#32
vst1.16 {d30,d31},[r1]!
vst1.16 {d18,d19},[r1]!
sub r1,r1,#32
vmull.s16 q12,d6,d2[1] @// y1 * cos1(part of b0)
vmull.s16 q13,d6,d2[3] @// y1 * cos3(part of b1)
vmull.s16 q14,d6,d3[1] @// y1 * sin3(part of b2)
vmull.s16 q15,d6,d3[3] @// y1 * sin1(part of b3)
vmlsl.s16 q12,d7,d1[1] @// y1 * cos1 + y3 * cos3(part of b0)
vmlsl.s16 q13,d7,d0[1] @// y1 * cos3 - y3 * sin1(part of b1)
vmlsl.s16 q14,d7,d1[3] @// y1 * sin3 - y3 * cos1(part of b2)
vmlsl.s16 q15,d7,d3[1] @// y1 * sin1 - y3 * sin3(part of b3)
vmull.s16 q11,d10,d0[0]
vmlsl.s16 q11,d11,d3[2]
vmull.s16 q10,d10,d0[0]
vmlsl.s16 q10,d11,d2[2]
vmull.s16 q8,d10,d0[0]
vmlsl.s16 q8,d11,d1[2]
vmull.s16 q9,d10,d0[0]
vmlsl.s16 q9,d11,d0[2]
cmp r12,r6
bge skip_last8rows_stage2_kernel2
vmlsl.s16 q12,d8,d3[1]
vmlal.s16 q13,d8,d2[1]
vmlal.s16 q14,d8,d0[1]
vmlal.s16 q15,d8,d2[3]
vmlal.s16 q12,d9,d0[1]
vmlal.s16 q13,d9,d3[1]
vmlsl.s16 q14,d9,d1[1]
vmlsl.s16 q15,d9,d2[1]
vmlsl.s16 q11,d4,d1[0]
vmlal.s16 q11,d5,d2[2]
vmlsl.s16 q10,d4,d3[0]
vmlal.s16 q10,d5,d0[2]
vmlal.s16 q8,d4,d3[0]
vmlal.s16 q8,d5,d3[2]
vmlal.s16 q9,d4,d1[0]
vmlsl.s16 q9,d5,d1[2]
cmp r12,#0xff00
bge skip_last8rows_stage2_kernel2
vld1.16 {d10,d11},[r11]!
vld1.16 {d6,d7},[r11]!
vld1.16 {d4,d5},[r0]!
vld1.16 {d8,d9},[r0]!
vmlsl.s16 q12,d6,d3[3] @// y1 * cos1(part of b0)
vmlsl.s16 q13,d6,d0[3] @// y1 * cos3(part of b1)
vmlal.s16 q14,d6,d2[3] @// y1 * sin3(part of b2)
vmlal.s16 q15,d6,d1[3] @// y1 * sin1(part of b3)
vmlsl.s16 q12,d7,d0[3] @// y1 * cos1 + y3 * cos3(part of b0)
vmlal.s16 q13,d7,d1[3] @// y1 * cos3 - y3 * sin1(part of b1)
vmlal.s16 q14,d7,d3[3] @// y1 * sin3 - y3 * cos1(part of b2)
vmlsl.s16 q15,d7,d1[1] @// y1 * sin1 - y3 * sin3(part of b3)
vmlal.s16 q12,d8,d2[3]
vmlal.s16 q13,d8,d3[3]
vmlsl.s16 q14,d8,d2[1]
vmlal.s16 q15,d8,d0[3]
vmlal.s16 q12,d9,d1[3]
vmlsl.s16 q13,d9,d1[1]
vmlal.s16 q14,d9,d0[3]
vmlsl.s16 q15,d9,d0[1]
vmlal.s16 q11,d10,d0[0]
vmlsl.s16 q11,d11,d1[2]
vmlsl.s16 q11,d4,d3[0]
vmlal.s16 q11,d5,d0[2]
vmlsl.s16 q10,d10,d0[0]
vmlsl.s16 q10,d11,d3[2]
vmlal.s16 q10,d4,d1[0]
vmlsl.s16 q10,d5,d1[2]
vmlsl.s16 q8,d10,d0[0]
vmlal.s16 q8,d11,d0[2]
vmlsl.s16 q8,d4,d1[0]
vmlal.s16 q8,d5,d2[2]
vmlal.s16 q9,d10,d0[0]
vmlsl.s16 q9,d11,d2[2]
vmlal.s16 q9,d4,d3[0]
vmlsl.s16 q9,d5,d3[2]
skip_last8rows_stage2_kernel2:
vadd.s32 q2,q11,q12
vsub.s32 q11,q11,q12
vadd.s32 q3,q10,q13
vsub.s32 q12,q10,q13
vadd.s32 q5,q8,q14
vsub.s32 q13,q8,q14
vadd.s32 q8,q9,q15
vsub.s32 q14,q9,q15
vqrshrn.s32 d18,q2,#shift_stage2_idct @// r0 = (a0 + b0 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d31,q11,#shift_stage2_idct @// r7 = (a0 - b0 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d19,q5,#shift_stage2_idct @// r2 = (a2 + b2 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d30,q13,#shift_stage2_idct @// r5 = (a2 - b2 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d20,q3,#shift_stage2_idct @// r1 = (a1 + b1 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d23,q12,#shift_stage2_idct @// r6 = (a1 - b1 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d21,q8,#shift_stage2_idct @// r3 = (a3 + b3 + rnd) >> 7(shift_stage1_idct)
vqrshrn.s32 d22,q14,#shift_stage2_idct @// r4 = (a3 - b3 + rnd) >> 7(shift_stage1_idct)
vld1.16 {d4,d5},[r1]!
vld1.16 {d8,d9},[r1]!
@ registers used: {q2,q4,q6,q7}, {q9,q15,q10,q11}
@d4=r0
@d12=r1
@d5=r2
@d13=r3
@d18=r4
@d20=r5
@d19=r6
@d21=r7
@d22=r8
@d30=r9
@d23=r10
@d31=r11
@d14=r12
@d8=r13
@d15=r14
@d9=r15
vtrn.16 q2,q6
vtrn.16 q9,q10
vtrn.16 q11,q15
vtrn.16 q7,q4
vtrn.32 d4,d5
vtrn.32 d12,d13
vtrn.32 d18,d19
vtrn.32 d20,d21
vtrn.32 d22,d23
vtrn.32 d30,d31
vtrn.32 d14,d15
vtrn.32 d8,d9
@ d4 =r0 1- 4 values
@ d5 =r2 1- 4 values
@ d12=r1 1- 4 values
@ d13=r3 1- 4 values
@ d18 =r0 5- 8 values
@ d19 =r2 5- 8 values
@ d20=r1 5- 8 values
@ d21=r3 5- 8 values
@ d22 =r0 9- 12 values
@ d23 =r2 9- 12 values
@ d30=r1 9- 12 values
@ d31=r3 9- 12 values
@ d14 =r0 13-16 values
@ d15 =r2 13- 16 values
@ d8=r1 13- 16 values
@ d9=r3 13- 16 values
vswp d5,d18
vswp d23,d14
vswp d13,d20
vswp d31,d8
@ q2: r0 1-8 values
@ q11: r0 9-16 values
@ q9 : r2 1-8 values
@ q7 : r2 9-16 values
@ q6 : r1 1- 8 values
@ q10: r3 1-8 values
@ q15: r1 9-16 values
@ q4: r3 9-16 values
@ registers free: q8,q14,q12,q13
vld1.8 {d16,d17},[r2],r8
vld1.8 {d28,d29},[r2],r5
vld1.8 {d24,d25},[r4],r8
vld1.8 {d26,d27},[r4],r5
vaddw.u8 q2,q2,d16
vaddw.u8 q11,q11,d17
vaddw.u8 q6,q6,d28
vaddw.u8 q15,q15,d29
vaddw.u8 q9,q9,d24
vaddw.u8 q7,q7,d25
vaddw.u8 q10,q10,d26
vaddw.u8 q4,q4,d27
vqmovun.s16 d16,q2
vqmovun.s16 d17,q11
vqmovun.s16 d28,q6
vqmovun.s16 d29,q15
vqmovun.s16 d24,q9
vqmovun.s16 d25,q7
vqmovun.s16 d26,q10
vqmovun.s16 d27,q4
vst1.8 {d16,d17},[r3],r7
vst1.8 {d28,d29},[r3],r7
vst1.8 {d24,d25},[r3],r7
vst1.8 {d26,d27},[r3],r7
subs r14,r14,#1
bne second_stage
vpop {d8 - d15}
ldmfd sp!,{r4-r12,pc}