blob: 9f8f69e71d4e4757bbe4b0393943343b06d5ed23 [file] [log] [blame]
;//
;// Copyright (C) 2007-2008 ARM Limited
;//
;// 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 Name: omxVCM4P10_InterpolateLuma_s.s
;// OpenMAX DL: v1.0.2
;// Revision: 12290
;// Date: Wednesday, April 9, 2008
;//
;//
;//
;//
;// Function:
;// omxVCM4P10_InterpolateLuma
;//
;// This function implements omxVCM4P10_InterpolateLuma in v6 assembly.
;// Performs quarter pel interpolation of inter luma MB.
;// It's assumed that the frame is already padded when calling this function.
;// Parameters:
;// [in] pSrc Pointer to the source reference frame buffer
;// [in] srcStep Reference frame step in byte
;// [in] dstStep Destination frame step in byte. Must be multiple of roi.width
;// [in] dx Fractional part of horizontal motion vector
;// component in 1/4 pixel unit; valid in the range [0,3]
;// [in] dy Fractional part of vertical motion vector
;// component in 1/4 pixel unit; valid in the range [0,3]
;// [in] roi Dimension of the interpolation region;the parameters roi.width and roi.height must
;// be equal to either 4, 8, or 16.
;// [out] pDst Pointer to the destination frame buffer.
;// if roi.width==4, 4-byte alignment required
;// if roi.width==8, 8-byte alignment required
;// if roi.width==16, 16-byte alignment required
;//
;// Return Value:
;// If the function runs without error, it returns OMX_Sts_NoErr.
;// It is assued that following cases are satisfied before calling this function:
;// pSrc or pDst is not NULL.
;// srcStep or dstStep >= roi.width.
;// dx or dy is in the range [0-3].
;// roi.width or roi.height is not out of range {4, 8, 16}.
;// If roi.width is equal to 4, Dst is 4 byte aligned.
;// If roi.width is equal to 8, pDst is 8 byte aligned.
;// If roi.width is equal to 16, pDst is 16 byte aligned.
;// srcStep and dstStep is multiple of 8.
;//
;//
INCLUDE omxtypes_s.h
INCLUDE armCOMM_s.h
M_VARIANTS CortexA8
EXPORT omxVCM4P10_InterpolateLuma
IF CortexA8
IMPORT armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
IMPORT armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
IMPORT armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe
IMPORT armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
ENDIF
;// Declare input registers
pSrc RN 0
srcStep RN 1
pDst RN 2
dstStep RN 3
iHeight RN 4
iWidth RN 5
;// Declare other intermediate registers
idx RN 6
idy RN 7
index RN 6
Temp RN 12
pArgs RN 11
IF CortexA8
;//
;// Interpolation of luma is implemented by processing block of pixels, size 4x4 at a time.
;//
M_ALLOC4 ppArgs, 16
;// Function header
M_START omxVCM4P10_InterpolateLuma, r11, d15
pSrcBK RN 8
;// Declare Neon registers
dCoeff5 DN 30.S16
dCoeff20 DN 31.S16
;// Registers used for implementing Horizontal interpolation
dSrc0c DN 14.U8
dSrc1c DN 16.U8
dSrc2c DN 18.U8
dSrc3c DN 20.U8
dSrc0d DN 15.U8
dSrc1d DN 17.U8
dSrc2d DN 19.U8
dSrc3d DN 21.U8
dAccH0 DN 22.U8
dAccH1 DN 24.U8
dAccH2 DN 26.U8
dAccH3 DN 28.U8
dResultH0 DN 22.U32
dResultH1 DN 24.U32
dResultH2 DN 26.U32
dResultH3 DN 28.U32
;// Registers used for implementing Vertical interpolation
dSrc0 DN 9.U8
dSrc1 DN 10.U8
dSrc2 DN 11.U8
dSrc3 DN 12.U8
dSrc4 DN 13.U8
dAccV0 DN 0.U8
dAccV1 DN 2.U8
dAccV2 DN 4.U8
dAccV3 DN 6.U8
dResultV0 DN 0.U32
dResultV1 DN 2.U32
dResultV2 DN 4.U32
dResultV3 DN 6.U32
;// Registers used for implementing Diagonal interpolation
dTAcc0 DN 0.U8
dTAcc1 DN 2.U8
dTAcc2 DN 4.U8
dTAcc3 DN 6.U8
dTRes0 DN 0.32
dTRes1 DN 2.32
dTRes2 DN 4.32
dTRes3 DN 6.32
dTResult0 DN 14.U8
dTResult1 DN 16.U8
dTResult2 DN 18.U8
dTResult3 DN 20.U8
dTempP0 DN 18.S16
dTempP1 DN 19.S16
dTempQ0 DN 20.S16
dTempQ1 DN 21.S16
dTempR0 DN 22.S16
dTempR1 DN 23.S16
dTempS0 DN 24.S16
dTempS1 DN 25.S16
qTempP01 QN 9.S16
qTempQ01 QN 10.S16
qTempR01 QN 11.S16
qTempS01 QN 12.S16
;// Intermediate values for averaging
qRes2 QN 7.S16
qRes3 QN 8.S16
qRes4 QN 9.S16
qRes5 QN 10.S16
qRes6 QN 11.S16
;// For implementing copy
dDst0 DN 9.32
dDst1 DN 10.32
dDst2 DN 11.32
dDst3 DN 12.32
;// Define stack arguments
M_ARG ptridx, 4
M_ARG ptridy, 4
M_ARG ptrWidth, 4
M_ARG ptrHeight, 4
;// Load structure elements of roi
M_LDR idx, ptridx
M_LDR idy, ptridy
M_LDR iWidth, ptrWidth
M_LDR iHeight, ptrHeight
ADD index, idx, idy, LSL #2 ;// [index] = [idy][idx]
M_ADR pArgs, ppArgs
;// Move coefficients Neon registers
VMOV dCoeff20, #20
VMOV dCoeff5, #5
Block4x4WidthLoop
Block4x4HeightLoop
STM pArgs, {pSrc,srcStep,pDst,dstStep}
;// switch table using motion vector as index
ADD pc, pc, index, LSL #2
B Case_f
B Case_0
B Case_1
B Case_2
B Case_3
B Case_4
B Case_5
B Case_6
B Case_7
B Case_8
B Case_9
B Case_a
B Case_b
B Case_c
B Case_d
B Case_e
B Case_f
Case_0
;// Case G
M_PRINTF "Case 0 \n"
;// Loads a 4x4 block of .8 and stores as .32
ADD Temp, pSrc, srcStep, LSL #1
VLD1 dSrc0, [pSrc], srcStep
VLD1 dSrc2, [Temp], srcStep
VLD1 dSrc1, [pSrc]
VLD1 dSrc3, [Temp]
ADD Temp, pDst, dstStep, LSL #1
VST1 dDst0[0], [pDst], dstStep
VST1 dDst2[0], [Temp], dstStep
VST1 dDst1[0], [pDst]
VST1 dDst3[0], [Temp]
M_ADR pArgs, ppArgs
B Block4x4LoopEnd
Case_1
;// Case a
M_PRINTF "Case 1 \n"
SUB pSrc, pSrc, #2
BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
VRHADD dAccH0, dAccH0, dSrc0c
VRHADD dAccH2, dAccH2, dSrc2c
VRHADD dAccH1, dAccH1, dSrc1c
VRHADD dAccH3, dAccH3, dSrc3c
ADD Temp, pDst, dstStep, LSL #1
VST1 dResultH0[0], [pDst], dstStep
VST1 dResultH2[0], [Temp], dstStep
VST1 dResultH1[0], [pDst]
VST1 dResultH3[0], [Temp]
M_ADR pArgs, ppArgs
B Block4x4LoopEnd
Case_2
;// Case b
M_PRINTF "Case 2 \n"
SUB pSrc, pSrc, #2
BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
ADD Temp, pDst, dstStep, LSL #1
VST1 dResultH0[0], [pDst], dstStep
VST1 dResultH2[0], [Temp], dstStep
VST1 dResultH1[0], [pDst]
VST1 dResultH3[0], [Temp]
M_ADR pArgs, ppArgs
B Block4x4LoopEnd
Case_3
;// Case c
M_PRINTF "Case 3 \n"
SUB pSrc, pSrc, #2
BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
VRHADD dAccH0, dAccH0, dSrc0d
VRHADD dAccH2, dAccH2, dSrc2d
VRHADD dAccH1, dAccH1, dSrc1d
VRHADD dAccH3, dAccH3, dSrc3d
ADD Temp, pDst, dstStep, LSL #1
VST1 dResultH0[0], [pDst], dstStep
VST1 dResultH2[0], [Temp], dstStep
VST1 dResultH1[0], [pDst]
VST1 dResultH3[0], [Temp]
M_ADR pArgs, ppArgs
B Block4x4LoopEnd
Case_4
;// Case d
M_PRINTF "Case 4 \n"
SUB pSrc, pSrc, srcStep, LSL #1
BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
VRHADD dAccV0, dAccV0, dSrc0
VRHADD dAccV2, dAccV2, dSrc2
VRHADD dAccV1, dAccV1, dSrc1
VRHADD dAccV3, dAccV3, dSrc3
ADD Temp, pDst, dstStep, LSL #1
VST1 dResultV0[0], [pDst], dstStep
VST1 dResultV2[0], [Temp], dstStep
VST1 dResultV1[0], [pDst]
VST1 dResultV3[0], [Temp]
M_ADR pArgs, ppArgs
B Block4x4LoopEnd
Case_5
;// Case e
M_PRINTF "Case 5 \n"
MOV pSrcBK, pSrc
SUB pSrc, pSrc, srcStep, LSL #1
BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
SUB pSrc, pSrcBK, #2
BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
VRHADD dAccH0, dAccH0, dAccV0
VRHADD dAccH2, dAccH2, dAccV2
VRHADD dAccH1, dAccH1, dAccV1
VRHADD dAccH3, dAccH3, dAccV3
ADD Temp, pDst, dstStep, LSL #1
VST1 dResultH0[0], [pDst], dstStep
VST1 dResultH2[0], [Temp], dstStep
VST1 dResultH1[0], [pDst]
VST1 dResultH3[0], [Temp]
M_ADR pArgs, ppArgs
B Block4x4LoopEnd
Case_6
;// Case f
M_PRINTF "Case 6 \n"
SUB pSrc, pSrc, srcStep, LSL #1
SUB pSrc, pSrc, #2
BL armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
VQRSHRUN dTResult0, qRes2, #5
VQRSHRUN dTResult1, qRes3, #5
VQRSHRUN dTResult2, qRes4, #5
VQRSHRUN dTResult3, qRes5, #5
VRHADD dTAcc0, dTAcc0, dTResult0
VRHADD dTAcc2, dTAcc2, dTResult2
VRHADD dTAcc1, dTAcc1, dTResult1
VRHADD dTAcc3, dTAcc3, dTResult3
ADD Temp, pDst, dstStep, LSL #1
VST1 dTRes0[0], [pDst], dstStep
VST1 dTRes2[0], [Temp], dstStep
VST1 dTRes1[0], [pDst]
VST1 dTRes3[0], [Temp]
M_ADR pArgs, ppArgs
B Block4x4LoopEnd
Case_7
;// Case g
M_PRINTF "Case 7 \n"
MOV pSrcBK, pSrc
ADD pSrc, pSrc, #1
SUB pSrc, pSrc, srcStep, LSL #1
BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
SUB pSrc, pSrcBK, #2
BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
VRHADD dAccH0, dAccH0, dAccV0
VRHADD dAccH2, dAccH2, dAccV2
VRHADD dAccH1, dAccH1, dAccV1
VRHADD dAccH3, dAccH3, dAccV3
ADD Temp, pDst, dstStep, LSL #1
VST1 dResultH0[0], [pDst], dstStep
VST1 dResultH2[0], [Temp], dstStep
VST1 dResultH1[0], [pDst]
VST1 dResultH3[0], [Temp]
M_ADR pArgs, ppArgs
B Block4x4LoopEnd
Case_8
;// Case h
M_PRINTF "Case 8 \n"
SUB pSrc, pSrc, srcStep, LSL #1
BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
ADD Temp, pDst, dstStep, LSL #1
VST1 dResultV0[0], [pDst], dstStep
VST1 dResultV2[0], [Temp], dstStep
VST1 dResultV1[0], [pDst]
VST1 dResultV3[0], [Temp]
M_ADR pArgs, ppArgs
B Block4x4LoopEnd
Case_9
;// Case i
M_PRINTF "Case 9 \n"
SUB pSrc, pSrc, srcStep, LSL #1
SUB pSrc, pSrc, #2
BL armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe
VEXT dTempP0, dTempP0, dTempP1, #2
VEXT dTempQ0, dTempQ0, dTempQ1, #2
VEXT dTempR0, dTempR0, dTempR1, #2
VEXT dTempS0, dTempS0, dTempS1, #2
VQRSHRUN dTResult0, qTempP01, #5
VQRSHRUN dTResult1, qTempQ01, #5
VQRSHRUN dTResult2, qTempR01, #5
VQRSHRUN dTResult3, qTempS01, #5
VRHADD dTAcc0, dTAcc0, dTResult0
VRHADD dTAcc2, dTAcc2, dTResult2
VRHADD dTAcc1, dTAcc1, dTResult1
VRHADD dTAcc3, dTAcc3, dTResult3
ADD Temp, pDst, dstStep, LSL #1
VST1 dTRes0[0], [pDst], dstStep
VST1 dTRes2[0], [Temp], dstStep
VST1 dTRes1[0], [pDst]
VST1 dTRes3[0], [Temp]
M_ADR pArgs, ppArgs
B Block4x4LoopEnd
Case_a
;// Case j
M_PRINTF "Case a \n"
SUB pSrc, pSrc, srcStep, LSL #1
SUB pSrc, pSrc, #2
BL armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
ADD Temp, pDst, dstStep, LSL #1
VST1 dTRes0[0], [pDst], dstStep
VST1 dTRes2[0], [Temp], dstStep
VST1 dTRes1[0], [pDst]
VST1 dTRes3[0], [Temp]
M_ADR pArgs, ppArgs
B Block4x4LoopEnd
Case_b
;// Case k
M_PRINTF "Case b \n"
SUB pSrc, pSrc, srcStep, LSL #1
SUB pSrc, pSrc, #2
BL armVCM4P10_InterpolateLuma_HalfDiagVerHor4x4_unsafe
VEXT dTempP0, dTempP0, dTempP1, #3
VEXT dTempQ0, dTempQ0, dTempQ1, #3
VEXT dTempR0, dTempR0, dTempR1, #3
VEXT dTempS0, dTempS0, dTempS1, #3
VQRSHRUN dTResult0, qTempP01, #5
VQRSHRUN dTResult1, qTempQ01, #5
VQRSHRUN dTResult2, qTempR01, #5
VQRSHRUN dTResult3, qTempS01, #5
VRHADD dTAcc0, dTAcc0, dTResult0
VRHADD dTAcc2, dTAcc2, dTResult2
VRHADD dTAcc1, dTAcc1, dTResult1
VRHADD dTAcc3, dTAcc3, dTResult3
ADD Temp, pDst, dstStep, LSL #1
VST1 dTRes0[0], [pDst], dstStep
VST1 dTRes2[0], [Temp], dstStep
VST1 dTRes1[0], [pDst]
VST1 dTRes3[0], [Temp]
M_ADR pArgs, ppArgs
B Block4x4LoopEnd
Case_c
;// Case n
M_PRINTF "Case c \n"
SUB pSrc, pSrc, srcStep, LSL #1
BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
VRHADD dAccV0, dAccV0, dSrc1
VRHADD dAccV2, dAccV2, dSrc3
VRHADD dAccV1, dAccV1, dSrc2
VRHADD dAccV3, dAccV3, dSrc4
ADD Temp, pDst, dstStep, LSL #1
VST1 dResultV0[0], [pDst], dstStep
VST1 dResultV2[0], [Temp], dstStep
VST1 dResultV1[0], [pDst]
VST1 dResultV3[0], [Temp]
M_ADR pArgs, ppArgs
B Block4x4LoopEnd
Case_d
;// Case p
M_PRINTF "Case d \n"
MOV pSrcBK, pSrc
SUB pSrc, pSrc, srcStep, LSL #1
BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
ADD pSrc, pSrcBK, srcStep
SUB pSrc, pSrc, #2
BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
VRHADD dAccH0, dAccH0, dAccV0
VRHADD dAccH2, dAccH2, dAccV2
VRHADD dAccH1, dAccH1, dAccV1
VRHADD dAccH3, dAccH3, dAccV3
ADD Temp, pDst, dstStep, LSL #1
VST1 dResultH0[0], [pDst], dstStep
VST1 dResultH2[0], [Temp], dstStep
VST1 dResultH1[0], [pDst]
VST1 dResultH3[0], [Temp]
M_ADR pArgs, ppArgs
B Block4x4LoopEnd
Case_e
;// Case q
M_PRINTF "Case e \n"
SUB pSrc, pSrc, srcStep, LSL #1
SUB pSrc, pSrc, #2
BL armVCM4P10_InterpolateLuma_HalfDiagHorVer4x4_unsafe
VQRSHRUN dTResult0, qRes3, #5
VQRSHRUN dTResult1, qRes4, #5
VQRSHRUN dTResult2, qRes5, #5
VQRSHRUN dTResult3, qRes6, #5
VRHADD dTAcc0, dTAcc0, dTResult0
VRHADD dTAcc2, dTAcc2, dTResult2
VRHADD dTAcc1, dTAcc1, dTResult1
VRHADD dTAcc3, dTAcc3, dTResult3
ADD Temp, pDst, dstStep, LSL #1
VST1 dTRes0[0], [pDst], dstStep
VST1 dTRes2[0], [Temp], dstStep
VST1 dTRes1[0], [pDst]
VST1 dTRes3[0], [Temp]
M_ADR pArgs, ppArgs
B Block4x4LoopEnd
Case_f
;// Case r
M_PRINTF "Case f \n"
MOV pSrcBK, pSrc
ADD pSrc, pSrc, #1
SUB pSrc, pSrc, srcStep, LSL #1
BL armVCM4P10_InterpolateLuma_HalfVer4x4_unsafe
ADD pSrc, pSrcBK, srcStep
SUB pSrc, pSrc, #2
BL armVCM4P10_InterpolateLuma_HalfHor4x4_unsafe
VRHADD dAccH0, dAccH0, dAccV0
VRHADD dAccH2, dAccH2, dAccV2
VRHADD dAccH1, dAccH1, dAccV1
VRHADD dAccH3, dAccH3, dAccV3
ADD Temp, pDst, dstStep, LSL #1
VST1 dResultH0[0], [pDst], dstStep
VST1 dResultH2[0], [Temp], dstStep
VST1 dResultH1[0], [pDst]
VST1 dResultH3[0], [Temp]
M_ADR pArgs, ppArgs
Block4x4LoopEnd
;// Width Loop
;//M_ADR pArgs, ppArgs
LDM pArgs, {pSrc,srcStep,pDst,dstStep} ;// Load arguments
SUBS iWidth, iWidth, #4
ADD pSrc, pSrc, #4
ADD pDst, pDst, #4
BGT Block4x4WidthLoop
;// Height Loop
SUBS iHeight, iHeight, #4
M_LDR iWidth, ptrWidth
M_ADR pArgs, ppArgs
ADD pSrc, pSrc, srcStep, LSL #2
ADD pDst, pDst, dstStep, LSL #2
SUB pSrc, pSrc, iWidth
SUB pDst, pDst, iWidth
BGT Block4x4HeightLoop
EndOfInterpolation
MOV r0, #0
M_END
ENDIF
;// End of CortexA8
END