xref: /aosp_15_r20/external/libvpx/vpx_dsp/arm/intrapred_neon_asm.asm (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
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  |vpx_v_predictor_4x4_neon|
12    EXPORT  |vpx_v_predictor_8x8_neon|
13    EXPORT  |vpx_v_predictor_16x16_neon|
14    EXPORT  |vpx_v_predictor_32x32_neon|
15    EXPORT  |vpx_h_predictor_4x4_neon|
16    EXPORT  |vpx_h_predictor_8x8_neon|
17    EXPORT  |vpx_h_predictor_16x16_neon|
18    EXPORT  |vpx_h_predictor_32x32_neon|
19    EXPORT  |vpx_tm_predictor_4x4_neon|
20    EXPORT  |vpx_tm_predictor_8x8_neon|
21    EXPORT  |vpx_tm_predictor_16x16_neon|
22    EXPORT  |vpx_tm_predictor_32x32_neon|
23    ARM
24    REQUIRE8
25    PRESERVE8
26
27    AREA ||.text||, CODE, READONLY, ALIGN=2
28
29;void vpx_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|vpx_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                ; |vpx_v_predictor_4x4_neon|
45
46;void vpx_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|vpx_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                ; |vpx_v_predictor_8x8_neon|
66
67;void vpx_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|vpx_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                ; |vpx_v_predictor_16x16_neon|
95
96;void vpx_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|vpx_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                ; |vpx_v_predictor_32x32_neon|
128
129;void vpx_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|vpx_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                ; |vpx_h_predictor_4x4_neon|
149
150;void vpx_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|vpx_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                ; |vpx_h_predictor_8x8_neon|
178
179;void vpx_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|vpx_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                ; |vpx_h_predictor_16x16_neon|
223
224;void vpx_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|vpx_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                ; |vpx_h_predictor_32x32_neon|
289
290;void vpx_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|vpx_tm_predictor_4x4_neon| PROC
299    ; Load ytop_left = above[-1];
300    sub                 r12, r2, #1
301    vld1.u8             {d0[]}, [r12]
302
303    ; Load above 4 pixels
304    vld1.32             {d2[0]}, [r2]
305
306    ; Compute above - ytop_left
307    vsubl.u8            q3, d2, d0
308
309    ; Load left row by row and compute left + (above - ytop_left)
310    ; 1st row and 2nd row
311    vld1.u8             {d2[]}, [r3]!
312    vld1.u8             {d4[]}, [r3]!
313    vmovl.u8            q1, d2
314    vmovl.u8            q2, d4
315    vadd.s16            q1, q1, q3
316    vadd.s16            q2, q2, q3
317    vqmovun.s16         d0, q1
318    vqmovun.s16         d1, q2
319    vst1.32             {d0[0]}, [r0], r1
320    vst1.32             {d1[0]}, [r0], r1
321
322    ; 3rd row and 4th row
323    vld1.u8             {d2[]}, [r3]!
324    vld1.u8             {d4[]}, [r3]
325    vmovl.u8            q1, d2
326    vmovl.u8            q2, d4
327    vadd.s16            q1, q1, q3
328    vadd.s16            q2, q2, q3
329    vqmovun.s16         d0, q1
330    vqmovun.s16         d1, q2
331    vst1.32             {d0[0]}, [r0], r1
332    vst1.32             {d1[0]}, [r0], r1
333    bx                  lr
334    ENDP                ; |vpx_tm_predictor_4x4_neon|
335
336;void vpx_tm_predictor_8x8_neon (uint8_t *dst, ptrdiff_t y_stride,
337;                                const uint8_t *above,
338;                                const uint8_t *left)
339; r0  uint8_t *dst
340; r1  ptrdiff_t y_stride
341; r2  const uint8_t *above
342; r3  const uint8_t *left
343
344|vpx_tm_predictor_8x8_neon| PROC
345    ; Load ytop_left = above[-1];
346    sub                 r12, r2, #1
347    vld1.8              {d0[]}, [r12]
348
349    ; preload 8 left
350    vld1.8              {d30}, [r3]
351
352    ; Load above 8 pixels
353    vld1.64             {d2}, [r2]
354
355    vmovl.u8            q10, d30
356
357    ; Compute above - ytop_left
358    vsubl.u8            q3, d2, d0
359
360    ; Load left row by row and compute left + (above - ytop_left)
361    ; 1st row and 2nd row
362    vdup.16             q0, d20[0]
363    vdup.16             q1, d20[1]
364    vadd.s16            q0, q3, q0
365    vadd.s16            q1, q3, q1
366
367    ; 3rd row and 4th row
368    vdup.16             q8, d20[2]
369    vdup.16             q9, d20[3]
370    vadd.s16            q8, q3, q8
371    vadd.s16            q9, q3, q9
372
373    vqmovun.s16         d0, q0
374    vqmovun.s16         d1, q1
375    vqmovun.s16         d2, q8
376    vqmovun.s16         d3, q9
377
378    vst1.64             {d0}, [r0], r1
379    vst1.64             {d1}, [r0], r1
380    vst1.64             {d2}, [r0], r1
381    vst1.64             {d3}, [r0], r1
382
383    ; 5th row and 6th row
384    vdup.16             q0, d21[0]
385    vdup.16             q1, d21[1]
386    vadd.s16            q0, q3, q0
387    vadd.s16            q1, q3, q1
388
389    ; 7th row and 8th row
390    vdup.16             q8, d21[2]
391    vdup.16             q9, d21[3]
392    vadd.s16            q8, q3, q8
393    vadd.s16            q9, q3, q9
394
395    vqmovun.s16         d0, q0
396    vqmovun.s16         d1, q1
397    vqmovun.s16         d2, q8
398    vqmovun.s16         d3, q9
399
400    vst1.64             {d0}, [r0], r1
401    vst1.64             {d1}, [r0], r1
402    vst1.64             {d2}, [r0], r1
403    vst1.64             {d3}, [r0], r1
404
405    bx                  lr
406    ENDP                ; |vpx_tm_predictor_8x8_neon|
407
408;void vpx_tm_predictor_16x16_neon (uint8_t *dst, ptrdiff_t y_stride,
409;                                const uint8_t *above,
410;                                const uint8_t *left)
411; r0  uint8_t *dst
412; r1  ptrdiff_t y_stride
413; r2  const uint8_t *above
414; r3  const uint8_t *left
415
416|vpx_tm_predictor_16x16_neon| PROC
417    ; Load ytop_left = above[-1];
418    sub                 r12, r2, #1
419    vld1.8              {d0[]}, [r12]
420
421    ; Load above 8 pixels
422    vld1.8              {q1}, [r2]
423
424    ; preload 8 left into r12
425    vld1.8              {d18}, [r3]!
426
427    ; Compute above - ytop_left
428    vsubl.u8            q2, d2, d0
429    vsubl.u8            q3, d3, d0
430
431    vmovl.u8            q10, d18
432
433    ; Load left row by row and compute left + (above - ytop_left)
434    ; Process 8 rows in each single loop and loop 2 times to process 16 rows.
435    mov                 r2, #2
436
437loop_16x16_neon
438    ; Process two rows.
439    vdup.16             q0, d20[0]
440    vdup.16             q8, d20[1]
441    vadd.s16            q1, q0, q2
442    vadd.s16            q0, q0, q3
443    vadd.s16            q11, q8, q2
444    vadd.s16            q8, q8, q3
445    vqmovun.s16         d2, q1
446    vqmovun.s16         d3, q0
447    vqmovun.s16         d22, q11
448    vqmovun.s16         d23, q8
449    vdup.16             q0, d20[2]                  ; proload next 2 rows data
450    vdup.16             q8, d20[3]
451    vst1.64             {d2,d3}, [r0], r1
452    vst1.64             {d22,d23}, [r0], r1
453
454    ; Process two rows.
455    vadd.s16            q1, q0, q2
456    vadd.s16            q0, q0, q3
457    vadd.s16            q11, q8, q2
458    vadd.s16            q8, q8, q3
459    vqmovun.s16         d2, q1
460    vqmovun.s16         d3, q0
461    vqmovun.s16         d22, q11
462    vqmovun.s16         d23, q8
463    vdup.16             q0, d21[0]                  ; proload next 2 rows data
464    vdup.16             q8, d21[1]
465    vst1.64             {d2,d3}, [r0], r1
466    vst1.64             {d22,d23}, [r0], r1
467
468    vadd.s16            q1, q0, q2
469    vadd.s16            q0, q0, q3
470    vadd.s16            q11, q8, q2
471    vadd.s16            q8, q8, q3
472    vqmovun.s16         d2, q1
473    vqmovun.s16         d3, q0
474    vqmovun.s16         d22, q11
475    vqmovun.s16         d23, q8
476    vdup.16             q0, d21[2]                  ; proload next 2 rows data
477    vdup.16             q8, d21[3]
478    vst1.64             {d2,d3}, [r0], r1
479    vst1.64             {d22,d23}, [r0], r1
480
481
482    vadd.s16            q1, q0, q2
483    vadd.s16            q0, q0, q3
484    vadd.s16            q11, q8, q2
485    vadd.s16            q8, q8, q3
486    vqmovun.s16         d2, q1
487    vqmovun.s16         d3, q0
488    vqmovun.s16         d22, q11
489    vqmovun.s16         d23, q8
490    vld1.8              {d18}, [r3]!                  ; preload 8 left into r12
491    vmovl.u8            q10, d18
492    vst1.64             {d2,d3}, [r0], r1
493    vst1.64             {d22,d23}, [r0], r1
494
495    subs                r2, r2, #1
496    bgt                 loop_16x16_neon
497
498    bx                  lr
499    ENDP                ; |vpx_tm_predictor_16x16_neon|
500
501;void vpx_tm_predictor_32x32_neon (uint8_t *dst, ptrdiff_t y_stride,
502;                                  const uint8_t *above,
503;                                  const uint8_t *left)
504; r0  uint8_t *dst
505; r1  ptrdiff_t y_stride
506; r2  const uint8_t *above
507; r3  const uint8_t *left
508
509|vpx_tm_predictor_32x32_neon| PROC
510    ; Load ytop_left = above[-1];
511    sub                 r12, r2, #1
512    vld1.8              {d0[]}, [r12]
513
514    ; Load above 32 pixels
515    vld1.8              {q1}, [r2]!
516    vld1.8              {q2}, [r2]
517
518    ; preload 8 left pixels
519    vld1.8              {d26}, [r3]!
520
521    ; Compute above - ytop_left
522    vsubl.u8            q8, d2, d0
523    vsubl.u8            q9, d3, d0
524    vsubl.u8            q10, d4, d0
525    vsubl.u8            q11, d5, d0
526
527    vmovl.u8            q3, d26
528
529    ; Load left row by row and compute left + (above - ytop_left)
530    ; Process 8 rows in each single loop and loop 4 times to process 32 rows.
531    mov                 r2, #4
532
533loop_32x32_neon
534    ; Process two rows.
535    vdup.16             q0, d6[0]
536    vdup.16             q2, d6[1]
537    vadd.s16            q12, q0, q8
538    vadd.s16            q13, q0, q9
539    vadd.s16            q14, q0, q10
540    vadd.s16            q15, q0, q11
541    vqmovun.s16         d0, q12
542    vqmovun.s16         d1, q13
543    vadd.s16            q12, q2, q8
544    vadd.s16            q13, q2, q9
545    vqmovun.s16         d2, q14
546    vqmovun.s16         d3, q15
547    vadd.s16            q14, q2, q10
548    vadd.s16            q15, q2, q11
549    vst1.64             {d0-d3}, [r0], r1
550    vqmovun.s16         d24, q12
551    vqmovun.s16         d25, q13
552    vqmovun.s16         d26, q14
553    vqmovun.s16         d27, q15
554    vdup.16             q1, d6[2]
555    vdup.16             q2, d6[3]
556    vst1.64             {d24-d27}, [r0], r1
557
558    ; Process two rows.
559    vadd.s16            q12, q1, q8
560    vadd.s16            q13, q1, q9
561    vadd.s16            q14, q1, q10
562    vadd.s16            q15, q1, q11
563    vqmovun.s16         d0, q12
564    vqmovun.s16         d1, q13
565    vadd.s16            q12, q2, q8
566    vadd.s16            q13, q2, q9
567    vqmovun.s16         d2, q14
568    vqmovun.s16         d3, q15
569    vadd.s16            q14, q2, q10
570    vadd.s16            q15, q2, q11
571    vst1.64             {d0-d3}, [r0], r1
572    vqmovun.s16         d24, q12
573    vqmovun.s16         d25, q13
574    vqmovun.s16         d26, q14
575    vqmovun.s16         d27, q15
576    vdup.16             q0, d7[0]
577    vdup.16             q2, d7[1]
578    vst1.64             {d24-d27}, [r0], r1
579
580    ; Process two rows.
581    vadd.s16            q12, q0, q8
582    vadd.s16            q13, q0, q9
583    vadd.s16            q14, q0, q10
584    vadd.s16            q15, q0, q11
585    vqmovun.s16         d0, q12
586    vqmovun.s16         d1, q13
587    vadd.s16            q12, q2, q8
588    vadd.s16            q13, q2, q9
589    vqmovun.s16         d2, q14
590    vqmovun.s16         d3, q15
591    vadd.s16            q14, q2, q10
592    vadd.s16            q15, q2, q11
593    vst1.64             {d0-d3}, [r0], r1
594    vqmovun.s16         d24, q12
595    vqmovun.s16         d25, q13
596    vqmovun.s16         d26, q14
597    vqmovun.s16         d27, q15
598    vdup.16             q0, d7[2]
599    vdup.16             q2, d7[3]
600    vst1.64             {d24-d27}, [r0], r1
601
602    ; Process two rows.
603    vadd.s16            q12, q0, q8
604    vadd.s16            q13, q0, q9
605    vadd.s16            q14, q0, q10
606    vadd.s16            q15, q0, q11
607    vqmovun.s16         d0, q12
608    vqmovun.s16         d1, q13
609    vadd.s16            q12, q2, q8
610    vadd.s16            q13, q2, q9
611    vqmovun.s16         d2, q14
612    vqmovun.s16         d3, q15
613    vadd.s16            q14, q2, q10
614    vadd.s16            q15, q2, q11
615    vst1.64             {d0-d3}, [r0], r1
616    vqmovun.s16         d24, q12
617    vqmovun.s16         d25, q13
618    vld1.8              {d0}, [r3]!                   ; preload 8 left pixels
619    vqmovun.s16         d26, q14
620    vqmovun.s16         d27, q15
621    vmovl.u8            q3, d0
622    vst1.64             {d24-d27}, [r0], r1
623
624    subs                r2, r2, #1
625    bgt                 loop_32x32_neon
626
627    bx                  lr
628    ENDP                ; |vpx_tm_predictor_32x32_neon|
629
630    END
631