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