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_intra_pred_luma_horz_neon.s 22@* 23@* @brief 24@* contains function definition for intra prediction interpolation filters 25@* 26@* 27@* @author 28@* parthiban v 29@* 30@* @par list of functions: 31@* - ihevc_intra_pred_luma_horz() 32@* 33@* @remarks 34@* none 35@* 36@******************************************************************************* 37@*/ 38@ 39@/** 40@******************************************************************************* 41@* 42@* @brief 43@* intra prediction interpolation filter for horizontal luma variable. 44@* 45@* @par description: 46@* horizontal intraprediction(mode 10) with.extern samples location 47@* pointed by 'pu1_ref' to the tu block location pointed by 'pu1_dst' refer 48@* to section 8.4.4.2.6 in the standard (special case) 49@* 50@* @param[in] pu1_src 51@* uword8 pointer to the source 52@* 53@* @param[out] pu1_dst 54@* uword8 pointer to the destination 55@* 56@* @param[in] src_strd 57@* integer source stride 58@* 59@* @param[in] dst_strd 60@* integer destination stride 61@* 62@* @param[in] nt 63@* integer transform block size 64@* 65@* @param[in] mode 66@* integer intraprediction mode 67@* 68@* @returns 69@* 70@* @remarks 71@* none 72@* 73@******************************************************************************* 74@*/ 75@void ihevc_intra_pred_luma_horz(uword8 *pu1_ref, 76@ word32 src_strd, 77@ uword8 *pu1_dst, 78@ word32 dst_strd, 79@ word32 nt, 80@ word32 mode) 81@**************variables vs registers***************************************** 82@r0 => *pu1_ref 83@r1 => src_strd 84@r2 => *pu1_dst 85@r3 => dst_strd 86 87.equ nt_offset, 104 88 89.text 90.align 4 91 92 93 94 95.globl ihevc_intra_pred_luma_horz_a9q 96 97.type ihevc_intra_pred_luma_horz_a9q, %function 98 99ihevc_intra_pred_luma_horz_a9q: 100 101 stmfd sp!, {r4-r12, r14} @stack stores the values of the arguments 102 vpush {d8 - d15} 103 ldr r4,[sp,#nt_offset] @loads nt 104 105 lsl r6,r4,#1 @two_nt 106 107 add r12,r0,r6 @*pu1_ref[two_nt] 108 cmp r4,#4 @if nt == 4 109 beq core_loop_4 110 111 cmp r4,#8 @if nt == 8 112 beq core_loop_8 113 114 cmp r4,#16 @if nt == 16 115 beq core_loop_16 116 sub r12,r12,#16 @move to 16th value pointer 117 add r9,r2,#16 118 119core_loop_32: 120 vld1.8 {q0},[r12] @load 16 values. d1[7] will have the 1st value. 121 122 vdup.8 q1,d1[7] @duplicate the i value. 123 124 vdup.8 q2,d1[6] @duplicate the ii value. 125 vdup.8 q3,d1[5] @duplicate the iii value. 126 vst1.8 {q1},[r2],r3 @store in 1st row 0-16 columns 127 vst1.8 {q1},[r9],r3 @store in 1st row 16-32 columns 128 129 vdup.8 q4,d1[4] 130 vst1.8 {q2},[r2],r3 131 vst1.8 {q2},[r9],r3 132 133 vdup.8 q1,d1[3] 134 vst1.8 {q3},[r2],r3 135 vst1.8 {q3},[r9],r3 136 137 vdup.8 q2,d1[2] 138 vst1.8 {q4},[r2],r3 139 vst1.8 {q4},[r9],r3 140 141 vdup.8 q3,d1[1] 142 vst1.8 {q1},[r2],r3 143 vst1.8 {q1},[r9],r3 144 145 vdup.8 q4,d1[0] 146 vst1.8 {q2},[r2],r3 147 vst1.8 {q2},[r9],r3 148 149 vdup.8 q1,d0[7] 150 vst1.8 {q3},[r2],r3 151 vst1.8 {q3},[r9],r3 152 153 vdup.8 q2,d0[6] 154 vst1.8 {q4},[r2],r3 155 vst1.8 {q4},[r9],r3 156 157 vdup.8 q3,d0[5] 158 vst1.8 {q1},[r2],r3 159 vst1.8 {q1},[r9],r3 160 161 vdup.8 q4,d0[4] 162 vst1.8 {q2},[r2],r3 163 vst1.8 {q2},[r9],r3 164 165 vdup.8 q1,d0[3] 166 vst1.8 {q3},[r2],r3 167 vst1.8 {q3},[r9],r3 168 169 vdup.8 q2,d0[2] 170 vst1.8 {q4},[r2],r3 171 vst1.8 {q4},[r9],r3 172 173 vdup.8 q3,d0[1] 174 vst1.8 {q1},[r2],r3 175 vst1.8 {q1},[r9],r3 176 sub r12,r12,#16 @move to 16th value pointer 177 178 vdup.8 q4,d0[0] 179 vst1.8 {q2},[r2],r3 180 vst1.8 {q2},[r9],r3 181 182 subs r4,r4,#16 @decrement the loop count by 16 183 vst1.8 {q3},[r2],r3 184 vst1.8 {q3},[r9],r3 185 186 vst1.8 {q4},[r2],r3 187 vst1.8 {q4},[r9],r3 188 bgt core_loop_32 189 vpop {d8 - d15} 190 ldmfd sp!,{r4-r12,r15} @reload the registers from sp 191 b end_func 192 193core_loop_16: 194 ldrb lr,[r12],#1 @pu1_ref[two_nt] 195 vld1.8 {q15},[r12] @pu1_ref[two_nt + 1 + col] 196 197 vdup.8 d28,lr 198 sub r12,r12,#17 199 vld1.8 {q0},[r12] 200 vdup.8 d26,d1[7] 201 vmovl.u8 q13,d26 202 203 vdup.8 q1,d1[6] 204 vsubl.u8 q12,d30,d28 205 206 vdup.8 q2,d1[5] 207 vshr.s16 q12,q12,#1 208 209 vdup.8 q3,d1[4] 210 vqadd.s16 q11,q13,q12 211 212 vdup.8 q4,d1[3] 213 vqmovun.s16 d22,q11 214 215 vst1.8 {d22},[r2]! 216 217 vdup.8 q5,d1[2] 218 vsubl.u8 q12,d31,d28 219 220 vdup.8 q6,d1[1] 221 vshr.s16 q12,q12,#1 222 223 vdup.8 q7,d1[0] 224 vqadd.s16 q11,q13,q12 225 226 vdup.8 q8,d0[7] 227 vqmovun.s16 d22,q11 228 229 vst1.8 {d22},[r2],r3 230 sub r2,r2,#8 231 232 vst1.8 {q1},[r2],r3 233 234 vst1.8 {q2},[r2],r3 235 vst1.8 {q3},[r2],r3 236 vst1.8 {q4},[r2],r3 237 238 vdup.8 q1,d0[6] 239 vst1.8 {q5},[r2],r3 240 241 vdup.8 q2,d0[5] 242 vst1.8 {q6},[r2],r3 243 244 vdup.8 q3,d0[4] 245 vst1.8 {q7},[r2],r3 246 247 vdup.8 q4,d0[3] 248 vst1.8 {q8},[r2],r3 249 250 vdup.8 q5,d0[2] 251 vst1.8 {q1},[r2],r3 252 253 vdup.8 q6,d0[1] 254 vst1.8 {q2},[r2],r3 255 256 vdup.8 q7,d0[0] 257 vst1.8 {q3},[r2],r3 258 259 vst1.8 {q4},[r2],r3 260 vst1.8 {q5},[r2],r3 261 vst1.8 {q6},[r2],r3 262 vst1.8 {q7},[r2],r3 263 vpop {d8 - d15} 264 ldmfd sp!,{r4-r12,r15} @reload the registers from sp 265 b end_func 266 267 268core_loop_8: 269 ldrb lr,[r12] @pu1_ref[two_nt] 270 add r12,r12,#1 @pu1_ref[two_nt + 1] 271 vld1.8 {d30},[r12] @pu1_ref[two_nt + 1 + col] 272 273 sub r12,r12,#9 274 vld1.8 {d0},[r12] 275 vdup.8 d26,d0[7] 276 vdup.8 d28,lr 277 278 vdup.8 d3,d0[6] 279 vmovl.u8 q13,d26 280 281 vdup.8 d4,d0[5] 282 vsubl.u8 q12,d30,d28 283 284 vdup.8 d5,d0[4] 285 vshr.s16 q12,q12,#1 286 287 vdup.8 d6,d0[3] 288 vqadd.s16 q11,q13,q12 289 290 vdup.8 d7,d0[2] 291 vqmovun.s16 d22,q11 292 293 vst1.8 {d22},[r2],r3 294 vst1.8 {d3},[r2],r3 295 296 vdup.8 d8,d0[1] 297 vst1.8 {d4},[r2],r3 298 vst1.8 {d5},[r2],r3 299 300 vdup.8 d9,d0[0] 301 vst1.8 {d6},[r2],r3 302 vst1.8 {d7},[r2],r3 303 304 vst1.8 {d8},[r2],r3 305 vst1.8 {d9},[r2],r3 306 vpop {d8 - d15} 307 ldmfd sp!,{r4-r12,r15} @reload the registers from sp 308 b end_func 309 310 311core_loop_4: 312 ldrb lr,[r12] @pu1_ref[two_nt] 313 add r12,r12,#1 @pu1_ref[two_nt + 1] 314 vld1.8 {d30},[r12] @pu1_ref[two_nt + 1 + col] 315 316 sub r12,r12,#5 317 vld1.8 {d0},[r12] 318 vdup.8 d28,lr 319 vdup.8 d26,d0[3] 320 vmovl.u8 q13,d26 321 322 vdup.8 d3,d0[2] 323 vsubl.u8 q12,d30,d28 324 325 vdup.8 d4,d0[1] 326 vshr.s16 q12,q12,#1 327 328 vdup.8 d5,d0[0] 329 vqadd.s16 q11,q13,q12 330 331 vqmovun.s16 d22,q11 332 333 vst1.32 {d22[0]},[r2],r3 334 vst1.32 {d3[0]},[r2],r3 335 vst1.32 {d4[0]},[r2],r3 336 vst1.32 {d5[0]},[r2],r3 337 vpop {d8 - d15} 338 ldmfd sp!,{r4-r12,r15} @reload the registers from sp 339end_func: 340 341 342 343