1 ; 2 ; Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3 ; 4 ; Use of this source code is governed by a BSD-style license 5 ; that can be found in the LICENSE file in the root of the source 6 ; tree. An additional intellectual property rights grant can be found 7 ; in the file PATENTS. All contributing project authors may 8 ; be found in the AUTHORS file in the root of the source tree. 9 ; 10 11 12 EXPORT |vp8_bilinear_predict16x16_neon| 13 ARM 14 REQUIRE8 15 PRESERVE8 16 17 AREA ||.text||, CODE, READONLY, ALIGN=2 18 ; r0 unsigned char *src_ptr, 19 ; r1 int src_pixels_per_line, 20 ; r2 int xoffset, 21 ; r3 int yoffset, 22 ; r4 unsigned char *dst_ptr, 23 ; stack(r5) int dst_pitch 24 25 |vp8_bilinear_predict16x16_neon| PROC 26 push {r4-r5, lr} 27 28 adr r12, bifilter16_coeff 29 ldr r4, [sp, #12] ;load parameters from stack 30 ldr r5, [sp, #16] ;load parameters from stack 31 32 cmp r2, #0 ;skip first_pass filter if xoffset=0 33 beq secondpass_bfilter16x16_only 34 35 add r2, r12, r2, lsl #3 ;calculate filter location 36 37 cmp r3, #0 ;skip second_pass filter if yoffset=0 38 39 vld1.s32 {d31}, [r2] ;load first_pass filter 40 41 beq firstpass_bfilter16x16_only 42 43 sub sp, sp, #272 ;reserve space on stack for temporary storage 44 vld1.u8 {d2, d3, d4}, [r0], r1 ;load src data 45 mov lr, sp 46 vld1.u8 {d5, d6, d7}, [r0], r1 47 48 mov r2, #3 ;loop counter 49 vld1.u8 {d8, d9, d10}, [r0], r1 50 51 vdup.8 d0, d31[0] ;first_pass filter (d0 d1) 52 vld1.u8 {d11, d12, d13}, [r0], r1 53 54 vdup.8 d1, d31[4] 55 56 ;First Pass: output_height lines x output_width columns (17x16) 57 filt_blk2d_fp16x16_loop_neon 58 pld [r0] 59 pld [r0, r1] 60 pld [r0, r1, lsl #1] 61 62 vmull.u8 q7, d2, d0 ;(src_ptr[0] * vp8_filter[0]) 63 vmull.u8 q8, d3, d0 64 vmull.u8 q9, d5, d0 65 vmull.u8 q10, d6, d0 66 vmull.u8 q11, d8, d0 67 vmull.u8 q12, d9, d0 68 vmull.u8 q13, d11, d0 69 vmull.u8 q14, d12, d0 70 71 vext.8 d2, d2, d3, #1 ;construct src_ptr[1] 72 vext.8 d5, d5, d6, #1 73 vext.8 d8, d8, d9, #1 74 vext.8 d11, d11, d12, #1 75 76 vmlal.u8 q7, d2, d1 ;(src_ptr[0] * vp8_filter[1]) 77 vmlal.u8 q9, d5, d1 78 vmlal.u8 q11, d8, d1 79 vmlal.u8 q13, d11, d1 80 81 vext.8 d3, d3, d4, #1 82 vext.8 d6, d6, d7, #1 83 vext.8 d9, d9, d10, #1 84 vext.8 d12, d12, d13, #1 85 86 vmlal.u8 q8, d3, d1 ;(src_ptr[0] * vp8_filter[1]) 87 vmlal.u8 q10, d6, d1 88 vmlal.u8 q12, d9, d1 89 vmlal.u8 q14, d12, d1 90 91 subs r2, r2, #1 92 93 vqrshrn.u16 d14, q7, #7 ;shift/round/saturate to u8 94 vqrshrn.u16 d15, q8, #7 95 vqrshrn.u16 d16, q9, #7 96 vqrshrn.u16 d17, q10, #7 97 vqrshrn.u16 d18, q11, #7 98 vqrshrn.u16 d19, q12, #7 99 vqrshrn.u16 d20, q13, #7 100 101 vld1.u8 {d2, d3, d4}, [r0], r1 ;load src data 102 vqrshrn.u16 d21, q14, #7 103 vld1.u8 {d5, d6, d7}, [r0], r1 104 105 vst1.u8 {d14, d15, d16, d17}, [lr]! ;store result 106 vld1.u8 {d8, d9, d10}, [r0], r1 107 vst1.u8 {d18, d19, d20, d21}, [lr]! 108 vld1.u8 {d11, d12, d13}, [r0], r1 109 110 bne filt_blk2d_fp16x16_loop_neon 111 112 ;First-pass filtering for rest 5 lines 113 vld1.u8 {d14, d15, d16}, [r0], r1 114 115 vmull.u8 q9, d2, d0 ;(src_ptr[0] * vp8_filter[0]) 116 vmull.u8 q10, d3, d0 117 vmull.u8 q11, d5, d0 118 vmull.u8 q12, d6, d0 119 vmull.u8 q13, d8, d0 120 vmull.u8 q14, d9, d0 121 122 vext.8 d2, d2, d3, #1 ;construct src_ptr[1] 123 vext.8 d5, d5, d6, #1 124 vext.8 d8, d8, d9, #1 125 126 vmlal.u8 q9, d2, d1 ;(src_ptr[0] * vp8_filter[1]) 127 vmlal.u8 q11, d5, d1 128 vmlal.u8 q13, d8, d1 129 130 vext.8 d3, d3, d4, #1 131 vext.8 d6, d6, d7, #1 132 vext.8 d9, d9, d10, #1 133 134 vmlal.u8 q10, d3, d1 ;(src_ptr[0] * vp8_filter[1]) 135 vmlal.u8 q12, d6, d1 136 vmlal.u8 q14, d9, d1 137 138 vmull.u8 q1, d11, d0 139 vmull.u8 q2, d12, d0 140 vmull.u8 q3, d14, d0 141 vmull.u8 q4, d15, d0 142 143 vext.8 d11, d11, d12, #1 ;construct src_ptr[1] 144 vext.8 d14, d14, d15, #1 145 146 vmlal.u8 q1, d11, d1 ;(src_ptr[0] * vp8_filter[1]) 147 vmlal.u8 q3, d14, d1 148 149 vext.8 d12, d12, d13, #1 150 vext.8 d15, d15, d16, #1 151 152 vmlal.u8 q2, d12, d1 ;(src_ptr[0] * vp8_filter[1]) 153 vmlal.u8 q4, d15, d1 154 155 vqrshrn.u16 d10, q9, #7 ;shift/round/saturate to u8 156 vqrshrn.u16 d11, q10, #7 157 vqrshrn.u16 d12, q11, #7 158 vqrshrn.u16 d13, q12, #7 159 vqrshrn.u16 d14, q13, #7 160 vqrshrn.u16 d15, q14, #7 161 vqrshrn.u16 d16, q1, #7 162 vqrshrn.u16 d17, q2, #7 163 vqrshrn.u16 d18, q3, #7 164 vqrshrn.u16 d19, q4, #7 165 166 vst1.u8 {d10, d11, d12, d13}, [lr]! ;store result 167 vst1.u8 {d14, d15, d16, d17}, [lr]! 168 vst1.u8 {d18, d19}, [lr]! 169 170 ;Second pass: 16x16 171 ;secondpass_filter 172 add r3, r12, r3, lsl #3 173 sub lr, lr, #272 174 175 vld1.u32 {d31}, [r3] ;load second_pass filter 176 177 vld1.u8 {d22, d23}, [lr]! ;load src data 178 179 vdup.8 d0, d31[0] ;second_pass filter parameters (d0 d1) 180 vdup.8 d1, d31[4] 181 mov r12, #4 ;loop counter 182 183 filt_blk2d_sp16x16_loop_neon 184 vld1.u8 {d24, d25}, [lr]! 185 vmull.u8 q1, d22, d0 ;(src_ptr[0] * vp8_filter[0]) 186 vld1.u8 {d26, d27}, [lr]! 187 vmull.u8 q2, d23, d0 188 vld1.u8 {d28, d29}, [lr]! 189 vmull.u8 q3, d24, d0 190 vld1.u8 {d30, d31}, [lr]! 191 192 vmull.u8 q4, d25, d0 193 vmull.u8 q5, d26, d0 194 vmull.u8 q6, d27, d0 195 vmull.u8 q7, d28, d0 196 vmull.u8 q8, d29, d0 197 198 vmlal.u8 q1, d24, d1 ;(src_ptr[pixel_step] * vp8_filter[1]) 199 vmlal.u8 q2, d25, d1 200 vmlal.u8 q3, d26, d1 201 vmlal.u8 q4, d27, d1 202 vmlal.u8 q5, d28, d1 203 vmlal.u8 q6, d29, d1 204 vmlal.u8 q7, d30, d1 205 vmlal.u8 q8, d31, d1 206 207 subs r12, r12, #1 208 209 vqrshrn.u16 d2, q1, #7 ;shift/round/saturate to u8 210 vqrshrn.u16 d3, q2, #7 211 vqrshrn.u16 d4, q3, #7 212 vqrshrn.u16 d5, q4, #7 213 vqrshrn.u16 d6, q5, #7 214 vqrshrn.u16 d7, q6, #7 215 vqrshrn.u16 d8, q7, #7 216 vqrshrn.u16 d9, q8, #7 217 218 vst1.u8 {d2, d3}, [r4], r5 ;store result 219 vst1.u8 {d4, d5}, [r4], r5 220 vst1.u8 {d6, d7}, [r4], r5 221 vmov q11, q15 222 vst1.u8 {d8, d9}, [r4], r5 223 224 bne filt_blk2d_sp16x16_loop_neon 225 226 add sp, sp, #272 227 228 pop {r4-r5,pc} 229 230 ;-------------------- 231 firstpass_bfilter16x16_only 232 mov r2, #4 ;loop counter 233 vdup.8 d0, d31[0] ;first_pass filter (d0 d1) 234 vdup.8 d1, d31[4] 235 236 ;First Pass: output_height lines x output_width columns (16x16) 237 filt_blk2d_fpo16x16_loop_neon 238 vld1.u8 {d2, d3, d4}, [r0], r1 ;load src data 239 vld1.u8 {d5, d6, d7}, [r0], r1 240 vld1.u8 {d8, d9, d10}, [r0], r1 241 vld1.u8 {d11, d12, d13}, [r0], r1 242 243 pld [r0] 244 pld [r0, r1] 245 pld [r0, r1, lsl #1] 246 247 vmull.u8 q7, d2, d0 ;(src_ptr[0] * vp8_filter[0]) 248 vmull.u8 q8, d3, d0 249 vmull.u8 q9, d5, d0 250 vmull.u8 q10, d6, d0 251 vmull.u8 q11, d8, d0 252 vmull.u8 q12, d9, d0 253 vmull.u8 q13, d11, d0 254 vmull.u8 q14, d12, d0 255 256 vext.8 d2, d2, d3, #1 ;construct src_ptr[1] 257 vext.8 d5, d5, d6, #1 258 vext.8 d8, d8, d9, #1 259 vext.8 d11, d11, d12, #1 260 261 vmlal.u8 q7, d2, d1 ;(src_ptr[0] * vp8_filter[1]) 262 vmlal.u8 q9, d5, d1 263 vmlal.u8 q11, d8, d1 264 vmlal.u8 q13, d11, d1 265 266 vext.8 d3, d3, d4, #1 267 vext.8 d6, d6, d7, #1 268 vext.8 d9, d9, d10, #1 269 vext.8 d12, d12, d13, #1 270 271 vmlal.u8 q8, d3, d1 ;(src_ptr[0] * vp8_filter[1]) 272 vmlal.u8 q10, d6, d1 273 vmlal.u8 q12, d9, d1 274 vmlal.u8 q14, d12, d1 275 276 subs r2, r2, #1 277 278 vqrshrn.u16 d14, q7, #7 ;shift/round/saturate to u8 279 vqrshrn.u16 d15, q8, #7 280 vqrshrn.u16 d16, q9, #7 281 vqrshrn.u16 d17, q10, #7 282 vqrshrn.u16 d18, q11, #7 283 vqrshrn.u16 d19, q12, #7 284 vqrshrn.u16 d20, q13, #7 285 vst1.u8 {d14, d15}, [r4], r5 ;store result 286 vqrshrn.u16 d21, q14, #7 287 288 vst1.u8 {d16, d17}, [r4], r5 289 vst1.u8 {d18, d19}, [r4], r5 290 vst1.u8 {d20, d21}, [r4], r5 291 292 bne filt_blk2d_fpo16x16_loop_neon 293 pop {r4-r5,pc} 294 295 ;--------------------- 296 secondpass_bfilter16x16_only 297 ;Second pass: 16x16 298 ;secondpass_filter 299 add r3, r12, r3, lsl #3 300 mov r12, #4 ;loop counter 301 vld1.u32 {d31}, [r3] ;load second_pass filter 302 vld1.u8 {d22, d23}, [r0], r1 ;load src data 303 304 vdup.8 d0, d31[0] ;second_pass filter parameters (d0 d1) 305 vdup.8 d1, d31[4] 306 307 filt_blk2d_spo16x16_loop_neon 308 vld1.u8 {d24, d25}, [r0], r1 309 vmull.u8 q1, d22, d0 ;(src_ptr[0] * vp8_filter[0]) 310 vld1.u8 {d26, d27}, [r0], r1 311 vmull.u8 q2, d23, d0 312 vld1.u8 {d28, d29}, [r0], r1 313 vmull.u8 q3, d24, d0 314 vld1.u8 {d30, d31}, [r0], r1 315 316 vmull.u8 q4, d25, d0 317 vmull.u8 q5, d26, d0 318 vmull.u8 q6, d27, d0 319 vmull.u8 q7, d28, d0 320 vmull.u8 q8, d29, d0 321 322 vmlal.u8 q1, d24, d1 ;(src_ptr[pixel_step] * vp8_filter[1]) 323 vmlal.u8 q2, d25, d1 324 vmlal.u8 q3, d26, d1 325 vmlal.u8 q4, d27, d1 326 vmlal.u8 q5, d28, d1 327 vmlal.u8 q6, d29, d1 328 vmlal.u8 q7, d30, d1 329 vmlal.u8 q8, d31, d1 330 331 vqrshrn.u16 d2, q1, #7 ;shift/round/saturate to u8 332 vqrshrn.u16 d3, q2, #7 333 vqrshrn.u16 d4, q3, #7 334 vqrshrn.u16 d5, q4, #7 335 vqrshrn.u16 d6, q5, #7 336 vqrshrn.u16 d7, q6, #7 337 vqrshrn.u16 d8, q7, #7 338 vqrshrn.u16 d9, q8, #7 339 340 vst1.u8 {d2, d3}, [r4], r5 ;store result 341 subs r12, r12, #1 342 vst1.u8 {d4, d5}, [r4], r5 343 vmov q11, q15 344 vst1.u8 {d6, d7}, [r4], r5 345 vst1.u8 {d8, d9}, [r4], r5 346 347 bne filt_blk2d_spo16x16_loop_neon 348 pop {r4-r5,pc} 349 350 ENDP 351 352 ;----------------- 353 354 bifilter16_coeff 355 DCD 128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112 356 357 END 358