Home | History | Annotate | Download | only in cpu_ref
      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