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