1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define ENTRY(f) .text; .align 4; .globl f; .type f,#function; f: .fnstart 18 #define PRIVATE(f) .text; .align 4; .type f,#function; f: .fnstart 19 #define END(f) .fnend; .size f, .-f; 20 21 .eabi_attribute 25,1 @Tag_ABI_align8_preserved 22 .arm 23 24 /* Number of fractional bits to preserve in intermediate results. The 25 * intermediate storage is 16-bit, and we started with 8 bit data (the integer 26 * part), so this should be between 0 and 8. 27 */ 28 .set FRACTION_BITS, 7 29 30 .set MAX_R, 25 31 32 33 /* A quick way of making a line of code conditional on some other condition. 34 * Use `.set cc, 1` or `.set cc, 0` to enable or disable lines prefixed with 35 * `ifcc`: 36 */ 37 .macro ifcc zzz:vararg 38 .if cc 39 \zzz 40 .endif 41 .endm 42 43 /* Fetch 16 columns of bytes (regardless of image format), convolve these 44 * vertically, and leave them in the register file. If working near the top or 45 * bottom of an image then clamp the addressing while loading the data in. 46 * 47 * The convolution is fully unrolled for windows up to max_r, with the 48 * outermost edges calculated first. This way it's possible to branch directly 49 * into the relevant part of the code for an arbitrary convolution radius. Two 50 * variants of the loop are produced; one eliminates the clamping code for a 51 * slight speed advantage. 52 * 53 * Where the macro is called with reg=x, the specified register is taken to 54 * contain a pre-calculated pointer into one of the two loops. 55 * 56 * Input: 57 * r1 -- src 58 * r2 -- pitch 59 * r5 -- r 60 * r6 -- rup 61 * r7 -- rdn 62 * r12 -- switch index 63 * q0-q3 -- coefficient table 64 * Output: 65 * r1 += 16 66 * q10,q11 -- 16 convolved columns 67 * Modifies: 68 * r10 = upper row pointer 69 * r11 = lower row pointer 70 * q12-q15 = temporary sums 71 */ 72 .macro fetch, max_r=MAX_R, labelc=1, labelnc=2, reg=r12 /*{{{*/ 73 .ifc \reg,r12 ; .set cc, 1 ; .else ; .set cc, 0 ; .endif 74 75 vld1.8 {d30,d31}, [r1] 76 mls r10, r2, r6, r1 77 78 vmovl.u8 q14, d30 79 pld [r1, #32] 80 vmovl.u8 q15, d31 81 .if \max_r < 16 // approximate 82 ifcc adr \reg, 1f 83 .else 84 ifcc ldr \reg, 2f 85 1: ifcc add \reg, \reg, pc 86 .endif 87 88 vmull.u16 q12, d28, d0[0] 89 ifcc sub \reg, r5, LSL #6 90 vmull.u16 q13, d29, d0[0] 91 mla r11, r2, r7, r1 92 vmull.u16 q14, d30, d0[0] 93 add r1, r1, #16 94 vmull.u16 q15, d31, d0[0] 95 bx \reg 96 97 ifcc .align 2 98 2: ifcc .word 1f-1b-8 99 100 .irp rowclamp, 1, 0 101 .set cc, \rowclamp 102 .align 4 103 .irp dreg, 6, 5, 4, 3, 2, 1, 0 ; .irp lane, 3, 2, 1, 0 104 .set i, \dreg * 4 + \lane 105 .if 0 < i && i <= \max_r 106 .if \rowclamp 107 vld1.8 {d20,d21}, [r10] 108 vld1.8 {d22,d23}, [r11] 109 cmp r6, #i 110 .else 111 vld1.8 {d20,d21}, [r10], r2 112 vld1.8 {d22,d23}, [r11] 113 sub r11, r11, r2 114 .endif 115 vswp d21, d22 116 pld [r10, #32] 117 vaddl.u8 q10, d20, d21 118 ifcc addhs r10, r10, r2 119 vaddl.u8 q11, d22, d23 120 ifcc cmp r7, #i 121 vmlal.u16 q12, d20, d\dreg[\lane] 122 pld [r11, #32] 123 vmlal.u16 q13, d21, d\dreg[\lane] 124 ifcc subhs r11, r11, r2 125 vmlal.u16 q14, d22, d\dreg[\lane] 126 ifcc nop 127 vmlal.u16 q15, d23, d\dreg[\lane] 128 .endif 129 .endr ; .endr 130 .if \rowclamp == 1 131 1: \labelc : 132 b 2f 133 .else 134 2: \labelnc : 135 .endif 136 .endr 137 138 vqrshrn.u32 d20, q12, #16 - FRACTION_BITS 139 vqrshrn.u32 d21, q13, #16 - FRACTION_BITS 140 vqrshrn.u32 d22, q14, #16 - FRACTION_BITS 141 vqrshrn.u32 d23, q15, #16 - FRACTION_BITS 142 .endm /*}}}*/ 143 144 /* Some portion of the convolution window (as much as will fit, and all of it 145 * for the uchar1 cases) is kept in the register file to avoid unnecessary 146 * memory accesses. This forces the horizontal loops to be unrolled because 147 * there's no indexed addressing into the register file. 148 * 149 * As in the fetch macro, the operations are ordered from outside to inside, so 150 * that jumping into the middle of the block bypasses the unwanted window taps. 151 * 152 * There are several variants of the macro because of the fixed offets of the 153 * taps -- the wider the maximum radius the further the centre tap is from the 154 * most recently fetched data. This means that pre-filling the window requires 155 * more data that won't be used and it means that rotating the window involves 156 * more mov operations. 157 * 158 * When the buffer gets too big the buffer at [r9] is used. 159 * 160 * Input: 161 * q4-q11 -- convoltion window 162 * r9 -- pointer to additional convolution window data 163 * Output: 164 * r9 -- updated buffer pointer (if used) 165 * d31 -- result to be stored 166 * Modifies: 167 * r12 -- temp buffer pointer 168 * q12-q13 -- temporaries for load and vext operations. 169 * q14-q15 -- intermediate sums 170 */ 171 #define TUNED_LIST1 8, 16 172 .macro hconv1_8/*{{{*/ 173 vmull.u16 q14, d18, d0[0] 174 vmull.u16 q15, d19, d0[0] 175 176 ldr r12, [pc, r5, LSL #2] 177 add pc, pc, r12 178 bkpt 179 100: .word 101f-100b 180 .word 102f-100b 181 .word 103f-100b 182 .word 104f-100b 183 .word 105f-100b 184 .word 106f-100b 185 .word 107f-100b 186 .word 108f-100b 187 108: vmlal.u16 q14, d16, d2[0] 188 vmlal.u16 q15, d17, d2[0] 189 vmlal.u16 q14, d20, d2[0] 190 vmlal.u16 q15, d21, d2[0] 191 107: vext.u16 q12, q8, q9, #1 192 vext.u16 q13, q9, q10, #7 193 vmlal.u16 q14, d24, d1[3] 194 vmlal.u16 q15, d25, d1[3] 195 vmlal.u16 q14, d26, d1[3] 196 vmlal.u16 q15, d27, d1[3] 197 106: vext.u16 q12, q8, q9, #2 198 vext.u16 q13, q9, q10, #6 199 vmlal.u16 q14, d24, d1[2] 200 vmlal.u16 q15, d25, d1[2] 201 vmlal.u16 q14, d26, d1[2] 202 vmlal.u16 q15, d27, d1[2] 203 105: vext.u16 q12, q8, q9, #3 204 vext.u16 q13, q9, q10, #5 205 vmlal.u16 q14, d24, d1[1] 206 vmlal.u16 q15, d25, d1[1] 207 vmlal.u16 q14, d26, d1[1] 208 vmlal.u16 q15, d27, d1[1] 209 104: //vext.u16 q12, q8, q9, #4 210 //vext.u16 q13, q9, q10, #4 211 vmlal.u16 q14, d17, d1[0] 212 vmlal.u16 q15, d18, d1[0] 213 vmlal.u16 q14, d19, d1[0] 214 vmlal.u16 q15, d20, d1[0] 215 103: vext.u16 q12, q8, q9, #5 216 vext.u16 q13, q9, q10, #3 217 vmlal.u16 q14, d24, d0[3] 218 vmlal.u16 q15, d25, d0[3] 219 vmlal.u16 q14, d26, d0[3] 220 vmlal.u16 q15, d27, d0[3] 221 102: vext.u16 q12, q8, q9, #6 222 vext.u16 q13, q9, q10, #2 223 vmlal.u16 q14, d24, d0[2] 224 vmlal.u16 q15, d25, d0[2] 225 vmlal.u16 q14, d26, d0[2] 226 vmlal.u16 q15, d27, d0[2] 227 101: vext.u16 q12, q8, q9, #7 228 vext.u16 q13, q9, q10, #1 229 vmlal.u16 q14, d24, d0[1] 230 vmlal.u16 q15, d25, d0[1] 231 vmlal.u16 q14, d26, d0[1] 232 vmlal.u16 q15, d27, d0[1] 233 234 vqrshrn.u32 d28, q14, #16 235 vqrshrn.u32 d29, q15, #16 236 vqrshrn.u16 d31, q14, #FRACTION_BITS 237 238 vmov q8, q9 239 vmov q9, q10 240 vmov q10, q11 241 .endm/*}}}*/ 242 243 .macro hconv1_16/*{{{*/ 244 vmull.u16 q14, d16, d0[0] 245 vmull.u16 q15, d17, d0[0] 246 247 ldr r12, [pc, r5, LSL #2] 248 add pc, pc, r12 249 bkpt 250 100: .word 101f-100b 251 .word 102f-100b 252 .word 103f-100b 253 .word 104f-100b 254 .word 105f-100b 255 .word 106f-100b 256 .word 107f-100b 257 .word 108f-100b 258 .word 109f-100b 259 .word 110f-100b 260 .word 111f-100b 261 .word 112f-100b 262 .word 113f-100b 263 .word 114f-100b 264 .word 115f-100b 265 .word 116f-100b 266 116: //vext.u16 q12, q6, q7, #0 267 //vext.u16 q13, q10, q11, #0 268 vmlal.u16 q14, d12, d4[0] 269 vmlal.u16 q15, d13, d4[0] 270 vmlal.u16 q14, d20, d4[0] 271 vmlal.u16 q15, d21, d4[0] 272 115: vext.u16 q12, q6, q7, #1 273 vext.u16 q13, q9, q10, #7 274 vmlal.u16 q14, d24, d3[3] 275 vmlal.u16 q15, d25, d3[3] 276 vmlal.u16 q14, d26, d3[3] 277 vmlal.u16 q15, d27, d3[3] 278 114: vext.u16 q12, q6, q7, #2 279 vext.u16 q13, q9, q10, #6 280 vmlal.u16 q14, d24, d3[2] 281 vmlal.u16 q15, d25, d3[2] 282 vmlal.u16 q14, d26, d3[2] 283 vmlal.u16 q15, d27, d3[2] 284 113: vext.u16 q12, q6, q7, #3 285 vext.u16 q13, q9, q10, #5 286 vmlal.u16 q14, d24, d3[1] 287 vmlal.u16 q15, d25, d3[1] 288 vmlal.u16 q14, d26, d3[1] 289 vmlal.u16 q15, d27, d3[1] 290 112: //vext.u16 q12, q6, q7, #4 291 //vext.u16 q13, q9, q10, #4 292 vmlal.u16 q14, d13, d3[0] 293 vmlal.u16 q15, d14, d3[0] 294 vmlal.u16 q14, d19, d3[0] 295 vmlal.u16 q15, d20, d3[0] 296 111: vext.u16 q12, q6, q7, #5 297 vext.u16 q13, q9, q10, #3 298 vmlal.u16 q14, d24, d2[3] 299 vmlal.u16 q15, d25, d2[3] 300 vmlal.u16 q14, d26, d2[3] 301 vmlal.u16 q15, d27, d2[3] 302 110: vext.u16 q12, q6, q7, #6 303 vext.u16 q13, q9, q10, #2 304 vmlal.u16 q14, d24, d2[2] 305 vmlal.u16 q15, d25, d2[2] 306 vmlal.u16 q14, d26, d2[2] 307 vmlal.u16 q15, d27, d2[2] 308 109: vext.u16 q12, q6, q7, #7 309 vext.u16 q13, q9, q10, #1 310 vmlal.u16 q14, d24, d2[1] 311 vmlal.u16 q15, d25, d2[1] 312 vmlal.u16 q14, d26, d2[1] 313 vmlal.u16 q15, d27, d2[1] 314 108: //vext.u16 q12, q7, q8, #0 315 //vext.u16 q13, q9, q10, #0 316 vmlal.u16 q14, d14, d2[0] 317 vmlal.u16 q15, d15, d2[0] 318 vmlal.u16 q14, d18, d2[0] 319 vmlal.u16 q15, d19, d2[0] 320 107: vext.u16 q12, q7, q8, #1 321 vext.u16 q13, q8, q9, #7 322 vmlal.u16 q14, d24, d1[3] 323 vmlal.u16 q15, d25, d1[3] 324 vmlal.u16 q14, d26, d1[3] 325 vmlal.u16 q15, d27, d1[3] 326 106: vext.u16 q12, q7, q8, #2 327 vext.u16 q13, q8, q9, #6 328 vmlal.u16 q14, d24, d1[2] 329 vmlal.u16 q15, d25, d1[2] 330 vmlal.u16 q14, d26, d1[2] 331 vmlal.u16 q15, d27, d1[2] 332 105: vext.u16 q12, q7, q8, #3 333 vext.u16 q13, q8, q9, #5 334 vmlal.u16 q14, d24, d1[1] 335 vmlal.u16 q15, d25, d1[1] 336 vmlal.u16 q14, d26, d1[1] 337 vmlal.u16 q15, d27, d1[1] 338 104: //vext.u16 q12, q7, q8, #4 339 //vext.u16 q13, q8, q9, #4 340 vmlal.u16 q14, d15, d1[0] 341 vmlal.u16 q15, d16, d1[0] 342 vmlal.u16 q14, d17, d1[0] 343 vmlal.u16 q15, d18, d1[0] 344 103: vext.u16 q12, q7, q8, #5 345 vext.u16 q13, q8, q9, #3 346 vmlal.u16 q14, d24, d0[3] 347 vmlal.u16 q15, d25, d0[3] 348 vmlal.u16 q14, d26, d0[3] 349 vmlal.u16 q15, d27, d0[3] 350 102: vext.u16 q12, q7, q8, #6 351 vext.u16 q13, q8, q9, #2 352 vmlal.u16 q14, d24, d0[2] 353 vmlal.u16 q15, d25, d0[2] 354 vmlal.u16 q14, d26, d0[2] 355 vmlal.u16 q15, d27, d0[2] 356 101: vext.u16 q12, q7, q8, #7 357 vext.u16 q13, q8, q9, #1 358 vmlal.u16 q14, d24, d0[1] 359 vmlal.u16 q15, d25, d0[1] 360 vmlal.u16 q14, d26, d0[1] 361 vmlal.u16 q15, d27, d0[1] 362 363 vqrshrn.u32 d28, q14, #16 364 vqrshrn.u32 d29, q15, #16 365 vqrshrn.u16 d31, q14, #FRACTION_BITS 366 367 vmov q6, q7 368 vmov q7, q8 369 vmov q8, q9 370 vmov q9, q10 371 vmov q10, q11 372 .endm/*}}}*/ 373 374 .macro hconv1_25/*{{{*/ 375 vext.u16 q12, q6, q7, #7 376 vmull.u16 q14, d24, d0[0] 377 vmull.u16 q15, d25, d0[0] 378 379 ldr r12, [pc, r5, LSL #2] 380 add pc, pc, r12 381 bkpt 382 100: .word 101f-100b 383 .word 102f-100b 384 .word 103f-100b 385 .word 104f-100b 386 .word 105f-100b 387 .word 106f-100b 388 .word 107f-100b 389 .word 108f-100b 390 .word 109f-100b 391 .word 110f-100b 392 .word 111f-100b 393 .word 112f-100b 394 .word 113f-100b 395 .word 114f-100b 396 .word 115f-100b 397 .word 116f-100b 398 .word 117f-100b 399 .word 118f-100b 400 .word 119f-100b 401 .word 120f-100b 402 .word 121f-100b 403 .word 122f-100b 404 .word 123f-100b 405 .word 124f-100b 406 .word 125f-100b 407 125: vext.u16 q12, q3, q4, #6 408 vext.u16 q13, q10, q11, #0 409 vmlal.u16 q14, d24, d6[1] 410 vmlal.u16 q15, d25, d6[1] 411 vmlal.u16 q14, d26, d6[1] 412 vmlal.u16 q15, d27, d6[1] 413 124: vext.u16 q12, q3, q4, #7 414 vext.u16 q13, q9, q10, #7 415 vmlal.u16 q14, d24, d6[0] 416 vmlal.u16 q15, d25, d6[0] 417 vmlal.u16 q14, d26, d6[0] 418 vmlal.u16 q15, d27, d6[0] 419 123: vext.u16 q12, q4, q5, #0 420 vext.u16 q13, q9, q10, #6 421 vmlal.u16 q14, d24, d5[3] 422 vmlal.u16 q15, d25, d5[3] 423 vmlal.u16 q14, d26, d5[3] 424 vmlal.u16 q15, d27, d5[3] 425 122: vext.u16 q12, q4, q5, #1 426 vext.u16 q13, q9, q10, #5 427 vmlal.u16 q14, d24, d5[2] 428 vmlal.u16 q15, d25, d5[2] 429 vmlal.u16 q14, d26, d5[2] 430 vmlal.u16 q15, d27, d5[2] 431 121: vext.u16 q12, q4, q5, #2 432 vext.u16 q13, q9, q10, #4 433 vmlal.u16 q14, d24, d5[1] 434 vmlal.u16 q15, d25, d5[1] 435 vmlal.u16 q14, d26, d5[1] 436 vmlal.u16 q15, d27, d5[1] 437 120: vext.u16 q12, q4, q5, #3 438 vext.u16 q13, q9, q10, #3 439 vmlal.u16 q14, d24, d5[0] 440 vmlal.u16 q15, d25, d5[0] 441 vmlal.u16 q14, d26, d5[0] 442 vmlal.u16 q15, d27, d5[0] 443 119: vext.u16 q12, q4, q5, #4 444 vext.u16 q13, q9, q10, #2 445 vmlal.u16 q14, d24, d4[3] 446 vmlal.u16 q15, d25, d4[3] 447 vmlal.u16 q14, d26, d4[3] 448 vmlal.u16 q15, d27, d4[3] 449 118: vext.u16 q12, q4, q5, #5 450 vext.u16 q13, q9, q10, #1 451 vmlal.u16 q14, d24, d4[2] 452 vmlal.u16 q15, d25, d4[2] 453 vmlal.u16 q14, d26, d4[2] 454 vmlal.u16 q15, d27, d4[2] 455 117: vext.u16 q12, q4, q5, #6 456 vext.u16 q13, q9, q10, #0 457 vmlal.u16 q14, d24, d4[1] 458 vmlal.u16 q15, d25, d4[1] 459 vmlal.u16 q14, d26, d4[1] 460 vmlal.u16 q15, d27, d4[1] 461 116: vext.u16 q12, q4, q5, #7 462 vext.u16 q13, q8, q9, #7 463 vmlal.u16 q14, d24, d4[0] 464 vmlal.u16 q15, d25, d4[0] 465 vmlal.u16 q14, d26, d4[0] 466 vmlal.u16 q15, d27, d4[0] 467 115: vext.u16 q12, q5, q6, #0 468 vext.u16 q13, q8, q9, #6 469 vmlal.u16 q14, d24, d3[3] 470 vmlal.u16 q15, d25, d3[3] 471 vmlal.u16 q14, d26, d3[3] 472 vmlal.u16 q15, d27, d3[3] 473 114: vext.u16 q12, q5, q6, #1 474 vext.u16 q13, q8, q9, #5 475 vmlal.u16 q14, d24, d3[2] 476 vmlal.u16 q15, d25, d3[2] 477 vmlal.u16 q14, d26, d3[2] 478 vmlal.u16 q15, d27, d3[2] 479 113: vext.u16 q12, q5, q6, #2 480 vext.u16 q13, q8, q9, #4 481 vmlal.u16 q14, d24, d3[1] 482 vmlal.u16 q15, d25, d3[1] 483 vmlal.u16 q14, d26, d3[1] 484 vmlal.u16 q15, d27, d3[1] 485 112: vext.u16 q12, q5, q6, #3 486 vext.u16 q13, q8, q9, #3 487 vmlal.u16 q14, d24, d3[0] 488 vmlal.u16 q15, d25, d3[0] 489 vmlal.u16 q14, d26, d3[0] 490 vmlal.u16 q15, d27, d3[0] 491 111: vext.u16 q12, q5, q6, #4 492 vext.u16 q13, q8, q9, #2 493 vmlal.u16 q14, d24, d2[3] 494 vmlal.u16 q15, d25, d2[3] 495 vmlal.u16 q14, d26, d2[3] 496 vmlal.u16 q15, d27, d2[3] 497 110: vext.u16 q12, q5, q6, #5 498 vext.u16 q13, q8, q9, #1 499 vmlal.u16 q14, d24, d2[2] 500 vmlal.u16 q15, d25, d2[2] 501 vmlal.u16 q14, d26, d2[2] 502 vmlal.u16 q15, d27, d2[2] 503 109: vext.u16 q12, q5, q6, #6 504 vext.u16 q13, q8, q9, #0 505 vmlal.u16 q14, d24, d2[1] 506 vmlal.u16 q15, d25, d2[1] 507 vmlal.u16 q14, d26, d2[1] 508 vmlal.u16 q15, d27, d2[1] 509 108: vext.u16 q12, q5, q6, #7 510 vext.u16 q13, q7, q8, #7 511 vmlal.u16 q14, d24, d2[0] 512 vmlal.u16 q15, d25, d2[0] 513 vmlal.u16 q14, d26, d2[0] 514 vmlal.u16 q15, d27, d2[0] 515 107: vext.u16 q12, q6, q7, #0 516 vext.u16 q13, q7, q8, #6 517 vmlal.u16 q14, d24, d1[3] 518 vmlal.u16 q15, d25, d1[3] 519 vmlal.u16 q14, d26, d1[3] 520 vmlal.u16 q15, d27, d1[3] 521 106: vext.u16 q12, q6, q7, #1 522 vext.u16 q13, q7, q8, #5 523 vmlal.u16 q14, d24, d1[2] 524 vmlal.u16 q15, d25, d1[2] 525 vmlal.u16 q14, d26, d1[2] 526 vmlal.u16 q15, d27, d1[2] 527 105: vext.u16 q12, q6, q7, #2 528 vext.u16 q13, q7, q8, #4 529 vmlal.u16 q14, d24, d1[1] 530 vmlal.u16 q15, d25, d1[1] 531 vmlal.u16 q14, d26, d1[1] 532 vmlal.u16 q15, d27, d1[1] 533 104: vext.u16 q12, q6, q7, #3 534 vext.u16 q13, q7, q8, #3 535 vmlal.u16 q14, d24, d1[0] 536 vmlal.u16 q15, d25, d1[0] 537 vmlal.u16 q14, d26, d1[0] 538 vmlal.u16 q15, d27, d1[0] 539 103: vext.u16 q12, q6, q7, #4 540 vext.u16 q13, q7, q8, #2 541 vmlal.u16 q14, d24, d0[3] 542 vmlal.u16 q15, d25, d0[3] 543 vmlal.u16 q14, d26, d0[3] 544 vmlal.u16 q15, d27, d0[3] 545 102: vext.u16 q12, q6, q7, #5 546 vext.u16 q13, q7, q8, #1 547 vmlal.u16 q14, d24, d0[2] 548 vmlal.u16 q15, d25, d0[2] 549 vmlal.u16 q14, d26, d0[2] 550 vmlal.u16 q15, d27, d0[2] 551 101: vext.u16 q12, q6, q7, #6 552 vext.u16 q13, q7, q8, #0 553 vmlal.u16 q14, d24, d0[1] 554 vmlal.u16 q15, d25, d0[1] 555 vmlal.u16 q14, d26, d0[1] 556 vmlal.u16 q15, d27, d0[1] 557 558 vqrshrn.u32 d28, q14, #16 559 vqrshrn.u32 d29, q15, #16 560 vqrshrn.u16 d31, q14, #FRACTION_BITS 561 562 vmov d7, d9 563 vmov q4, q5 564 vmov q5, q6 565 vmov q6, q7 566 vmov q7, q8 567 vmov q8, q9 568 vmov q9, q10 569 vmov q10, q11 570 .endm/*}}}*/ 571 572 #define TUNED_LIST4 6, 12 573 .macro hconv4_6/*{{{*/ 574 vmull.u16 q14, d14, d0[0] 575 vmull.u16 q15, d15, d0[0] 576 577 ldr r12, [pc, r5, LSL #2] 578 add pc, pc, r12 579 bkpt 580 100: .word 101f-100b 581 .word 102f-100b 582 .word 103f-100b 583 .word 104f-100b 584 .word 105f-100b 585 .word 106f-100b 586 106: vmlal.u16 q14, d8, d1[2] 587 vmlal.u16 q15, d9, d1[2] 588 vmlal.u16 q14, d20, d1[2] 589 vmlal.u16 q15, d21, d1[2] 590 105: vmlal.u16 q14, d9, d1[1] 591 vmlal.u16 q15, d10, d1[1] 592 vmlal.u16 q14, d19, d1[1] 593 vmlal.u16 q15, d20, d1[1] 594 104: vmlal.u16 q14, d10, d1[0] 595 vmlal.u16 q15, d11, d1[0] 596 vmlal.u16 q14, d18, d1[0] 597 vmlal.u16 q15, d19, d1[0] 598 103: vmlal.u16 q14, d11, d0[3] 599 vmlal.u16 q15, d12, d0[3] 600 vmlal.u16 q14, d17, d0[3] 601 vmlal.u16 q15, d18, d0[3] 602 102: vmlal.u16 q14, d12, d0[2] 603 vmlal.u16 q15, d13, d0[2] 604 vmlal.u16 q14, d16, d0[2] 605 vmlal.u16 q15, d17, d0[2] 606 101: vmlal.u16 q14, d13, d0[1] 607 vmlal.u16 q15, d14, d0[1] 608 vmlal.u16 q14, d15, d0[1] 609 vmlal.u16 q15, d16, d0[1] 610 611 vqrshrn.u32 d28, q14, #16 612 vqrshrn.u32 d29, q15, #16 613 vqrshrn.u16 d31, q14, #FRACTION_BITS 614 615 vmov q4, q5 616 vmov q5, q6 617 vmov q6, q7 618 vmov q7, q8 619 vmov q8, q9 620 vmov q9, q10 621 vmov q10, q11 622 .endm/*}}}*/ 623 624 .macro hconv4_12/*{{{*/ 625 vmull.u16 q14, d8, d0[0] 626 vmull.u16 q15, d9, d0[0] 627 628 ldr r12, [pc, r5, LSL #2] 629 add pc, pc, r12 630 bkpt 631 100: .word 101f-100b 632 .word 102f-100b 633 .word 103f-100b 634 .word 104f-100b 635 .word 105f-100b 636 .word 106f-100b 637 .word 107f-100b 638 .word 108f-100b 639 .word 109f-100b 640 .word 110f-100b 641 .word 111f-100b 642 .word 112f-100b 643 112: add r12, r9, #0x1a0 644 bic r12, r12, #0x200 645 vld1.u16 {d24,d25}, [r12:128] 646 vmlal.u16 q14, d24, d3[0] 647 vmlal.u16 q15, d25, d3[0] 648 vmlal.u16 q14, d20, d3[0] 649 vmlal.u16 q15, d21, d3[0] 650 111: add r12, r9, #0x1a8 651 bic r12, r12, #0x200 652 vld1.u16 {d24}, [r12:64]! 653 bic r12, r12, #0x200 654 vld1.u16 {d25}, [r12:64] 655 vmlal.u16 q14, d24, d2[3] 656 vmlal.u16 q15, d25, d2[3] 657 vmlal.u16 q14, d19, d2[3] 658 vmlal.u16 q15, d20, d2[3] 659 110: add r12, r9, #0x1b0 660 bic r12, r12, #0x200 661 vld1.u16 {d24,d25}, [r12:128] 662 vmlal.u16 q14, d24, d2[2] 663 vmlal.u16 q15, d25, d2[2] 664 vmlal.u16 q14, d18, d2[2] 665 vmlal.u16 q15, d19, d2[2] 666 109: add r12, r9, #0x1b8 667 bic r12, r12, #0x200 668 vld1.u16 {d24}, [r12:64]! 669 bic r12, r12, #0x200 670 vld1.u16 {d25}, [r12:64] 671 vmlal.u16 q14, d24, d2[1] 672 vmlal.u16 q15, d25, d2[1] 673 vmlal.u16 q14, d17, d2[1] 674 vmlal.u16 q15, d18, d2[1] 675 108: add r12, r9, #0x1c0 676 bic r12, r12, #0x200 677 vld1.u16 {d24,d25}, [r12:128] 678 vmlal.u16 q14, d24, d2[0] 679 vmlal.u16 q15, d25, d2[0] 680 vmlal.u16 q14, d16, d2[0] 681 vmlal.u16 q15, d17, d2[0] 682 107: add r12, r9, #0x1c8 683 bic r12, r12, #0x200 684 vld1.u16 {d24}, [r12:64]! 685 bic r12, r12, #0x200 686 vld1.u16 {d25}, [r12:64] 687 vmlal.u16 q14, d24, d1[3] 688 vmlal.u16 q15, d25, d1[3] 689 vmlal.u16 q14, d15, d1[3] 690 vmlal.u16 q15, d16, d1[3] 691 106: add r12, r9, #0x1d0 692 bic r12, r12, #0x200 693 vld1.u16 {d24,d25}, [r12:128] 694 vmlal.u16 q14, d24, d1[2] 695 vmlal.u16 q15, d25, d1[2] 696 vmlal.u16 q14, d14, d1[2] 697 vmlal.u16 q15, d15, d1[2] 698 105: add r12, r9, #0x1d8 699 bic r12, r12, #0x200 700 vld1.u16 {d24}, [r12:64]! 701 bic r12, r12, #0x200 702 vld1.u16 {d25}, [r12:64] 703 vmlal.u16 q14, d24, d1[1] 704 vmlal.u16 q15, d25, d1[1] 705 vmlal.u16 q14, d13, d1[1] 706 vmlal.u16 q15, d14, d1[1] 707 104: add r12, r9, #0x1e0 708 bic r12, r12, #0x200 709 vld1.u16 {d24,d25}, [r12:128] 710 vmlal.u16 q14, d24, d1[0] 711 vmlal.u16 q15, d25, d1[0] 712 vmlal.u16 q14, d12, d1[0] 713 vmlal.u16 q15, d13, d1[0] 714 103: add r12, r9, #0x1e8 715 bic r12, r12, #0x200 716 vld1.u16 {d24}, [r12:64]! 717 bic r12, r12, #0x200 718 vld1.u16 {d25}, [r12:64] 719 vmlal.u16 q14, d24, d0[3] 720 vmlal.u16 q15, d25, d0[3] 721 vmlal.u16 q14, d11, d0[3] 722 vmlal.u16 q15, d12, d0[3] 723 102: add r12, r9, #0x1f0 724 bic r12, r12, #0x200 725 vld1.u16 {d24,d25}, [r12:128] 726 vmlal.u16 q14, d24, d0[2] 727 vmlal.u16 q15, d25, d0[2] 728 vmlal.u16 q14, d10, d0[2] 729 vmlal.u16 q15, d11, d0[2] 730 101: add r12, r9, #0x1f8 731 bic r12, r12, #0x200 732 vld1.u16 {d24}, [r12:64] 733 vmlal.u16 q14, d24, d0[1] 734 vmlal.u16 q15, d8, d0[1] 735 vmlal.u16 q14, d9, d0[1] 736 vmlal.u16 q15, d10, d0[1] 737 738 vqrshrn.u32 d28, q14, #16 739 vqrshrn.u32 d29, q15, #16 740 vqrshrn.u16 d31, q14, #FRACTION_BITS 741 742 vst1.u8 {q4}, [r9:128]! 743 bic r9, r9, #0x200 744 vmov q4, q5 745 vmov q5, q6 746 vmov q6, q7 747 vmov q7, q8 748 vmov q8, q9 749 vmov q9, q10 750 vmov q10, q11 751 .endm/*}}}*/ 752 753 .macro hconv4_25/*{{{*/ 754 add r12, r9, #0x198 755 bic r12, r12, #0x200 756 vld1.u16 {d24}, [r12:64]! 757 bic r12, r12, #0x200 758 vld1.u16 {d25}, [r12:64] 759 vmull.u16 q14, d24, d0[0] 760 vmull.u16 q15, d25, d0[0] 761 762 ldr r12, [pc, r5, LSL #2] 763 add pc, pc, r12 764 bkpt 765 100: .word 101f-100b 766 .word 102f-100b 767 .word 103f-100b 768 .word 104f-100b 769 .word 105f-100b 770 .word 106f-100b 771 .word 107f-100b 772 .word 108f-100b 773 .word 109f-100b 774 .word 110f-100b 775 .word 111f-100b 776 .word 112f-100b 777 .word 113f-100b 778 .word 114f-100b 779 .word 115f-100b 780 .word 116f-100b 781 .word 117f-100b 782 .word 118f-100b 783 .word 119f-100b 784 .word 120f-100b 785 .word 121f-100b 786 .word 122f-100b 787 .word 123f-100b 788 .word 124f-100b 789 .word 125f-100b 790 125: add r12, r9, #0x0d0 791 bic r12, r12, #0x200 792 vld1.u16 {d24,d25}, [r12:128] 793 vmlal.u16 q14, d24, d6[1] 794 vmlal.u16 q15, d25, d6[1] 795 vmlal.u16 q14, d20, d6[1] 796 vmlal.u16 q15, d21, d6[1] 797 124: add r12, r9, #0x0d8 798 bic r12, r12, #0x200 799 vld1.u16 {d24}, [r12:64]! 800 bic r12, r12, #0x200 801 vld1.u16 {d25}, [r12] 802 vmlal.u16 q14, d24, d6[0] 803 vmlal.u16 q15, d25, d6[0] 804 vmlal.u16 q14, d19, d6[0] 805 vmlal.u16 q15, d20, d6[0] 806 123: add r12, r9, #0x0e0 807 bic r12, r12, #0x200 808 vld1.u16 {d24,d25}, [r12:128] 809 vmlal.u16 q14, d24, d5[3] 810 vmlal.u16 q15, d25, d5[3] 811 vmlal.u16 q14, d18, d5[3] 812 vmlal.u16 q15, d19, d5[3] 813 122: add r12, r9, #0x0e8 814 bic r12, r12, #0x200 815 vld1.u16 {d24}, [r12:64]! 816 bic r12, r12, #0x200 817 vld1.u16 {d25}, [r12] 818 vmlal.u16 q14, d24, d5[2] 819 vmlal.u16 q15, d25, d5[2] 820 vmlal.u16 q14, d17, d5[2] 821 vmlal.u16 q15, d18, d5[2] 822 121: add r12, r9, #0x0f0 823 bic r12, r12, #0x200 824 vld1.u16 {d24,d25}, [r12:128] 825 vmlal.u16 q14, d24, d5[1] 826 vmlal.u16 q15, d25, d5[1] 827 vmlal.u16 q14, d16, d5[1] 828 vmlal.u16 q15, d17, d5[1] 829 120: add r12, r9, #0x0f8 830 bic r12, r12, #0x200 831 vld1.u16 {d24}, [r12:64]! 832 bic r12, r12, #0x200 833 vld1.u16 {d25}, [r12] 834 vmlal.u16 q14, d24, d5[0] 835 vmlal.u16 q15, d25, d5[0] 836 vmlal.u16 q14, d15, d5[0] 837 vmlal.u16 q15, d16, d5[0] 838 119: add r12, r9, #0x100 839 bic r12, r12, #0x200 840 vld1.u16 {d24,d25}, [r12:128] 841 vmlal.u16 q14, d24, d4[3] 842 vmlal.u16 q15, d25, d4[3] 843 vmlal.u16 q14, d14, d4[3] 844 vmlal.u16 q15, d15, d4[3] 845 118: add r12, r9, #0x108 846 bic r12, r12, #0x200 847 vld1.u16 {d24}, [r12:64]! 848 bic r12, r12, #0x200 849 vld1.u16 {d25}, [r12] 850 vmlal.u16 q14, d24, d4[2] 851 vmlal.u16 q15, d25, d4[2] 852 vmlal.u16 q14, d13, d4[2] 853 vmlal.u16 q15, d14, d4[2] 854 117: add r12, r9, #0x110 855 bic r12, r12, #0x200 856 vld1.u16 {d24,d25}, [r12:128] 857 vmlal.u16 q14, d24, d4[1] 858 vmlal.u16 q15, d25, d4[1] 859 vmlal.u16 q14, d12, d4[1] 860 vmlal.u16 q15, d13, d4[1] 861 116: add r12, r9, #0x118 862 bic r12, r12, #0x200 863 vld1.u16 {d24}, [r12:64]! 864 bic r12, r12, #0x200 865 vld1.u16 {d25}, [r12] 866 vmlal.u16 q14, d24, d4[0] 867 vmlal.u16 q15, d25, d4[0] 868 vmlal.u16 q14, d11, d4[0] 869 vmlal.u16 q15, d12, d4[0] 870 115: add r12, r9, #0x120 871 bic r12, r12, #0x200 872 vld1.u16 {d24,d25}, [r12:128] 873 vmlal.u16 q14, d24, d3[3] 874 vmlal.u16 q15, d25, d3[3] 875 vmlal.u16 q14, d10, d3[3] 876 vmlal.u16 q15, d11, d3[3] 877 114: add r12, r9, #0x128 878 bic r12, r12, #0x200 879 vld1.u16 {d24}, [r12:64]! 880 bic r12, r12, #0x200 881 vld1.u16 {d25}, [r12] 882 vmlal.u16 q14, d24, d3[2] 883 vmlal.u16 q15, d25, d3[2] 884 vmlal.u16 q14, d9, d3[2] 885 vmlal.u16 q15, d10, d3[2] 886 113: add r12, r9, #0x130 887 bic r12, r12, #0x200 888 vld1.u16 {d24,d25}, [r12:128] 889 vmlal.u16 q14, d24, d3[1] 890 vmlal.u16 q15, d25, d3[1] 891 vmlal.u16 q14, d8, d3[1] 892 vmlal.u16 q15, d9, d3[1] 893 112: add r12, r9, #0x138 894 bic r12, r12, #0x200 895 vld1.u16 {d24}, [r12:64]! 896 bic r12, r12, #0x200 897 vld1.u16 {d25}, [r12] 898 add r12, r9, #0x1f8 899 bic r12, r12, #0x200 900 vld1.u16 {d26}, [r12:64] 901 vmlal.u16 q14, d24, d3[0] 902 vmlal.u16 q15, d25, d3[0] 903 vmlal.u16 q14, d26, d3[0] @ Could be d7, without the load, right? 904 vmlal.u16 q15, d8, d3[0] 905 111: add r12, r9, #0x140 906 bic r12, r12, #0x200 907 vld1.u16 {d24,d25}, [r12:128] 908 add r12, r9, #0x1f0 909 bic r12, r12, #0x200 910 vld1.u16 {d26,d27}, [r12:128] 911 vmlal.u16 q14, d24, d2[3] 912 vmlal.u16 q15, d25, d2[3] 913 vmlal.u16 q14, d26, d2[3] 914 vmlal.u16 q15, d27, d2[3] 915 110: add r12, r9, #0x148 916 bic r12, r12, #0x200 917 vld1.u16 {d24}, [r12:64]! 918 bic r12, r12, #0x200 919 vld1.u16 {d25}, [r12] 920 add r12, r9, #0x1e8 921 bic r12, r12, #0x200 922 vld1.u16 {d26}, [r12:64]! 923 bic r12, r12, #0x200 924 vld1.u16 {d27}, [r12:64] 925 vmlal.u16 q14, d24, d2[2] 926 vmlal.u16 q15, d25, d2[2] 927 vmlal.u16 q14, d26, d2[2] 928 vmlal.u16 q15, d27, d2[2] 929 109: add r12, r9, #0x150 930 bic r12, r12, #0x200 931 vld1.u16 {d24,d25}, [r12:128] 932 add r12, r9, #0x1e0 933 bic r12, r12, #0x200 934 vld1.u16 {d26,d27}, [r12:128] 935 vmlal.u16 q14, d24, d2[1] 936 vmlal.u16 q15, d25, d2[1] 937 vmlal.u16 q14, d26, d2[1] 938 vmlal.u16 q15, d27, d2[1] 939 108: add r12, r9, #0x158 940 bic r12, r12, #0x200 941 vld1.u16 {d24}, [r12:64]! 942 bic r12, r12, #0x200 943 vld1.u16 {d25}, [r12] 944 add r12, r9, #0x1d8 945 bic r12, r12, #0x200 946 vld1.u16 {d26}, [r12:64]! 947 bic r12, r12, #0x200 948 vld1.u16 {d27}, [r12:64] 949 vmlal.u16 q14, d24, d2[0] 950 vmlal.u16 q15, d25, d2[0] 951 vmlal.u16 q14, d26, d2[0] 952 vmlal.u16 q15, d27, d2[0] 953 107: add r12, r9, #0x160 954 bic r12, r12, #0x200 955 vld1.u16 {d24,d25}, [r12:128] 956 add r12, r9, #0x1d0 957 bic r12, r12, #0x200 958 vld1.u16 {d26,d27}, [r12:128] 959 vmlal.u16 q14, d24, d1[3] 960 vmlal.u16 q15, d25, d1[3] 961 vmlal.u16 q14, d26, d1[3] 962 vmlal.u16 q15, d27, d1[3] 963 106: add r12, r9, #0x168 964 bic r12, r12, #0x200 965 vld1.u16 {d24}, [r12:64]! 966 bic r12, r12, #0x200 967 vld1.u16 {d25}, [r12] 968 add r12, r9, #0x1c8 969 bic r12, r12, #0x200 970 vld1.u16 {d26}, [r12:64]! 971 bic r12, r12, #0x200 972 vld1.u16 {d27}, [r12:64] 973 vmlal.u16 q14, d24, d1[2] 974 vmlal.u16 q15, d25, d1[2] 975 vmlal.u16 q14, d26, d1[2] 976 vmlal.u16 q15, d27, d1[2] 977 105: add r12, r9, #0x170 978 bic r12, r12, #0x200 979 vld1.u16 {d24,d25}, [r12:128] 980 add r12, r9, #0x1c0 981 bic r12, r12, #0x200 982 vld1.u16 {d26,d27}, [r12:128] 983 vmlal.u16 q14, d24, d1[1] 984 vmlal.u16 q15, d25, d1[1] 985 vmlal.u16 q14, d26, d1[1] 986 vmlal.u16 q15, d27, d1[1] 987 104: add r12, r9, #0x178 988 bic r12, r12, #0x200 989 vld1.u16 {d24}, [r12:64]! 990 bic r12, r12, #0x200 991 vld1.u16 {d25}, [r12] 992 add r12, r9, #0x1b8 993 bic r12, r12, #0x200 994 vld1.u16 {d26}, [r12:64]! 995 bic r12, r12, #0x200 996 vld1.u16 {d27}, [r12:64] 997 vmlal.u16 q14, d24, d1[0] 998 vmlal.u16 q15, d25, d1[0] 999 vmlal.u16 q14, d26, d1[0] 1000 vmlal.u16 q15, d27, d1[0] 1001 103: add r12, r9, #0x180 1002 bic r12, r12, #0x200 1003 vld1.u16 {d24,d25}, [r12:128] 1004 add r12, r9, #0x1b0 1005 bic r12, r12, #0x200 1006 vld1.u16 {d26,d27}, [r12:128] 1007 vmlal.u16 q14, d24, d0[3] 1008 vmlal.u16 q15, d25, d0[3] 1009 vmlal.u16 q14, d26, d0[3] 1010 vmlal.u16 q15, d27, d0[3] 1011 102: add r12, r9, #0x188 1012 bic r12, r12, #0x200 1013 vld1.u16 {d24}, [r12:64]! 1014 bic r12, r12, #0x200 1015 vld1.u16 {d25}, [r12] 1016 add r12, r9, #0x1a8 1017 bic r12, r12, #0x200 1018 vld1.u16 {d26}, [r12:64]! 1019 bic r12, r12, #0x200 1020 vld1.u16 {d27}, [r12:64] 1021 vmlal.u16 q14, d24, d0[2] 1022 vmlal.u16 q15, d25, d0[2] 1023 vmlal.u16 q14, d26, d0[2] 1024 vmlal.u16 q15, d27, d0[2] 1025 101: add r12, r9, #0x190 1026 bic r12, r12, #0x200 1027 vld1.u16 {d24,d25}, [r12:128]! 1028 bic r12, r12, #0x200 1029 vld1.u16 {d26,d27}, [r12:128] 1030 vmlal.u16 q14, d24, d0[1] 1031 vmlal.u16 q15, d25, d0[1] 1032 vmlal.u16 q14, d26, d0[1] 1033 vmlal.u16 q15, d27, d0[1] 1034 1035 vqrshrn.u32 d28, q14, #16 1036 vqrshrn.u32 d29, q15, #16 1037 vqrshrn.u16 d31, q14, #FRACTION_BITS 1038 1039 vst1.u8 {q4}, [r9:128]! 1040 bic r9, r9, #0x200 1041 vmov q4, q5 1042 vmov q5, q6 1043 vmov q6, q7 1044 vmov q7, q8 1045 vmov q8, q9 1046 vmov q9, q10 1047 vmov q10, q11 1048 .endm/*}}}*/ 1049 1050 /* Dedicated function wrapper for the fetch macro, for the cases where 1051 * performance isn't that important, to keep code size down. 1052 */ 1053 PRIVATE(fetch_generic_asm) 1054 push {r10,r11} 1055 fetch 1056 pop {r10,r11} 1057 bx lr 1058 END(fetch_generic_asm) 1059 1060 /* Given values in q10 and q11, and an index in r11, sweep the (r11&15)th value 1061 * across to fill the rest of the register pair. Used for filling the right 1062 * hand edge of the window when starting too close to the right hand edge of 1063 * the image. 1064 * Also returns a dup-ed copy of the last element in q12 for the tail-fill 1065 * case (this happens incidentally in common path, but must be done 1066 * deliberately in the fast-out path). 1067 */ 1068 PRIVATE(prefetch_clampright1) 1069 ands r12, r11, #15 1070 beq 1f 1071 sub r12, r12, #1 1072 sub sp, sp, #64 1073 vst1.u16 {q10,q11}, [sp] 1074 add r12, sp, r12, LSL #1 1075 vld1.u16 {d24[]}, [r12] 1076 vld1.u16 {d25[]}, [r12] 1077 vst1.u16 {q12}, [r12]! 1078 vst1.u16 {q12}, [r12] 1079 vld1.u16 {q10,q11}, [sp] 1080 add sp, sp, #64 1081 bx lr 1082 1: vdup.u16 q12, d23[3] 1083 bx lr 1084 END(prefetch_clampright1) 1085 1086 PRIVATE(prefetch_clampright4) 1087 ands r12, r11, #15 1088 beq 1f 1089 sub r12, r12, #4 1090 sub sp, sp, #64 1091 vst1.u16 {q10,q11}, [sp] 1092 add r12, sp, r12, LSL #1 1093 vld1.u64 {d24}, [r12] 1094 vld1.u64 {d25}, [r12] 1095 vst1.u16 {q12}, [r12]! 1096 vst1.u16 {q12}, [r12] 1097 vld1.u16 {q10,q11}, [sp] 1098 add sp, sp, #64 1099 bx lr 1100 1: vmov.u16 d24, d23 1101 vmov.u16 d25, d23 1102 bx lr 1103 END(prefetch_clampright4) 1104 1105 1106 /* Helpers for prefetch, below. 1107 */ 1108 .macro prefetch_out qa, qb, store, qsa, qsb, qsb_hi 1109 .if \store > 0 1110 .ifc \qsa,\qsb 1111 vst1.u16 {\qsa}, [r9:128]! 1112 vst1.u16 {\qsb}, [r9:128]! 1113 .else 1114 vst1.u16 {\qsa,\qsb}, [r9:256]! 1115 .endif 1116 .elseif \store == 0 1117 vmov.u16 \qa, \qsa 1118 vmov.u16 \qb, \qsb 1119 .else 1120 vmov.u16 \qb, \qsb_hi 1121 .endif 1122 .endm 1123 1124 .macro prefetch_one qa, qb, rem, c, store=0, step=1 1125 .set i, (need - 16) - \rem 1126 .if i >= 0 1127 1: cmp r10, #i+16 1128 blo 2f 1129 prefetch_out \qa, \qb, \store, q9, q9, d19 1130 b 1f 1131 2: cmp r11, #i+16 1132 bls 3f 1133 prefetch_out \qa, \qb, \store, q10, q11, d23 1134 bl fetch_generic_asm 1135 b 2f 1136 3: bl prefetch_clampright\step 1137 prefetch_out \qa, \qb, \store, q10, q11, d23 1138 4: b 4f+4 1139 @q12 contains pad word from prefetch_clampright call 1140 prefetch_out \qa, \qb, \store, q12, q12, d25 1141 .if \rem > 0 1142 b 4f+4 1143 .else 1144 1: 1145 2: 1146 3: 1147 4: nop 1148 .endif 1149 .endif 1150 .endm 1151 1152 /* Fill the convolution window with context data. The aim here is to load 1153 * exactly rlf + rrt columns, and in the main loop to read as many columns as 1154 * will be written. This is complicated by the need to handle cases when the 1155 * input starts very close to the left or right (or both) edges of the image, 1156 * and where these do not fall on 16-byte boundaries. 1157 * 1158 * Input: 1159 * r1 -- src 1160 * r2 -- pitch 1161 * r3 -- count 1162 * r4 -- inlen 1163 * r5 -- r 1164 * r6 -- rup 1165 * r7 -- rdn 1166 * r8 -- rlf 1167 * r9 -- buffer (if needed) 1168 * Output: 1169 * r1 += rlf + min(count, rrt) 1170 * Modifies: 1171 * r10 -- fill start index in the window 1172 * r11 -- fill stop index in the window 1173 * r12 -- scratch 1174 */ 1175 .macro prefetch step=1, max_r=25 1176 .set need, ((\max_r + \max_r) * \step + 15) & ~15 1177 .if \step == 1 1178 rsb r10, r8, #need - (\max_r * \step) 1179 .else 1180 mov r10, r8, LSL #2 1181 rsb r10, r10, #need - (\max_r * \step) 1182 .endif 1183 add r11, r10, r4 1184 cmp r11, #need 1185 movhi r11, #need 1186 1187 bl fetch_generic_asm 1188 .if \step == 1 1189 vdup.u16 q9, d20[0] 1190 .else 1191 vmov.u16 d18, d20 1192 vmov.u16 d19, d20 1193 .endif 1194 ands r12, r10, #15 1195 beq 2f 1196 sub sp, sp, #32 1197 vst1.u16 {q10,q11}, [sp] 1198 sub r12, sp, r12, LSL #1 1199 sub sp, sp, #16 1200 vst1.u16 {q9}, [sp] 1201 sub sp, sp, #16 1202 vst1.u16 {q9}, [sp] 1203 vld1.u16 {q10,q11}, [r12] 1204 add sp, sp, #64 1205 sub r1, r1, r10 1206 bic r10, r10, #15 1207 add r1, r1, r10 1208 2: 1209 .if \step > 1 1210 /* it's only in the uchar2 and uchar4 cases where the register file 1211 * is insufficient (given MAX_R <= 25). 1212 */ 1213 prefetch_one xx, xx, 192, c=\max_r, step=\step, store=1 1214 prefetch_one xx, xx, 176, c=\max_r, step=\step, store=1 1215 prefetch_one xx, xx, 160, c=\max_r, step=\step, store=1 1216 prefetch_one xx, xx, 144, c=\max_r, step=\step, store=1 1217 prefetch_one xx, xx, 128, c=\max_r, step=\step, store=1 1218 prefetch_one xx, xx, 112, c=\max_r, step=\step, store=1 1219 prefetch_one xx, xx, 96, c=\max_r, step=\step, store=1 1220 prefetch_one xx, xx, 80, c=\max_r, step=\step, store=1 1221 prefetch_one xx, xx, 64, c=\max_r, step=\step, store=1 1222 prefetch_one xx, xx, 48, c=\max_r, step=\step, store=1 1223 .else 1224 /* q3 normally contains the coefficient table, but it's not fully 1225 * used. In the uchar1, r=25 case the other half of q3 is used for 1226 * the last two window taps to avoid falling out to memory. 1227 */ 1228 prefetch_one xx, d7, 48, c=\max_r, step=\step, store=-1 1229 .endif 1230 prefetch_one q4, q5, 32, c=\max_r, step=\step, store=0 1231 prefetch_one q6, q7, 16, c=\max_r, step=\step, store=0 1232 prefetch_one q8, q9, 0, c=\max_r, step=\step, store=0 1233 1234 .if \step == 1 1235 add r10, r8, #\max_r * \step 1236 .else 1237 mov r10, r8, LSL #2 1238 add r10, r10, #\max_r * \step 1239 .endif 1240 subs r4, r4, r10 1241 movlo r4, #0 1242 .endm 1243 1244 /* The main loop. 1245 * 1246 * Input: 1247 * r0 = dst 1248 * r1 = src 1249 * r2 = pitch 1250 * r3 = count 1251 * r4 = inlen 1252 * r5 = r 1253 * r6 = rup 1254 * r7 = rdn 1255 * r9 = buffer 1256 * Modifies 1257 * r8 = fetch code pointer 1258 */ 1259 .macro mainloop core, step=1, max_r=25, labelc="", labelnc="" 1260 ldr r8, 3f 1261 1: add r8, r8, pc 1262 sub r8, r5, LSL #5 1263 sub r8, r5, LSL #4 1264 cmp r5, r6 1265 cmpeq r5, r7 1266 beq 5f 1267 1268 /* if (r != rup || r != rdn) then the address-clamping table should 1269 * be used rather than the short-cut version. 1270 */ 1271 ldr r8, 3f+4 1272 2: add r8, r8, pc 1273 sub r8, r5, LSL #6 1274 b 5f 1275 .align 3 1276 3: .word \labelnc-1b-8 1277 .word \labelc-2b-8 1278 .align 4 1279 3: fetch max_r=\max_r, labelc=\labelc, labelnc=\labelnc, reg=r8 1280 1281 /* For each call to fetch two are made to \core. It would be 1282 * preferable to have twice the work done in \core, but the 1283 * register file is too small for this to be straightforward. 1284 */ 1285 \core 1286 vst1.u8 {d31}, [r0]! 1287 \core 1288 vst1.u8 {d31}, [r0]! 1289 1290 sub r3, r3, #16 1291 5: subs r4, r4, #16 1292 bhs 3b 1293 adds r4, r4, #16 1294 bne 1f 1295 .if \step==1 1296 vdup.u16 q10, d19[3] 1297 vdup.u16 q11, d19[3] 1298 .else 1299 vmov.u64 d20, d19 1300 vmov.u64 d21, d19 1301 vmov.u64 d22, d19 1302 vmov.u64 d23, d19 1303 .endif 1304 b 4f 1305 1306 1: sub r1, r1, #16 1307 add r1, r1, r4 1308 bl fetch_generic_asm 1309 1310 .if \step==1 1311 vdup.u16 q12, d23[3] 1312 .else 1313 vmov.u64 d24, d23 1314 vmov.u64 d25, d23 1315 .endif 1316 rsb r4, r4, #0 1317 tst r4, #8 1318 beq 1f 1319 vmov q10, q11 1320 vmov q11, q12 1321 1: tst r4, #4 1322 beq 1f 1323 vext.u16 q10, q10, q11, #4 1324 vext.u16 q11, q11, q12, #4 1325 1: tst r4, #2 1326 beq 1f 1327 vext.u16 q10, q10, q11, #2 1328 vext.u16 q11, q11, q12, #2 1329 1: tst r4, #1 1330 beq 4f 1331 vext.u16 q10, q10, q11, #1 1332 vext.u16 q11, q11, q12, #1 1333 4: cmp r3, #0 1334 beq 5f 1335 3: \core 1336 .if \step==1 1337 vdup.u16 q11, d23[3] 1338 .else 1339 vmov.u64 d22, d23 1340 .endif 1341 subs r3, r3, #8 1342 blo 4f 1343 vst1.u8 {d31}, [r0]! 1344 beq 5f 1345 b 3b 1346 4: tst r3, #4 1347 beq 1f 1348 vst1.u32 {d31[0]}, [r0]! 1349 vext.u8 d31, d31, d31, #4 1350 1: tst r3, #2 1351 beq 1f 1352 vst1.u16 {d31[0]}, [r0]! 1353 vext.u8 d31, d31, d31, #2 1354 1: tst r3, #1 1355 beq 5f 1356 vst1.u8 {d31[0]}, [r0]! 1357 vext.u8 d31, d31, d31, #1 1358 5: nop 1359 .endm 1360 1361 .irep r, TUNED_LIST1, 25 1362 PRIVATE(convolve1_\r) 1363 push {r12,lr} 1364 1365 sub r1, r1, r8 1366 1367 prefetch step=1, max_r=\r 1368 1369 mainloop core=hconv1_\r, step=1, max_r=\r, labelc=.Lcnv1_\r, labelnc=.Lcnvnc1_\r 1370 1371 pop {r12,pc} 1372 END(convolve1_\r) 1373 .endr 1374 1375 .irep r, TUNED_LIST4, 25 1376 PRIVATE(convolve4_\r) 1377 sub r12, sp, #0x200 1378 bic r9, r12, #0x3fc 1379 mov sp, r9 1380 push {r12,lr} 1381 1382 /* r9 now points to a buffer on the stack whose address has the low 1383 * 10 bits clear. This allows easy address calculation in the 1384 * wrap-around cases. 1385 */ 1386 1387 sub r1, r1, r8, LSL #2 1388 1389 prefetch step=4, max_r=\r 1390 1391 mainloop core=hconv4_\r, step=4, max_r=\r, labelc=.Lcnv4_\r, labelnc=.Lcnvnc4_\r 1392 1393 pop {r12,lr} 1394 add sp, r12, #0x200 1395 bx lr 1396 END(convolve4_\r) 1397 .endr 1398 1399 /* void rsdIntrinsicBlurU1_K( 1400 * void *out, // r0 1401 * void *in, // r1 1402 * size_t w, // r2 1403 * size_t h, // r3 1404 * size_t p, // [sp] 1405 * size_t x, // [sp,#4] 1406 * size_t y, // [sp,#8] 1407 * size_t count, // [sp,#12] 1408 * size_t r, // [sp,#16] 1409 * uint16_t *tab); // [sp,#20] 1410 */ 1411 ENTRY(rsdIntrinsicBlurU1_K) 1412 push {r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} 1413 vpush {d8-d15} 1414 ldr r5, [sp,#120] 1415 ldr r8, [sp,#108] 1416 ldr r6, [sp,#112] 1417 sub r9, r2, r8 1418 sub r7, r3, r6 1419 ldr r2, [sp,#104] 1420 ldr r3, [sp,#116] 1421 sub r9, r9, r3 1422 sub r7, r7, #1 1423 1424 ldr r12, [sp,#124] 1425 1426 add r1, r1, r8 1427 1428 cmp r6, r5 1429 movhi r6, r5 1430 cmp r7, r5 1431 movhi r7, r5 1432 cmp r8, r5 1433 movhi r8, r5 1434 cmp r9, r5 1435 movhi r9, r5 1436 1437 add r4, r8, r9 1438 add r4, r4, r3 1439 1440 vld1.u16 {d0,d1,d2,d3}, [r12]! 1441 vld1.u16 {d4,d5,d6}, [r12]! 1442 1443 adr lr, 1f 1444 .irep r, TUNED_LIST1 1445 cmp r5, #\r 1446 bls convolve1_\r 1447 .endr 1448 b convolve1_25 1449 1450 1: vpop {d8-d15} 1451 pop {r4,r5,r6,r7,r8,r9,r10,r11,r12,pc} 1452 END(rsdIntrinsicBlurU1_K) 1453 1454 /* void rsdIntrinsicBlurU4_K( 1455 * void *out, // r0 1456 * void *in, // r1 1457 * size_t w, // r2 1458 * size_t h, // r3 1459 * size_t p, // [sp] 1460 * size_t x, // [sp,#4] 1461 * size_t y, // [sp,#8] 1462 * size_t count, // [sp,#12] 1463 * size_t r, // [sp,#16] 1464 * uint16_t *tab); // [sp,#20] 1465 */ 1466 ENTRY(rsdIntrinsicBlurU4_K) 1467 push {r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} 1468 vpush {d8-d15} 1469 ldr r5, [sp,#120] 1470 ldr r8, [sp,#108] 1471 ldr r6, [sp,#112] 1472 sub r9, r2, r8 1473 sub r7, r3, r6 1474 ldr r2, [sp,#104] 1475 ldr r3, [sp,#116] 1476 sub r9, r9, r3 1477 sub r7, r7, #1 1478 1479 ldr r12, [sp,#124] 1480 1481 add r1, r1, r8, LSL #2 1482 1483 cmp r6, r5 1484 movhi r6, r5 1485 cmp r7, r5 1486 movhi r7, r5 1487 cmp r8, r5 1488 movhi r8, r5 1489 cmp r9, r5 1490 movhi r9, r5 1491 1492 mov r3, r3, LSL #2 1493 add r4, r8, r9 1494 add r4, r3, r4, LSL #2 1495 1496 vld1.u16 {d0,d1,d2,d3}, [r12]! 1497 vld1.u16 {d4,d5,d6}, [r12]! 1498 1499 adr lr, 1f 1500 .irep r, TUNED_LIST4 1501 cmp r5, #\r 1502 bls convolve4_\r 1503 .endr 1504 b convolve4_25 1505 1506 1: vpop {d8-d15} 1507 pop {r4,r5,r6,r7,r8,r9,r10,r11,r12,pc} 1508 END(rsdIntrinsicBlurU4_K) 1509