1;
2;  Copyright (c) 2014 The WebM project authors. All Rights Reserved.
3;
4;  Use of this source code is governed by a BSD-style license
5;  that can be found in the LICENSE file in the root of the source
6;  tree. An additional intellectual property rights grant can be found
7;  in the file PATENTS.  All contributing project authors may
8;  be found in the AUTHORS file in the root of the source tree.
9;
10
11    EXPORT  |vp9_v_predictor_4x4_neon|
12    EXPORT  |vp9_v_predictor_8x8_neon|
13    EXPORT  |vp9_v_predictor_16x16_neon|
14    EXPORT  |vp9_v_predictor_32x32_neon|
15    EXPORT  |vp9_h_predictor_4x4_neon|
16    EXPORT  |vp9_h_predictor_8x8_neon|
17    EXPORT  |vp9_h_predictor_16x16_neon|
18    EXPORT  |vp9_h_predictor_32x32_neon|
19    EXPORT  |vp9_tm_predictor_4x4_neon|
20    EXPORT  |vp9_tm_predictor_8x8_neon|
21    EXPORT  |vp9_tm_predictor_16x16_neon|
22    EXPORT  |vp9_tm_predictor_32x32_neon|
23    ARM
24    REQUIRE8
25    PRESERVE8
26
27    AREA ||.text||, CODE, READONLY, ALIGN=2
28
29;void vp9_v_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride,
30;                              const uint8_t *above,
31;                              const uint8_t *left)
32; r0  uint8_t *dst
33; r1  ptrdiff_t y_stride
34; r2  const uint8_t *above
35; r3  const uint8_t *left
36
37|vp9_v_predictor_4x4_neon| PROC
38    vld1.32             {d0[0]}, [r2]
39    vst1.32             {d0[0]}, [r0], r1
40    vst1.32             {d0[0]}, [r0], r1
41    vst1.32             {d0[0]}, [r0], r1
42    vst1.32             {d0[0]}, [r0], r1
43    bx                  lr
44    ENDP                ; |vp9_v_predictor_4x4_neon|
45
46;void vp9_v_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride,
47;                              const uint8_t *above,
48;                              const uint8_t *left)
49; r0  uint8_t *dst
50; r1  ptrdiff_t y_stride
51; r2  const uint8_t *above
52; r3  const uint8_t *left
53
54|vp9_v_predictor_8x8_neon| PROC
55    vld1.8              {d0}, [r2]
56    vst1.8              {d0}, [r0], r1
57    vst1.8              {d0}, [r0], r1
58    vst1.8              {d0}, [r0], r1
59    vst1.8              {d0}, [r0], r1
60    vst1.8              {d0}, [r0], r1
61    vst1.8              {d0}, [r0], r1
62    vst1.8              {d0}, [r0], r1
63    vst1.8              {d0}, [r0], r1
64    bx                  lr
65    ENDP                ; |vp9_v_predictor_8x8_neon|
66
67;void vp9_v_predictor_16x16_neon(uint8_t *dst, ptrdiff_t y_stride,
68;                                const uint8_t *above,
69;                                const uint8_t *left)
70; r0  uint8_t *dst
71; r1  ptrdiff_t y_stride
72; r2  const uint8_t *above
73; r3  const uint8_t *left
74
75|vp9_v_predictor_16x16_neon| PROC
76    vld1.8              {q0}, [r2]
77    vst1.8              {q0}, [r0], r1
78    vst1.8              {q0}, [r0], r1
79    vst1.8              {q0}, [r0], r1
80    vst1.8              {q0}, [r0], r1
81    vst1.8              {q0}, [r0], r1
82    vst1.8              {q0}, [r0], r1
83    vst1.8              {q0}, [r0], r1
84    vst1.8              {q0}, [r0], r1
85    vst1.8              {q0}, [r0], r1
86    vst1.8              {q0}, [r0], r1
87    vst1.8              {q0}, [r0], r1
88    vst1.8              {q0}, [r0], r1
89    vst1.8              {q0}, [r0], r1
90    vst1.8              {q0}, [r0], r1
91    vst1.8              {q0}, [r0], r1
92    vst1.8              {q0}, [r0], r1
93    bx                  lr
94    ENDP                ; |vp9_v_predictor_16x16_neon|
95
96;void vp9_v_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride,
97;                                const uint8_t *above,
98;                                const uint8_t *left)
99; r0  uint8_t *dst
100; r1  ptrdiff_t y_stride
101; r2  const uint8_t *above
102; r3  const uint8_t *left
103
104|vp9_v_predictor_32x32_neon| PROC
105    vld1.8              {q0, q1}, [r2]
106    mov                 r2, #2
107loop_v
108    vst1.8              {q0, q1}, [r0], r1
109    vst1.8              {q0, q1}, [r0], r1
110    vst1.8              {q0, q1}, [r0], r1
111    vst1.8              {q0, q1}, [r0], r1
112    vst1.8              {q0, q1}, [r0], r1
113    vst1.8              {q0, q1}, [r0], r1
114    vst1.8              {q0, q1}, [r0], r1
115    vst1.8              {q0, q1}, [r0], r1
116    vst1.8              {q0, q1}, [r0], r1
117    vst1.8              {q0, q1}, [r0], r1
118    vst1.8              {q0, q1}, [r0], r1
119    vst1.8              {q0, q1}, [r0], r1
120    vst1.8              {q0, q1}, [r0], r1
121    vst1.8              {q0, q1}, [r0], r1
122    vst1.8              {q0, q1}, [r0], r1
123    vst1.8              {q0, q1}, [r0], r1
124    subs                r2, r2, #1
125    bgt                 loop_v
126    bx                  lr
127    ENDP                ; |vp9_v_predictor_32x32_neon|
128
129;void vp9_h_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride,
130;                              const uint8_t *above,
131;                              const uint8_t *left)
132; r0  uint8_t *dst
133; r1  ptrdiff_t y_stride
134; r2  const uint8_t *above
135; r3  const uint8_t *left
136
137|vp9_h_predictor_4x4_neon| PROC
138    vld1.32             {d1[0]}, [r3]
139    vdup.8              d0, d1[0]
140    vst1.32             {d0[0]}, [r0], r1
141    vdup.8              d0, d1[1]
142    vst1.32             {d0[0]}, [r0], r1
143    vdup.8              d0, d1[2]
144    vst1.32             {d0[0]}, [r0], r1
145    vdup.8              d0, d1[3]
146    vst1.32             {d0[0]}, [r0], r1
147    bx                  lr
148    ENDP                ; |vp9_h_predictor_4x4_neon|
149
150;void vp9_h_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride,
151;                              const uint8_t *above,
152;                              const uint8_t *left)
153; r0  uint8_t *dst
154; r1  ptrdiff_t y_stride
155; r2  const uint8_t *above
156; r3  const uint8_t *left
157
158|vp9_h_predictor_8x8_neon| PROC
159    vld1.64             {d1}, [r3]
160    vdup.8              d0, d1[0]
161    vst1.64             {d0}, [r0], r1
162    vdup.8              d0, d1[1]
163    vst1.64             {d0}, [r0], r1
164    vdup.8              d0, d1[2]
165    vst1.64             {d0}, [r0], r1
166    vdup.8              d0, d1[3]
167    vst1.64             {d0}, [r0], r1
168    vdup.8              d0, d1[4]
169    vst1.64             {d0}, [r0], r1
170    vdup.8              d0, d1[5]
171    vst1.64             {d0}, [r0], r1
172    vdup.8              d0, d1[6]
173    vst1.64             {d0}, [r0], r1
174    vdup.8              d0, d1[7]
175    vst1.64             {d0}, [r0], r1
176    bx                  lr
177    ENDP                ; |vp9_h_predictor_8x8_neon|
178
179;void vp9_h_predictor_16x16_neon(uint8_t *dst, ptrdiff_t y_stride,
180;                                const uint8_t *above,
181;                                const uint8_t *left)
182; r0  uint8_t *dst
183; r1  ptrdiff_t y_stride
184; r2  const uint8_t *above
185; r3  const uint8_t *left
186
187|vp9_h_predictor_16x16_neon| PROC
188    vld1.8              {q1}, [r3]
189    vdup.8              q0, d2[0]
190    vst1.8              {q0}, [r0], r1
191    vdup.8              q0, d2[1]
192    vst1.8              {q0}, [r0], r1
193    vdup.8              q0, d2[2]
194    vst1.8              {q0}, [r0], r1
195    vdup.8              q0, d2[3]
196    vst1.8              {q0}, [r0], r1
197    vdup.8              q0, d2[4]
198    vst1.8              {q0}, [r0], r1
199    vdup.8              q0, d2[5]
200    vst1.8              {q0}, [r0], r1
201    vdup.8              q0, d2[6]
202    vst1.8              {q0}, [r0], r1
203    vdup.8              q0, d2[7]
204    vst1.8              {q0}, [r0], r1
205    vdup.8              q0, d3[0]
206    vst1.8              {q0}, [r0], r1
207    vdup.8              q0, d3[1]
208    vst1.8              {q0}, [r0], r1
209    vdup.8              q0, d3[2]
210    vst1.8              {q0}, [r0], r1
211    vdup.8              q0, d3[3]
212    vst1.8              {q0}, [r0], r1
213    vdup.8              q0, d3[4]
214    vst1.8              {q0}, [r0], r1
215    vdup.8              q0, d3[5]
216    vst1.8              {q0}, [r0], r1
217    vdup.8              q0, d3[6]
218    vst1.8              {q0}, [r0], r1
219    vdup.8              q0, d3[7]
220    vst1.8              {q0}, [r0], r1
221    bx                  lr
222    ENDP                ; |vp9_h_predictor_16x16_neon|
223
224;void vp9_h_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride,
225;                                const uint8_t *above,
226;                                const uint8_t *left)
227; r0  uint8_t *dst
228; r1  ptrdiff_t y_stride
229; r2  const uint8_t *above
230; r3  const uint8_t *left
231
232|vp9_h_predictor_32x32_neon| PROC
233    sub                 r1, r1, #16
234    mov                 r2, #2
235loop_h
236    vld1.8              {q1}, [r3]!
237    vdup.8              q0, d2[0]
238    vst1.8              {q0}, [r0]!
239    vst1.8              {q0}, [r0], r1
240    vdup.8              q0, d2[1]
241    vst1.8              {q0}, [r0]!
242    vst1.8              {q0}, [r0], r1
243    vdup.8              q0, d2[2]
244    vst1.8              {q0}, [r0]!
245    vst1.8              {q0}, [r0], r1
246    vdup.8              q0, d2[3]
247    vst1.8              {q0}, [r0]!
248    vst1.8              {q0}, [r0], r1
249    vdup.8              q0, d2[4]
250    vst1.8              {q0}, [r0]!
251    vst1.8              {q0}, [r0], r1
252    vdup.8              q0, d2[5]
253    vst1.8              {q0}, [r0]!
254    vst1.8              {q0}, [r0], r1
255    vdup.8              q0, d2[6]
256    vst1.8              {q0}, [r0]!
257    vst1.8              {q0}, [r0], r1
258    vdup.8              q0, d2[7]
259    vst1.8              {q0}, [r0]!
260    vst1.8              {q0}, [r0], r1
261    vdup.8              q0, d3[0]
262    vst1.8              {q0}, [r0]!
263    vst1.8              {q0}, [r0], r1
264    vdup.8              q0, d3[1]
265    vst1.8              {q0}, [r0]!
266    vst1.8              {q0}, [r0], r1
267    vdup.8              q0, d3[2]
268    vst1.8              {q0}, [r0]!
269    vst1.8              {q0}, [r0], r1
270    vdup.8              q0, d3[3]
271    vst1.8              {q0}, [r0]!
272    vst1.8              {q0}, [r0], r1
273    vdup.8              q0, d3[4]
274    vst1.8              {q0}, [r0]!
275    vst1.8              {q0}, [r0], r1
276    vdup.8              q0, d3[5]
277    vst1.8              {q0}, [r0]!
278    vst1.8              {q0}, [r0], r1
279    vdup.8              q0, d3[6]
280    vst1.8              {q0}, [r0]!
281    vst1.8              {q0}, [r0], r1
282    vdup.8              q0, d3[7]
283    vst1.8              {q0}, [r0]!
284    vst1.8              {q0}, [r0], r1
285    subs                r2, r2, #1
286    bgt                 loop_h
287    bx                  lr
288    ENDP                ; |vp9_h_predictor_32x32_neon|
289
290;void vp9_tm_predictor_4x4_neon (uint8_t *dst, ptrdiff_t y_stride,
291;                                const uint8_t *above,
292;                                const uint8_t *left)
293; r0  uint8_t *dst
294; r1  ptrdiff_t y_stride
295; r2  const uint8_t *above
296; r3  const uint8_t *left
297
298|vp9_tm_predictor_4x4_neon| PROC
299    ; Load ytop_left = above[-1];
300    sub                 r12, r2, #1
301    ldrb                r12, [r12]
302    vdup.u8             d0, r12
303
304    ; Load above 4 pixels
305    vld1.32             {d2[0]}, [r2]
306
307    ; Compute above - ytop_left
308    vsubl.u8            q3, d2, d0
309
310    ; Load left row by row and compute left + (above - ytop_left)
311    ; 1st row and 2nd row
312    ldrb                r12, [r3], #1
313    ldrb                r2, [r3], #1
314    vdup.u16            q1, r12
315    vdup.u16            q2, r2
316    vadd.s16            q1, q1, q3
317    vadd.s16            q2, q2, q3
318    vqmovun.s16         d0, q1
319    vqmovun.s16         d1, q2
320    vst1.32             {d0[0]}, [r0], r1
321    vst1.32             {d1[0]}, [r0], r1
322
323    ; 3rd row and 4th row
324    ldrb                r12, [r3], #1
325    ldrb                r2, [r3], #1
326    vdup.u16            q1, r12
327    vdup.u16            q2, r2
328    vadd.s16            q1, q1, q3
329    vadd.s16            q2, q2, q3
330    vqmovun.s16         d0, q1
331    vqmovun.s16         d1, q2
332    vst1.32             {d0[0]}, [r0], r1
333    vst1.32             {d1[0]}, [r0], r1
334    bx                  lr
335    ENDP                ; |vp9_tm_predictor_4x4_neon|
336
337;void vp9_tm_predictor_8x8_neon (uint8_t *dst, ptrdiff_t y_stride,
338;                                const uint8_t *above,
339;                                const uint8_t *left)
340; r0  uint8_t *dst
341; r1  ptrdiff_t y_stride
342; r2  const uint8_t *above
343; r3  const uint8_t *left
344
345|vp9_tm_predictor_8x8_neon| PROC
346    ; Load ytop_left = above[-1];
347    sub                 r12, r2, #1
348    ldrb                r12, [r12]
349    vdup.u8             d0, r12
350
351    ; preload 8 left
352    vld1.8              {d30}, [r3]
353
354    ; Load above 8 pixels
355    vld1.64             {d2}, [r2]
356
357    vmovl.u8            q10, d30
358
359    ; Compute above - ytop_left
360    vsubl.u8            q3, d2, d0
361
362    ; Load left row by row and compute left + (above - ytop_left)
363    ; 1st row and 2nd row
364    vdup.16             q0, d20[0]
365    vdup.16             q1, d20[1]
366    vadd.s16            q0, q3, q0
367    vadd.s16            q1, q3, q1
368
369    ; 3rd row and 4th row
370    vdup.16             q8, d20[2]
371    vdup.16             q9, d20[3]
372    vadd.s16            q8, q3, q8
373    vadd.s16            q9, q3, q9
374
375    vqmovun.s16         d0, q0
376    vqmovun.s16         d1, q1
377    vqmovun.s16         d2, q8
378    vqmovun.s16         d3, q9
379
380    vst1.64             {d0}, [r0], r1
381    vst1.64             {d1}, [r0], r1
382    vst1.64             {d2}, [r0], r1
383    vst1.64             {d3}, [r0], r1
384
385    ; 5th row and 6th row
386    vdup.16             q0, d21[0]
387    vdup.16             q1, d21[1]
388    vadd.s16            q0, q3, q0
389    vadd.s16            q1, q3, q1
390
391    ; 7th row and 8th row
392    vdup.16             q8, d21[2]
393    vdup.16             q9, d21[3]
394    vadd.s16            q8, q3, q8
395    vadd.s16            q9, q3, q9
396
397    vqmovun.s16         d0, q0
398    vqmovun.s16         d1, q1
399    vqmovun.s16         d2, q8
400    vqmovun.s16         d3, q9
401
402    vst1.64             {d0}, [r0], r1
403    vst1.64             {d1}, [r0], r1
404    vst1.64             {d2}, [r0], r1
405    vst1.64             {d3}, [r0], r1
406
407    bx                  lr
408    ENDP                ; |vp9_tm_predictor_8x8_neon|
409
410;void vp9_tm_predictor_16x16_neon (uint8_t *dst, ptrdiff_t y_stride,
411;                                const uint8_t *above,
412;                                const uint8_t *left)
413; r0  uint8_t *dst
414; r1  ptrdiff_t y_stride
415; r2  const uint8_t *above
416; r3  const uint8_t *left
417
418|vp9_tm_predictor_16x16_neon| PROC
419    ; Load ytop_left = above[-1];
420    sub                 r12, r2, #1
421    ldrb                r12, [r12]
422    vdup.u8             q0, r12
423
424    ; Load above 8 pixels
425    vld1.8              {q1}, [r2]
426
427    ; preload 8 left into r12
428    vld1.8              {d18}, [r3]!
429
430    ; Compute above - ytop_left
431    vsubl.u8            q2, d2, d0
432    vsubl.u8            q3, d3, d1
433
434    vmovl.u8            q10, d18
435
436    ; Load left row by row and compute left + (above - ytop_left)
437    ; Process 8 rows in each single loop and loop 2 times to process 16 rows.
438    mov                 r2, #2
439
440loop_16x16_neon
441    ; Process two rows.
442    vdup.16             q0, d20[0]
443    vdup.16             q8, d20[1]
444    vadd.s16            q1, q0, q2
445    vadd.s16            q0, q0, q3
446    vadd.s16            q11, q8, q2
447    vadd.s16            q8, q8, q3
448    vqmovun.s16         d2, q1
449    vqmovun.s16         d3, q0
450    vqmovun.s16         d22, q11
451    vqmovun.s16         d23, q8
452    vdup.16             q0, d20[2]                  ; proload next 2 rows data
453    vdup.16             q8, d20[3]
454    vst1.64             {d2,d3}, [r0], r1
455    vst1.64             {d22,d23}, [r0], r1
456
457    ; Process two rows.
458    vadd.s16            q1, q0, q2
459    vadd.s16            q0, q0, q3
460    vadd.s16            q11, q8, q2
461    vadd.s16            q8, q8, q3
462    vqmovun.s16         d2, q1
463    vqmovun.s16         d3, q0
464    vqmovun.s16         d22, q11
465    vqmovun.s16         d23, q8
466    vdup.16             q0, d21[0]                  ; proload next 2 rows data
467    vdup.16             q8, d21[1]
468    vst1.64             {d2,d3}, [r0], r1
469    vst1.64             {d22,d23}, [r0], r1
470
471    vadd.s16            q1, q0, q2
472    vadd.s16            q0, q0, q3
473    vadd.s16            q11, q8, q2
474    vadd.s16            q8, q8, q3
475    vqmovun.s16         d2, q1
476    vqmovun.s16         d3, q0
477    vqmovun.s16         d22, q11
478    vqmovun.s16         d23, q8
479    vdup.16             q0, d21[2]                  ; proload next 2 rows data
480    vdup.16             q8, d21[3]
481    vst1.64             {d2,d3}, [r0], r1
482    vst1.64             {d22,d23}, [r0], r1
483
484
485    vadd.s16            q1, q0, q2
486    vadd.s16            q0, q0, q3
487    vadd.s16            q11, q8, q2
488    vadd.s16            q8, q8, q3
489    vqmovun.s16         d2, q1
490    vqmovun.s16         d3, q0
491    vqmovun.s16         d22, q11
492    vqmovun.s16         d23, q8
493    vld1.8              {d18}, [r3]!                  ; preload 8 left into r12
494    vmovl.u8            q10, d18
495    vst1.64             {d2,d3}, [r0], r1
496    vst1.64             {d22,d23}, [r0], r1
497
498    subs                r2, r2, #1
499    bgt                 loop_16x16_neon
500
501    bx                  lr
502    ENDP                ; |vp9_tm_predictor_16x16_neon|
503
504;void vp9_tm_predictor_32x32_neon (uint8_t *dst, ptrdiff_t y_stride,
505;                                  const uint8_t *above,
506;                                  const uint8_t *left)
507; r0  uint8_t *dst
508; r1  ptrdiff_t y_stride
509; r2  const uint8_t *above
510; r3  const uint8_t *left
511
512|vp9_tm_predictor_32x32_neon| PROC
513    ; Load ytop_left = above[-1];
514    sub                 r12, r2, #1
515    ldrb                r12, [r12]
516    vdup.u8             q0, r12
517
518    ; Load above 32 pixels
519    vld1.8              {q1}, [r2]!
520    vld1.8              {q2}, [r2]
521
522    ; preload 8 left pixels
523    vld1.8              {d26}, [r3]!
524
525    ; Compute above - ytop_left
526    vsubl.u8            q8, d2, d0
527    vsubl.u8            q9, d3, d1
528    vsubl.u8            q10, d4, d0
529    vsubl.u8            q11, d5, d1
530
531    vmovl.u8            q3, d26
532
533    ; Load left row by row and compute left + (above - ytop_left)
534    ; Process 8 rows in each single loop and loop 4 times to process 32 rows.
535    mov                 r2, #4
536
537loop_32x32_neon
538    ; Process two rows.
539    vdup.16             q0, d6[0]
540    vdup.16             q2, d6[1]
541    vadd.s16            q12, q0, q8
542    vadd.s16            q13, q0, q9
543    vadd.s16            q14, q0, q10
544    vadd.s16            q15, q0, q11
545    vqmovun.s16         d0, q12
546    vqmovun.s16         d1, q13
547    vadd.s16            q12, q2, q8
548    vadd.s16            q13, q2, q9
549    vqmovun.s16         d2, q14
550    vqmovun.s16         d3, q15
551    vadd.s16            q14, q2, q10
552    vadd.s16            q15, q2, q11
553    vst1.64             {d0-d3}, [r0], r1
554    vqmovun.s16         d24, q12
555    vqmovun.s16         d25, q13
556    vqmovun.s16         d26, q14
557    vqmovun.s16         d27, q15
558    vdup.16             q1, d6[2]
559    vdup.16             q2, d6[3]
560    vst1.64             {d24-d27}, [r0], r1
561
562    ; Process two rows.
563    vadd.s16            q12, q1, q8
564    vadd.s16            q13, q1, q9
565    vadd.s16            q14, q1, q10
566    vadd.s16            q15, q1, q11
567    vqmovun.s16         d0, q12
568    vqmovun.s16         d1, q13
569    vadd.s16            q12, q2, q8
570    vadd.s16            q13, q2, q9
571    vqmovun.s16         d2, q14
572    vqmovun.s16         d3, q15
573    vadd.s16            q14, q2, q10
574    vadd.s16            q15, q2, q11
575    vst1.64             {d0-d3}, [r0], r1
576    vqmovun.s16         d24, q12
577    vqmovun.s16         d25, q13
578    vqmovun.s16         d26, q14
579    vqmovun.s16         d27, q15
580    vdup.16             q0, d7[0]
581    vdup.16             q2, d7[1]
582    vst1.64             {d24-d27}, [r0], r1
583
584    ; Process two rows.
585    vadd.s16            q12, q0, q8
586    vadd.s16            q13, q0, q9
587    vadd.s16            q14, q0, q10
588    vadd.s16            q15, q0, q11
589    vqmovun.s16         d0, q12
590    vqmovun.s16         d1, q13
591    vadd.s16            q12, q2, q8
592    vadd.s16            q13, q2, q9
593    vqmovun.s16         d2, q14
594    vqmovun.s16         d3, q15
595    vadd.s16            q14, q2, q10
596    vadd.s16            q15, q2, q11
597    vst1.64             {d0-d3}, [r0], r1
598    vqmovun.s16         d24, q12
599    vqmovun.s16         d25, q13
600    vqmovun.s16         d26, q14
601    vqmovun.s16         d27, q15
602    vdup.16             q0, d7[2]
603    vdup.16             q2, d7[3]
604    vst1.64             {d24-d27}, [r0], r1
605
606    ; Process two rows.
607    vadd.s16            q12, q0, q8
608    vadd.s16            q13, q0, q9
609    vadd.s16            q14, q0, q10
610    vadd.s16            q15, q0, q11
611    vqmovun.s16         d0, q12
612    vqmovun.s16         d1, q13
613    vadd.s16            q12, q2, q8
614    vadd.s16            q13, q2, q9
615    vqmovun.s16         d2, q14
616    vqmovun.s16         d3, q15
617    vadd.s16            q14, q2, q10
618    vadd.s16            q15, q2, q11
619    vst1.64             {d0-d3}, [r0], r1
620    vqmovun.s16         d24, q12
621    vqmovun.s16         d25, q13
622    vld1.8              {d0}, [r3]!                   ; preload 8 left pixels
623    vqmovun.s16         d26, q14
624    vqmovun.s16         d27, q15
625    vmovl.u8            q3, d0
626    vst1.64             {d24-d27}, [r0], r1
627
628    subs                r2, r2, #1
629    bgt                 loop_32x32_neon
630
631    bx                  lr
632    ENDP                ; |vp9_tm_predictor_32x32_neon|
633
634    END
635